Urutkan elemen yang berbeda dari daftar dalam urutan menurun berdasarkan frekuensi

12

Tulis fungsi yang mengambil daftar atau larik, dan mengembalikan daftar elemen yang berbeda, diurutkan dalam urutan menurun berdasarkan frekuensi.

Contoh:

Diberikan:

["John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John"]

Nilai pengembalian yang diharapkan:

["Doe","Harry","John","Dick"]
belvi
sumber
Code-golf atau code-challenge?
marinus
Golf kode. Itu kesalahan. Hanya memperbaikinya
belvi

Jawaban:

13

APL (14)

{∪⍵[⍒+⌿∘.≡⍨⍵]}

Ini adalah fungsi yang mengambil daftar, misalnya:

      names
 John  Doe  Dick  Harry  Harry  Doe  Doe  Harry  Doe  John 
      {∪⍵[⍒+⌿∘.≡⍨⍵]} names
 Doe  Harry  John  Dick

Penjelasan:

  • ∘.≡⍨⍵: bandingkan setiap elemen dalam array dengan setiap elemen lain dalam array, memberikan matriks
  • +⌿: jumlah kolom dari matriks, memberikan berapa kali setiap elemen terjadi
  • : berikan indeks sortir ke bawah
  • ⍵[... ]: menyusun ulang berdasarkan indeks yang diberikan
  • : dapatkan elemen unik
marinus
sumber
3
Namun entah bagaimana mereka menyebut pergi dari bahasa cerdas singkat ini ke Jawa "kemajuan"? (-:
hippietrail
8

Python 3 - 47 43; Python 2 - 40 39

Untuk Python 3:

f=lambda n:sorted(set(n),key=n.count)[::-1]

Untuk Python 2:

f=lambda n:sorted(set(n),cmp,n.count,1)

Demo:

>>> names = ["John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John"]
>>> f(names)
['Doe', 'Harry', 'John', 'Dick']
Blckknght
sumber
1
Saya sedang mencoba memposting yang sama, tetapi di sini ada modifikasi. f=lambda n:sorted(set(n),cmp,n.count,1)39 karakter
YOU
1
Hmm, saya tidak menyadari Anda bisa melewati cmpfungsi non-Tidak ada dan keyfungsi. Keren.
Blckknght
1
Sedikit lebih pendek:f=lambda n:sorted(set(n),key=n.count)[::-1]
grc
Terima kasih @grc, alien smiley memang menyimpan beberapa karakter dalam case Python 3.
Blckknght
5

Mathematica, 31

Sort[GatherBy@n][[-1;;1;;-1,1]]

{"Doe", "Harry", "John", "Dick"}

(Dengan n = {"John", "Doe", "Dick", "Harry", "Harry", "Doe", "Doe", "Harry", "Doe", "John"})

Ajasja
sumber
Sial, kau ada di sana: D
Yves Klett
@YvesKlett Terima kasih. Saya berpikir untuk menyingkirkan Reverse, tetapi Sort[GatherBy@n][[-1;;1, 1]]tidak berhasil :). Ada ide?
Ajasja
4

Mathematica (26 37)

Dengan n = {"John", "Doe", "Dick", "Harry", "Harry", "Doe", "Doe", "Harry", "Doe", "John"}:

Last/@Gather@n~SortBy~Length//Reverse

{"Doe", "Harry", "John", "Dick"}


Mathematica V10 + (26) :

