จัดกลุ่มรายการตามความถี่


26

รับรายการจำนวนเต็มจัดกลุ่มองค์ประกอบที่เกิดขึ้นเป็นอันดับแรกจากนั้นจัดกลุ่มรายการถัดไปเป็นลำดับถัดไปเรื่อย ๆ จนกระทั่งแต่ละองค์ประกอบที่ไม่ซ้ำกันในรายการได้รับการจัดกลุ่มหนึ่งครั้ง


ตัวอย่าง:

การป้อนข้อมูล: [1,2,3]

เอาท์พุท: [[1,2,3]]


การป้อนข้อมูล: [1,1,1,2,2,3,3,4,5,6]

เอาท์พุท: [[1],[2,3],[4,5,6]]


การป้อนข้อมูล: [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]

เอาท์พุท: [[6, 8],[5],[1],[7],[9,4,-56]]


การป้อนข้อมูล: []

เอาท์พุท: []


การป้อนข้อมูล: (empty input)

เอาท์พุท: ERROR/Undefined/Doesn't matter


กฎระเบียบ

  • การจัดกลุ่มจะต้องเปลี่ยนจากความถี่สูงสุดไปเป็นความถี่ต่ำสุด
  • คำสั่งภายในของการจัดกลุ่มเป็นแบบสุ่ม (ตัวอย่างที่ 3 อาจมี[8,6]แทน)
  • นี่คือชนะน้อยที่สุดนับไบต์

ที่เกี่ยวข้อง


1
เอาต์พุตสามารถอยู่ในรูปแบบสตริงได้หรือไม่? กล่าวคือ รายการของรายการ แต่แต่ละหมายเลขแทนด้วยอักขระแทนที่จะเป็นจำนวนเต็ม
— mb7744

คำตอบ:


6

Pyth , 8 7 ไบต์

_{M.g/Q

ลองออนไลน์!

1 ไบต์ต้องขอบคุณ FryAmTheEggman


@ DigitalTrauma คุณไม่สามารถ; มันอยู่ในแลมบ์ดา; ตัวแปรโดยนัยมีอยู่kซึ่งฉันได้ข้ามไปแล้ว
— Leun Nun

เข้าใจแล้ว - ขอบคุณสำหรับคำอธิบาย!
— Digital Trauma

ขอแสดงความยินดี
— Magic Octopus Urn

@MagicOctopusUrn ขอบคุณ
— Leun Nun

7

Mathematica, 43 ไบต์

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

ลองออนไลน์! (ใช้คณิตศาสตร์)

อีกวิธีหนึ่งคือ:

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

5
ไม่มีในตัว?
— Magic Octopus Urn

เป็นGatherByตัวเลือกที่ไม่แน่ใจเพราะผมไม่ทราบว่าภาษา
— Magic Octopus Urn

1
@carusocomputing มันเรียงลำดับกลุ่มตามการปรากฏตัวครั้งแรกขององค์ประกอบในรายการต้นฉบับดังนั้นฉันยังคงต้องเรียงลำดับกลุ่มในภายหลัง โดยการเรียงลำดับรายการก่อนฉันสามารถบันทึก byte ด้วยSplitBy(เช่นกันSortByจริง ๆ แล้วจะซับซ้อนกว่าถ้าฉันทำGatherByก่อน)
— Martin Ender

น่าสนใจดังนั้น "ต้องเรียงจากมากไปน้อย" ยุ่งเหยิงใช่ไหม?
— Magic Octopus Urn

@carusocomputing แน่นอน
— 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))]

ลองออนไลน์!

นี่คือการส่งครั้งแรกของฉันหลังจากปีของการอ่าน

โดยพื้นฐานแล้วมันจะใส่องค์ประกอบทั้งหมดลงในตัวนับ (พจนานุกรมจำนวนองค์ประกอบแต่ละรายการในรายการ) และ . most_common ()ใส่รายการในลำดับความถี่ในการตัดสินใจ หลังจากนั้นมันเป็นเพียงเรื่องของการจัดรูปแบบรายการลงในรายการที่ถูกต้อง

ที่บันทึกไว้ 4 ไบต์ขอบคุณที่OVS


4
ยินดีต้อนรับสู่ PPCG :) อย่าติดเหมือนที่ฉันทำ
— Magic Octopus Urn

การสร้างฟังก์ชั่น itemgetter ของคุณเองนั้นสั้นกว่าการนำเข้า 4 ไบต์:o=lambda n:lambda l:l[n]
— ovs

5

JavaScript (ES6), 95 101 ไบต์

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)

