Grupos de artículos repetidos

10

Descripción del desafío

Dada una lista / matriz de elementos, muestra todos los grupos de elementos repetidos consecutivos.

Descripción de entrada / salida

Su entrada es una lista / matriz de elementos (puede suponer que todos son del mismo tipo). No necesita admitir todos los tipos que tiene su idioma, pero debe admitir al menos uno (preferiblemente int, pero tipos como boolean, aunque no muy interesantes, también están bien). Resultados de muestra:

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

En cuanto a las listas vacías, la salida no está definida, puede ser nada, una lista vacía o una excepción, lo que mejor se adapte a sus propósitos de golf. Tampoco tiene que crear una lista separada de listas, por lo que este también es un resultado perfectamente válido:

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

1 1 1
2 2
3 3 3
4
9

Lo importante es mantener a los grupos separados de alguna manera.

shooqie
fuente
¿Quizás sacamos una lista que tiene un valor separador especial?
xnor
@xnor: ¿Puedes dar un ejemplo? Una serie de ints por separado, por ejemplo, 0s sería una mala idea ya que no puede haber 0s en la entrada ...
shooqie
Por ejemplo, [4, 4, '', 2, 2, '', 9, 9]o [4, 4, [], 2, 2, [], 9, 9].
xnor
En realidad, qué tipos tenemos que soportar. ¿Pueden los elementos mismos ser listas? Me imagino que algunos idiomas tienen tipos incorporados que no se pueden imprimir o tienen una extraña verificación de igualdad.
xnor
@xnor: Sí, eso es lo que me preocupaba: si tu entrada tiene listas dentro, usar una lista vacía como separador puede ser confuso. Es por eso que incluí "puedes asumir que todos los artículos son del mismo tipo", para que puedas usar un tipo diferente como separador.
shooqie

Respuestas:

15

Mathematica, 5 bytes

Split

... hay un incorporado para eso.

Martin Ender
fuente
99
…¡qué sorpresa!
Fatalize
11
@Fatalize La verdadera sorpresa es lo corto que es.
Martin Ender
8

Retina , 15 8 bytes

Gracias a Lynn por sugerir un formato de E / S más simple.

!`(.)\1*

Trata la entrada como una lista de caracteres (y usa saltos de línea para separar grupos).

Pruébalo en línea!

Esto simplemente funciona haciendo coincidir grupos e imprimiéndolos todos (que usa la separación de salto de línea automáticamente).

Martin Ender
fuente
Le pregunté sobre abbcccddda bb ccc dddser un formato de E / S aceptable, y el OP lo aprobó, ¿así que supongo que !`(.)\1*está bien?
Lynn
@ Lynn Oh, eso es mucho más simple, gracias.
Martin Ender
4

JavaScript (ES6), 39 37 bytes

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

Funciona en cualquier token de palabras separadas por espacios. Guardado 2 bytes gracias a @ MartinEnder ♦. Lo mejor que puedo hacer para la entrada de matriz y el retorno es 68:

a=>a.reduce((l,r)=>(l==r?c.push(r):b.push(c=[r]),r),b=[c=[a[0]]])&&b
Neil
fuente
1
Agregué
4

MATL , 9 bytes

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

La entrada es una serie de filas de números , con espacios o comas como separadores.

Pruébalo en línea! Prueba con números no enteros .


MATL, 11 bytes

lidgvYsG7XQ

La entrada es una matriz de columnas de números o caracteres , que se usa ;como separador.

Pruébalo en línea! Prueba con números arbitrarios . Prueba con personajes .

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
fuente
3

gs2, 2 bytes

c-

Pruébalo en línea!

ces una agrupación integrada que hace exactamente esto, por lo que lo llamamos en STDIN (que es una cadena, es decir, una lista de caracteres) y obtenemos una lista de cadenas. Lamentablemente, el resultado es indistinguible de la entrada, por lo que debemos agregar separadores. -(unirse por espacios) hace el truco.

Una respuesta alternativa es (2 bytes de CP437), que simplemente se ajusta ca una función anónima.

Lynn
fuente
2

Brachylog , 13 bytes

:{s.dl1}fs.c?

Advertencia: esto es extremadamente ineficiente, y entenderá por qué en la explicación.

Esto espera una lista (por ejemplo [1:1:2:2:2]) como entrada. Los elementos dentro de la lista pueden ser prácticamente cualquier cosa.

Explicación

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

Esto funciona solo por la forma en que se s - Subsetunifica: los conjuntos más pequeños están al final. Por lo tanto, lo primero que encuentra que se concatena con la entrada son las ejecuciones más largas, por ejemplo, [[1:1]:[2:2:2]]y no por ejemplo [[1:1]:[2:2]:[2]].

Fatalizar
fuente
2

J , 13 bytes

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

Como J no admite matrices irregulares, cada ejecución de elementos iguales está encuadrada. La entrada es una matriz de valores y la salida es una matriz de matrices en caja.

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

Explicación

<;.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
millas
fuente
2

Dyalog APL , 9 bytes

⊢⊂⍨1,2≠/⊢

el argumento
⊂⍨particionado en
1el primer elemento
,y luego
2≠/donde los pares posteriores difieren
en el argumento

Adán
fuente
2

Python 2, 43 bytes

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

Funciona en listas de booleanos. Ejemplo:

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