Keys@Sort[Counts[n],#>#2&]
Yves Klett
sumber
@ garej versi lama digunakan. Posting sebagai jawaban lain?
Yves Klett
Saya sudah menambahkan ke Anda jika Anda tidak keberatan ...
garej
@ garej. Terima kasih, solusi luar biasa!
Yves Klett
3

Perl 6 (36 byte, 35 karakter)

»dapat diganti dengan >>, jika Anda tidak dapat menangani UTF-8. Saya hampir yakin ini bisa lebih pendek, tetapi Bagkelasnya relatif aneh dalam perilakunya (sayangnya), dan tidak benar-benar lengkap, karena relatif baru (tetapi dapat menghitung argumen). {}mendeklarasikan fungsi anonim.

{(sort -*.value,pairs bag @_)».key}

Output sampel (dari Perl 6 REPL):

> my @names = ("John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John")
John Doe Dick Harry Harry Doe Doe Harry Doe John
> {(sort -*.value,pairs bag @_)».key}(@names)
Doe Harry John Dick
Konrad Borowski
sumber
3

Ruby: 34 37 karakter

f=->a{a.sort_by{|z|-a.count(z)}&a}

(diedit: solusi 30-char sebelumnya adalah fungsi dari body)

ditulis ulang
sumber
Anda dapat memangkas beberapa karakter dengan f=->a{a.sort_by{|z|-a.count(z)}&a}. The &tidak uniq.
histokrat
3

GolfScript, 14 karakter (19 sebagai fungsi fungsi, juga 14 sebagai program penuh)

:a.|{[.]a\-,}$

Kode ini mengambil array pada stack dan mengurutkan elemen uniknya dalam urutan menurun berdasarkan jumlah kemunculannya. Misalnya, jika array input adalah:

["John" "Doe" "Dick" "Harry" "Harry" "Doe" "Doe" "Harry" "Doe" "John"]

maka array output akan menjadi

["Doe" "Harry" "John" "Dick"]

Catatan: Kode di atas adalah urutan pernyataan. Untuk mengubahnya menjadi fungsi bernama, bungkus dengan tanda kurung dan berikan ke nama, seperti pada:

{:a.|{[.]a\-,}$}:f;

Atau, untuk mengubah kode menjadi program lengkap yang membaca daftar dari input standar (menggunakan notasi daftar yang ditunjukkan di atas) dan mencetaknya ke output standar, tambahkan ~dan tambahkan `kode tersebut. The [. dapat dihilangkan dalam kasus ini (karena kita tahu akan ada apa-apa lagi di tumpukan), sehingga program 14-karakter yang dihasilkan akan:

~:a.|{]a\-,}$`

Bagaimana cara kerjanya?

  • :amenyimpan salinan array asli dalam variabel auntuk digunakan nanti.

  • .| menghitung penyatuan array dengan sendirinya, menghilangkan duplikat sebagai efek samping.

  • { }$mengurutkan array de-duplikat menggunakan tombol pengurutan khusus yang dihitung oleh kode di dalam kurung kurawal. Kode ini mengambil setiap elemen array, menggunakan pengurangan array untuk menghapusnya dari input array asli yang disimpan a, dan menghitung jumlah elemen yang tersisa. Dengan demikian, elemen diurutkan dalam urutan frekuensi yang menurun.

Ps. Lihat di sini untuk versi 30 karakter aslinya.

Ilmari Karonen
sumber
Saya pikir itu [a\])^harus setara dengan [.;]a\-. Mengurutkan berdasarkan jumlah elemen yang tidak cocok adalah ide bagus.
Peter Taylor
Sayangnya, tidak: ^kolaps duplikat, -tidak. (Dan ITYM (, tidak ).) [a\](\-Akan berfungsi, tetapi tidak akan menyimpan karakter apa pun.
Ilmari Karonen
2

R: 23 karakter

n <- c("John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John")

names(sort(table(n),T))
## [1] "Doe"   "Harry" "John"  "Dick" 

Tetapi ia menggunakan jalan pintas yang tidak begitu bagus Tuntuk TRUE...

Henrik
sumber
1

jika ini bisa muat di sini: In sql-server

create table #t1 (name varchar(10))
insert into #t1 values ('John'),('Doe'),('Dick'),('Harry'),('Harry'),('Doe'),('Doe'),('Harry'),('Doe'),('John')


select name from #t1 group by name order by count(*) desc

ATAU

with cte as
(

select name,count(name) as x from #t1 group by name
)

select name from cte order by x desc

melihatnya dalam aksi

vhadalgi
sumber
1
Mengapa CTE? select name from #t1 group by name order by count(*) desc
manatwork
1

PHP, 63 62 61 karakter

function R($a){foreach($a as$v)$b[$v]++;arsort($b);return$b;}

Demo:

$c = array("John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John");
$d = print_r(R($c));

Array ( [Doe] => 4 [Harry] => 3 [John] => 2 [Dick] => 1 )
Vereos
sumber
lihatlah array_count_values()... Itu saja yang harus Anda gunakan (termasuk arsort())
bwoebi
array_count_values()tidak menghapus nilai duplikat, atau memesannya, seperti yang saya lihat.
Vereos
Itu menghapus duplikat ... Itu hanya tidak memerintahkan mereka ... => arsort
bwoebi
@ bwoebi Anda benar. Sayangnya menulis dengan cara itu adalah 1 karakter lebih lama dari jawaban ini.
Tim Seguine
Mengapa dengan cara yang array_count_valueslebih lama? <?$u=array_count_values($_GET);arsort($u);print_r($u);menurut saya
Jörg Hülsermann
1

Ruby: 59 karakter

f=->n{n.group_by{|i|i}.sort_by{|i|-i[1].size}.map{|i|i[0]}}

Contoh dijalankan:

irb(main):001:0> f=->n{n.group_by{|i|i}.sort_by{|i|-i[1].size}.map{|i|i[0]}}
=> #<Proc:0x93b2e10@(irb):2 (lambda)>

irb(main):004:0> f[["John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John"]]
=> ["Doe", "Harry", "John", "Dick"]
manatwork
sumber
1

Mathematica, 39 karakter

f = Reverse[First /@ SortBy[Tally@#, Last]] &

names = {"John", "Doe", "Dick", "Harry", "Harry",
         "Doe", "Doe", "Harry", "Doe", "John"};

f@names

{Doe, Harry, John, Dick}

Chris Degnen
sumber
1

JavaScript (ECMAScript5): 118 113 karakter

function f(n){m={}
for(i in n){m[n[i]]=m[n[i]]+1||1}
return Object.keys(m).sort(function(a,b){return m[b]-m[a]})}

http://jsfiddle.net/mblase75/crg5B/

Blazemonger
sumber
Dengan Harmony fungsi lemak panah : f=n=>{m={};n.forEach(e=>m[e]=m[e]+1||1);return Object.keys(m).sort((a,b)=>m[b]-m[a])}. (Saat ini hanya di Firefox.)
manatwork
Anda dapat menggunakan m[n[i]]=-~m[n[i]]untuk menambah, dan Anda tidak perlu {} di sekitar badan loop.
Neil
1

Haskell - 53 Karakter

import Data.List
import Data.Ord

f :: (Eq a, Ord a) => [a] -> [a]
f=map head.(sortBy$flip$comparing length).group.sort

Penjelasan: dua baris pertama adalah impor yang diperlukan, baris kode berikutnya adalah tipe tanda tangan (umumnya tidak diperlukan), fungsi sebenarnya adalah baris terakhir. Fungsi mengurutkan daftar berdasarkan urutan alami, mengelompokkan elemen yang sama ke dalam daftar, mengurutkan daftar dengan mengurangi ukuran, dan mengambil elemen pertama dalam setiap daftar.

panjang total termasuk impor: 120

tanpa impor tetapi dengan jenis tanda tangan: 86

fungsinya sendiri: 53

jgon
sumber
1

Clojure: 43 karakter

Fungsi:

#(keys(sort-by(comp - val)(frequencies %)))

Demo (dalam balasan):

user=> (def names ["John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John"])
#'user/names
user=> (#(keys(sort-by(comp - val)(frequencies %))) names)
("Doe" "Harry" "John" "Dick")
Charles Simpson
sumber
0

Perl

untuk memenuhi spesifikasi i / o tertentu, saya perlu 120 karakter

s!"([^"]+)"[],]!$a{$1}++!e while(<>);print 'MostOccuring = [',join(',',map{qq("$_")}sort{$a{$a}<=>$a{$b}}keys %a),"]\n"

kode terpendek murni dengan mengambil satu item per baris dan mencetak satu item per baris saya hanya perlu 55 karakter

$a{$_}++ while(<>);print sort{$a{$a}<=>$a{$b}}keys %a)
Hildred
sumber
0