อย่างไร?

สำหรับแต่ละองค์ประกอบxของอินพุตอาร์เรย์aเราคำนวณจำนวนnขององค์ประกอบของaที่แตกต่างจากx :

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

เราใช้ดัชนีnและxเพื่อเติมอาร์เรย์o :

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

แก้ไข : เนื่องจาก JS ไม่สนับสนุนดัชนีอาเรย์เชิงลบเราจึงต้องใช้สูตรx * x + (x > 0)ในการบังคับดัชนีบวก

สิ่งนี้ทำให้เรามีอาร์เรย์ที่มีองค์ประกอบที่ไม่ซ้ำกันของรายการต้นฉบับจัดกลุ่มตามความถี่และเรียงลำดับจากความถี่ที่มากที่สุดถึงน้อยที่สุด

อย่างไรก็ตามทั้งอาร์เรย์ด้านนอกและอาร์เรย์ภายในอาจมีช่องว่างมากมายที่เราต้องการกรองออก เราทำสิ่งนี้กับฟังก์ชั่นF , ใช้กับoและแต่ละองค์ประกอบ:

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

กรณีทดสอบ


ผมคิดว่าช่วยให้คุณประหยัดไบต์:Set 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 นี่ค่อนข้างแตกต่างจากแนวทางปัจจุบันของฉัน บางทีคุณควรโพสต์มันเป็นคำตอบใหม่?
— Arnauld

ฉันไม่คิดว่าการเปลี่ยนo[n]จากแถวลำดับเป็นชุดนั้นแตกต่างกัน แต่ฉันเล่นกอล์ฟกับคำตอบของ @ RickHitchcock อยู่แล้วดังนั้นจึงไม่มีประเด็นมากมาย
— Neil



2

Clojure, 74 ไบต์

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

ดูเหมือน verbose ค่อนข้าง: /


เอาชนะฉันให้ได้ (และเอาชนะฉันไปสักสองสามไบต์ใช้วิธีcomp -ย้อนกลับอย่างฉลาด!) ไม่สั้นเท่ากับภาษาอื่น ๆ แต่ฉันคิดว่ามันน่าสนุกเพราะ Clojure มี "การรวมกลุ่ม" และ "ความถี่" ที่สร้างขึ้น
— MattPutnam

เมื่อฉันอ่านคำอธิบายงานฉันหวังว่าจะได้ 50 หรือ 60 ไบต์ แต่การใช้งานจริงกลับกลายเป็นว่าเป็นเรื่องยากขึ้น
— NikoNyrh

2

Perl 6 , 43 ไบต์

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

ทดสอบมัน

ขยาย:

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

ว้าวฉันลืมไปตลอดBagเลย
— Magic Octopus Urn

2

ยูทิลิตี Bash + GNU, 71 61

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

ป้อนข้อมูลเป็นรายการที่คั่นด้วยบรรทัดใหม่ เอาต์พุตเป็นรายการที่คั่นด้วยบรรทัดใหม่ของค่าที่คั่นด้วยเครื่องหมายจุลภาค

ลองมันออนไลน์


2

MATL , 9 ไบต์

9B#uw3XQP

อินพุตเป็นเวกเตอร์คอลัมน์โดยใช้;เป็นตัวคั่น

ลองออนไลน์!

คำอธิบาย

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 ไบต์

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

ลองออนไลน์

( ดูเหมือนว่าAW ของ kจะต้องมีการเพิ่ม@ก่อน#แต่ oK ไม่ได้ทำ)

คำอธิบาย:

                     = /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สำหรับคนอื่นที่สงสัยว่าkมันคือokอะไร Ba-dum-tssss ...
— Magic Octopus Urn


2

Mathematica, 79 ไบต์

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

อินพุต

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

เอาท์พุต

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


The GatherBy ฉันพูดถึง Martin! ฉันสงสัยว่าจะทำอย่างไร :)
— Magic Octopus Urn

