Binning in tempo


12

Il compito di questa sfida è mettere gli elementi di un array in intervalli di tempo. L'input sarà un array non decrescente di numeri interi positivi che rappresentano il tempo degli eventi e un numero intero che rappresenta la dimensione di ciascun bin. Cominciamo con un esempio. Chiamiamo array di input Ae array di output O.

`A = [1,1,1,2,7,10]` and `bin_size = 2`.

`O = [4,0,0,1,1]`.

Perché ? Con a bin_size = 2, avremo i seguenti intervalli:, in (0,2], (2,4], (4,6], (6,8], (8,10]cui quattro elementi si (1,1,1,2)trovano nel primo intervallo (0,2], nessuno nel secondo e terzo intervallo, uno 7nell'intervallo (6,8]e uno 10nell'intervallo (8,10].

Il tuo codice dovrebbe considerare ogni intervallo di lunghezza a bin_sizepartire da 0e contare quanti numeri Aci sono in ciascuno. Dovresti sempre includere l'estremità destra di un intervallo in un cestino, quindi nell'esempio sopra 2è incluso nel conteggio di 4. Il codice dovrebbe essere eseguito in tempo lineare nella somma delle lunghezze dell'input e dell'output.

Altri esempi:

`A = [1,2,7,12,15]`  and `bin_size = 5`.

`O = [2, 1, 2]`.

`A = [1,2,7,12,15]`  and `bin_size = 3`.

`O = [2,0,1,1,1]`.

Puoi presumere che input e output possano essere dati in qualsiasi formato che ritieni conveniente. Puoi usare tutte le lingue e le librerie che ti piacciono.


Sono 0consentite uscite con messaggi finali ? Quindi tornare [2,0,1,1,1,0]invece di [2,0,1,1,1]?
Kevin Cruijssen,

Nessun zero finale per favore.

2
Che dire delle situazioni in cui il valore massimo dell'array non è un multiplo di bin_size, dovremmo davvero gestirle? Sembra che la maggior parte delle risposte lo faccia, ma in tal caso, sarebbe bello aggiungere un caso di prova per questo scenario per evitare confusione.
Kirill L.

@KirillL. Sì, dovrebbero essere gestiti anche loro.

1
@GPS 0 non è un numero intero positivo. Questo non è un incidente :)

Risposte:


9

R , 48 byte

function(n,s)table(cut(n,0:ceiling(max(n)/s)*s))

Provalo online!

Ancora una volta, tablee cutting ad un factorfare il trucco per il binning. Emette un nome vectordove namessono gli intervalli, ad esempio nella notazione degli intervalli (0,5].

EDIT: ripristina la versione precedente che funziona quando snon si divide n.


Davvero non R, ma su TIO questo sembra produrre a format you [most likely do not] find convenientsenza la tableparte.
mio pronome è monicareinstate il

@someone è esattamente per questo che è lì. cutdivide il vettore in fattori con livelli indicati dagli intervalli e tableconta le occorrenze di ciascun valore univoco nel suo input.
Giuseppe,

1
@Qualcuno ah, vedo, ho frainteso il tuo commento. No, penso che non sarebbe valido poiché abbiamo bisogno dei conteggi di ogni cestino.
Giuseppe,

1
Non pienamente provato, ma penso che si può risparmiare un paio di byte reaplacing 0:ceiling(max(n)/s)*scon seq(0,max(n)+s-1,s). Funziona almeno per i due campioni nella domanda.
Gregor Thomas,

1
@Gregor Hmm se funziona 1:max(n/s+1)*s-sè un altro miglioramento dato che i due sono equivalenti
Giuseppe,


3

Perl 5 -a -i , 32 28 byte

Dai il conto dopo l'opzione -i. Fornisci ogni elemento di input su una riga separata su STDIN

