Групи повторюваних предметів


10

Опис виклику

Дано список / масив елементів, відобразити всі групи послідовно повторюваних елементів.

Опис вводу / виводу

Ваш вхід - це список / масив елементів (ви можете припустити, що всі вони одного типу). Вам не потрібно підтримувати кожен тип вашого мови, але він повинен підтримувати принаймні один (бажано int, але такі типи boolean, хоча і не дуже цікаві, теж чудові). Приклади виходів:

[4, 4, 2, 2, 9, 9] -> [[4, 4], [2, 2], [9, 9]]
[1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4] -> [[1, 1, 1], [2, 2], [3, 3, 3], [4, 4, 4, 4]]
[1, 1, 1, 3, 3, 1, 1, 2, 2, 2, 1, 1, 3] -> [[1, 1, 1], [3, 3], [1, 1], [2, 2, 2], [1, 1], [3]]
[9, 7, 8, 6, 5] -> [[9], [7], [8], [6], [5]]
[5, 5, 5] -> [[5, 5, 5]]
['A', 'B', 'B', 'B', 'C', 'D', 'X', 'Y', 'Y', 'Z'] -> [['A'], ['B', 'B', 'B'], ['C'], ['D'], ['X'], ['Y', 'Y'], ['Z']]
[True, True, True, False, False, True, False, False, True, True, True] -> [[True, True, True], [False, False], [True], [False, False], [True, True, True]]
[0] -> [[0]]

Щодо порожніх списків, вихід не визначений - це може бути нічого, порожній список чи виняток - все, що найкраще підходить для ваших цілей гольфу. Вам також не доведеться створювати окремий список списків, тому це також ідеально правильний вихід:

[1, 1, 1, 2, 2, 3, 3, 3, 4, 9] ->

1 1 1
2 2
3 3 3
4
9

Важливо - якось тримати групи розділеними.


Може, ми виводимо список, який має якесь особливе значення роздільника?
xnor

@xnor: Ви можете навести приклад? Масив ints, розділений, наприклад, 0s, було б поганою ідеєю, оскільки 0у вході може бути s
shooqie

Наприклад, [4, 4, '', 2, 2, '', 9, 9]або [4, 4, [], 2, 2, [], 9, 9].
xnor

Власне, які типи ми маємо підтримувати. Чи можуть самі елементи бути списками? Я думаю, що деякі мови мають вбудовані типи, які не можуть бути надруковані або мають дивну перевірку рівності.
xnor

@xnor: Так, це мене викликало занепокоєння - якщо ваше введення має списки всередині нього, то використання порожнього списку як роздільника може бути заплутаним. Ось чому я включив "Ви можете припустити, що всі елементи одного типу", щоб можна було використовувати інший тип як роздільник.
shooqie

Відповіді:




8

Сітківка , 15 8 байт

Дякуємо Lynn, що запропонувала простіший формат вводу / виводу.

!`(.)\1*

Розглядає дані як список символів (і використовує стрічкові канали для окремих груп).

Спробуйте в Інтернеті!

Це просто працює, поєднуючи групи та роздруковуючи їх усі (що автоматично використовує розділення каналів).


Я запитав про abbcccddda bb ccc dddбути прийнятний формат вводу / виводу, і ОП схвалив, так що я думаю , !`(.)\1*це добре?
Лінн

@Lynn О, це дійсно набагато простіше, дякую.
Мартін Ендер

4

JavaScript (ES6), 39 37 байт

f=
s=>s.replace(/(\w+) (?!\1\b)/g,`$1
`)
;
<input oninput=o.textContent=f(this.value);><pre id=o>

Працює на будь-яких словоподібних жетонах. Збережено 2 байти завдяки @ MartinEnder ♦ Найкраще, що я міг зробити для введення та повернення масиву, це 68:

a=>a.reduce((l,r)=>(l==r?c.push(r):b.push(c=[r]),r),b=[c=[a[0]]])&&b

1
Я додав відповідь на масив у 56
edc65

4

MATL , 9 байт

Y'v"@Z}Y"

Y'     % Take input. Run-length encoding. Gives two row arrays: values and run lengths
v      % Concatenate vertically   
"      % For each column
  @Z}  %   Push column and split into its two elements
  Y"   %   Run-length decoding
       % End for. Implicitly display

Введення - це рядковий масив чисел з пробілами чи комами як роздільники.

Спробуйте в Інтернеті! Тест з не цілими числами .


MATL, 11 байт

lidgvYsG7XQ

Введення - це масив стовпців або чисел, і символів , який використовується ;як роздільник.