Itera a través de la lista de entrada, almacenando el último elemento visto. Se imprime una barra separadora antes de cada elemento que es diferente a la anterior, verificada como que tiene bit xor ^de 0. La inicialización p=-1evita un separador antes del primer elemento.

xnor
fuente
Lástima que groupbysea ​​un dolor ...
Sp3000
2

CJam, 9 bytes

Dos soluciones:

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

Pruébalo aquí.

Explicación

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.
}%
Martin Ender
fuente
2

Haskell, 22 bytes

import Data.List
group

Hay un incorporado. Funciona en cualquier tipo que sea compatible con la igualdad.

xnor
fuente
2
¿Alguna razón por la que esto es wiki comunitario?
Fatalize
1
Eso es noble, pero como nadie más lo está haciendo, ¿por qué no preguntas sobre eso en meta?
Fatalize
2

MATL, 8 7 bytes

Eliminado 1 byte gracias a @Suever

ly&Y'Y{

Funciona con enteros / flotantes / caracteres / booleanos / puntos de unicornio / otras entradas imaginarias.
Para booleanos, las entradas son T/F, las salidas son 1/0.

Pruébalo en línea!


Agrupado y repetido

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
cubilete
fuente
1

C #, 117 bytes

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

sin golf (no realmente)

    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
fuente
1

Pyth, 9 7 bytes

mr9]dr8

¡Crédito a @LeakyNun por 2 bytes!

Explicación:

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

Respuesta anterior, 12 bytes

hf.Am!t{dT./

Olvidé la longitud de ejecución incorporada, pero creo que este es un enfoque correcto, así que lo mantuve.

Explicación:

                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
fuente
Esto es 7 bytes
Leaky Nun
@LeakyNun ¡Oh cierto! Eso es genial.
busukxuan
1
Creo que esto funciona para 6.
FryAmTheEggman
@FryAmTheEggman Agradable abuso de m.
Leaky Nun
@FryAmTheEggman Wow, no entiendo oO
busukxuan
1

Pyth , 36 35 bytes

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

Enlace de prueba

Editar: explicación:

                                      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
fuente
1

Retina , 24 22 bytes

2 bytes gracias a Martin Ender.

Una respuesta 15 bytes ya existe, por lo que este es sólo otro enfoque que cuesta más bytes.

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

Pruébalo en línea!

Se divide en espacios cuyo número anterior difiere del procedimiento.

Esta es una demostración de lookarounds.

Monja permeable
fuente
1

05AB1E, 13 bytes

¬svyÊi¶}yðJ?y

Explicado

¬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

Debería funcionar para cualquier lista.
Probado en int y char.

Pruébalo en línea

Emigna
fuente
1

Swift, 43 bytes

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

Supone que i es una matriz de objetos equiparables; funciona para cualquier cosa, desde ints hasta cadenas y objetos personalizados. Un poco descarado, ya que la salida contiene muchas líneas nuevas, pero hacerla más bonita costaría bytes.

Versión más bonita y sin golf:

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
}

Esta versión imprime cada grupo en una nueva línea a expensas de más código.

Ideas para mejorar

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

Esta versión tiene 47 bytes, pero es un enfoque diferente, ¿quizás hay algo para optimizar allí? El mayor problema es la declaración de devolución.

juliand665
fuente
1

C, 88 77 bytes

Movido el strmcmp interior de los printf 11 bytes de ahorro

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

Entrada de muestra:

(parámetros de línea de comando)

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

Salida de muestra:

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

Probado en:

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

Estoy tratando de arreglar la falla de segmentación 5.3.0.

88 Versión

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

Java 134 bytes

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

itera y decide si se separa con una nueva línea o un espacio.

Rohan Jhunjhunwala
fuente
para empezar, podría eliminar publicy staticpalabras clave. También puede quitar las llaves en el bucle for
user902383
Hecho en user902383
Rohan Jhunjhunwala el
1

ListSharp , 134 bytes

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 no admite funciones, por lo que la matriz se guarda en un archivo local llamado l.txt expediente

downrep_nation
fuente
1

Rubí , 24 bytes

En Arrayinstancias de ruby tienen un método incorporadogroup_by

Entonces la solución será:

a.group_by{|x| x}.values
Farkhat Mikhalko
fuente
0

TSQL, 132 bytes

Esto es un poco diferente de las otras respuestas: sql no tiene matrices, la entrada obvia para sql es una tabla.

Golfizado:

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)

Sin golf:

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)

Violín

t-clausen.dk
fuente
0

Perl 5-39 bytes

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

Pyke, 2 bytes (no competitivo)

Solo admite enteros

$f

Pruébalo aquí!

split_at(input, delta(input))

Se agregó el nodo split_at, divide la entrada cuando el segundo argumento es verdadero

Azul
fuente
0

sed, 33 23 + 1 = 24 bytes

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

Necesita la -ropción

Ejemplo de uso:

$ 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
fuente
0

JavaScript (ES6), 56

Entrada: conjunto de números o cadenas

Salida: matriz de matrices

Primera vez que usa una comparación exacta en código de golf

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

Clojure, 19 bytes

#(partition-by + %)

Es una función integrada, pero requiere una función de mapeo. En este caso, +sirve como una función de identidad.

MattPutnam
fuente
0

Javascript (usando una biblioteca externa) (178 bytes)

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

Descargo de responsabilidad: estoy usando una biblioteca que escribí para implementar LINQ de C # en JS. No me ayudó exactamente a ganar, pero bueno

Imagen

Imagen2

applejacks01
fuente