Kelompokkan Daftar berdasarkan Frekuensi


26

Diberikan daftar bilangan bulat, kelompokkan elemen-elemen yang paling banyak muncul terlebih dahulu, lalu kelompokkan yang paling banyak berikutnya dan seterusnya hingga setiap elemen unik dalam daftar dikelompokkan satu kali.


Contoh:

Memasukkan: [1,2,3]

Keluaran: [[1,2,3]]


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

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


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

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


Memasukkan: []

Keluaran: []


Memasukkan: (empty input)

Keluaran: ERROR/Undefined/Doesn't matter


Aturan

  • Pengelompokan harus dari frekuensi maksimal ke frekuensi minimal.
  • Urutan internal dari pengelompokan bersifat sewenang-wenang (misalnya, Contoh 3 bisa saja memiliki EG [8,6]).
  • Ini adalah , kemenangan byte-count terendah.

Terkait


1
Bisakah output dalam format string? Yaitu. Daftar daftar, tetapi setiap angka diwakili oleh karakter, bukan bilangan bulat.
mb7744

Jawaban:



7

Mathematica, 43 byte

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

Cobalah online! (Menggunakan Matematika.)

Kalau tidak:

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

5
Tidak ada bawaan?
Magic Gurita Guci

Merupakan GatherBypilihan, tidak yakin karena saya tidak tahu bahasa.
Magic Gurita Guci

1
@carusocomputing Ini mengurutkan grup berdasarkan kemunculan pertama elemen dalam daftar asli, jadi saya masih harus mengurutkan grup setelahnya. Dengan menyortir daftar terlebih dahulu, saya dapat menyimpan byte dengan SplitBy(juga SortBysebenarnya akan lebih rumit jika saya lakukan GatherBydulu).
Martin Ender

Menarik, jadi "harus dalam urutan dari maksimal ke minimal" mengacaukannya?
Magic Gurita Guci

@cococuting Tepat.
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))]

Cobalah online!

Ini adalah pengiriman pertama saya setelah bertahun-tahun membaca.

Ini pada dasarnya menempatkan semua elemen ke Counter (kamus berapa banyak setiap elemen dalam daftar) dan .most_common () menempatkan item dalam urutan frekuensi decending. Setelah itu, tinggal memformat item ke daftar yang benar.

Disimpan 4 byte berkat ovs .


4
Selamat datang di PPCG :). Jangan kecanduan seperti saya.
Magic Gurita Guci

Membuat fungsi itemgetter Anda sendiri adalah 4 byte lebih pendek daripada mengimpornya:o=lambda n:lambda l:l[n]
Ov

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)

Bagaimana?

Untuk setiap elemen x dari larik input a , kami menghitung jumlah n elemen a yang berbeda dari x :

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

Kami menggunakan indeks n dan x untuk mengisi array o :

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

Sunting : Karena JS tidak mendukung indeks array negatif, kami membutuhkan rumus x * x + (x > 0)untuk memaksakan indeks positif.

Ini memberi kita array array yang mengandung elemen unik dari daftar asli, dikelompokkan berdasarkan frekuensi dan dipesan dari yang paling sering ke yang paling jarang.

Namun, baik array luar maupun array dalam berpotensi memiliki banyak slot kosong yang ingin kami filter. Kami melakukan ini dengan fungsi F , diterapkan pada o dan setiap elemennya:

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

Uji kasus


Saya pikir Setmenghemat 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 Ini sangat berbeda dari pendekatan saya saat ini. Mungkin Anda harus mempostingnya sebagai jawaban baru?
Arnauld

Saya tidak berpikir mengubah o[n]dari array ke set yang berbeda, tapi saya sudah golf jawaban @ RickHitchcock jadi tidak banyak gunanya.
Neil



2

Clojure, 74 byte

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

Tampak cukup verbose: /


Kalahkan saya (dan kalahkan saya beberapa byte, penggunaan pintar comp -untuk membalikkan!). Tidak sesingkat bahasa lain, tapi saya pikir itu lucu karena Clojure memiliki "grup-oleh" dan "frekuensi".
MattPutnam

Ketika saya membaca deskripsi tugas, saya berharap 50 atau 60 byte, tetapi implementasi yang sebenarnya ternyata sedikit lebih rumit.
NikoNyrh

2

Perl 6 , 43 byte

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

Menguji

Diperluas:

*                   # 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, saya selalu lupa Bag, bagus!
Magic Gurita Guci

2

Utilitas Bash + GNU, 71 61

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

Masukan sebagai daftar batas-baris baru. Keluaran sebagai daftar nilai dipisahkan-koma yang dipisahkan oleh baris baru.

Cobalah online .


2

MATL , 9 byte

9B#uw3XQP

Input adalah vektor kolom, menggunakan ;sebagai pemisah.

Cobalah online!

Penjelasan

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}#:'=

Cobalah online.