Спробуйте в Інтернеті! Тест з довільними числами . Тест з символами .

l     % Push 1
i     % Take input, say [4;4;2;2;9;9]
d     % Consecutive differences of input: [0;-2;0;7;0]
g     % Convert to logical: gives 1 if consecutive entries were different: [0;1;0;1;0]
v     % Concatenate vertically with the initial 1: [1;0;1;0;1;0]
Ys    % Cumulative sum. Each value is a group label: [1;1;2;2;3;3]
G     % Push input again
7XQ   % Split into horizontal arrays as indicated by group labels: {[4 4];[2 2];[9 9]}
      % Implicitly display

3

gs2, 2 байти

c-

Спробуйте в Інтернеті!

cце вбудована група, яка робить саме це, тому ми називаємо це на STDIN (це рядок, тобто список знаків) і отримуємо список рядків. На жаль, результат не відрізняється від вхідних даних, тому нам потрібно додати роздільники! -(об'єднайте пробіли) робить трюк.

Альтернативна відповідь - (2 байти CP437), яка просто cперетворюється на анонімну функцію.


2

Брахілог , 13 байт

:{s.dl1}fs.c?

Попередження: це вкрай неефективно, і ви зрозумієте, чому в поясненні.

Тут очікується список (наприклад [1:1:2:2:2]) як вхідний. Елементів у списку може бути майже все, що завгодно.

Пояснення

:{     }f       Find all ordered subsets of the Input with a unique element in them
  s.                Output is a subset of the input
    dl1             Output minus all duplicates has a length of 1 (i.e. one unique value)
         s.     Output is an ordered subset of those subsets
           c?   The concatenation of those subsets is the Input

Це працює лише через те, як s - Subsetуніфікується: найменші набори знаходяться в кінці. Тому перше, що з’ясовується, що зв'язування з входом - це найдовші пробіги, наприклад, [[1:1]:[2:2:2]]а не, наприклад [[1:1]:[2:2]:[2]].


2

J , 13 байт

<;.1~1,2~:/\]

Оскільки J не підтримує нерівні масиви, кожен запуск рівних елементів розміщується у вікні. Вхід - це масив значень, а вихід - масив коробкових масивів.

Використання

   f =: <;.1~1,2~:/\]
   f 4 4 2 2 9 9
┌───┬───┬───┐
│4 4│2 2│9 9│
└───┴───┴───┘
   f 1 1 1 3 3 1 1 2 2 2 1 1 3
┌─────┬───┬───┬─────┬───┬─┐
│1 1 1│3 3│1 1│2 2 2│1 1│3│
└─────┴───┴───┴─────┴───┴─┘
   f 'ABBBCDXYYZ'
┌─┬───┬─┬─┬─┬──┬─┐
│A│BBB│C│D│X│YY│Z│
└─┴───┴─┴─┴─┴──┴─┘
   f 0
┌─┐
│0│
└─┘

Пояснення

<;.1~1,2~:/\]  Input: s
            ]  Identify function to get s
       2       The constant 2
           \   Operate on each overlapping sublist of size 2
        ~:/      Are the two values unequal, 1 if true else 0
     1,        Prepend a 1 to it
<;.1~          Using the list just made, chop s at each index equal to 1 and box it
               Return this as the result

2

Діалог APL , 9 байт

⊢⊂⍨1,2≠/⊢

аргумент,
⊂⍨розділений на
1перший елемент,
,а потім,
2≠/де наступні пари відрізняються
аргументом


2

Python 2, 43 байти

p=-1
for x in input():print"|"[:x^p],x,;p=x

Працює за списками булів. Приклад:

>> [True,True,False,False,False,True,False,True,False]
 True  True | False  False  False | True | False | True | False

Ітератується через вхідний список, зберігаючи останній бачений елемент. Перед кожним елементом, який відрізняється від попереднього, друкується панель роздільника, перевіряється як бітовий xor ^0. Ініціалізація p=-1дозволяє уникнути поділу перед першим елементом.


Шкода groupby, такий біль ...
Sp3000

2

CJam, 9 байт

Два рішення:

