Группы повторяющихся элементов

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

Важно, чтобы группы были каким-то образом разделены.

shooqie
источник
Может быть, мы выводим список, который имеет какое-то специальное значение разделителя?
xnor
@xnor: Можете ли вы привести пример? Массив ints, разделенный, например, 0s, был бы плохой идеей, поскольку 0во входных данных могут быть s ...
shooqie
Например, [4, 4, '', 2, 2, '', 9, 9]или [4, 4, [], 2, 2, [], 9, 9].
xnor
На самом деле, какие типы мы должны поддерживать. Могут ли сами элементы быть списками? Я предполагаю, что некоторые языки имеют встроенные типы, которые не могут быть напечатаны или имеют странную проверку на равенство.
xnor
@xnor: Да, это то, что меня беспокоило - если у вашего ввода есть списки внутри, то использование пустого списка в качестве разделителя может сбить с толку. Вот почему я включил «вы можете предполагать, что все элементы принадлежат к одному типу», поэтому в качестве разделителя можно использовать другой тип.
Shooqie

Ответы:

15

Mathematica, 5 байтов

Split

... есть встроенный для этого.

Мартин Эндер
источник
9
…какой сюрприз!
Фатализировать
11
@Fatalize Настоящий сюрприз в том, насколько он короткий.
Мартин Эндер
8

Сетчатка , 15 8 байт

Спасибо Линн за предложение более простого формата ввода / вывода.

!`(.)\1*

Обрабатывает ввод как список символов (и использует перевод строки для разделения групп).

Попробуйте онлайн!

Это просто работает путем сопоставления групп и печати их всех (при этом автоматически используется разделение строк).

Мартин Эндер
источник
Я спросил о abbcccddda bb ccc dddбыть приемлемый формат ввода / вывода, и ОП одобрил, так что я думаю , !`(.)\1*это хорошо?
Линн
@ Линн О, это действительно намного проще, спасибо.
Мартин Эндер
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]].

Fatalize
источник
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

Дьялог АПЛ , 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исключается разделитель перед первым элементом.

XNOR
источник
Жаль, 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

Haskell, 22 байта

import Data.List
group

Там есть встроенный. Работает на любом типе, который поддерживает равенство.

XNOR
источник
2
Любая причина, почему это вики сообщества?
Фатализировать
1
Это благородно, но так как никто больше не делает этого, почему бы тебе не спросить об этом на мета?
Фатализировать
2

MATL, 8 7 байт

Удалено 1 байт благодаря @Suever

ly&Y'Y{

Работает с целыми числами / числами с плавающей запятой / символами / логическими значениями / точками единорога / другими мнимыми входами.
Для логических значений входы есть 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)));
    }
downrep_nation
источник
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
busukxuan
источник
Это 7 байтов
Leaky Nun
@ LeakyNun О, верно! Это классно.
Busukxuan
1
Я считаю, что это работает для 6.
FryAmTheEggman
@FryAmTheEggman Хорошее злоупотребление m.
Дрянная Монахиня
@FryAmTheEggman Wow, я не понимаю oO
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)
Arfie
источник
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.

Попробуйте онлайн

Emigna
источник
1

Swift, 43 байта

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

Предполагается, что я являюсь массивом уравниваемых объектов; работает для всего: от целых до строк и пользовательских объектов. Отчасти дерзкий в том, что вывод содержит много новых строк, но создание этого красивее будет стоить байтов.

Более симпатичная, негольфированная версия:

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 байтов, но это другой подход, так что, может быть, там есть что оптимизировать? Самая большая проблема - это обратное утверждение.

juliand665
источник
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
Рохан Джхунджхунвала
1

ListSharp , 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 файл

downrep_nation
источник
1

Рубин , 24 байта

В Arrayинстансах ruby есть встроенный методgroup_by

Таким образом, решение будет:

a.group_by{|x| x}.values
Фархат Михалко
источник
0

TSQL, 132 байта

Это немного отличается от других ответов - sql не имеет массивов, очевидным вводом для sql является таблица.

Golfed:

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)

Ungolfed:

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)

скрипка

t-clausen.dk
источник
0

Perl 5 - 39 байт

print$_.($/)[$_ eq@a[++$-]]for@a=sort@a
Kaundur
источник
0

Пайк, 2 байта (неконкурентный)

Поддерживает только целые числа

$f

Попробуй это здесь!

split_at(input, delta(input))

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

синий
источник
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
Marco
источник
0

JavaScript (ES6), 56

Ввод: массив чисел или строк

Вывод: массив массивов

Впервые использую точное сравнение в гольф-коде

a=>a.map(x=>x!==p?o.push(g=[p=x]):g.push(x),p=o=g=[])&&o
edc65
источник
0

Clojure, 19 байт

#(partition-by + %)

Это встроенная функция, но она требует функции отображения. В этом случае +выполняет функцию идентичности.

MattPutnam
источник
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. Это не помогло мне победить, ну да ладно

Образ

Image2

applejacks01
источник