Enumera ogni serie di numeri identici sul posto


27

Dato un elenco di numeri interi assolutamente positivi, passa attraverso ciascun numero distinto e sostituisci tutte le occorrenze di esso con indici successivi (zero o uno basato) di una nuova serie.

Esempi

[][]/[]

[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
Quindi in pratica il numero di volte in cui è apparsa la sequenza finora?
Jo King

1
@JoKing Sì, questo è un altro modo per affermarlo, ma "finora" implica zero-based e "fino a quando non includendo questo" implica one-based. Volevo mantenere la scelta.
Adám

Risposte:


23

JavaScript (ES6), 26 byte

1-indicizzati.

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

Provalo online!

Commentate

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
Non ho idea di come funzioni, ma sembra sicuramente elegante.
Adám

Non ho mai visto -~prima - questa è una gemma assoluta.
DaveMongoose,

In alternativa, è possibile utilizzare aper memorizzare i valori, ma è necessario -/ ~indice quindi non viene salvato alcun byte.
user202729


1
@DaveMongoose -~è in realtà un'alternativa comunemente usata +1(poiché ha una precedenza diversa) in molte lingue
ASCII, solo il

10

R , 27 byte

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

Provalo online!

Spiegazione :

ave(x,x,FUN=seq)divide il vettore xin sotto-vettori usando i valori di xcome chiavi di raggruppamento. Quindi seqviene chiamata la funzione per ciascun gruppo e ogni risultato viene riorganizzato nella posizione originale del gruppo.

Meglio vedere un esempio:

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 funzione restituisce una sequenza 1:length(y)nel caso yabbia length(y) > 1, ma restituisce una sequenza 1:y[1]se ycontiene solo un elemento.
Questo fortunatamente non è un problema perché in quel caso R - lamentandosi di molti avvisi - seleziona solo il primo valore che è per inciso quello che vogliamo :)


2
Brillante! Aggiungerò una taglia per questo. Mai visto aveprima
Giuseppe

Sono onorato, grazie mille! :)
digEmAll

6

MATL , 4 byte

&=Rs

Questa soluzione è basata su 1

Provalo su MATL Online !

Spiegazione

Usa [1,2,3,2]come esempio

    # 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, sapevo che c'era un vecchio problema che mi ha fatto pensare a qualcosa di simile, è Unique is Cheap e la soluzione MATL ha un personaggio diverso!
Giuseppe

5

APL (Dyalog Unicode) , 7 byte

Mille grazie a H.PWiz, Adám e dzaima per tutto il loro aiuto nel debugging e nella correzione di questo.

+/¨⊢=,\

Provalo online!

Spiegazione

La versione non tacita a 10 byte sarà più semplice da spiegare per prima

{+/¨⍵=,\⍵}

{         } 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 versione tacita fa tre cose

  • In primo luogo, rimuove l'istanza di used in ,\⍵come ,\a destra da sola può implicitamente capire che dovrebbe operare sull'argomento giusto.
  • In secondo luogo, per ⍵=, sostituiamo con , che sta per argomento giusto
  • In terzo luogo, ora che non abbiamo argomenti espliciti (in questo caso ), possiamo rimuovere le parentesi graffe {}poiché le funzioni tacite non le usano


5

J , 7 byte

1#.]=]\

Provalo online!

1-indicizzati.

Spiegazione:

]\ 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 byte

-1 byte grazie a ngn!

{+/'x=,\x}

Provalo online!


1
Heh, sei felice di aver reso i dati strettamente positivi ...
Adám,

@Adám Sì, altrimenti avrei bisogno di inscatolare i prefissi :)
Galen Ivanov

1
in k: ='->=
ngn






2

R , 41 byte

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

Provalo online!

Stranamente, la restituzione di un indice in base zero è più breve in R.


Ancora una volta Giuseppe, la tua superiore conoscenza di R mi ha battuto. Avevo un metodo abbastanza ingegnoso a 60 byte, ma purtroppo non era abbastanza!
Sumner18

@ Sumner18 pubblicalo comunque! Imparo sempre molto dagli approcci degli altri, e ottenere feedback è il modo più veloce per imparare!
Giuseppe

grazie per l'incoraggiamento! Ho pubblicato il mio ora e sono sempre aperto a suggerimenti per il miglioramento!
Sumner18

