Gruppi di elementi ripetuti


10

Descrizione della sfida

Dato un elenco / matrice di elementi, visualizza tutti i gruppi di elementi consecutivi ripetuti.

Descrizione input / output

Il tuo input è un elenco / matrice di elementi (puoi presumere che siano tutti dello stesso tipo). Non è necessario supportare ogni tipo di linguaggio, ma deve supportarne almeno uno (preferibilmente int, ma anche tipi come boolean, sebbene non molto interessanti, vanno bene). Output di esempio:

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

Per quanto riguarda gli elenchi vuoti, l'output non è definito - può essere nulla, un elenco vuoto o un'eccezione - qualunque cosa si adatti meglio ai tuoi scopi di golf. Non è necessario creare un elenco separato di elenchi, quindi anche questo è un risultato perfettamente valido:

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

1 1 1
2 2
3 3 3
4
9

L'importante è mantenere i gruppi separati in qualche modo.


Forse abbiamo prodotto un elenco con un valore di separazione speciale?
xnor

@xnor: puoi fornire un esempio? Un array di ints separati da, per esempio, 0s sarebbe una cattiva idea poiché ci possono essere 0s nell'input ...
shooqie

Ad esempio, [4, 4, '', 2, 2, '', 9, 9]oppure [4, 4, [], 2, 2, [], 9, 9].
xnor

In realtà, quali tipi dobbiamo supportare. Gli elementi stessi possono essere elenchi? Immagino che alcune lingue abbiano tipi incorporati che non possono essere stampati o che hanno uno strano controllo dell'uguaglianza.
xnor

@xnor: Sì, questo è ciò che mi preoccupava: se il tuo input contiene elenchi al suo interno, l'utilizzo di un elenco vuoto come separatore potrebbe creare confusione. Ecco perché ho incluso "puoi presumere che tutti gli elementi siano dello stesso tipo", in modo che possa utilizzare un tipo diverso come separatore.
shooqie,

Risposte:




8

Retina , 15 8 byte

Grazie a Lynn per aver suggerito un formato I / O più semplice.

!`(.)\1*

Tratta l'input come un elenco di caratteri (e utilizza gli avanzamenti di riga per separare i gruppi).

Provalo online!

Funziona semplicemente abbinando i gruppi e stampandoli tutti (che utilizza automaticamente la separazione dell'alimentazione di linea).


Ho chiesto abbcccddda bb ccc dddessere un formato I / O accettabile e l'OP lo ha approvato, quindi credo che vada !`(.)\1*bene?
Lynn,

@Lynn Oh, è davvero molto più semplice, grazie.
Martin Ender,

4

JavaScript (ES6), 39 37 byte

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

Funziona su qualsiasi token simile a una parola separato da spazi. Salvato 2 byte grazie a @ MartinEnder ♦. Il meglio che potrei fare per l'input dell'array e il ritorno è 68:

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

1
Ho aggiunto una risposta di matrice a 56
edc65

4

MATL , 9 byte

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

L'input è un array di numeri di righe , con spazi o virgole come separatori.

Provalo online! Test con numeri non interi .


MATL, 11 byte

lidgvYsG7XQ

L'input è una matrice di colonne di numeri o caratteri , usando; come separatore.

Provalo online! Prova con numeri arbitrari . Prova con i personaggi .

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 byte

c-

Provalo online!

cè un raggruppamento incorporato che fa esattamente questo, quindi lo chiamiamo su STDIN (che è una stringa, cioè un elenco di caratteri) e otteniamo un elenco di stringhe. Purtroppo, il risultato è indistinguibile dall'input, quindi è necessario aggiungere separatori! -(unisci per spazi) fa il trucco.

Una risposta alternativa è (2 byte di CP437), che si avvolge semplicemente cin una funzione anonima.


2

Brachylog , 13 byte

:{s.dl1}fs.c?

Attenzione: questo è estremamente inefficiente e capirai perché nella spiegazione.

Questo si aspetta un elenco (ad esempio [1:1:2:2:2]) come input. Gli elementi all'interno dell'elenco possono essere praticamente qualsiasi cosa.

Spiegazione

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

Funziona solo per il modo in cui s - Subsetunifica: i set più piccoli sono alla fine. Pertanto, la prima cosa che trova concatenati all'Input sono le corse più lunghe, ad esempio [[1:1]:[2:2:2]]e non ad esempio [[1:1]:[2:2]:[2]].


2

J , 13 byte

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

Poiché J non supporta matrici irregolari, ogni serie di elementi uguali è racchiusa in un riquadro. L'input è un array di valori e l'output è un array di array in box.

uso

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

Spiegazione

<;.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

Dyalog APL , 9 byte

⊢⊂⍨1,2≠/⊢

l'argomento
⊂⍨partizionato al
1primo elemento
,e quindi
2≠/dove le coppie successive differiscono
nell'argomento


2

