Enumere cada série de números idênticos no local


27

Dada uma lista de números inteiros estritamente positivos, passe por cada número distinto e substitua todas as ocorrências por índices sucessivos (zero ou um com base) de uma nova série.

Exemplos

[][]/[]

[42][0]/[1]

[7,7,7][0,1,2]/[1,2,3]

[10,20,30][0,0,0]/[1,1,1]

[5,12,10,12,12,10][0,0,0,1,2,1]/[1,1,1,2,3,2]

[2,7,1,8,2,8,1,8,2,8][0,0,0,0,1,1,1,2,2,3]/[1,1,1,1,2,2,2,3,3,4]

[3,1,4,1,5,9,2,6,5,3,5,9][0,0,0,1,0,0,0,0,1,1,2,1]/[1,1,1,2,1,1,1,1,2,2,3,2]


2
Então, basicamente, o número de vezes que apareceu a sequência até agora?
Jo King

1
@JoKing Sim, essa é outra maneira de dizer isso, mas "até agora" implica em base zero e "até e incluindo isso" implica em base única. Eu queria manter a escolha.
Adám 8/01

Respostas:


23

JavaScript (ES6), 26 bytes

1 indexado.

a=>a.map(o=x=>o[x]=-~o[x])

Experimente online!

Comentado

a =>                // a[] = input array
  a.map(o =         // assign the callback function of map() to the variable o, so that
                    // we have an object that can be used to store the counters
    x =>            // for each value x in a[]:
      o[x] = -~o[x] //   increment o[x] and yield the result
                    //   the '-~' syntax allows to go from undefined to 1
  )                 // end of map()

1
Não tenho ideia de como isso funciona, mas com certeza parece elegante.
Adám 8/01

Eu nunca vi -~antes - isso é uma jóia absoluta.
DaveMongoose

Como alternativa, é possível usar apara armazenar os valores, mas é necessário -/ ~o índice para que nenhum byte seja salvo.
user202729 9/01


1
O @DaveMongoose -~é na verdade uma alternativa comumente usada +1(já que tem precedência diferente) em vários idiomas
somente ASCII

10

R , 27 bytes

function(x)ave(x,x,FUN=seq)

Experimente online!

Explicação:

ave(x,x,FUN=seq)divide o vetor xem subvectores usando valores de xcomo chaves de agrupamento. Em seguida, a seqfunção é chamada para cada grupo e cada resultado é reorganizado na posição original do grupo.

Melhor ver um exemplo:

x <- c(5,7,5,5,7,6)
ave(x, x, FUN=seq) # returns 1,1,2,3,2


 ┌───┬───┬───┬───┬───┐57557
 └───┴───┴───┴───┴───┘            
   |   |   |    |  |     |   ▼    ▼  |
 GROUP A : seq(c(5,5,5)) = c(1,2,3)
   |   |   |    |  |     |   ▼    ▼  |
 ┌───┐ | ┌───┬───┐ |1|23|
 └───┘ | └───┴───┘ |
       ▼           ▼
 GROUP B : seq(c(7,7)) = c(1,2)
       |           |
       ▼           ▼
     ┌───┐       ┌───┐1 │       │ 2
     └───┘       └───┘ 

   |   |   |   |   |
   ▼   ▼   ▼   ▼   ▼ 
 ┌───┬───┬───┬───┬───┐11232
 └───┴───┴───┴───┴───┘  

Nota :

seq(y)A função retorna uma sequência 1:length(y)caso ytenha length(y) > 1, mas retorna uma sequência de 1:y[1]se ycontiver apenas um elemento.
Felizmente, isso não é um problema porque, nesse caso, R - reclamando com muitos avisos - seleciona apenas o primeiro valor que é aliás o que queremos :)


2
Brilhante! Vou adicionar uma recompensa por isso. Nunca visto aveantes.
Giuseppe

Estou honrado, muito obrigado! :)
digEmAll 14/01

6

MATL , 4 bytes

&=Rs