2

Rubino, 35 byte

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

È piuttosto banale, sfortunatamente: crea un hash che memorizzi il totale per ogni voce incontrata finora.

Alcune altre opzioni divertenti che purtroppo non erano abbastanza brevi:

->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 byte

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

-19 byte grazie a Giuseppe, rimuovendo quale, e tabella, e solo lievi modifiche all'implementazione

Originale

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

Non posso competere con le conoscenze di Giuseppe, quindi la mia presentazione è un po 'più lunga della sua, ma usando le mie conoscenze di base, ho sentito che questa soluzione era piuttosto ingegnosa.

r<-table(x) conta il numero di volte in cui appare ogni numero e lo memorizza in r, per riferimento futuro

names() ottiene i valori di ogni voce univoca nella tabella e ripetiamo questi nomi con un ciclo for.

La parte rimanente verifica quali voci sono uguali alle iterazioni e memorizza una sequenza di valori (da 1 al numero di voci dell'iterazione)

Provalo online!


è possibile rimuovere il which()per salvare 7 byte.
Giuseppe

Il tuo uso di 1:r[i]mi ha dato l'idea di rimuoverlo table()completamente: x=z=scan();for(i in x)z[y]=1:sum(y<-x==i);z43 byte! Questo è un approccio simpatico!
Giuseppe

Sembra che nessuno di noi possa competere con la conoscenza R di digEmAll !
Giuseppe

L'ho visto ed ero assolutamente sbalordito!
Sumner18

2

Haskell , 44 byte

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

Provalo online!

Spiegazione

Attraversa l'elenco da sinistra a destra mantenendo l'elenco xdegli elementi visitati, inizialmente []:

Per ogni incontro di un yconteggio tutti gli elementi uguali nell'elenco x.


1
Un po 'più a lungo ma forse comunque interessante: (#(0*));(x:r)#g=g x:r# \y->0^abs(y-x)+g y;e#g=e provalo online!
Laikoni,

@Laikoni: Come ti è venuto in mente, dovresti pubblicarlo totalmente!
ბიმო


2

Perl 6 , 15 byte

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

Provalo online!

È possibile spostare ++a prima di %per un indice basato.

Spiegazione:

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

2

Haskell , 47 46 byte

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

Provalo online!

Un approccio diverso rispetto alla risposta di BMO che si è rivelata un po 'più lunga. (E prende in prestito gentilmente la loro bella tuta di prova.)

L'idea è di scorrere l'elenco di input e tenere traccia del numero di volte in cui si è verificato ciascun elemento aggiornando una funzione 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 []    = []

Sono sorte due interessanti opportunità di golf. Innanzitutto per il valore iniziale di g, una funzione costante che ignora il suo argomento e restituisce 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 in secondo luogo un'espressione sulle variabili xe yche produce 1se è xuguale ye 0altrimenti:

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!

Potrebbero esserci ancora modi più brevi. Qualcuno ha un'idea?


1
È possibile utilizzare 0^(x-y)^2.
Christian Sievers,


1

Rubino , 34 byte

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

Provalo online!


Non riesco a credere di aver provato ->a{i=-1;a.map{|v|a[0..i+=1].count v}}e di non aver pensato di costruire un nuovo array, lol. Bel lavoro.
DaveMongoose,

1

bash, 37 24 byte

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

TIO

se valido, esiste anche questa variazione, come suggerito da DigitalTrauma

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

TIO


1
Passa l'elenco come args della riga di comando - tio.run/##S0oszvj/Py2/SKHCuporNTkjX0ElOjG6IlZbO5ar9v///8b/… - solo 24 byte.
Trauma digitale

@DigitalTrauma, grazie comunque non so se ha infranto le regole. anche perché è stato chiesto di sostituire l'elenco e forse dovrebbe essere qualcosa di simile a tio.run/…
Nahuel Fouilleul

2
@NahuelFouilleul Va bene, sono ammessi anche programmi completi, e questo è un metodo valido per inserire / produrre una lista (IMO)
ASCII-only

1

Perl 5, 11 byte

$_=$h{$_}++

TIO

spiegazioni a seguito di commento

  • $_la variabile speciale di perl che contiene la linea corrente quando si passa in rassegna su input ( -po -nswitch)
  • $h{$_}++autovivifica la mappa %he crea una voce con chiave $_e incrementi e fornisce il valore prima dell'incremento
  • la variabile speciale viene stampata a causa -pdell'interruttore, l' -linterruttore rimuove la fine della linea in ingresso e aggiunge la fine della linea in uscita

Sembra fantastico. Ti interessa spiegare?
Adám,

@Adám, grazie per il tuo feedback, certo, fatto
Nahuel Fouilleul,



1

Attache , 23 byte

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

Provalo online!

Spiegazione

{`~&>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 byte

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

Provalo online!

-2 byte grazie solo a ASCII


Sembrava troppo semplice, ma non riuscivo ad accorciarmi con un approccio diverso.



@ Solo ASCII è una risposta valida? Nessuna intestazione inclusa, nessuna dichiarazione, è uno snippet più molti avvisi anche se genera.
AZTECCO

Gli avvisi di @AZTECCO vanno bene (stderr viene ignorato), purché faccia ciò che dovrebbe essere accettabile. si noti che questa è una dichiarazione di funzione, oltre ad alcune dichiarazioni di variabili: è possibile inserirla ovunque come espressione di livello superiore e verrà compilata correttamente. un sacco di risposte C (e quelli in lingue con la sintassi meno rigorosa) non hanno in genere un bel paio di avvertimenti a causa della bytesaves che non sono buoni stile di codice
ASCII-only

Ok, posso capire, ma c'è ancora qualcosa che non va per me. Se vogliamo testare con un set diverso (in dimensioni) dobbiamo modificare il codice, anche nel ciclo di stampa, più l'input dovrebbe essere solo il set, non la sua dimensione. "Dato un elenco di numeri interi assolutamente positivi ... "quindi penso che l'input dovrebbe essere solo l'elenco.
AZTECCO,

@AZTECCO non è sicuro che questa discussione debba appartenere ai commenti di questa risposta, ma potresti voler dare un'occhiata a meta - in particolare su I / O e formati di risposta .
attinat

1

K (ngn / k) , 18 byte

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

Provalo online!


VECCHIO APPROCCIO

K (ngn / k) , 27 23 22 byte

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

Provalo online!


questa non è una soluzione abbastanza ... rapida e sporca, la affinerò più tardi quando avrò la possibilità di pensare a un approccio migliore

spiegazione:

  • =xrestituisce un dict in cui le chiavi sono elementi di x e i valori sono i loro indici ( 3 1 4 5 9 2 6!(0 9;1 3;,2;4 8 10;5 11;,6;,7))
  • i: assegnare dict a i
  • #:'contare i valori per ogni chiave ( 3 1 4 5 9 2 6!2 2 1 3 2 1 1)
  • !:'enumera ogni valore ( 3 1 4 5 9 2 6!(0 1;0 1;,0;0 1 2;0 1;,0;,0))
  • ,/.:estrae valori e appiattisci elenco ( 0 1 0 1 0 0 1 2 0 1 0 0)
  • x[,/.:i]: estrarre gli indici da i, appiattire e assegnare ciascun valore dall'elenco di destra in questi indici

fastidiosamente, l'elenco viene aggiornato ma l'assegnazione restituisce un valore nullo, quindi devo restituire l'elenco dopo il punto e virgola ( ;x)

modifica: rimossi due punti estranei

edit2: rimosso compito non necessario


0

Retina 0.8.2 , 30 byte

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

Provalo online! Il link include casi di test. 1-indicizzati. Spiegazione: La prima parte del regex corrisponde a turno a ciascun numero intero nell'elenco. Il gruppo del lookbehind corrisponde a ciascuna occorrenza di quell'intero su quella riga fino all'intero corrente incluso. L'intero viene quindi sostituito con il numero di corrispondenze.


0

Lotto, 61 byte

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

1-indicizzati. Poiché la sostituzione delle variabili avviene prima dell'analisi, il set/acomando finisce per incrementare il nome della variabile dato concatenando la lettera ccon l'intero dall'elenco (le variabili numeriche passano da zero a Batch). Il risultato viene quindi copiato su un altro numero intero per facilitare l'output (più precisamente, salva un byte).



0

Japt, 8 byte

£¯YÄ è¶X

Provalo qui

£¯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
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.