Gruppieren Sie eine Liste nach Häufigkeit


26

Bei einer Liste von Ganzzahlen gruppieren Sie die Elemente, die zuerst am häufigsten vorkommen, und gruppieren Sie dann die nächsten am häufigsten usw., bis jedes einzelne Element in der Liste einmal gruppiert wurde.


Beispiele:

Eingang: [1,2,3]

Ausgabe: [[1,2,3]]


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

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


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

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


Eingang: []

Ausgabe: []


Eingang: (empty input)

Ausgabe: ERROR/Undefined/Doesn't matter


Regeln

  • Die Gruppierungen müssen von der Maximalfrequenz zur Minimalfrequenz gehen.
  • Die interne Reihenfolge der Gruppierungen ist willkürlich (zB könnte Beispiel 3 [8,6]stattdessen haben).
  • Dies ist , die niedrigste Anzahl an Bytes gewinnt.

verbunden


1
Kann die Ausgabe im String-Format erfolgen? Dh Eine Liste von Listen, aber jede Zahl wird durch ein Zeichen anstelle einer Ganzzahl dargestellt.
mb7744

Antworten:



7

Mathematica, 43 Bytes

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

Probieren Sie es online! (Verwenden von Mathematik.)

Alternative:

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

5
Es gibt kein eingebautes?
Magic Octopus Urn

Ist GatherByeine Option, nicht sicher, weil ich die Sprache nicht kenne.
Magic Octopus Urn

1
@carusocomputing Sortiert die Gruppen nach dem ersten Vorkommen der Elemente in der ursprünglichen Liste, sodass ich die Gruppen danach immer noch sortieren muss. Indem ich die Liste zuerst sortiere, kann ich ein Byte mit speichern SplitBy(auch das SortBywäre tatsächlich komplizierter, wenn ich es GatherByzuerst getan hätte ).
Martin Ender

Interessant, also das "muss in Ordnung sein von maximal bis minimal" vermasselt das?
Magic Octopus Urn

@carusocomputing Genau.
Martin Ender

5

Python 2 , 145 141 Bytes

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

Probieren Sie es online!

Dies ist meine erste Vorlage nach Jahren des Lesens.

Im Grunde genommen werden alle Elemente in einem Zähler abgelegt ( Verzeichnis der Anzahl der Elemente in der Liste) und .most_common () ordnet die Elemente in absteigender Reihenfolge der Häufigkeit an. Danach müssen die Elemente nur noch in der richtigen Liste formatiert werden.

4 Bytes dank ovs gespart .


4
Willkommen bei PPCG :). Werden Sie nicht so süchtig wie ich.
Magic Octopus Urn

Das Erstellen einer eigenen Itemgetter-Funktion ist 4 Byte kürzer als das Importieren:o=lambda n:lambda l:l[n]
ovs

5

JavaScript (ES6), 95 bis 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)

Wie?

Für jedes Element x des Eingabearrays a berechnen wir die Anzahl n der Elemente von a , die sich von x unterscheiden :

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

Wir verwenden die Indizes n und x , um das Array o zu füllen :

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

Bearbeiten : Da JS keine negativen Array-Indizes unterstützt, benötigen wir die Formel x * x + (x > 0), um positive Indizes zu erzwingen.

Dies gibt uns ein Array von Arrays, die die eindeutigen Elemente der ursprünglichen Liste enthalten, gruppiert nach Häufigkeit und geordnet von am häufigsten bis am seltensten.

Sowohl das äußere als auch das innere Array haben möglicherweise viele leere Slots, die herausgefiltert werden sollen. Wir tun dies mit der Funktion F , die auf o und jedes seiner Elemente angewendet wird :

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

Testfälle


Ich denke , ein Setspart ein 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 Das ist ganz anders als meine derzeitige Vorgehensweise. Vielleicht solltest du es als neue Antwort posten?
Arnauld

Ich habe nicht gedacht, dass der Wechsel o[n]von einem Array zu einem Set so anders ist, aber ich habe bereits @ RickHitchcocks Antwort golfen, also gibt es nicht so viel Sinn.
Neil



2

Clojure, 74 Bytes

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

Sieht ziemlich ausführlich aus: /


Schlagen Sie mich dazu (und schlagen Sie mich durch ein paar Bytes, kluger Gebrauch, comp -um umzukehren!). Nicht so kurz wie andere Sprachen, aber ich fand es amüsant, da Clojure "Group-by" und "Frequenzen" eingebaut hat.
MattPutnam

Als ich die Aufgabenbeschreibung las, hoffte ich auf 50 oder 60 Bytes, aber die tatsächliche Implementierung erwies sich als etwas kniffliger.
NikoNyrh

2

Perl 6 , 43 Bytes

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

Probier es aus

Erweitert:

*                   # 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])

Wow, vergesse ich immer Bag, nette!
Magic Octopus Urn

2

Bash + GNU-Dienstprogramme, 71 61

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

Eingabe als durch neue Zeilen getrennte Liste. Ausgabe als durch Zeilenumbrüche getrennte Liste von durch Kommas getrennten Werten.

Probieren Sie es online aus .


2

MATL , 9 Bytes

9B#uw3XQP

Die Eingabe ist ein Spaltenvektor, der ;als Trennzeichen verwendet wird.

Probieren Sie es online!

Erläuterung

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 Bytes

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

Probieren Sie es online aus.

