Enumera cada serie de números idénticos en el lugar

27

Dada una lista de enteros estrictamente positivos, revise cada número distinto y reemplace todas las ocurrencias con índices sucesivos (basados ​​en cero o uno) de una nueva serie.

Ejemplos

[][]/[]

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

Adán
fuente
2
Entonces, ¿básicamente la cantidad de veces que ha aparecido la secuencia hasta ahora?
Jo King
1
@JoKing Sí, esa es otra forma de decirlo, pero "hasta ahora" implica una base cero, y "hasta e incluyendo esto" implica una base. Quería mantener la elección.
Adám

Respuestas:

23

JavaScript (ES6), 26 bytes

1 indexado.

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

Pruébalo en línea!

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()
Arnauld
fuente
1
No tengo idea de cómo funciona, pero seguro que se ve elegante.
Adám
No he visto -~antes, eso es una joya absoluta.
DaveMongoose
Alternativamente, es posible usarlo apara almacenar los valores, pero es necesario para -/ ~el índice para que no se guarde ningún byte.
user202729
@DaveMongoose Consejos para jugar golf en JavaScript
user202729
1
@DaveMongoose -~es en realidad una alternativa de uso común +1(ya que tiene una precedencia diferente) en muchos idiomas
solo ASCII el
10

R , 27 bytes

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

Pruébalo en línea!

Explicacion:

ave(x,x,FUN=seq)divide el vector xen sub-vectores usando valores de xcomo claves de agrupación. Luego seqse llama a la función para cada grupo y cada resultado se reorganiza en la posición original del grupo.

Mejor ver un ejemplo:

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)La función devuelve una secuencia 1:length(y)en caso de que la ytenga length(y) > 1, pero devuelve una secuencia de 1:y[1]si ycontiene solo un elemento.
Afortunadamente, esto no es un problema porque en ese caso R , quejándose con muchas advertencias, selecciona solo el primer valor que, por cierto, es lo que queremos :)

digEmAll
fuente
2
¡Brillante! Agregaré una recompensa por esto. Nunca visto aveantes.
Giuseppe
Me siento honrado, muchas gracias! :)
digEmAll
6

MATL , 4 bytes

&=Rs

Esta solución está basada en 1

¡Pruébalo en MATL Online !

Explicación

Usos [1,2,3,2]como ejemplo

    # 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
Suever
fuente
2
¡Ah, sabía que había un viejo problema que me hizo pensar en algo similar, es único, es barato y la solución MATL tiene un carácter diferente!
Giuseppe
5

APL (Dyalog Unicode) , 7 bytes

Muchas, muchas gracias a H.PWiz, Adám y dzaima por toda su ayuda para depurar y corregir esto.

+/¨⊢=,\

Pruébalo en línea!

Explicación

La versión no tácita de 10 bytes será más fácil de explicar primero

{+/¨⍵=,\⍵}

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

La versión tácita hace tres cosas.

  • Primero, elimina la instancia de used in ,\⍵as ,\a la derecha por sí misma, puede deducir implícitamente que se supone que debe funcionar con el argumento correcto.
  • Segundo, para ⍵=, reemplazamos el con , que significa argumento correcto
  • Tercero, ahora que no tenemos argumentos explícitos (en este caso ), podemos eliminar las llaves {}ya que las funciones tácitas no las usan.
Sherlock9
fuente
5

AWK , 14

  • 1 byte guardado gracias a @NahuelFouilleul
{print++a[$1]}

Pruébalo en línea!

Lo anterior hace indexación basada en uno. Si prefiere la indexación basada en cero, es un byte adicional:

{print a[$1]++}

Pruébalo en línea!

Trauma digital
fuente
1
tenga en cuenta que el segundo puede ahorrar un byte {print++a[$1]}sin espacio parece estar funcionando
Nahuel Fouilleul
@NahuelFouilleul ¡Gracias!
Trauma digital el
5

J , 7 bytes

1#.]=]\

Pruébalo en línea!

1 indexado.

Explicación:

]\ 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 gracias a ngn!

{+/'x=,\x}

Pruébalo en línea!

Galen Ivanov
fuente
1
Je, estás contento de que hice los datos estrictamente positivos ...
Adám
@ Adám Sí, de lo contrario tendría que encerrar los prefijos :)
Galen Ivanov
1
en k: ='->=
ngn
2

Jalea , 4 bytes

ċṪ$Ƥ

Pruébalo en línea!

Para cada prefijo de la lista de entrada, cuenta el número de ocurrencias de su último elemento en sí mismo.

Sr. Xcoder
fuente
Alternativamente, la vieja escuela ;\ċ"también es 4.
Jonathan Allan
2

R , 41 bytes

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

Pruébalo en línea!

Curiosamente, devolver un índice basado en cero es más corto en R.

