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


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.