$G[~-$_/$^I]--}{say-$_ for@G

Provalo online!


2
Questo è impressionante.

3

Python 2 , 62 byte

I,s=input()
B=[0]*(~-I[-1]/s+1)
for i in I:B[~-i/s]+=1
print B

Provalo online!


1
Prima di tutto: bella risposta, l'ho già fatto +1 (e ho creato una porta in Java, perché è un po 'più corta di quella che avevo). Gli zero finali non sono consentiti tuttavia (appena richiesto OP), quindi I[-1]/s+1dovrebbe essere ~-I[-1]/s+1invece.
Kevin Cruijssen,

@KevinCruijssen Grazie per l'avviso!
Dead Possum

3

05AB1E , 18 byte

θs/Å0¹vDyI/î<©è>®ǝ

Provalo online!


Non conosco bene 05AB1E, ma questo sembra chiamare A.count max (A) , quindi il tempo di esecuzione non è lineare in len (A) + len (O) . È corretto o ho sbagliato qualcosa?
Dennis,

Il conteggio di @Dennis sarebbe O(max(A)*max(A))... quindi è quadratico sul massimo di A ... OP ha specificato che doveva essere lineare in termini di ... cosa esattamente?
Magic Octopus Urn

2
@MagicOctopusUrn Il tuo codice dovrebbe essere eseguito in tempo lineare nella somma delle lunghezze dell'input e dell'output , secondo l'ultima revisione.
Dennis,

2
@Dennis che sembra piuttosto arbitrario.
Magic Octopus Urn

2
@MagicOctopusUrn È l'unica definizione ragionevole per il tempo lineare per questa domanda, penso.

2

APL + WIN, 23 byte

Richiede l'immissione di schermate di bin e il vettore di numeri interi:

+⌿<\v∘.≤b×⍳⌈⌈/(v←⎕)÷b←⎕    

Spiegazione:

⎕ Prompt for input

⌈⌈/(v←⎕)÷b←⎕ divide the integers by bin size, take maximum and round up for number of bins

b×⍳ take number of bins from previous step and create a vector of bin upper boundaries

v∘.≤ apply outer product to generate boolean matrix where elements of vector ≤ boundaries

<\ switch off all 1's after first 1 in each row to filter multiple bin allocations

+⌿ sum columns for the result


2

Java 8, 75 byte

a->b->{var r=new int[~-a[a.length-1]/b+1];for(int i:a)r[~-i/b]++;return r;}

Port of @ DeadPossum's Python 2 answer , quindi assicurati di votare la sua risposta!

Spiegazione:

Provalo online.

a->b->{          // Method with integer-array and integer parameters and no return-type
  var r=new int[~-a[a.length-1]/b+1];
                 //  Result integer-array of size `((last_item-1)/bin_length)+1`
  for(int i:a)   //  Loop over the input-array
    r[~-i/b]++;  //   Increase the value at index `(i+1)/bin_length` by 1
  return r;}     //  Return the result-array


2

JavaScript (ES6), 60 byte / O (len (a) + max (a) / n)

5 byte salvati grazie a @Neil

Accetta input nella sintassi del curry (a)(n).

a=>n=>[...a.map(x=>o[x=~-x/n|0]=-~o[x],o=[])&&o].map(n=>~~n)

Provalo online!

O solo 43 byte / O (len (a)) se sono ammessi elementi vuoti.


[...o].map(n=>n|0)ottiene il primo output dalla seconda soluzione in meno byte.
Neil,

@Neil Non sono sicuro del motivo per cui ho scelto qualcosa di così contorto. : - /
Arnauld

2

Haskell , 63 75 70 byte

l!n=l#[n,2*n..]
[]#_=[]
l#(b:i)|h<-length$takeWhile(<=b)l=h:drop h l#i

Spiacenti, questo più breve non è lineare ma quadratico;

l!n=l#[n,2*n..]
[]#_=[]
l#(b:i)=sum[1|a<-l,a<=b]:[a|a<-l,a>b]#i

Provalo online!


1

Pyth, 23 22 byte

Jm/tdeQhQK*]ZheJhXRK1J

Provalo qui