Esta solução é baseada em 1

Experimente no MATL Online !

Explicação

Usa [1,2,3,2]como exemplo

    # Implicitly grab the input array of length N
    #
    #   [1,2,3,2]
    #
&=  # Create an N x N boolean matrix by performing an element-wise comparison
    # between the original array and its transpose:
    #
    #     1 2 3 2
    #     -------
    # 1 | 1 0 0 0
    # 2 | 0 1 0 1
    # 3 | 0 0 1 0
    # 2 | 0 1 0 1
    #
R   # Take the upper-triangular portion of this matrix (sets below-diagonal to 0)
    #
    #   [1 0 0 0
    #    0 1 0 1
    #    0 0 1 0
    #    0 0 0 1]
    #
s   # Compute the sum down the columns
    #
    #   [1,1,1,2]
    #
    # Implicitly display the result

2
ah, eu sabia que havia um problema antigo que me fazia pensar em algo semelhante, é Único é Barato e a solução MATL tem um caractere diferente!
Giuseppe

5

APL (Dyalog Unicode) , 7 bytes

Muito, muito obrigado a H.PWiz, Adám e dzaima por toda sua ajuda na depuração e correção disso.

+/¨⊢=,\

Experimente online!

Explicação

A versão não-tácita de 10 bytes será mais fácil de explicar primeiro

{+/¨⍵=,\⍵}

{         } A user-defined function, a dfn
      ,\⍵  The list of prefixes of our input list 
           (⍵ more generally means the right argument of a dfn)
           \ is 'scan' which both gives us our prefixes 
           and applies ,/ over each prefix, which keeps each prefix as-is
    ⍵=     Checks each element of  against its corresponding prefix
           This checks each prefix for occurrences of the last element of that prefix
           This gives us several lists of 0s and 1s
 +/¨       This sums over each list of 0s and 1s to give us the enumeration we are looking for

A versão tácita faz três coisas

  • Em primeiro lugar, ele remove a instância do usado em ,\⍵como ,\à direita, por si só pode figurar implicitamente que é suposto para operar no argumento de direito.
  • Segundo, pois ⍵=, substituímos por com , que significa argumento correto
  • Terceiro, agora que não temos argumentos explícitos (neste caso ), podemos remover os chavetas {}porque as funções tácitas não os usam


5

J , 7 bytes

1#.]=]\

Experimente online!

1 indexado.

Explicação:

]\ all the prefixes (filled with zeros, but there won't be any 0s in the input):
   ]\ 5 12 10 12 12 10
5  0  0  0  0  0
5 12  0  0  0  0
5 12 10  0  0  0
5 12 10 12  0  0
5 12 10 12 12  0
5 12 10 12 12 10

]= is each number from the input equal to the prefix:
   (]=]\) 5 12 10 12 12 10
1 0 0 0 0 0
0 1 0 0 0 0
0 0 1 0 0 0
0 1 0 1 0 0
0 1 0 1 1 0
0 0 1 0 0 1

