Bir Listeyi Frekansa Göre Gruplama


26

Bir tamsayı listesi verildiğinde, en önce gerçekleşen öğeleri gruplandırın, ardından listedeki her bir benzersiz öğe bir kez gruplanıncaya kadar en sonuncuyu ve diğerlerini gruplandırın.


Örnekler:

Giriş: [1,2,3]

Çıktı: [[1,2,3]]


Giriş: [1,1,1,2,2,3,3,4,5,6]

Çıktı: [[1],[2,3],[4,5,6]]


Giriş: [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]

Çıktı: [[6, 8],[5],[1],[7],[9,4,-56]]


Giriş: []

Çıktı: []


Giriş: (empty input)

Çıktı: ERROR/Undefined/Doesn't matter


kurallar

  • Gruplamalar maksimum frekanstan minimum frekansa geçmelidir.
  • Grupların iç sırası isteğe bağlıdır ( [8,6]bunun yerine EG örnek 3 olabilir ).
  • Bu , en düşük bayt sayma kazançtır.

İlgili


1
Çıktı dize biçiminde olabilir mi? Yani. Bir listeler listesi, ancak her sayı bir tamsayı yerine bir karakterle temsil edilir.
mb7744

Yanıtlar:



7

Mathematica, 43 bayt

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

Çevrimiçi deneyin! (Matematik kullanarak.)

Alternatif:

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

5
Yerleşik yok mu?
Magic Octopus Urn,

GatherByben dilini bilmiyorum emin, çünkü bir seçenek.
Magic Octopus Urn,

1
@carusocomputing Grupları, ilk listedeki öğelerin ilk oluşumuna göre sıralar, bu yüzden grupları daha sonra sıralamak zorunda kalacağım. Önce listeyi sıralayarak, bir byte kaydedebilirim SplitBy( ilk önce SortByyaparsam daha da karmaşık olurdu GatherBy).
Martin Ender

İlginç, öyleyse "maksimalden minimuma kadar sıralı olmalı" diye hitap ediyor
Magic Octopus Urn,

@carusocomputing Kesinlikle.
Martin Ender

5

Python 2 , 145 141 bayt

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

Çevrimiçi deneyin!

Bu yıllarca okuduktan sonra ilk gönderim.

Temel olarak, tüm öğeleri bir Sayaç içine koyar (listedeki her bir öğenin kaç tanesinin sözlüğü) ve .most_common () öğeleri azalan sıklık sırasına koyar. Ondan sonra, sadece öğeleri doğru listeye biçimlendirme meselesi.

Ovs sayesinde 4 byte kurtarıldı .


4
PPCG'ye Hoşgeldiniz :). Benim kadar bağımlısı olma.
Magic Octopus Urn,

Kendi itemgetter işlevi oluşturma aktarmadan 4'ten bayt kısadır:o=lambda n:lambda l:l[n]
ovs

5

JavaScript (ES6), 95 101 bayt

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)

Nasıl?

Her bir eleman için, x Girdi dizisi bir a , biz dizi hesaplamak n elemanlarının bir farklı olduğu , x :

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

Biz endeksi kullanmak , n ve x dizisini doldurmak için o :

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

Düzenleme : JS negatif dizi endekslerini desteklemediğinden, x * x + (x > 0)pozitif endeksleri zorlamak için formüle ihtiyacımız var .

Bu, bize orijinal listenin benzersiz öğelerini içeren, sıklığa göre gruplandırılmış ve en sık sık en az sıkça sıralanan bir dizi dizisi verir.

Bununla birlikte, hem dış dizi hem de iç diziler potansiyel olarak filtrelemek istediğimiz birçok boş yuvaya sahiptir. Bunu, F'ye , o'ya ve elemanlarının her birine uygulanan :

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

Test durumları


Ben düşünüyorum Setsize byte kaydeder: 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 Bu benim şu anki yaklaşımımdan oldukça farklı. Belki de yeni bir cevap olarak göndermelisin?
Arnauld,

Ben değiştirmeyi düşünmedim o[n]kümesine bir diziden farklı, ama RickHitchcock cevabı zaten bu yüzden bu kadar nokta orada değil @ Zaten golfed.
Neil



2

Clojure, 74 bayt

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

Çok ayrıntılı görünüyor:


Beni dövün (ve beni bir kaç byte yenin, zekice kullanın comp -!). Diğer diller kadar kısa değil ama
Clojure'un

Görev tanımını okuduğumda 50 ya da 60 bayt umuyordum, ancak gerçek uygulamanın biraz daha zor olduğu ortaya çıktı.
NikoNyrh

2

Perl 6 , 43 bayt

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

Dene

Expanded:

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

Vay canına, her zaman unutuyorum Baggüzel olanı!
Magic Octopus Urn,

2

Bash + GNU yardımcı programları, 71 61

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

Yeni satır ayrılmış bir liste olarak giriş yapın. Yeni satırlı, virgülle ayrılmış değerler listesi olarak çıktı alın.

Çevrimiçi deneyin .


2

MATL , 9 bayt

9B#uw3XQP

Giriş, ;ayırıcı olarak kullanan bir sütun vektörüdür .

Çevrimiçi deneyin!

açıklama

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 bayt

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

Çevrimiçi deneyin.

