Nhóm một danh sách theo tần suất


26

Đưa ra một danh sách các số nguyên, nhóm các phần tử xảy ra nhiều nhất trước, sau đó nhóm nhiều nhất tiếp theo và cứ thế cho đến khi mỗi phần tử duy nhất trong danh sách được nhóm lại một lần.


Ví dụ:

Đầu vào: [1,2,3]

Đầu ra: [[1,2,3]]


Đầu vào: [1,1,1,2,2,3,3,4,5,6]

Đầu ra: [[1],[2,3],[4,5,6]]


Đầu vào: [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]

Đầu ra: [[6, 8],[5],[1],[7],[9,4,-56]]


Đầu vào: []

Đầu ra: []


Đầu vào: (empty input)

Đầu ra: ERROR/Undefined/Doesn't matter


Quy tắc

  • Các nhóm phải đi từ tần số tối đa đến tần số tối thiểu.
  • Thứ tự nội bộ của các nhóm là tùy ý (ví dụ EG 3 có thể có [8,6]thay thế).
  • Đây là , byte thấp nhất.

Liên quan


1
Đầu ra có thể ở định dạng chuỗi? I E. Một danh sách các danh sách, nhưng mỗi số được biểu thị bằng một ký tự thay vì một số nguyên.
mb7744

Câu trả lời:



7

Toán học, 43 byte

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

Hãy thử trực tuyến! (Sử dụng toán học.)

Cách khác:

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

5
Không có tích hợp?
Bạch tuộc ma thuật Urn

GatherBymột lựa chọn, không chắc chắn vì tôi không biết ngôn ngữ.
Bạch tuộc ma thuật Urn

1
@carusocomputing Nó sắp xếp các nhóm theo sự xuất hiện đầu tiên của các thành phần trong danh sách ban đầu, vì vậy tôi vẫn phải sắp xếp các nhóm sau đó. Bằng cách sắp xếp danh sách trước, tôi có thể lưu một byte bằng SplitBy(cũng SortBythực sự sẽ phức tạp hơn nếu tôi làm GatherBytrước).
Martin Ender

Thật thú vị, vậy "phải theo thứ tự từ tối đa đến tối thiểu" mà lộn xộn?
Bạch tuộc ma thuật Urn

@carusocomputing Chính xác.
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))]

Hãy thử trực tuyến!

Đây là bài nộp đầu tiên của tôi sau nhiều năm đọc.

Về cơ bản, nó đặt tất cả các phần tử vào một Counter (từ điển có bao nhiêu phần tử trong danh sách) và. Maximum_common () đặt các mục theo thứ tự tần số giảm dần. Sau đó, vấn đề chỉ là định dạng các mục vào đúng danh sách.

Đã lưu 4 byte nhờ vào ovs .


4
Chào mừng bạn đến với PPCG :). Đừng nghiện như tôi đã làm.
Bạch tuộc ma thuật Urn

Tạo chức năng itemgetter của riêng bạn ngắn hơn 4 byte so với nhập nó:o=lambda n:lambda l:l[n]
ovs

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)

Làm sao?

Với mỗi phần tử x của mảng đầu vào a , chúng tôi tính số n của các phần tử của a khác với x :

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

Chúng tôi sử dụng các chỉ số nx để điền vào mảng o :

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

Chỉnh sửa : Vì JS không hỗ trợ các chỉ số mảng âm, nên chúng tôi cần công thức x * x + (x > 0)để buộc các chỉ số dương.

Điều này cung cấp cho chúng tôi một mảng các mảng chứa các thành phần duy nhất của danh sách gốc, được nhóm theo tần suất và được sắp xếp theo thứ tự từ thường xuyên nhất đến ít thường xuyên nhất.

Tuy nhiên, cả mảng bên ngoài và mảng bên trong có khả năng có nhiều vị trí trống mà chúng tôi muốn lọc ra. Chúng tôi thực hiện điều này với hàm F , áp dụng cho o và từng phần tử của nó:

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

