Raggruppa un elenco per frequenza


26

Dato un elenco di numeri interi, raggruppa gli elementi che si verificano per primi, quindi raggruppa il successivo e così via fino a quando ogni elemento univoco nell'elenco non è stato raggruppato una volta.


Esempi:

Ingresso: [1,2,3]

Produzione: [[1,2,3]]


Ingresso: [1,1,1,2,2,3,3,4,5,6]

Produzione: [[1],[2,3],[4,5,6]]


Ingresso: [1,1,1,4,5,6,6,6,7,7,8,8,8,8,8,8,8,9,5,6,5,6,5,6,5,6,-56]

Produzione: [[6, 8],[5],[1],[7],[9,4,-56]]


Ingresso: []

Produzione: []


Ingresso: (empty input)

Produzione: ERROR/Undefined/Doesn't matter


Regole

  • I raggruppamenti devono andare dalla frequenza massima alla frequenza minima.
  • L'ordine interno dei raggruppamenti è arbitrario (invece l'esempio 3 potrebbe avere [8,6]).
  • Questo è , vince il conteggio di byte più basso.

Relazionato


1
L'output può essere in formato stringa? Vale a dire. Un elenco di elenchi, ma ogni numero rappresentato da un carattere anziché da un numero intero.
— mb7744,

Risposte:



7

Mathematica, 43 byte