( AW’lerin k’sinden@ önce bir ekstraya ihtiyaç var gibi gözüküyor #, ancak OK bunu gerektirmiyor .)

Açıklama:

                     = /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 başkalarının ne kolduğunu merak edenler için , aslında bu ok. Ba-dum-tssss ...
Magic Octopus Urn

2

Brachylog , 10 bayt

ọtᵒ¹tᵍhᵐ²|

Çevrimiçi deneyin!

açıklama

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 bayt

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

giriş

[{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)

çıktı

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


GatherBy Martin'e bahsettiğim! Bunun nasıl yapıldığını merak ettim :).
Magic Octopus Urn,

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

Length[f=...]. Ve First/@olduğunu #&@@@.
Martin Ender

sabit, sabit ve sabit
J42161217

2

R , 84 77 bayt

Mb7744 sayesinde -7 bayt

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

Stdin'den okur; Tamsayı alt düzenleyicileri ile artan düzende bir liste döndürür. Eğer string yerine string döndürebilirsek, 11 byte bırakabilirim (çağrıyı kaldırabilirim as.double), ama bununla ilgili. R'nin tableişlevi burada ağır kaldırma yapar ve girişindeki her bireyin oluşumunu sayar; daha sonra onları count ( names) ile toplar . Tabii ki, bu bir dize, bu yüzden onu bir tamsayıya / çiftliğe zorlamak zorundayız.

Çevrimiçi deneyin!


"Hangisini" ortadan kaldırarak ve mantıksal endekslemeyi kullanarak 7 bayt kaybedebilirsiniz
mb7744

@ mb7744 oh duh.
Giuseppe

1
R ile başka bir bıçak aldım. Lambda sözdiziminin ne kadar uzun sürdüğü talihsiz bir durum, bu yüzden kaçınmaya çalışıyorum. Buna karşılık lapply, iç içe geçmişleri kullanmak zorunda kaldım , ancak en azından bu durumda kısa bir değişken atayabilirim lapply. Fonksiyona bir değişken function
atamıyor gibiyim

2

JavaScript (ES6), 100 98 96 93 bayt

@Neil sayesinde 2 bayt kaydedildi (ayrıca kodumda bir uç hata oluştu). @TomasLangkaas sayesinde 3 bayt daha kaydedildi.

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

Test durumları

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


Testiniz kusurludur (sıfır için çalışmaz) ama filtreleme ve unshifting yerine tersine çevirerek bayt tasarruf hala yapabilirsiniz düşünüyorum: 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, 0 için test etmeliydim! Kodunuz düzeltildi, artı daha kısa, bu yüzden bunun için teşekkür ederim
Rick Hitchcock

Değiştirerek 3 bayttan daha fazla tasarruf .filter(a=>1/a[0])edin .filter(a=>''+a).
Tomas Langkaas,

Güzel, @TomasLangkaas, teşekkürler. (2 bayt kaydeder.)
Rick Hitchcock

Benim kötü (sayma ile sorun var), ancak .filter(a=>a+a)ekstra bayt sağlayacaktır.
Tomas Langkaas

1

V , 60 , 54 bayt

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

Çevrimiçi deneyin!

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

V'yi sevdiğim kadarıyla, bu iş için mümkün olan en kötü dil olduğundan eminim. Özellikle listeler için bir desteğe sahip olmadığı ve temelde sayılar için bir desteğe sahip olmadığı düşünüldüğünde. Sadece dize manipülasyonu.


1

C #, 119 bayt

Sadece hızlı bir bıçakla:

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 System.Func<int[],int[][]>F=ve izini kaldırabilirsiniz ;. Bu, bu tür kuzuların bayt sayısının bir parçası değil.
Kevin Cruijssen

@KevinCruijssen, hiçbir fikrim yoktu. Teşekkürler!
El-E-Yemek

1

R , 66 bayt

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

Çevrimiçi deneyin!

Çıktıda tamsayılar dize biçiminde ise, 48 bayta kadar düşebilir (@ Giuseppe'nin cevabında belirtildiği gibi).


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.doublebir bayt daha kısadır ve aynı şekilde çalışması gerekiras.integer
Giuseppe

Peki, bir tamsayı ya da bir çift dönmek isteyip istemediğinize bağlıdır. Eğer çift tamamsa, belki karakter de olabilir, ve ikimiz de bazı baytları kurtarabiliriz.
mb7744

1

PowerShell, 77, 70 bayt

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

Not: Bu sonuçların doğru bir şekilde gruplandırıldığını görmek için (görsel olarak her dizinin içeriği arasında bir ayrım olmadığından), | write-hostyukarıdaki satırın sonuna eklemek isteyebilirsiniz .

Teşekkür

Sayesinde:

  • TessellatingHeckler kitlesel / üstlenmeden daha yaklaşım golfed bir şekilde yeniden yazarak 7 bayt kaydetmek için.

Önceki

77 bayt

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

Güzel, teşekkürler. ,()For grouping'i dahil etmek zorunda kaldım (çıktı sadece bir sürekli dizi olarak gösteriliyordu çünkü). Bu benim orijinal girişimimden çok daha fazla golf sahası; mükemmel iş!
JohnLBevan

0

Groovy, 71 bayt

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

Aslında bunu yarattıktan sonra groupBy'yi öğrendim. Collect'in tek seçeneğim olmadığını bilmiyordum.


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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.