Grupy powtarzających się pozycji

10

Opis wyzwania

Biorąc pod uwagę listę / tablicę elementów, wyświetl wszystkie grupy kolejnych powtarzających się elementów.

Opis wejścia / wyjścia

Twoje dane wejściowe to lista / tablica elementów (możesz założyć, że wszystkie są tego samego typu). Nie musisz obsługiwać każdego typu, który ma Twój język, ale musi obsługiwać co najmniej jeden (najlepiej int, ale typy takie boolean, choć niezbyt interesujące, są również w porządku). Przykładowe wyniki:

[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]]

Jeśli chodzi o puste listy, wynik jest niezdefiniowany - może to być nic, pusta lista lub wyjątek - cokolwiek najbardziej odpowiada twoim celom golfowym. Nie musisz też tworzyć osobnej listy list, więc jest to również całkowicie poprawny wynik:

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

1 1 1
2 2
3 3 3
4
9

Ważne jest, aby grupy były w jakiś sposób rozdzielone.

shooqie
źródło
Może wypisujemy listę, która ma jakąś specjalną wartość separatora?
xnor
@xnor: Czy możesz podać przykład? Tablica ints rozdzielone, na przykład, 0że ów zły pomysł, ponieważ nie może być 0ów w wejściu ...
shooqie
Na przykład [4, 4, '', 2, 2, '', 9, 9]lub [4, 4, [], 2, 2, [], 9, 9].
xnor
W rzeczywistości jakie typy musimy wspierać. Czy same elementy mogą być listami? Wyobrażam sobie, że niektóre języki mają wbudowane typy, które nie mogą być drukowane lub mają dziwne sprawdzanie równości.
xnor
@ xnor: Tak, właśnie o to mi chodziło - jeśli twoje dane wejściowe mają w sobie listy, to użycie pustej listy jako separatora może być mylące. Dlatego dołączyłem „możesz założyć, że wszystkie elementy są tego samego typu”, aby można było użyć innego typu jako separatora.
shooqie,

Odpowiedzi:

15

Mathematica, 5 bajtów

Split

... jest do tego wbudowany.

Martin Ender
źródło
9
…co za niespodzianka!
Fatalize
11
@Fatalize Prawdziwą niespodzianką jest to, jak krótki jest.
Martin Ender
8

Siatkówka , 15 8 bajtów

Dzięki Lynn za zaproponowanie prostszego formatu We / Wy.

!`(.)\1*

Traktuje dane wejściowe jako listę znaków (i używa linii do oddzielenia grup).

Wypróbuj online!

Działa to po prostu poprzez dopasowanie grup i wydrukowanie ich wszystkich (co automatycznie wykorzystuje separację linii).

Martin Ender
źródło
Zapytałem o to, czy abbcccddda bb ccc dddjest akceptowalnym formatem We / Wy, a OP go zaakceptował, więc myślę, że !`(.)\1*jest w porządku?
Lynn,
@ Lynn Och, to naprawdę o wiele prostsze, dzięki.
Martin Ender
4

JavaScript (ES6), 39 37 bajtów

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

Działa na dowolnych tokenach typu słowo oddzielonych spacją. Zaoszczędź 2 bajty dzięki @ MartinEnder ♦. Najlepsze, co mogę zrobić dla danych wejściowych i zwracanych z tablicy, to 68:

a=>a.reduce((l,r)=>(l==r?c.push(r):b.push(c=[r]),r),b=[c=[a[0]]])&&b
Neil
źródło
1
Dodałem odpowiedź tablicową o 56
edc65
4

MATL , 9 bajtów

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

Dane wejściowe to tablica wierszy liczb , ze spacjami lub przecinkami jako separatorami.

Wypróbuj online! Testuj na liczbach niecałkowitych .


MATL, 11 bajtów

lidgvYsG7XQ

Dane wejściowe to tablica kolumn zawierająca liczby lub znaki , używana ;jako separator.

Wypróbuj online! Testuj z dowolnymi liczbami . Testuj ze znakami .

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
Luis Mendo
źródło
3

gs2, 2 bajty

c-

Wypróbuj online!