C #: 111 karakter

List<string>M(List<string>l){return l.GroupBy(q=>q).OrderByDescending(g=>g.Count()).Select(g=>g.Key).ToList();}

(di dalam kelas)

var names = new List<string> {"John", "Doe", "Dick", "Harry", "Harry", "Doe", "Doe", "Harry", "Doe", "John"};
foreach(var s in M(names))
{
    Console.WriteLine(s);
}

Kelinci betina

Harry

John

***

Solusi sederhana menggunakan LINQ.

paavohtl
sumber
Anda juga dapat menghapus .ToList () , karena urutannya disebutkan melalui foreach
Adam Speight
Itu benar, tapi kemudian saya harus mengubah tipe kembali ke IEnumerable <string> .
paavohtl
0

R (22)

names(sort(-table(x)))

Sebagai fungsi itu akan membutuhkan 11 karakter lagi.

Pemakaian:

> x = c("John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John")
> names(sort(-table(x)))
[1] "Doe"   "Harry" "John"  "Dick"
lambruscoAcido
sumber
Ini mengambil input dari variabel, yang tidak diizinkan oleh konsensus komunitas .
Buah Esolanging
0

Scala (71)

(x.groupBy(a=>a)map(t=>(t._1,t._2.length))toList)sortBy(-_._2)map(_._1)

Tidak Disatukan:

def f(x:Array[String]) =
  (x.groupBy(a => a) map (t => (t._1, t._2.length)) toList) 
    sortBy(-_._2) map(_._1)
lambruscoAcido
sumber
0

J, 8 byte

~.\:#/.~

Pemakaian

Nama-nama disimpan sebagai array dari string kotak.

   'John';'Doe';'Dick';'Harry';'Harry';'Doe';'Doe';'Harry';'Doe';'John'
┌────┬───┬────┬─────┬─────┬───┬───┬─────┬───┬────┐
│John│Doe│Dick│Harry│Harry│Doe│Doe│Harry│Doe│John│
└────┴───┴────┴─────┴─────┴───┴───┴─────┴───┴────┘
   f =: ~.\:#/.~
   f 'John';'Doe';'Dick';'Harry';'Harry';'Doe';'Doe';'Harry';'Doe';'John'
┌───┬─────┬────┬────┐
│Doe│Harry│John│Dick│
└───┴─────┴────┴────┘

Penjelasan

~.\:#/.~   Input: A
    #/.~   Finds the size of each set of identical items (Frequencies)
~.         List the distinct values in A
           Note: the distinct values and frequencies will be in the same order
  \:       Sort the distinct values in decreasing order according to the frequencies
           Return the sorted list implicitly
mil
sumber
0

CJam, 15 byte (mungkin tidak bersaing)

q~$e`{0=W*}$1f=

Ini dapat menggunakan fitur CJam dari setelah tantangan ini diposting. Aku terlalu malas untuk memeriksanya.

Buah Esolanging
sumber