Python 2, 43 byte

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

Funziona su elenchi di booleani. Esempio:

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

Scorre l'elenco di input, memorizzando l'ultimo elemento visualizzato. Prima di ogni elemento diverso da quello precedente, viene stampata una barra di separazione, verificata con xor bit a ^0 di 0. L'inizializzazione p=-1evita un separatore prima del primo elemento.


Peccato che groupbyun tale dolore ...
Sp3000

2

CJam, 9 byte

Due soluzioni:

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

Provalo qui.

Spiegazione

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.

O

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

MATL, 8 7 byte

Rimosso 1 byte grazie a @Suever

ly&Y'Y{

Funziona con numeri interi / float / caratteri / booleani / punti unicorno / altri input immaginari.
Per i booleani, gli input sono T/F, gli output sono 1/0.

Provalo online!


Raggruppati e ripetuti

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 byte

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

ungolfed (non proprio)

    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 byte

mr9]dr8

Ringraziamo @LeakyNun per 2 byte!

Spiegazione:

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

Vecchia risposta, 12 byte

hf.Am!t{dT./

Ho dimenticato la lunghezza della corsa integrata, ma penso che questo sia un approccio corretto, quindi l'ho tenuto.

Spiegazione:

                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

Questo è 7 byte
Leaky Nun

@LeakyNun Oh giusto! Questo è figo.
Busukxuan,

1
Credo che questo
funzioni

@FryAmTheEggman Bello abuso di m.
Leaky Nun,

@FryAmTheEggman Wow, non capisco oO
busukxuan

1

Pyth , 36 35 byte

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

Test link

Modifica: spiegazione:

                                      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

Retina , 24 22 byte

2 byte grazie a Martin Ender.

Una risposta 15 byte già esistente, quindi questo è solo un altro approccio che costa più byte.

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

Provalo online!

Si divide su spazi il cui numero precedente differisce dal procedimento.

Questa è una dimostrazione di soluzioni.


1

05AB1E, 13 byte

¬svyÊi¶}yðJ?y

spiegato

¬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

Dovrebbe funzionare per qualsiasi elenco.
Testato su int e char.

Provalo online


1

Rapido, 43 byte

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

Presuppone che i sia una matrice di oggetti equabili; funziona per qualsiasi cosa, dagli ints alle stringhe agli oggetti personalizzati. Un po 'sfacciato in quanto l'output contiene molte nuove righe, ma rendere quel più carino costerebbe byte.

Versione più carina, non golfata:

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
}

Questa versione stampa ogni gruppo su una nuova riga a spese di più codice.

Idee per il miglioramento

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

Questa versione ha 47 byte, ma è un approccio diverso, quindi forse c'è qualcosa da ottimizzare lì? Il problema più grande è la dichiarazione di ritorno.


1

C, 88 77 byte

Spostato strmcmp all'interno del printf salvataggio di 11 byte

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

Uso:

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

Input di esempio:

(parametri della riga di comando)

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

Uscita campione:

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

Testato su:

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

Sto cercando di correggere l'errore di segmentazione 5.3.0.

88 Versione

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

1

Java 134 byte

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

scorre attraverso e decide se separare con una nuova linea o uno spazio.


per cominciare potresti rimuovere publice staticparole chiave. puoi anche rimuovere le parentesi graffe per il ciclo
user902383

Fatto @utente902383
Rohan Jhunjhunwala il

1

ListSharp , 134 byte

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 non supporta le funzioni, quindi l'array viene salvato in un file locale chiamato l.txt file


1

Rubino , 24 byte

In ruby, le Arrayistanze hanno il metodo incorporatogroup_by

Quindi la soluzione sarà:

a.group_by{|x| x}.values

0

TSQL, 132 byte

Questo è un po 'diverso dalle altre risposte - sql non ha array, l'input ovvio per sql è una tabella.

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)

Violino


0

Perl 5 - 39 byte

print$_.($/)[$_ eq@a[++$-]]for@a=sort@a

0

Pyke, 2 byte (non competitivo)

Supporta solo numeri interi

$f

Provalo qui!

split_at(input, delta(input))

Aggiunto nodo split_at, divide l'input quando 2nd arg è veritiero


0

sed, 33 23 + 1 = 24 byte

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

Ha bisogno -rdell'opzione.

Esempio di utilizzo:

$ 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

Input: matrice di numeri o stringhe

Output: matrice di array

Prima volta in assoluto utilizzando il confronto esatto nel codice golf

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

0

Clojure, 19 byte

#(partition-by + %)

È integrato, ma richiede una funzione di mappatura. In questo caso, +funge da funzione di identità.


0

Javascript (utilizzando una libreria esterna) (178 byte)

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

Disclaimer: sto usando una libreria che ho scritto per implementare LINQ da C # in JS. Non mi ha aiutato esattamente a vincere, ma vabbè

Immagine

image2

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.