Jm/tdeQhQK*]ZheJhXRK1J
Jm/tdeQhQ                 Find the bin for each time and save them as J.
         K*]ZheJ          Create empty bins.
                 XRK1J    Increment the bins for each time within them.
                h         Take the first (because mapping returned copies).

1

Rubino , 53 50 byte

Modifica: -3 byte di iamnotmaynard.

->a,b{(0..~-a.max/b).map{|i|a.count{|x|~-x/b==i}}}

Provalo online!


Questo non funziona quando a.maxnon è un multiplo di b(es. f[[1,1,1,2,7,10],3]=> [4, 0, 1]Ma dovrebbe dare [4, 0, 2]). Avevo provato lo stesso approccio.
Ripristina Monica - notmaynard,

(o meglio [4, 0, 1, 1])
Ripristina Monica - notmaynard

Bene, questo è risolvibile passando a un valore di intervallo massimo float, ma chiederò anche a OP di chiarire questo nella descrizione dell'attività.
Kirill L.


Bello, ancora meglio, grazie.
Kirill L.

1

Questo puzzle è essenzialmente un tipo di conteggio. Non conosciamo la lunghezza dell'output senza prima passare attraverso l'input.

C (clang) , 53 byte

i,j;f(*A,l,b,*O){for(j=0;j<l;O[(A[j++]+b-1)/b-1]++);}

Provalo online!

Questa soluzione accetta i seguenti parametri:
Ainput array
llength of A
bbin_size
Ostorage for Output. Deve avere una lunghezza sufficiente
e restituisce un output in O.

Questa soluzione ha un handicap: non restituisce la lunghezza dell'array di output O, quindi il chiamante non sa quanto stampare.

La seguente versione supera questo handicap:

C (clang) , 79 byte

i,j,k;f(*A,l,b,*O,*m){for(k=j=0;j<l;O[i=(A[j++]+b-1)/b-1]++,k=k>i?k:i);*m=++k;}

Provalo online!

Prende un parametro aggiuntivo me ne restituisce la lunghezza O. Mi è costato 26 byte.


1

C (gcc) , 102 90 89 86 byte

#define P!printf("%d ",k)
i,j,k;f(s){for(i=s;~scanf("%d",&j);k++)for(;j>i;i+=s)k=P;P;}

Provalo online!

Grazie a Kevin Cruijssen per il taglio di 12 byte e plafoniera per altri 4 byte!


1
90 byte usando for-loops, rimuovendo inte cambiando ==1in >0.
Kevin Cruijssen,

Prego. A proposito, solo una nota, al momento non è valido (proprio come la mia risposta Java ora cancellata era). Deve essere eseguito in O(n)tempo, quindi non puoi avere alcun for-loop nidificato .. (Tuttavia, la tua risposta in C ++ sembra a posto. Quindi ho fatto +1 su quello. :))
Kevin Cruijssen

È ancora O (n). Il ciclo interno stamperà sempre un valore e in totale stamperemo (valore massimo + 1) / valori binsize.
G. Sliepen,

Hmm, ma non è già il loop esterno eseguendo il O(n)loop sugli elementi di input. Anche se il ciclo interno farebbe solo un ciclo 2 volte è già sopra O(n). O sto fraintendendo qualcosa .. Devo ammettere che i Otempi non sono davvero la mia esperienza ..
Kevin Cruijssen

1
Ma il ciclo interno non esegue l'iterazione su tutti gli elementi di input, ma itera solo per quanti valori di output è necessario stampare per "raggiungere" la posizione corrispondente all'elemento di input più recente. Se il vettore di input è costituito da molti duplicati o valori che differiscono meno della dimensione del cestino, il ciclo interno non eseguirà alcuna iterazione. D'altra parte, se il vettore di input è molto scarso, il ciclo interno eseguirà più iterazioni, stampando 0. Quindi, per essere corretti, il codice viene eseguito nel tempo O ((numero di elementi di input) + (dimensione dell'ultimo elemento / bin)). Questo è ancora lineare.
G. Sliepen,
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.