Grupos de itens repetidos


10

Descrição do Desafio

Dada uma lista / matriz de itens, exiba todos os grupos de itens repetidos consecutivos.

Descrição de entrada / saída

Sua entrada é uma lista / matriz de itens (você pode assumir que todos são do mesmo tipo). Você não precisa dar suporte a todos os tipos que seu idioma possui, mas deve suportar pelo menos um (de preferência int, mas tipos como boolean, embora não sejam muito interessantes, também são bons). Saídas de amostra:

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

Quanto às listas vazias, a saída é indefinida - não pode ser nada, uma lista vazia ou uma exceção - o que melhor se adapte aos seus objetivos de golfe. Você também não precisa criar uma lista separada de listas, portanto, essa é uma saída perfeitamente válida:

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

1 1 1
2 2
3 3 3
4
9

O importante é manter os grupos separados de alguma forma.


Talvez nós produzimos uma lista que tenha algum valor separador especial?
Xnor

@xnor: Você pode fornecer um exemplo? Uma matriz de ints separados por, por exemplo, 0s seria uma má idéia, pois pode haver 0s na entrada ...
shooqie

Por exemplo, [4, 4, '', 2, 2, '', 9, 9]ou [4, 4, [], 2, 2, [], 9, 9].
Xnor

Na verdade, que tipos temos para apoiar. Os próprios elementos podem ser listas? Eu imagino que alguns idiomas tenham tipos internos que não podem ser impressos ou que tenham uma estranha verificação de igualdade.
Xnor

@xnor: Sim, era isso que me preocupava - se sua entrada tem listas dentro dela, usar a lista vazia como separador pode ser confuso. Por isso eu incluí "você pode assumir que todos os itens são do mesmo tipo", para que possa usar um tipo diferente como separador.
Shooqie 4/16

Respostas:




8

Retina , 15 8 bytes

Agradecemos a Lynn por sugerir um formato de E / S mais simples.

!`(.)\1*

Trata a entrada como uma lista de caracteres (e usa alimentações de linha para separar grupos).

Experimente online!

Isso simplesmente funciona combinando grupos e imprimindo todos (que usa a separação de alimentação de linha automaticamente).


Perguntei sobre abbcccddda bb ccc dddser um formato de E / S aceitável e o OP aprovado, então acho que !`(.)\1*está bem?
Lynn

@ Lynn Oh, isso é realmente muito mais simples, obrigado.
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 em quaisquer tokens semelhantes a palavras, separados por espaço. Economizou 2 bytes graças a @ MartinEnder ♦. O melhor que eu poderia fazer para a entrada e o retorno da matriz é 68:

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

11
I adicionou-se uma resposta de matriz a 56
edc65

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

A entrada é uma matriz de números de linhas , com espaços ou vírgulas como separadores.

Experimente online! Teste com números não inteiros .


MATL, 11 bytes

lidgvYsG7XQ

A entrada é uma matriz de colunas de números ou caracteres , usando ;como separador.

Experimente online! Teste com números arbitrários . Teste com caracteres .

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 bytes

c-

Experimente online!

cé um agrupamento interno que faz exatamente isso, por isso chamamos STDIN (que é uma string, ou seja, uma lista de caracteres) e obtemos uma lista de strings. Infelizmente, o resultado é indistinguível da entrada, por isso precisamos adicionar separadores! -(junção por espaços) faz o truque.

Uma resposta alternativa é (2 bytes do CP437), que simplesmente envolve cuma função anônima.


2

Braquilog , 13 bytes

:{s.dl1}fs.c?

Aviso: isso é extremamente ineficiente e você entenderá o porquê da explicação.

Isso espera uma lista (por exemplo [1:1:2:2:2]) como entrada. Os elementos dentro da lista podem ser praticamente qualquer coisa.

Explicação

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

Isso funciona apenas por causa da maneira como os s - Subsetunifica: os menores conjuntos estão no final. Portanto, a primeira coisa que acha que concatena com a entrada é a execução mais longa, por exemplo, [[1:1]:[2:2:2]]e não por exemplo [[1:1]:[2:2]:[2]].


2

J , 13 bytes

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

Como J não suporta matrizes irregulares, cada execução de elementos iguais é encaixotada. A entrada é uma matriz de valores e a saída é uma matriz de matrizes in a 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│
└─┘

Explicação

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

⊢⊂⍨1,2≠/⊢

o argumento
⊂⍨particionado no
1primeiro elemento
,e,
2≠/em seguida, onde os pares subsequentes diferem
no argumento