Giuseppe
fuente
Una vez más, Giuseppe, tu conocimiento superior de R me ha vencido. Tenía un método decentemente ingenioso en 60 bytes, pero ¡ay, no fue suficiente!
Sumner18
@ Sumner18 publicarlo de todos modos! ¡Siempre aprendo mucho de los enfoques de otras personas, y obtener comentarios es la forma más rápida de aprender!
Giuseppe
¡gracias por darme ánimos! ¡He publicado el mío ahora y siempre estoy abierto a sugerencias para mejorar!
Sumner18
2

Ruby, 35 bytes

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

Desafortunadamente, es bastante mundano: cree un hash que almacene el total de cada entrada encontrada hasta ahora.

Algunas otras opciones divertidas que desafortunadamente no fueron lo suficientemente cortas:

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

R , 62 43 bytes

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

-19 bytes gracias a Giuseppe, al eliminar cuál, y tabla, y solo pequeños cambios en la implementación

Original

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

No puedo competir con el conocimiento de Giuseppe, por lo que mi sumisión es algo más larga que la suya, pero usando mi conocimiento básico, sentí que esta solución era bastante ingeniosa.

r<-table(x) cuenta la cantidad de veces que aparece cada número y lo almacena en r, para referencia futura

names() obtiene los valores de cada entrada única en la tabla e iteramos sobre estos nombres con un bucle for.

La porción restante verifica qué entradas son iguales a las iteraciones y almacena una secuencia de valores (desde 1 hasta el número de entradas de la iteración)

Pruébalo en línea!

Sumner18
fuente
puede eliminar el which()para guardar 7 bytes.
Giuseppe
Su uso de 1:r[i]me dio la idea de eliminar por table()completo: ¡ x=z=scan();for(i in x)z[y]=1:sum(y<-x==i);zson 43 bytes! Este es un buen enfoque!
Giuseppe
¡Parece que ninguno de nosotros puede competir con el conocimiento R de digEmAll !
Giuseppe
¡Vi eso y quedé absolutamente estupefacto!
Sumner18
2

Haskell , 44 bytes

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

Pruébalo en línea!

Explicación

Atraviesa la lista de izquierda a derecha manteniendo la lista xde elementos visitados, inicialmente []:

Para cada encuentro de un yconteo, todos los elementos iguales en la lista x.