Sort[...,...&]SortBy[...,-Last@#&]เป็นเพียง
— Martin Ender

Length[f=...]. และเป็นFirst/@ #&@@@
— Martin Ender

คงที่คงที่และคงที่
— J42161217

2

R , 84 77 ไบต์

-7 ไบต์ขอบคุณ mb7744

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

อ่านจาก stdin; ส่งคืนรายการที่มีตัวคั่นย่อยของจำนวนเต็มในลำดับที่เพิ่มขึ้น หากเราสามารถส่งคืนสตริงแทน ints ได้ฉันสามารถวาง 11 ไบต์ (ลบการเรียกไปยังas.double) แต่นั่นเป็นเรื่องเกี่ยวกับมัน tableฟังก์ชั่นของ R คือการยกของหนักที่นี่นับจำนวนการเกิดของสมาชิกแต่ละคนของอินพุต จากนั้นจะรวมพวกเขาด้วยการนับ ( names) แน่นอนว่าเป็นสตริงดังนั้นเราต้องบีบบังคับให้เป็นจำนวนเต็ม / คู่

ลองออนไลน์!


คุณสามารถสูญเสีย 7 ไบต์โดยการกำจัด "ซึ่ง" และใช้การทำดัชนีเชิงตรรกะ
— mb7744

@ mb7744 oh duh
— Giuseppe

1
ฉันใช้แทงอีกอันกับอาร์โชคไม่ดีที่แลมบ์ดาไวยากรณ์อยู่ในสถานะนี้นานเท่าไหร่ดังนั้นฉันจึงพยายามหลีกเลี่ยงมัน ในการแลกเปลี่ยนผมใช้ซ้อนกันlapply's lapplyแต่อย่างน้อยในกรณีที่ฉันสามารถกำหนดตัวแปรระยะสั้นไป ดูเหมือนว่าฉันจะไม่สามารถกำหนดตัวแปรให้กับฟังก์ชันได้function...
— mb7744

2

JavaScript (ES6), 100 98 96 93 ไบต์

บันทึก 2 ไบต์ด้วย @Neil (และเขาแก้ไขข้อผิดพลาดของ edge-case ในรหัสของฉัน) บันทึกอีก 3 ไบต์ขอบคุณ @TomasLangkaas

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

กรณีทดสอบ

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


การทดสอบของคุณเป็นข้อบกพร่อง (ไม่ทำงานสำหรับศูนย์) แต่ฉันคิดว่าคุณยังสามารถบันทึกไบต์โดยการกรองและการย้อนกลับแทน a=>a.sort().map((_,n)=>a.filter((v,i)=>i-a.indexOf(v)==n&v!=a[i+1])).filter(a=>1/a[0]).reverse()unshifting:
— Neil

อ่าฉันควรรู้แล้วว่าจะทำการทดสอบ 0! แก้ไขรหัสของคุณมันบวกได้สั้นลงเพื่อขอบคุณที่:)
— ริกฮิตช์ค็อก

บันทึกอีก 3 ไบต์โดยการเปลี่ยนไป.filter(a=>1/a[0]) .filter(a=>''+a)
— Tomas Langkaas

ขอขอบคุณ @TomasLangkaas (บันทึก 2 ไบต์)
— Rick Hitchcock

ฉันไม่ดี (มีปัญหากับการนับ) แต่.filter(a=>a+a)จะให้ไบต์พิเศษ
— Tomas Langkaas

1

V , 60 , 54 ไบต์

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

ลองออนไลน์!

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 ฉันค่อนข้างแน่ใจว่านี่เป็นภาษาที่เลวร้ายที่สุดสำหรับงานนี้ โดยเฉพาะอย่างยิ่งเมื่อพิจารณาว่ามันไม่รองรับรายการและโดยทั่วไปจะไม่รองรับหมายเลข เพียงแค่การจัดการสตริง


1

C#, 119 bytes

Just a quick stab at it:

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 You can remove the System.Func<int[],int[][]>F= and trailing ; though. That isn't part of the byte-count for these kind of lambdas.
— Kevin Cruijssen

@KevinCruijssen, I had no idea. Thanks!
— Hand-E-Food

1

R, 66 bytes

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

Try it online!

If in the output the integers may be in string format, can drop to 48 bytes (as mentioned in @Giuseppe's answer).


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 is shorter by one byte, and it should work the same as as.integer
— Giuseppe

Well, it depends whether you want to return an integer or a double. If double is okay, maybe character would be as well, and we could both save some bytes.
— mb7744

1

PowerShell, 77, 70 bytes

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

NB: To see that these results are correctly grouped (since visually there's no deliniation between the contents of each array), you may wish to append | write-host to the end of the above line.

Acknowledgements

Thanks to:

  • TessellatingHeckler for saving 7 bytes by massively refactoring / rewriting to a way more golfed approach.

Previous

77 bytes

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

Nice, thanks. I had to inlclude the ,() for grouping (since output was just showing as one continuous array). This is way more golfy than my original attempt; awesome work!
— JohnLBevan

0

Groovy, 71 bytes

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

I actually just learned about groupBy after creating this. I didn't know collect wasn't my only choice.


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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.