2

Python 2, 43 bytes

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

Trabalha em listas de booleanos. Exemplo:

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

Repete a lista de entrada, armazenando o último elemento visto. Uma barra separadora é impressa antes de cada elemento que é diferente do anterior, marcada como tendo xor ^de bit a 0. 0. A inicialização p=-1evita um separador antes do primeiro elemento.


Pena que groupbyé essa dor um ...
SP3000

2

CJam, 9 bytes

Duas soluções:

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

Teste aqui.

Explicação

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.

Ou

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 bytes

Removido 1 byte graças a @Suever

ly&Y'Y{

Trabalha com números inteiros / flutuantes / caracteres / booleanos / pontos unicórnio / outras entradas imaginárias.
Para booleanos, entradas são T/F, saídas são 1/0.

Experimente online!


Agrupados e repetidos

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

ungolfed (não 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)));
    }

1

Pitão, 9 7 bytes

mr9]dr8

Crédito para @LeakyNun por 2 bytes!

Explicação:

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

Resposta antiga, 12 bytes

hf.Am!t{dT./

Esqueci o comprimento da execução interno, mas acho que essa é uma abordagem correta, então a mantive.

Explicação:

                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

Isso é 7 bytes #
Leaky Nun 4/16

@LeakyNun Oh right! Isso é legal.
busukxuan

11
Eu acredito que isso funciona para 6.
FryAmTheEggman

@FryAmTheEggman Nice abuse of m.
Leaky Nun

@FryAmTheEggman Wow, eu não entendo oO
busukxuan 4/16

1

Pitão , 36 35 bytes

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

Link de teste

Editar: explicação:

                                      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 bytes

2 bytes graças a Martin Ender.

A resposta de 15 bytes já existe, por isso esta é apenas uma outra abordagem que custa mais bytes.

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

Experimente online!

Divide-se em espaços cujo número anterior difere do processo.

Esta é uma demonstração de lookarounds.


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

Deve funcionar para qualquer lista.
Testado em int e char.

Experimente online


1

Rápido, 43 bytes

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

Assume i como uma matriz de objetos equáveis; funciona para qualquer coisa, de ints a strings e objetos personalizados. Tipo de atrevido em que a saída contém muitas novas linhas, mas tornar esse mais bonito custaria bytes.

Versão mais bonita e não destruída:

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 versão imprime todos os grupos em uma nova linha à custa de mais código.

Idéias para melhoria

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

Esta versão tem 47 bytes, mas é uma abordagem diferente, então talvez haja algo para otimizar por aí? O maior problema é a declaração de retorno.


1

C, 88 bytes

Movido o strmcmp interior para printf salvar 11 bytes

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 amostra:

(parâmetros da linha de comando)

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

Saída de amostra:

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

Testado em:

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

Estou tentando corrigir a falha de segmentação 5.3.0.

88 Versão

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

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 e decide se deve separar com uma nova linha ou um espaço.


para iniciantes, você pode remover publice staticpalavras - chave. Também você pode remover chaves em loop
user902383

Feito @ user902383
Rohan Jhunjhunwala

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

O ListSharp não suporta funções, para que a matriz seja salva em um arquivo local chamado l.txt Arquivo


1

Ruby , 24 bytes

Em Arrayinstâncias de ruby, o método internogroup_by

Então a solução será:

a.group_by{|x| x}.values

0

TSQL, 132 bytes

Isso é um pouco diferente das outras respostas - o sql não possui matrizes, a entrada óbvia para o sql é uma tabela.

Golfe:

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 bytes

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

0

Pyke, 2 bytes (não competitivo)

Suporta apenas números inteiros

$f

Experimente aqui!

split_at(input, delta(input))

Nó split_at adicionado, divide a entrada quando o segundo argumento é verdadeiro


0

sed, 33 23 + 1 = 24 bytes

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

Precisa da -ropção.

Exemplo 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

0

JavaScript (ES6), 56

Entrada: matriz de números ou seqüências de caracteres

Saída: matriz de matrizes

Primeira vez usando comparações exatas no código de golfe

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

0

Clojure, 19 bytes

#(partition-by + %)

É um built-in, mas é preciso uma função de mapeamento. Nesse caso, +serve como uma função de identidade.


0

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

Isenção de responsabilidade: estou usando uma biblioteca que escrevi para implementar o LINQ de c # em JS. Não me ajudou exatamente a vencer, mas tudo bem

Imagem

Image2

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.