ბიმო
fuente
1
Un poco más largo pero quizás interesante: ¡ (#(0*));(x:r)#g=g x:r# \y->0^abs(y-x)+g y;e#g=e Pruébelo en línea!
Laikoni
@Laikoni: ¿Cómo se te ocurrió eso? ¡Deberías publicarlo totalmente!
ბიმო
2

Perl 6 , 15 bytes

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

Pruébalo en línea!

Puede mover el ++a antes del %para un índice basado en uno.

Explicación:

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

Haskell , 47 46 bytes

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

Pruébalo en línea!

Un enfoque diferente a la respuesta de BMO que resultó un poco más largo. (Y amablemente toma prestado su bonito traje de prueba).

La idea es iterar sobre la lista de entrada y realizar un seguimiento de la cantidad de veces que cada elemento ha ocurrido al actualizar una función g. Sin golf:

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

Surgieron dos interesantes oportunidades de golf. Primero para el valor inicial de g, una función constante que ignora su argumento y devuelve 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

Y en segundo lugar, una expresión sobre variables xy yque produce 1si xes igual yy de lo 0contrario:

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!

Todavía puede haber formas más cortas. Alguien tiene una idea?

Laikoni
fuente
1
Puedes usar 0^(x-y)^2.
Christian Sievers
1

Java (JDK) , 76 bytes

a->{for(int l=a.length,i,c;l-->0;a[l]=c)for(c=i=0;i<l;)c+=a[l]==a[i++]?1:0;}

Pruébalo en línea!

Créditos

Olivier Grégoire
fuente
1
-2 bytes cambiando for(c=0,i=l;i-->0;)c+=a[l]==a[i]?1:0;a for(c=i=0;i<l;)c+=a[l]==a[i++]?1:0;.
Kevin Cruijssen
1

Ruby , 34 bytes

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

Pruébalo en línea!

GB
fuente
No puedo creer que lo intenté ->a{i=-1;a.map{|v|a[0..i+=1].count v}}y no pensé en construir una nueva matriz, jajaja. Buen trabajo.
DaveMongoose
1

bash, 37 24 bytes

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

TIO

si es válido, también existe esta variación, como lo sugiere DigitalTrauma

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

TIO

Nahuel Fouilleul
fuente
1
Pase la lista como argumentos de línea de comando: tio.run/##S0oszvj/Py2/SKHCuporNTkjX0ElOjG6IlZbO5ar9v///8b/… - solo 24 bytes.
Trauma digital
@ DigitalTrauma, gracias, sin embargo, no sé si rompió las reglas. también como se le pidió que reemplazara la lista y tal vez debería ser algo como tio.run/…
Nahuel Fouilleul
2
@NahuelFouilleul Está bien, también se permiten programas completos, y ese es un método válido de entrada / salida de una lista (IMO)
solo ASCII
1

Perl 5, 11 bytes

$_=$h{$_}++

TIO

explicaciones después del comentario

  • $_La variable especial de Perl que contiene la línea actual cuando se repite la entrada ( -po -nconmutadores)
  • $h{$_}++autovivifica el mapa %hy crea una entrada con clave $_e incrementos y da el valor antes del incremento
  • la variable especial se imprime debido al -pinterruptor, el -linterruptor elimina el final de la línea en la entrada y agrega el final de la línea en la salida
Nahuel Fouilleul
fuente
Eso se ve increíble. ¿Le importaria explicar?
Adám
@ Adám, gracias por tus comentarios, seguro, hecho
Nahuel Fouilleul
1

Adjunto , 23 bytes

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

Pruébalo en línea!

Explicación

{`~&>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
Conor O'Brien
fuente
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]);}

Pruébalo en línea!

-2 bytes gracias a solo ASCII


Esto se sintió demasiado sencillo, pero no podía acortarme más con un enfoque diferente.

attinat
fuente
63
ASCII solo el
@ Solo ASCII ¿Es esta una respuesta válida? Sin encabezado incluido, sin declaraciones, es un fragmento más muchas advertencias, aunque da salida.
AZTECCO
Las advertencias de @AZTECCO están bien (se ignora stderr), siempre que haga lo que debe, es aceptable. tenga en cuenta que esta es una declaración de función, más algunas declaraciones de variables: puede colocarla en cualquier lugar como expresión de nivel superior y se compilará bien. una gran cantidad de respuestas c (y los de idiomas con la sintaxis menos estricto) no tienen en general un buen número de advertencias debido a bytesaves que no son buenas estilo de código
ASCII de sólo
Ok, puedo entenderlo, pero todavía hay algo que no me conviene. Si queremos probar con un conjunto diferente (en tamaño), tenemos que modificar el código, incluso en el ciclo de impresión, además la entrada debe ser solo el conjunto, no su tamaño ". Dada una lista de enteros estrictamente positivos ... "así que creo que la entrada debería ser solo la lista.
AZTECCO
@AZTECCO no está seguro de si esta discusión debe pertenecer a los comentarios de esta respuesta, pero es posible que desee echar un vistazo a meta - específicamente en E / S y formatos de respuesta .
attinat
1

K (ngn / k) , 18 bytes

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

Pruébalo en línea!


ANTIGUO ENFOQUE

K (ngn / k) , 27 23 22 bytes

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

Pruébalo en línea!


esto no es bonito ... solución rápida y sucia, voy a refinar esto más adelante cuando tenga la oportunidad de pensar en un mejor enfoque

explicación:

  • =xdevuelve un dict donde las claves son elementos de xy los valores son sus índices ( 3 1 4 5 9 2 6!(0 9;1 3;,2;4 8 10;5 11;,6;,7))
  • i: asignar dict a i
  • #:'contar valores para cada clave ( 3 1 4 5 9 2 6!2 2 1 3 2 1 1)
  • !:'enumerar cada valor ( 3 1 4 5 9 2 6!(0 1;0 1;,0;0 1 2;0 1;,0;,0))
  • ,/.:extraer valores y aplanar la lista ( 0 1 0 1 0 0 1 2 0 1 0 0)
  • x[,/.:i]: extraer índices de i, aplanar y asignar cada valor de la lista del lado derecho en estos índices

molestamente, la lista se actualiza pero la asignación devuelve un valor nulo, así que necesito devolver la lista después del punto y coma ( ;x)

editar: eliminó dos puntos extraños

edit2: se eliminó la asignación innecesaria

garabatear
fuente
0

Retina 0.8.2 , 30 bytes

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

Pruébalo en línea! El enlace incluye casos de prueba. 1 indexado. Explicación: La primera parte de la expresión regular coincide con cada número entero en la lista. El grupo de lookbehind coincide con cada aparición de ese entero en esa línea hasta e incluyendo el entero actual. El número entero se sustituye con el número de coincidencias.

Neil
fuente
0

Lote, 61 bytes

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

1 indexado. Debido a que la sustitución de variables ocurre antes del análisis, el set/acomando termina incrementando el nombre de la variable dado al concatenar la letra ccon el entero de la lista (las variables numéricas están predeterminadas a cero en Batch). El resultado se copia a otro entero para facilitar la salida (más precisamente, guarda un byte).

Neil
fuente
0

Japt, 8 bytes

£¯YÄ è¶X

Pruébalo aquí

£¯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
Lanudo
fuente