{e`:a:e~}
{e`{(*}%}

Тестуйте це тут.

Пояснення

e`   e# Run-length encode (gives a list of pairs [run-length value]).
:a   e# Wrap each pair in a singleton list.
:e~  e# Run-length decode each list.

Або

e`   e# Run-length encode.
{    e# Map this block over each pair...
  (  e#   Pull out the run length.
  *  e#   Repeat the list containing only the value that many times.
}%

2

Хаскелл, 22 байти

import Data.List
group

Там є вбудований. Працює на будь-якому типі, що підтримує рівність.


2
Будь-яка причина, чому це вікі спільноти?
Фаталізувати


1
Це благородно, але оскільки ніхто інший цього не робить, чому б ви не запитали про це на мета?
Фаталізувати

2

MATL, 8 7 байт

Видалено 1 байт завдяки @Suever

ly&Y'Y{

Працює з цілими числами / floats / символами / booleans / єдинорогами / іншими уявними входами.
Для булевих входів є T/F, входи є 1/0.

Спробуйте в Інтернеті!


Групуються та повторюються

ly&Y'Y{
l          % push 1 onto the stack
 y         % duplicate the input
  &Y'      % run-length encoding (secondary output only)
     Y{    % break up array into cell array of subarrays

1

C #, 117 байт

void f(List<String>m){Console.Write(m[0]+String.Join("",m.GetRange(1,m.Count()-1).Select((i,j)=>i==m[j]?i:"\n"+i)));}

неозорий (не дуже)

    public static void f(List<String>m)
    {
        Console.Write(m[0]+String.Join("",m.GetRange(1,m.Count()-1).Select((i,j)=>i==m[j]?i:"\n"+i)));
    }

1

Pyth, 9 7 байт

mr9]dr8

Кредит на @LeakyNun за 2 байти!

Пояснення:

             input
     r8      run-length decode
m            for each...
   ]d        ...treat each run as standalone encoded form...
 r9          ...decode 
             print

Стара відповідь, 12 байт

hf.Am!t{dT./

Забув про вбудовану довжину пробігу, але я думаю, що це нормальний підхід, тому я його дотримав.

Пояснення:

                input
          ./    all possible partitions
 f       T      filter by...
  .A            ...whether all groups of integers...
    m!t{d       ...have length one after deduplication
h               get the first element (first one has no adjacent [1,1] and [1])
                print

Це 7 байт
Leaky Nun

@LeakyNun О так! Круто.
busukxuan

1
Я вважаю, що це працює для 6.
FryAmTheEggman

@FryAmTheEggman Приємне зловживання m.
Leaky Nun

@FryAmTheEggman Нічого собі, я не розумію о
busukxuan

1

Pyth , 36 35 байт

VQIqNk=hZ).?=+Y]*]kZ=Z1=kN;t+Y]*]kZ

Тест-посилання

Редагувати: пояснення:

                                      standard variables: Y=[], Z=0, k='', Q=input
VQ                                    iterate over input
  IqNk                                if the current entity is equal to k:
      =hZ)                            increase Z.
          .?                          else:
               ]*]kZ                  list of length Z filled with k
            =+Y                       add it to Y
                    =Z1               set Z to 1
                       =kN            set k to the current entity
                          ;           end loop
                              ]*]kZ   list of length Z filled with k
                            +Y        add it to Y
                           t          implicitly print the tail of Y (removing the first element)

1

Сітківка , 24 22 байти

2 байти завдяки Мартіну Ендеру.

Відповідь на 15 байтів вже існує, тому це лише інший підхід, який коштує більше байтів.