Union/@SortBy[l=#,f=-l~Count~#&]~SplitBy~f&

Provalo online! (Usando la matematica.)

In alternativa:

SortBy[Union[l=#],f=-l~Count~#&]~SplitBy~f&

5
Non è integrato?
— Magic Octopus Urn,

È GatherByun'opzione, non sono sicuro perché non conosco la lingua.
— Magic Octopus Urn,

1
@carusocomputing Ordina i gruppi in base alla prima occorrenza degli elementi nell'elenco originale, quindi dovrei comunque ordinare i gruppi in seguito. Ordinando prima l'elenco, posso salvare un byte con SplitBy(inoltre SortBysarebbe effettivamente più complicato se lo facessi GatherByprima).
— Martin Ender,

Interessante, quindi il "deve essere in ordine dal massimo al minimo" rovina tutto?
— Magic Octopus Urn,

@carusocomputing Esatto.
— Martin Ender,

5

Python 2 , 145 141 byte

import collections as c,itertools as i;o=lambda n:lambda l:l[n]
print[map(o(0),g)for _,g in i.groupby(c.Counter(input()).most_common(),o(1))]

Provalo online!

Questa è la mia prima presentazione dopo anni di lettura.

Fondamentalmente mette tutti gli elementi in un contatore (dizionario di quanti di ciascun elemento nell'elenco) e .most_common () mette gli elementi in ordine decrescente di frequenza. Dopodiché, si tratta solo di formattare gli elementi nell'elenco giusto.

Salvato 4 byte grazie a ovs .


4
Benvenuto in PPCG :). Non diventare dipendente come me.
— Magic Octopus Urn,

La creazione della tua funzione itemgetter è più corta di 4 byte rispetto all'importazione:o=lambda n:lambda l:l[n]
— ovs

5

JavaScript (ES6), 95 101 byte

a=>a.map(x=>(o[a.map(y=>n+=x!=y,n=0)|n]=o[n]||[])[x*x+(x>0)]=x,o=[])&&(F=o=>o.filter(a=>a))(o).map(F)

Come?

Per ogni elemento x dell'array di input a , calcoliamo il numero n di elementi di a che sono diversi da x :

a.map(y => n += x != y, n = 0) | n

Usiamo gli indici n e x per riempire l'array o :

(o[n] = o[n] || [])[x * x + (x > 0)] = x

Modifica : poiché JS non supporta indici di array negativi, abbiamo bisogno della formula x * x + (x > 0)per forzare indici positivi.

Questo ci offre una serie di array contenenti gli elementi univoci della lista originale, raggruppati per frequenza e ordinati dal più frequente al meno frequente.

Tuttavia, sia l'array esterno che quello interno hanno potenzialmente molti slot vuoti che vogliamo filtrare. Lo facciamo con la funzione F , applicata a o e ciascuno dei suoi elementi:

F = o => o.filter(a => a)

Casi test


Penso che un Setpuoi risparmiare un byte: a=>a.map(e=>(r[n=0,a.map(f=>n+=e!=f),n]||(r[n]=new Set)).add(e),r=[])&&r.filter(s=>s).map(s=>[...s]).
— Neil,

@Neil Questo è abbastanza diverso dal mio attuale approccio. Forse dovresti pubblicarlo come una nuova risposta?
— Arnauld,

Non pensavo che passare o[n]da un array a un set fosse così diverso, ma ho già giocato a golf con la risposta di @ RickHitchcock comunque, quindi non ha molto senso.
— Neil,



2

Clojure, 74 byte

#(for[[_ g](sort-by(comp - key)(group-by val(frequencies %)))](map key g))

Sembra abbastanza prolisso: /


Sconfiggimi (e picchiami di qualche byte, uso intelligente comp -per invertire!). Non così breve come altre lingue, ma ho pensato che fosse divertente dato che Clojure ha "raggruppamento" e "frequenze" integrate.
— MattPutnam,

Quando ho letto la descrizione dell'attività speravo in 50 o 60 byte, ma l'implementazione effettiva si è rivelata un po 'più complicata.
— NikoNyrh,

2

Perl 6 , 43 byte

*.Bag.classify(-*.value).sort».value».key

Provalo

Allargato:

*                   # WhateverCode lambda (this is the input)
                    # [1,1,1,2,2,3,3,4,5,6]

.Bag                # turn into a Bag
                    # (1=>3,5=>1,4=>1,3=>2,6=>1,2=>2).Bag

.classify(-*.value) # classify by how many times each was seen
                    # {-2=>[3=>2,2=>2],-3=>[1=>3],-1=>[5=>1,4=>1,6=>1]}

.sort\              # sort (this is why the above is negative)
                    # {-3=>[1=>3],-2=>[3=>2,2=>2],-1=>[5=>1,4=>1,6=>1]}

».value\            # throw out the classification
                    # ([1=>3],[3=>2,2=>2],[5=>1,4=>1,6=>1])

».key               # throw out the counts
                    # ([1],[3,2],[5,4,6])

Caspita, mi dimentico sempre Bag, bello!
— Magic Octopus Urn,

2

Utilità Bash + GNU, 71 61

sort|uniq -c|sort -nr|awk '{printf$1-a?"\n%d":",%d",$2;a=$1}'

Input come un elenco delimitato da nuova riga. Output come un elenco delimitato da nuova riga di valori separati da virgola.

Provalo online .


2

MATL , 9 byte

9B#uw3XQP

L'input è un vettore di colonna, che utilizza ;come separatore.

Provalo online!

Spiegazione

9B#u   % Call 'unique' function with first and fourth outputs: unique entries and
       % number of occurrences
w      % Swap
3XQ    % Call 'accumarray' with anonymous function @(x){sort(x).'}. The output is
       % a cell array with the elements of the input grouped by their frequency.
       % Cells are sorted by increasing frequency. Some cells may be empty, but
       % those won't be displayed
P      % Flip cell array, so that groups with higher frequency appear first.
       % Implicitly display

2

k, 22 byte

{x@!x}{(>x)@=x@>x}#:'=

Provalo online.

( La k di AW sembra richiedere un extra @prima di #, ma oK no.)

Spiegazione:

                     = /group identical numbers in a map/dict
                  #:'  /get number of times each number is repeated
                       /this is almost the answer, but without the inner lists
      {      x@>x}     /order "number of times" greatest to least
            =          /group them (to make the smaller groups)
       (>x)@           /get the actual numbers into place
{x@!x}                 /get values of the map/dict it's in

github.com/JohnEarnest/ok per chiunque si chieda cosa ksia, in realtà è ok. Ba-dum-tssss ...
— Magic Octopus Urn

2

Brachylog , 10 byte

ọtᵒ¹tᵍhᵐ²|

Provalo online!

Spiegazione

Example input: [2,1,1,3]

ọ            Occurences:            [[2,1],[1,2],[3,1]]
 tᵒ¹         Order desc. by tail:   [[1,2],[3,1],[2,1]]
    tᵍ       Group by tail:         [[[1,2]],[[3,1],[2,1]]]
      hᵐ²    Map twice head:        [[1],[3,2]]

         |   Else (Input = [])      Input = Output

2

Mathematica, 79 byte

Table[#&@@@f[[i]],{i,Length[f=GatherBy[Sort[Tally@#,#1[[2]]>#2[[2]]&],Last]]}]&

ingresso

[{1, 1, 1, 4, 5, 6, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 9, 5, 6, 5, 6, 5, 6, 5, 6, -56}]

produzione

{{8, 6}, {5}, {1}, {7}, {-56, 9, 4}}


The GatherBy di cui ho parlato con Martin! Mi chiedevo come sarebbe stato fatto :).
— Magic Octopus Urn,

Sort[...,...&]è giusto SortBy[...,-Last@#&].
— Martin Ender,

Length[f=...]. Ed First/@è #&@@@.
— Martin Ender,

fisso, fisso e fisso
— J42161217

2

R , 84 77 byte

-7 byte grazie a mb7744

unique(lapply(x<-sort(table(scan()),T),function(y)as.double(names(x[x==y]))))

Legge da stdin; restituisce un elenco con sottovettori di numeri interi in ordine crescente. Se potessimo restituire stringhe invece di ints, allora potrei rilasciare 11 byte (rimuovendo la chiamata a as.double), ma questo è tutto. La tablefunzione di R fa il sollevamento pesante qui, contando le occorrenze di ciascun membro del suo input; quindi li aggrega per count ( names). Certo, questa è una stringa, quindi dobbiamo costringerla a un numero intero / doppio.

Provalo online!


Puoi perdere 7 byte eliminando il "quale" e utilizzando l'indicizzazione logica
— mb7744

@ mb7744 oh duh.
— Giuseppe,

1
Ho preso un'altra pugnalata con R. È sfortunato quanto sia lunga la sintassi lambda, quindi ho deciso di evitare. In cambio ho dovuto usare quelli nidificati lapply, ma almeno in quel caso posso assegnare una breve variabile a lapply. Non riesco ad assegnare una variabile alla funzione function...
— mb7744

2

JavaScript (ES6), 100 98 96 93 byte

Salvato 2 byte grazie a @Neil (in più ha risolto un bug del caso limite nel mio codice). Salvati altri 3 byte grazie a @TomasLangkaas.

a=>a.sort().map((_,n)=>a.filter((v,i)=>i-a.indexOf(v)==n&v!=a[i+1])).filter(a=>a+a).reverse()

Casi test

f=
a=>a.sort().map((_,n)=>a.filter((v,i)=>i-a.indexOf(v)==n&v!=a[i+1])).filter(a=>a+a).reverse()

console.log(JSON.stringify(f([1,2,3])))
console.log(JSON.stringify(f([1,1,1,2,2,3,3,4,5,6])))
console.log(JSON.stringify(f([1,1,1,4,5,6,6,6,7,7,8,8,8,8,8,8,8,9,5,6,5,6,5,6,5,6,-56])))
console.log(JSON.stringify(f([])))


Il test è viziata (non funziona per lo zero), ma penso che si può ancora salvare byte filtrando e invertendo invece di unshifting: a=>a.sort().map((_,n)=>a.filter((v,i)=>i-a.indexOf(v)==n&v!=a[i+1])).filter(a=>1/a[0]).reverse().
— Neil,

Ahh, avrei dovuto sapere di provare per 0! Il tuo codice lo risolve, inoltre è più breve, quindi grazie per quello
— :)

Salva altri 3 byte cambiando .filter(a=>1/a[0])in .filter(a=>''+a).
— Tomas Langkaas,

Bello, @TomasLangkaas, grazie. (Salva 2 byte.)
— Rick Hitchcock,

Mio male (ho problemi con il conteggio), ma .filter(a=>a+a)fornirebbe il byte in più.
— Tomas Langkaas,

1

V , 60 , 54 byte

Úòͨ¼¾©î±/± ±òHòø 
pkJjòú!
Ǩ^ƒ ©î±/o
Îf ld|;D
òV{Jk

Provalo online!

hexdump:

00000000: daf2 cda8 bc81 bea9 eeb1 2fb1 20b1 f248  ........../. ..H
00000010: f2f8 200a 706b 4a6a f2fa 210a c7a8 5e83  .. .pkJj..!...^.
00000020: 20a9 81ee b12f 6f0a ce66 206c 647c 3b44   ..../o..f ld|;D
00000030: 0af2 567b 4a6b                           ..V{Jk

Per quanto io ami V, sono abbastanza sicuro che questa sia la peggior lingua possibile per l'attività. Soprattutto se si considera che non ha supporto per gli elenchi e sostanzialmente nessun supporto per i numeri. Solo manipolazione di stringhe.


1

C #, 119 byte

Solo una rapida pugnalata:

using System.Linq;
a=>a.GroupBy(x=>x)
    .GroupBy(x=>x.Count(),x=>x.Key)
    .OrderBy(x=>-x.Key)
    .Select(x=>x.ToArray())
    .ToArray()

2
+1 È possibile rimuovere il System.Func<int[],int[][]>F=e trailing ;comunque. Questo non fa parte del conteggio dei byte per questo tipo di lambda.
— Kevin Cruijssen,

@KevinCruijssen, non ne avevo idea. Grazie!
— Hand-E-Food,

1

R , 66 byte

(l=lapply)(l(split(x<-table(scan()),factor(-x)),names),as.integer)

Provalo online!

Se nell'output gli interi possono essere in formato stringa, possono scendere a 48 byte (come indicato nella risposta di @ Giuseppe).


Ungolfed:

input <- scan(); # read input
x <- table(input); # count how many times each integer appears, in a named vector
y <- split(x, factor(-x)) # split the count into lists in increasing order
z <- lapply(y, names) # access the the original values which are still
                      # attached via the names
lapply(z, as.integer) # convert the names back to integers

as.doubleè più corto di un byte e dovrebbe funzionare comeas.integer
— Giuseppe,

Bene, dipende se si desidera restituire un numero intero o un doppio. Se il doppio va bene, forse lo sarebbe anche il personaggio e potremmo salvare entrambi dei byte.
— mb7744,

1

PowerShell, 77, 70 byte

($a=$args)|group{($a-eq$_).count}|sort n* -Des|%{,($_.group|sort -u)}

NB: Per vedere che questi risultati sono correttamente raggruppati (dal momento che visivamente non c'è delineamento tra i contenuti di ciascun array), potresti voler aggiungere | write-hostalla fine della riga sopra.

Ringraziamenti

Grazie a:

  • TessellatingHeckler per il salvataggio di 7 byte mediante il refactoring / riscrittura massiccia di un approccio più golfizzato.

Precedente

77 byte

param($x)$x|group|sort count -desc|group count|%{,($_.group|%{$_.group[0]})}

Bene grazie. Ho dovuto includere il ,()raggruppamento per (dal momento che l'output mostrava solo un array continuo). Questo è molto più goloso del mio tentativo originale; lavoro fantastico!
— JohnLBevan,

0

Groovy, 71 byte

{a->a.groupBy{a.count(it)}.sort{-it.key}.values().collect{it.unique()}}

In realtà ho appena imparato a conoscere GroupBy dopo averlo creato. Non sapevo che collezionare non fosse la mia unica scelta.


{
    a->                 // [1,2,1,2,3,3,3,6,5,4]
    a.groupBy{      
        a.count(it)     // [2:[1,2,1,2],3:[3,3,3],1:[6,5,4]]
    }.sort{             
        -it.key         // [3:[3,3,3],2:[1,2,1,2],1:[6,5,4]]
    }.values().collect{ // [[3,3,3],[1,2,1,2],[6,5,4]]
        it.unique()
    }                   // [[3],[1,2],[6,5,4]]
}

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.