( AW's k tampaknya membutuhkan tambahan @sebelum #, tetapi oK tidak.)

Penjelasan:

                     = /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 untuk orang lain bertanya-tanya apa kitu, sebenarnya ok. Ba-dum-tssss ...
Magic Octopus Mm

2

Brachylog , 10 byte

ọtᵒ¹tᵍhᵐ²|

Cobalah online!

Penjelasan

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

memasukkan

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

keluaran

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


The GatherBy yang saya sebutkan kepada Martin! Saya bertanya-tanya bagaimana ini akan dilakukan :).
Magic Gurita Guci

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

Length[f=...]. Dan First/@itu #&@@@.
Martin Ender

diperbaiki, diperbaiki dan diperbaiki
J42161217

2

R , 84 77 byte

-7 byte berkat mb7744

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

Baca dari stdin; mengembalikan daftar dengan subvektor bilangan bulat dalam urutan yang meningkat. Jika kita bisa mengembalikan string alih-alih int, maka saya bisa menjatuhkan 11 byte (menghapus panggilan ke as.double), tapi hanya itu. tableFungsi R melakukan pengangkatan berat di sini, menghitung kemunculan setiap anggota dari inputnya; lalu menggabungkannya dengan hitungan ( names). Tentu saja, itu sebuah string, jadi kita harus memaksanya ke integer / double.

Cobalah online!


Anda dapat kehilangan 7 byte dengan menghilangkan "yang", dan menggunakan pengindeksan logis
mb7744

@ mb7744 oh ya
Giuseppe

1
Saya mengambil bacokan lain dengan R. Sangat disayangkan berapa lama sintaks lambda, jadi saya mencoba menghindarinya. Sebagai gantinya saya harus menggunakan nested lapply, tetapi setidaknya dalam kasus itu saya dapat menetapkan variabel pendek lapply. Sepertinya saya tidak dapat menetapkan variabel ke fungsi function...
mb7744

2

JavaScript (ES6), 100 98 96 93 byte

Disimpan 2 byte berkat @Neil (ditambah lagi ia memperbaiki bug kasus tepi dalam kode saya). Disimpan 3 byte lebih banyak berkat @TomasLangkaas.

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

Uji kasus

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


Pengujian cacat (tidak bekerja untuk nol) tapi saya pikir Anda masih bisa menyimpan byte dengan menyaring dan membalikkan bukan 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, aku seharusnya tahu untuk menguji 0! Kode Anda memperbaikinya, ditambah lebih pendek, jadi terima kasih untuk itu
:)

Hemat 3 byte lebih banyak dengan mengubah .filter(a=>1/a[0])ke .filter(a=>''+a).
Tomas Langkaas

Bagus, @TomasLangkaas, terima kasih. (Menghemat 2 byte.)
Rick Hitchcock

Buruk saya (mengalami kesulitan dalam menghitung), tetapi .filter(a=>a+a)akan memberikan byte ekstra.
Tomas Langkaas

1

V , 60 , 54 byte

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

Cobalah 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

Seperti saya suka V, saya cukup yakin ini adalah bahasa yang paling buruk untuk tugas ini. Terutama mengingat tidak memiliki dukungan untuk daftar, dan pada dasarnya tidak ada dukungan untuk angka. Hanya manipulasi string.


1

C #, 119 byte

Cukup menusuknya:

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 Anda dapat menghapus System.Func<int[],int[][]>F=dan mengekarnya ;. Itu bukan bagian dari byte-count untuk lambda semacam ini.
Kevin Cruijssen

@KevinCruijssen, saya tidak tahu. Terima kasih!
Hand-E-Food

1

R , 66 byte

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

Cobalah online!

Jika dalam output bilangan bulat mungkin dalam format string, dapat turun menjadi 48 byte (seperti yang disebutkan dalam jawaban @ Giuseppe).


Tidak Disatukan:

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.doublelebih pendek satu byte, dan seharusnya bekerja sama denganas.integer
Giuseppe

Yah, itu tergantung apakah Anda ingin mengembalikan integer atau double. Jika dobel oke, mungkin karakter juga, dan kami berdua bisa menghemat beberapa byte.
mb7744

1

PowerShell, 77, 70 byte

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

NB: Untuk melihat bahwa hasil ini dikelompokkan dengan benar (karena secara visual tidak ada deliniasi antara konten setiap array), Anda mungkin ingin menambahkan | write-hostke akhir baris di atas.

Ucapan Terima Kasih

Terimakasih untuk:

  • TessellatingHeckler untuk menghemat 7 byte dengan melakukan refactoring / penulisan ulang secara besar-besaran dengan cara yang lebih pegolf.

Sebelumnya

77 byte

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

Terima kasih banyak. Saya harus menyertakan ,()untuk pengelompokan (karena output hanya ditampilkan sebagai satu array kontinu). Ini jauh lebih golf daripada upaya awal saya; kerja luar biasa!
JohnLBevan

0

Groovy, 71 byte

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

Saya sebenarnya baru belajar tentang groupBy setelah membuat ini. Saya tidak tahu mengoleksi bukan satu-satunya pilihan saya.


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

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.