S-`(?<=(\d+)) (?!\1\b)

Спробуйте в Інтернеті!

Він розділяється на пробіли, попереднє число яких відрізняється від вихідних.

Це демонстрація краєвидів.


1

05AB1E, 13 байт

¬svyÊi¶}yðJ?y

Пояснив

¬s             # push first element of list to stack and swap with input
  v            # for each X in input
   yÊi¶}       # if X is different from last iteration, push a newline
        yðJ?   # push X followed by a space to stack and join stack to string
            y  # push X to stack for next iterations comparison

Має працювати для будь-якого списку.
Випробуваний на int та char.

Спробуйте в Інтернеті


1

Свіфт, 43 байти

var p=0;i.map{print($0==p ?"":",",$0);p=$0}

Передбачає, що я є масивом вирівнюваних об'єктів; працює для всього, від ints до рядків до спеціальних об'єктів. Нахабний у тому, що вихід містить багато нових рядків, але зробити це гарнішим буде коштувати байтів.

Гарніша, неозорима версія:

var prev = Int.max // unlikely to be the first element, but not the end of the world if it happens to be.
i.map { n in
    print(n == prev ? " " : "\n•", n, terminator: "")
    prev = n
}

Ця версія друкує кожну групу в новому рядку за рахунок більшого коду.

Ідеї ​​для вдосконалення

i.reduce(0){print($0==$1 ?"":"•",$1);return $1}

Ця версія має 47 байт, але це інший підхід, тож, можливо, є що оптимізувати там? Найбільша проблема - декларація про повернення.


1

C, 88 77 байт

Переміщено strmcmp всередину printf економії 11 байт

f(char**a){*a++;char*x;for(;*a;x=*a++)printf(strcmp(*a,x)?"\n%s ":"%s ",*a);}

Використання:

f(char**a){*a++;char*x;for(;*a;x=*a++)printf(strcmp(*a,x)?"\n%s ":"%s ",*a);}
main(c,v)char**v;{f(v);}

Зразок введення:

(параметри командного рядка)

1 1 1 1 2 2 2 2 3 3 3 3 4 5 6 7777

Вибірка зразка:

1 1 1 1
2 2 2 2
3 3 3 3
4
5
6
7777

Тестовано на:

gcc 4.4.7 (Red Hat 4.4.7-16)  - OK
gcc 5.3.0 (Cygwin)            - Segmetation Fault
gcc 4.8.1 (Windows)           - OK

Я намагаюся виправити помилку сегментації 5.3.0.

88 Версія

f(char**a){*a++;char*x;for(;*a;x=*a++)strcmp(*a,x)?printf("\n%s ",*a):printf("%s ",*a);}

1

Java 134 байт

void a(String[]a){int i=0,l=a.length;for(;i<l-1;i++)System.out.print(a[i]+((a[i].equals(a[i+1]))?" ":"\n"));System.out.print(a[l-1]);}

повторюється і вирішує, розділяти нову лінію чи пробіл.


для початку ви могли видалити publicі staticключові слова. також ви можете зняти фігурні дужки для циклу
user902383

Готово @ user902383
Rohan Jhunjhunwala

1

СписокШорп , 134 байти

STRG l = READ[<here>+"\\l.txt"]
[FOREACH NUMB IN 1 TO l LENGTH-1 AS i]
{
[IF l[i] ISNOT l[i-1]]
STRG o=o+"\n"
STRG o=o+l[i]
}
SHOW = o

ListSharp не підтримує функції, тому масив зберігається у локальному файлі, який називається l.txt файл



0

TSQL, 132 байти

Це трохи відрізняється від інших відповідей - у sql немає масивів, очевидним входом для sql є таблиця.

Гольф:

DECLARE @ table(i int identity, v varchar(20))
INSERT @ values(1),(1),(1),(3),(3),(1),(1),(2),(2),(2),(1),(1),(3)

SELECT REPLICATE(v+' ',COUNT(*))FROM(SELECT i,i-row_number()over(partition
by v order by i)x,v FROM @)z GROUP BY x,v ORDER BY max(i)

Безголівки:

DECLARE @ table(i int identity, v varchar(20))
INSERT @ values(1),(1),(1),(3),(3),(1),(1),(2),(2),(2),(1),(1),(3)

SELECT
  REPLICATE(v+' ',COUNT(*))
FROM 
  (
     SELECT
       i,
       i-row_number()over(partition by v order by i)x,
       v
     FROM @
  )z
GROUP BY
  x,v
ORDER BY
  max(i)

Скрипка



0

Пайк, 2 байти (не конкурентоспроможний)

Підтримує лише цілі числа

$f

Спробуйте тут!

split_at(input, delta(input))

Доданий вузол split_at, розбиває введення, коли другий аргумент є правдою


0

sed, 33 23 + 1 = 24 байти

s/([^ ]+)( \1)* */&\n/g

Для цього потрібен -rваріант.

Приклад використання:

$ echo '1 1 1 2 2 3 3 3 4 9 9' | sed -r 's/([^ ]+)( \1)* */&\n/g'
1 1 1 
2 2 
3 3 3 
4 
9 9

0

JavaScript (ES6), 56

Введення: масив чисел або рядків

Вихід: масив масивів

Перший раз, коли використовується точне порівняння у коді для гольфу

a=>a.map(x=>x!==p?o.push(g=[p=x]):g.push(x),p=o=g=[])&&o

0

Clojure, 19 байт

#(partition-by + %)

Це вбудований, але він займає функцію відображення. У цьому випадку +виконує функцію ідентичності.


0

Javascript (за допомогою зовнішньої бібліотеки) (178 байт)

(s)=>_.From(s).Aggregate((t,e)=>{if(0===t.Items.length)return t.Items.push([e]),t;var s=t.Items[t.Items.length-1];return s[0]===e?(s.push(e),t):(t.Items.push([e]),t)},{Items:[]})

Відмова: Я використовую бібліотеку, яку я написав для реалізації LINQ з C # в JS. Це не зовсім допомогло мені виграти, але о добре

Зображення

Зображення2

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.