cjest wbudowanym grupowaniem, które robi to dokładnie, więc wywołujemy go na STDIN (który jest łańcuchem, tj. listą znaków) i otrzymujemy listę łańcuchów. Niestety wynik jest nie do odróżnienia od danych wejściowych, dlatego musimy dodać separatory! -(łączenie spacjami) załatwia sprawę.

Alternatywną odpowiedzią jest (2 bajty CP437), która po prostu pakuje csię w anonimową funkcję.

Lynn
źródło
2

Brachylog , 13 bajtów

:{s.dl1}fs.c?

Ostrzeżenie: jest to wyjątkowo nieefektywne i zrozumiesz dlaczego w wyjaśnieniu.

Oczekuje to listy (np. [1:1:2:2:2]) Jako danych wejściowych. Elementy na liście mogą być prawie wszystkim.

Wyjaśnienie

:{     }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

Działa to tylko ze względu na sposób s - Subsetujednolicenia: najmniejsze zestawy znajdują się na końcu. Dlatego pierwszą rzeczą, która stwierdza, że ​​konkatenaty do danych wejściowych są najdłuższe przebiegi, np. [[1:1]:[2:2:2]]I nie na przykład [[1:1]:[2:2]:[2]].

Fatalizować
źródło
2

J , 13 bajtów

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

Ponieważ J nie obsługuje tablic obdartych, każdy ciąg równych elementów jest zapakowany. Dane wejściowe to tablica wartości, a dane wyjściowe to tablica tablic pudełkowych.

Stosowanie

   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│
└─┘

Wyjaśnienie

<;.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
mile
źródło
2

Dyalog APL , 9 bajtów

⊢⊂⍨1,2≠/⊢

argument
⊂⍨podzielony na
1pierwszy element,
,a następnie
2≠/tam, gdzie kolejne pary różnią
się argumentem

Adám
źródło
2

Python 2, 43 bajty

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

Działa na listach booleanów. Przykład:

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

Iteruje przez listę wejściową, przechowując ostatnio widziany element. Pasek separatora jest drukowany przed każdym elementem innym niż poprzedni, sprawdzany jako mający xor bitowy równy ^0. Inicjalizacja p=-1pozwala uniknąć separatora przed pierwszym elementem.

xnor
źródło
Szkoda, że groupbytaki ból ...
Sp3000,
2

CJam, 9 bajtów

Dwa rozwiązania:

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

Sprawdź to tutaj.

Wyjaśnienie

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.

Lub

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.
}%
Martin Ender
źródło
2

Haskell, 22 bajty

import Data.List
group

Jest wbudowany. Działa na każdym typie, który obsługuje równość.

xnor
źródło
2
Jest jakiś powód, dla którego jest to wiki społeczności?
Fatalize
1
To szlachetne, ale skoro nikt inny tego nie robi, dlaczego nie pytasz o to na Meta?
Fatalize
2

MATL, 8 7 bajtów

Usunięto 1 bajt dzięki @Suever

ly&Y'Y{

Współpracuje z liczbami całkowitymi / zmiennoprzecinkowymi / znakami / booleanami / punktami jednorożca / innymi wymyślonymi danymi wejściowymi.
W przypadku wartości logicznych dane wejściowe są T/F, dane wyjściowe są 1/0.

Wypróbuj online!


Zgrupowane i powtarzane

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
zlewka
źródło
1

C #, 117 bajtów

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)));}

bez golfa (niezupełnie)

    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
źródło
1

Pyth, 9 7 bajtów

mr9]dr8

Kredyt @LeakyNun na 2 bajty!

Wyjaśnienie:

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

Stara odpowiedź, 12 bajtów

hf.Am!t{dT./

Zapomniałem o wbudowanej długości przebiegu, ale myślę, że jest to dobre podejście, więc je zachowałem.

Wyjaśnienie:

                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
źródło
To jest 7 bajtów
Leaky Nun
@LeakyNun O racja! To super.
busukxuan
1
Wierzę, że to działa na 6.
FryAmTheEggman
@FryAmTheEggman Nice nadużycie m.
Leaky Nun
@FryAmTheEggman Wow, nie rozumiem oO
busukxuan
1

Pyt , 36 35 bajtów

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

Link testowy

Edycja: wyjaśnienie:

                                      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
źródło
1

Siatkówka , 24 22 bajtów

2 bajty dzięki Martinowi Enderowi.

15-bajtowy odpowiedź już istnieje, więc jest to po prostu inne podejście, które kosztuje więcej bajtów.

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

Wypróbuj online!

Dzieli się na spacje, których poprzedni numer różni się od postępowania.

To demonstracja spojrzeń.

Leaky Nun
źródło
1

05AB1E, 13 bajtów

¬svyÊi¶}yðJ?y