Các trường hợp thử nghiệm


Tôi nghĩ rằng một Settiết kiệm cho bạn một 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 Điều này khá khác với cách tiếp cận hiện tại của tôi. Có lẽ bạn nên đăng nó như một câu trả lời mới?
Arnauld

Tôi không nghĩ việc thay đổi o[n]từ một mảng thành một tập hợp là khác nhau, nhưng dù sao tôi cũng đã đánh golf câu trả lời của @ RickHitchcock vì vậy không có nhiều điểm.
Neil



2

Clojure, 74 byte

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

Trông khá dài dòng: /


Đánh bại tôi với nó (và đánh bại tôi bằng một vài byte, sử dụng thông minh comp -để đảo ngược!). Không ngắn như các ngôn ngữ khác, nhưng tôi nghĩ nó thật thú vị vì Clojure có "nhóm" và "tần số" được tích hợp.
MattPutnam

Khi tôi đọc mô tả tác vụ, tôi đã hy vọng 50 hoặc 60 byte, nhưng việc thực hiện thực tế hóa ra lại phức tạp hơn một chút.
NikoNyrh

2

Perl 6 , 43 byte

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

Kiểm tra nó

Mở rộng:

*                   # 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, tôi luôn quên về Bag, một trong những tốt đẹp!
Bạch tuộc ma thuật Urn

2

Tiện ích Bash + GNU, 71 61

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

Nhập dưới dạng danh sách giới hạn dòng mới. Xuất ra dưới dạng một danh sách được phân tách bằng dòng mới của các giá trị được phân tách bằng dấu phẩy.

Hãy thử trực tuyến .


2

MATL , 9 byte

9B#uw3XQP

Đầu vào là một vectơ cột, sử dụng ;như dấu phân cách.

Hãy thử trực tuyến!

Giải trình

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

Hãy thử trực tuyến.

( AW's k dường như yêu cầu thêm @trước #, nhưng oK thì không.)

Giải trình:

                     = /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 cho bất cứ ai khác tự hỏi knó thực sự là gì ok. Ba-dum-tssss ...
Bạch tuộc ma thuật Urn

2

Brachylog , 10 byte

ọtᵒ¹tᵍhᵐ²|

Hãy thử trực tuyến!

Giải trình

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

Toán học, 79 byte

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

đầu vào

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

đầu ra

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


GatherBy tôi đã đề cập với Martin! Tôi tự hỏi làm thế nào điều này sẽ được thực hiện :).
Bạch tuộc ma thuật Urn

Sort[...,...&]chỉ là SortBy[...,-Last@#&].
Martin Ender

Length[f=...]. Và First/@#&@@@.
Martin Ender

cố định, cố định và cố định
J42161217

2

R , 84 77 byte

-7 byte nhờ mb7744

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

Đọc từ stdin; trả về một danh sách với các phần tử con của số nguyên theo thứ tự tăng dần. Nếu chúng ta có thể trả về chuỗi thay vì ints, thì tôi có thể giảm 11 byte (loại bỏ cuộc gọi đến as.double), nhưng đó là về nó. tableChức năng của R thực hiện việc nâng vật nặng ở đây, đếm số lần xuất hiện của từng thành viên đầu vào; sau đó nó tổng hợp chúng bằng cách đếm ( names). Tất nhiên, đó là một chuỗi, vì vậy chúng ta phải ép buộc nó thành một số nguyên / gấp đôi.

Hãy thử trực tuyến!


Bạn có thể mất 7 byte bằng cách loại bỏ "cái" và sử dụng lập chỉ mục logic
mb7744

@ mb7744 oh duh.
Giuseppe

1
Tôi đã đâm một nhát vào nó với R. Thật không may là cú pháp lambda dài bao nhiêu, vì vậy tôi đã cố gắng tránh nó. Đổi lại, tôi phải sử dụng các lồng nhau lapply, nhưng ít nhất trong trường hợp đó tôi có thể gán một biến ngắn cho lapply. Tôi dường như không thể gán một biến cho hàm function...
mb7744

2

JavaScript (ES6), 100 98 96 93 byte

Đã lưu 2 byte nhờ @Neil (cộng với anh ấy đã sửa lỗi trường hợp cạnh trong mã của tôi). Đã lưu thêm 3 byte nhờ @TomasLangkaas.

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

Các trường hợp thử nghiệm

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


Thử nghiệm của bạn không hoàn hảo (không hoạt động với số không) nhưng tôi nghĩ bạn vẫn có thể lưu byte bằng cách lọc và đảo ngược thay vì không dịch chuyển : 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, tôi nên biết để kiểm tra 0! Mã của bạn sửa nó, cộng với nó ngắn hơn, vì vậy cảm ơn bạn vì điều đó :)
Rick Hitchcock