1#. sum each row:
   (1#.]=]\) 5 12 10 12 12 10
1 1 1 2 3 2

K (oK) , 11 10 bytes

-1 byte graças a ngn!

{+/'x=,\x}

Experimente online!


1
Heh, você está feliz por ter tornado os dados estritamente positivos ...
Adám

@ Adám Sim, caso contrário, eu precisaria caixa os prefixos :)
Galen Ivanov

1
em k: ='->=
ngn 31/01






2

R , 41 bytes

function(x)diag(diffinv(outer(x,x,"==")))

Experimente online!

Estranhamente, retornar um índice baseado em zero é mais curto em R.


Mais uma vez Giuseppe, seu conhecimento superior de R me venceu. Eu tinha um método decentemente engenhoso de 60 bytes, mas, infelizmente, não era suficiente!
Sumner18

@ Sumner18 publicá-lo de qualquer maneira! Eu sempre aprendo muito com as abordagens de outras pessoas, e obter feedback é a maneira mais rápida de aprender!
Giuseppe

obrigado pelo incentivo! Publiquei o meu agora e estou sempre aberto a sugestões de melhorias!
Sumner18

2

Ruby, 35 bytes

->a{f=Hash.new 0;a.map{|v|f[v]+=1}}

Infelizmente, é bastante mundano - crie um hash que armazene o total de cada entrada encontrada até agora.

Algumas outras opções divertidas que infelizmente não eram curtas o suficiente:

->a{a.dup.map{a.count a.pop}.reverse}   # 37
->a{i=-1;a.map{|v|a[0..i+=1].count v}}  # 38

2

R , 62 43 bytes

x=z=scan();for(i in x)z[y]=1:sum(y<-x==i);z

-19 bytes graças a Giuseppe, removendo what, e table, e apenas pequenas alterações na implementação

Original

x=z=scan();for(i in names(r<-table(x)))z[which(x==i)]=1:r[i];z

Como não posso competir com o conhecimento de Giuseppe, minha submissão é um pouco mais longa que a dele, mas, usando meu conhecimento básico, senti que essa solução era bastante engenhosa.

r<-table(x) conta o número de vezes que cada número aparece e o armazena em r, para referência futura

names() obtém os valores de cada entrada exclusiva na tabela e iteramos sobre esses nomes com um loop for.

A parte restante verifica quais entradas são iguais às iterações e armazena uma sequência de valores (de 1 ao número de entradas da iteração)

Experimente online!


você pode remover o which()para salvar 7 bytes.
Giuseppe

Seu uso de 1:r[i]me deu a idéia de remover table()completamente: x=z=scan();for(i in x)z[y]=1:sum(y<-x==i);zsão 43 bytes! Esta é uma boa abordagem!
Giuseppe

Parece que nenhum de nós pode competir com o conhecimento de R do digEmAll !
Giuseppe

Vi isso e fiquei absolutamente pasmo!
Sumner18

2

Haskell , 44 bytes

([]#)
x#(y:z)=sum[1|a<-x,a==y]:(y:x)#z
_#e=e

Experimente online!

Explicação

Percorre a lista da esquerda para a direita, mantendo a lista xdos elementos visitados, inicialmente []:

Para cada encontro de uma ycontagem, todos os elementos iguais na lista x.


1
Um pouco mais, mas talvez interessante: (#(0*));(x:r)#g=g x:r# \y->0^abs(y-x)+g y;e#g=e experimente online!
Laikoni 10/01

@Laikoni: Como você chegou a isso, deveria publicá-lo totalmente!
ბიმო 10/01


2

Perl 6 , 15 bytes

*>>.&{%.{$_}++}

Experimente online!

Você pode mover o ++para antes do %para um índice baseado em um.

Explicação:

*>>.&{        }  # Map the input to
      %          # An anonymous hash
       .{$_}     # The current element indexed
            ++   # Incremented

2

Haskell , 47 46 bytes

(#(*0))
(x:r)#g=g x:r# \y->0^(y-x)^2+g y
e#g=e

Experimente online!

Uma abordagem diferente da resposta da BMO, que ficou um pouco mais longa. (E gentilmente pede emprestado seu belo traje de teste.)

A idéia é percorrer a lista de entrada e acompanhar o número de vezes que cada elemento ocorreu, atualizando uma função g. Ungolfed:

f (const 0)
f g (x:r) = g x : f (\ y -> if x==y then 1 + g y else g y) r
f g []    = []

Surgiram duas oportunidades interessantes de golfe. Primeiro para o valor inicial de g, uma função constante que desconsidera seu argumento e retorna 0:

const 0  -- the idiomatic way
(\_->0)  -- can be shorter if parenthesis are not needed
min 0    -- only works as inputs are guaranteed to be non-negative
(0*)     -- obvious in hindsight but took me a while to think of

E, em segundo lugar, uma expressão sobre variáveis xe yque produz 1se xiguais you 0não:

if x==y then 1else 0  -- yes you don't need a space after the 1
fromEnum$x==y         -- works because Bool is an instance of Enum
sum[1|x==y]           -- uses that the sum of an empty list is zero
0^abs(x-y)            -- uses that 0^0=1 and 0^x=0 for any positive x
0^(x-y)^2             -- Thanks to  Christian Sievers!

Ainda pode haver maneiras mais curtas. Alguém teve uma ideia?


1
Você pode usar 0^(x-y)^2.
Christian Sievers


1

Ruby , 34 bytes

->a{r=[];a.map{|x|(r<<x).count x}}

Experimente online!


Não acredito que tentei ->a{i=-1;a.map{|v|a[0..i+=1].count v}}e não pensei em apenas construir uma nova matriz, lol. Bom trabalho.
DaveMongoose

1

bash, 37 24 bytes

f()(for x;{ r+=$[a[x]++]\ ;};echo $r)

TIO

se válida, também há essa variação, conforme sugerido pelo DigitalTrauma

for x;{ echo $[a[x]++];}

TIO


1
Passe a lista como linha de comando args - tio.run/##S0oszvj/Py2/SKHCuporNTkjX0ElOjG6IlZbO5ar9v///8b/… - apenas 24 bytes.
Digital Trauma

@DigitalTrauma, obrigado no entanto, não sei se ele quebrou as regras. também como foi solicitado a substituir a lista e talvez devesse ser algo como tio.run/…
Nahuel Fouilleul

2
@NahuelFouilleul Tudo bem, programas completos também são permitidos, e esse é um método válido de entrada / saída de uma lista (IMO)
somente ASCII

1

Perl 5, 11 bytes

$_=$h{$_}++

TIO

explicações após o comentário

  • $_variável especial do perl que contém a linha atual ao passar pela entrada ( -pou -ncomutadores)
  • $h{$_}++autivivifica o mapa %he cria uma entrada com chave $_e incrementos e fornece o valor antes do incremento
  • a variável especial é impressa por causa da -pchave, a -lchave remove o fim da linha na entrada e adiciona o fim da linha na saída

Isso parece incrível. Gostaria de explicar?
Adám 11/01

@ Adám, obrigado pelo seu feedback, com certeza, feito
Nahuel Fouilleul



1

Anexo , 23 bytes

{`~&>Zip[_,_[0:#_::0]]}

Experimente online!

Explicação

{`~&>Zip[_,_[0:#_::0]]}
{                     }    _: input (e.g., [5, 12, 10, 12, 12, 10])
             0:#_          range from 0 to length of input (inclusive)
                           e.g., [0, 1, 2, 3, 4, 5, 6]
                 ::0       descending range down to 0 for each element
                           e.g., [[0], [1, 0], [2, 1, 0], [3, 2, 1, 0], [4, 3, 2, 1, 0], [5, 4, 3, 2, 1, 0], [6, 5, 4, 3, 2, 1, 0]]
           _[       ]      get input elements at those indices
                           e.g., [[5], [12, 5], [10, 12, 5], [12, 10, 12, 5], [12, 12, 10, 12, 5], [10, 12, 12, 10, 12, 5], [nil, 10, 12, 12, 10, 12, 5]]
     Zip[_,          ]     concatenate each value with this array
                           e.g., [[5, [5]], [12, [12, 5]], [10, [10, 12, 5]], [12, [12, 10, 12, 5]], [12, [12, 12, 10, 12, 5]], [10, [10, 12, 12, 10, 12, 5]]]
   &>                      using each sub-array spread as arguments...
 `~                            count frequency
                               e.g. [12, [12, 10, 12, 5]] = 12 ~ [12, 10, 12, 5] = 2

1

C (gcc) , 65 62 bytes

c,d;f(a,b)int*a;{for(;c=d=b--;a[b]=d)for(;c--;d-=a[c]!=a[b]);}

Experimente online!

-2 bytes graças ao ASCII-only


Isso parecia muito simples, mas eu não conseguia ficar mais curto com uma abordagem diferente.



@ Somente ASCII é uma resposta válida? Nenhum cabeçalho incluído, nenhuma declaração, é um trecho de código com muitos avisos, embora seja emitido.
AZTECCO 14/01

Os avisos do @AZTECCO são bons (o stderr é ignorado), desde que faça o que deveria, é aceitável. note que esta é uma declaração de função, além de algumas declarações de variáveis ​​- você pode colocá-la em qualquer lugar como uma expressão de nível superior e ela será compilada corretamente. um monte de c respostas (e aqueles em linguagens com sintaxe menos rigoroso) que geralmente têm algumas advertências por causa de bytesaves que não são estilo do código de boa
ASCII-only

Ok, eu posso entender, mas ainda há algo errado para mim. Se quisermos testar com um conjunto diferente (em tamanho), precisamos modificar o código, mesmo no loop de impressão, mais a entrada deve ser apenas o conjunto, não o seu tamanho. "Dada uma lista de números inteiros estritamente positivos ... "então eu acho que a entrada deve ser apenas a lista.
AZTECCO 15/01

O @AZTECCO não tem certeza se essa discussão deve pertencer aos comentários desta resposta, mas você pode dar uma olhada na meta - especificamente nos formatos de E / S e resposta .
attinat 15/01

1

K (ngn / k) , 18 bytes

(,/.!'#'=x)@<,/.=x

Experimente online!


ABORDAGEM ANTIGA

K (ngn / k) , 27 23 22 bytes

{x[,/.=x]:,/.!'#'=x;x}

Experimente online!


isso não é bonito ... solução rápida e suja, refino isso mais tarde quando tiver a chance de pensar em uma abordagem melhor

explicação:

  • =xretorna um ditado em que chaves são itens de x e valores são seus índices ( 3 1 4 5 9 2 6!(0 9;1 3;,2;4 8 10;5 11;,6;,7))
  • i: atribuir ditado a i
  • #:'contar valores para cada chave ( 3 1 4 5 9 2 6!2 2 1 3 2 1 1)
  • !:'enumere cada valor ( 3 1 4 5 9 2 6!(0 1;0 1;,0;0 1 2;0 1;,0;,0))
  • ,/.:extrair valores e achatar list ( 0 1 0 1 0 0 1 2 0 1 0 0)
  • x[,/.:i]: extrair índices de i, achatar e atribuir cada valor da lista do lado direito a esses índices

irritantemente, a lista é atualizada, mas um valor nulo é retornado pela atribuição, então eu preciso retornar a lista após o ponto-e-vírgula ( ;x)

editar: dois pontos estranhos removidos

edit2: removida atribuição desnecessária


0

Retina 0.8.2 , 30 bytes

\b(\d+)\b(?<=(\b\1\b.*?)+)
$#2

Experimente online! O link inclui casos de teste. 1 indexado. Explicação: A primeira parte do regex corresponde a cada número inteiro na lista por vez. O grupo lookbehind corresponde a cada ocorrência desse número inteiro nessa linha até e incluindo o número inteiro atual. O número inteiro é então substituído pelo número de correspondências.


0

Lote, 61 bytes

@setlocal
@for %%n in (%*)do @set/ac=c%%n+=1&call echo %%c%%

1 indexado. Como a substituição de variável ocorre antes da análise, o set/acomando acaba incrementando o nome da variável fornecido concatenando a letra ccom o número inteiro da lista (as variáveis ​​numéricas são padronizadas como zero no lote). O resultado é copiado para outro número inteiro para facilitar a saída (mais precisamente, ele salva um byte).



0

Japonês, 8 bytes

£¯YÄ è¶X

Experimente aqui

£¯YÄ è¶X
             :Implicit input of array U
£            :Map each X at 0-based index Y
 ¯           :  Slice U to index
  YÄ         :    Y+1
     è       :  Count the elements
      ¶X     :    Equal to X
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.