Wyjaśnione

¬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

Powinien działać na dowolnej liście.
Testowane na int i char.

Wypróbuj online

Emigna
źródło
1

Szybki, 43 bajty

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

Zakłada, że ​​i jest tablicą równych obiektów; działa na wszystko od ints do ciągów znaków do niestandardowych obiektów. W pewnym sensie bezczelny, ponieważ dane wyjściowe zawierają wiele nowych wierszy, ale sprawienie, że ładniejszy kosztowałoby bajty.

Ładniejsza, nie golfowa wersja:

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
}

Ta wersja drukuje każdą grupę w nowym wierszu kosztem więcej kodu.

Pomysły na ulepszenia

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

Ta wersja ma 47 bajtów, ale to inne podejście, więc może jest coś, co można zoptymalizować? Największym problemem jest instrukcja return.

juliand665
źródło
1

C, 88 77 bajtów

Przeniesiono do strmcmp wewnątrz printf zapisywanie 11 bajtów

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

Stosowanie:

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);}

Przykładowe dane wejściowe:

(Parametry wiersza polecenia)

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

Przykładowe dane wyjściowe:

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

Testowane na:

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

Próbuję naprawić błąd segmentacji 5.3.0.

88 Wersja

f(char**a){*a++;char*x;for(;*a;x=*a++)strcmp(*a,x)?printf("\n%s ",*a):printf("%s ",*a);}
Giacomo Garabello
źródło
1

Java 134 bajty

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]);}

iteruje i decyduje, czy oddzielić nową linią, czy spacją.

Rohan Jhunjhunwala
źródło
na początek możesz usunąć publici staticsłowa kluczowe. można również usunąć nawiasy klamrowe w pętli for
user902383
Sporządzono @ user902383
Rohan Jhunjhunwala w
1

ListSharp , 134 bajty

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 nie obsługuje funkcji, więc tablica jest zapisywana w lokalnym pliku o nazwie l.txt plik

downrep_nation
źródło
1

Rubinowy , 24 bajty

W Arrayinstancjach ruby ma wbudowaną metodęgroup_by

Tak więc rozwiązaniem będzie:

a.group_by{|x| x}.values
Farkhat Mikhalko
źródło
0

TSQL, 132 bajty

To trochę różni się od innych odpowiedzi - sql nie ma tablic, oczywistym wejściem dla sql jest tabela.

Gra w golfa:

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)

Nie golfowany:

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)

Skrzypce

t-clausen.dk
źródło
0

Perl 5 - 39 bajtów

print$_.($/)[$_ eq@a[++$-]]for@a=sort@a
Kaundur
źródło
0

Pyke, 2 bajty (niekonkurencyjny)

Obsługuje tylko liczby całkowite

$f

Wypróbuj tutaj!

split_at(input, delta(input))

Dodano węzeł split_at, dzieli dane wejściowe, gdy 2. argument jest prawdziwy

niebieski
źródło
0

sed, 33 23 + 1 = 24 bajty

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

Potrzebuje -ropcji.

Przykład użycia:

$ 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
źródło
0

JavaScript (ES6), 56

Dane wejściowe: tablica liczb lub ciągów znaków

Dane wyjściowe: tablica tablic

Po raz pierwszy użyłem dokładnego porównania w kodzie golfowym

a=>a.map(x=>x!==p?o.push(g=[p=x]):g.push(x),p=o=g=[])&&o
edc65
źródło
0

Clojure, 19 bajtów

#(partition-by + %)

Jest wbudowany, ale wymaga funkcji mapowania. W tym przypadku +służy jako funkcja tożsamości.

MattPutnam
źródło
0

JavaScript (przy użyciu zewnętrznej biblioteki) (178 bajtów)

(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:[]})

Oświadczenie: Używam biblioteki, którą napisałem, aby zaimplementować LINQ z C # do JS. Nie pomogło mi to wygrać, ale no cóż

Wizerunek

Zdjęcie 2

applejacks01
źródło