( AW's k scheint ein Extra @vor dem zu erfordern #, aber OK nicht.)

Erläuterung:

                     = /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 für alle anderen, die sich fragen, was kes eigentlich ist ok. Ba-Dum-Tssss ...
Magic Octopus Urn

2

Brachylog , 10 Bytes

ọtᵒ¹tᵍhᵐ²|

Probieren Sie es online!

Erläuterung

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 Bytes

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

Eingang

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

Ausgabe

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


Das GatherBy habe ich Martin gegenüber erwähnt! Ich habe mich gefragt, wie das gemacht wird :).
Magic Octopus Urn

Sort[...,...&]ist einfach SortBy[...,-Last@#&].
Martin Ender

Length[f=...]. Und First/@ist #&@@@.
Martin Ender

fest, fest und fest
J42161217

2

R , 84 77 Bytes

-7 Bytes dank mb7744

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

Liest von stdin; Gibt eine Liste mit Untervektoren von ganzen Zahlen in aufsteigender Reihenfolge zurück. Wenn wir Strings anstelle von ints zurückgeben könnten, dann könnte ich 11 Bytes löschen (den Aufruf von entfernen as.double), aber das war es auch schon. Die tableFunktion von R übernimmt hier das schwere Heben, indem die Vorkommen jedes Mitglieds seiner Eingabe gezählt werden. dann aggregiert es sie nach count ( names). Natürlich ist das eine Zeichenkette, also müssen wir sie zu einer Ganzzahl / einem Doppelten zwingen.

Probieren Sie es online!


Sie können 7 Bytes verlieren, indem Sie das "
Was

@ mb7744 oh duh.
Giuseppe

1
Ich habe es erneut mit R probiert. Es ist bedauerlich, wie lang die Lambda-Syntax ist, und ich habe versucht, sie zu umgehen. Im Gegenzug musste ich geschachtelte verwenden lapply, aber zumindest in diesem Fall kann ich eine kurze Variable zuweisen lapply. Ich kann der Funktion scheinbar keine Variable zuweisen function...
mb7744

2

JavaScript (ES6), 100 98 96 93 Byte

2 Bytes dank @Neil gespart (und einen Edge-Case-Fehler in meinem Code behoben). 3 weitere Bytes dank @TomasLangkaas gespeichert.

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

Testfälle

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


Ihr Test ist fehlerhaft (funktioniert nicht für Null) , aber ich denke , man kann immer noch speichern Bytes durch Filtern und statt unshifting Umkehrung: 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, ich hätte es wissen müssen, um auf 0 zu testen! Ihr Code behebt es und es ist kürzer, also danke dafür
Rick Hitchcock

Speichern 3 weitere Bytes durch Änderung .filter(a=>1/a[0])zu .filter(a=>''+a).
Tomas Langkaas

Schön, @TomasLangkaas, danke. (Spart 2 Bytes.)
Rick Hitchcock

Mein schlechtes (habe Probleme mit dem Zählen), .filter(a=>a+a)würde aber das extra Byte liefern.
Tomas Langkaas

1

V , 60 , 54 Bytes

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

Probieren Sie es 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

So sehr ich V auch liebe, ich bin mir ziemlich sicher, dass dies die schlechteste Sprache für diese Aufgabe ist. Besonders wenn man bedenkt, dass es keine Unterstützung für Listen und im Grunde keine Unterstützung für Zahlen gibt. Nur die Manipulation von Strings.


1

C #, 119 Bytes

Nur ein kurzer Versuch:

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 Sie können das System.Func<int[],int[][]>F=und das Nachziehen jedoch entfernen ;. Das ist nicht Teil der Byteanzahl für diese Art von Lambdas.
Kevin Cruijssen

@ KevinCruijssen, ich hatte keine Ahnung. Vielen Dank!
Hand-E-Food

1

R , 66 Bytes

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

Probieren Sie es online!

Wenn die Ganzzahlen in der Ausgabe möglicherweise im Zeichenfolgenformat vorliegen, können sie auf 48 Byte sinken (wie in der Antwort von @ Giuseppe angegeben).


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.doubleist um ein Byte kürzer und sollte genauso funktionieren wieas.integer
Giuseppe

Nun, es hängt davon ab, ob Sie eine Ganzzahl oder ein Double zurückgeben möchten. Wenn double in Ordnung ist, wäre das vielleicht auch ein Zeichen, und wir könnten beide ein paar Bytes sparen.
mb7744

1

PowerShell, 77, 70 Byte

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

Hinweis: Um sicherzustellen, dass diese Ergebnisse korrekt gruppiert sind (da visuell keine Abgrenzung zwischen den Inhalten der einzelnen Arrays besteht), möchten Sie möglicherweise | write-hostdas Ende der obigen Zeile anhängen .

Danksagung

Dank an:

  • TessellatingHeckler für das Einsparen von 7 Bytes durch massives Refactoring / Umschreiben, um den Golfansatz zu verbessern.

Bisherige

77 Bytes

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

Nett, danke. Ich musste die ,()für die Gruppierung einschließen (da die Ausgabe nur als ein kontinuierliches Array angezeigt wurde). Das ist viel mehr Golf als mein ursprünglicher Versuch; Gute Arbeit!
JohnLBevan

0

Groovy, 71 Bytes

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

Ich habe gerade erst von groupBy erfahren, als ich das erstellt habe. Ich wusste nicht, dass Sammeln nicht meine einzige Wahl ist.


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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.