Lưu thêm 3 byte bằng cách thay đổi .filter(a=>1/a[0])thành .filter(a=>''+a).
Tomas Langkaas

Rất vui, @TomasLangkaas, cảm ơn. (Lưu 2 byte.)
Rick Hitchcock

Xấu của tôi (gặp khó khăn khi đếm), nhưng .filter(a=>a+a)sẽ cung cấp thêm byte.
Tomas Langkaas

1

V , 60 , 54 byte

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

Hãy thử trực tuyến!

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

Tôi yêu V rất nhiều, tôi khá chắc chắn đây là ngôn ngữ tồi tệ nhất có thể cho nhiệm vụ. Đặc biệt là xem xét nó không có hỗ trợ cho danh sách, và về cơ bản không hỗ trợ cho các con số. Chỉ cần thao tác chuỗi.


1

C #, 119 byte

Chỉ cần một cú đâm nhanh vào nó:

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 Bạn có thể xóa System.Func<int[],int[][]>F=và theo dõi ;mặc dù. Đó không phải là một phần của số byte cho các loại lambdas này.
Kevin Cruijssen

@KevinCruijssen, tôi không có ý kiến ​​gì. Cảm ơn!
Thực phẩm điện tử

1

R , 66 byte

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

Hãy thử trực tuyến!

Nếu trong đầu ra, số nguyên có thể ở định dạng chuỗi, có thể giảm xuống 48 byte (như được đề cập trong câu trả lời của @ Giuseppe).


Ung dung:

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.doublengắn hơn một byte và nó sẽ hoạt động giống nhưas.integer
Giuseppe

Vâng, nó phụ thuộc vào việc bạn muốn trả về một số nguyên hay gấp đôi. Nếu nhân đôi là ổn, có lẽ ký tự cũng sẽ như vậy và cả hai chúng ta có thể lưu một số byte.
mb7744

1

PowerShell, 77, 70 byte

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

Lưu ý: Để thấy rằng các kết quả này được nhóm chính xác (vì trực quan không có phân định giữa các nội dung của từng mảng), bạn có thể muốn nối | write-hostvào cuối dòng trên.

Lời cảm ơn

Nhờ vào:

  • TessellatingHeckler để lưu 7 byte bằng cách tái cấu trúc / viết lại ồ ạt theo cách tiếp cận nhiều hơn.

Trước

77 byte

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

Tốt đẹp, cảm ơn. Tôi đã phải bao ,()gồm các nhóm để phân nhóm (vì đầu ra chỉ hiển thị dưới dạng một mảng liên tục). Đây là cách chơi golf nhiều hơn so với nỗ lực ban đầu của tôi; công việc tuyệt vời
JohnLBevan

0

Groovy, 71 byte

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

Tôi thực sự chỉ tìm hiểu về groupBy sau khi tạo ra điều này. Tôi không biết thu thập không phải là lựa chọn duy nhất của tôi.


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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.