按频率分组列表


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


规则

  • 分组必须从最大频率到最小频率。
  • 分组的内部顺序是任意的(例如,EG示例3可以具有[8,6])。
  • 这是,最低字节数获胜。

有关


1
输出可以是字符串格式吗?就是 列表列表,但每个数字均由字符而不是整数表示。
mb7744

Answers:



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它将按原始列表中元素的第一个出现对组进行排序,因此之后我仍然必须对组进行排序。通过首先对列表进行排序,我可以保存一个字节SplitBy(而且SortBy如果我GatherBy先这样做的话,实际上会更复杂)。
Martin Ender

有趣的是,“必须按从最大到最小的顺序排列”会变得混乱吗?
Magic Octopus Urn

@carusocomputing完全正确。
Martin Ender

5

Python 2中145个 141字节

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

在线尝试!

这是我多年阅读后的第一篇论文。

基本上,它将所有元素放入一个Counter(列表中每个元素的字典),. most_common()将这些元素按降序排列。之后,只需将项目格式化为正确的列表即可。

由于ovs,节省了4个字节。


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的输入阵列的一个,我们计算数Ñ的元件的一个是来自不同的X

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

我们使用索引nx填充数组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这与我当前的方法完全不同。也许您应该将其发布为新答案?
Arnauld

我不认为o[n]从数组更改为集合有什么不同,但是无论如何我已经打了@RickHitchcock的答案,所以没有太多的意义。
尼尔



2

Clojure,74个字节

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

看起来很冗长:/


击败我(并击败我几个字节,巧妙地使用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 ...
魔术八达通

2

Brachylog,10个字节

ọtᵒ¹tᵍhᵐ²|

在线尝试!

说明

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个字节

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

输入

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

输出

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


我向马丁提起了聚会!我不知道该怎么做:)。
Magic Octopus Urn

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

Length[f=...]。和First/@#&@@@
Martin Ender

固定,固定和固定
J42161217

2

R84 77字节

-7字节归功于mb7744

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

从stdin读取;返回一个列表,该列表具有按整数顺序递增的子向量。如果我们可以返回字符串而不是整数,那么我可以删除11个字节(删除对的调用as.double),仅此而已。R table函数在这里很繁重,它计算输入中每​​个成员的出现次数;然后按计数(names)进行汇总。当然,这是一个字符串,因此我们必须将其强制为整数/双精度。

在线尝试!


您可以通过消除“哪个”并使用逻辑索引来丢失7个字节
mb7744

@ mb7744哦,嗯。
朱塞佩

1
我用R再次刺中了它。不幸的是lambda语法有多长时间,所以我着手尝试避免使用它。作为交换,我不得不使用nested lapply,但是至少在那种情况下,我可以将short变量分配给lapply。我似乎无法为该函数分配变量function...
mb7744

2

JavaScript(ES6),100 98 96 93字节

@Neil节省了2个字节(此外,他还修复了我代码中的一个边缘案例错误)。多亏@TomasLangkaas,节省了3个字节。

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()
尼尔

啊,我早该知道要测试0!您的代码已修复它,而且代码更短,因此,谢谢您
Rick Hitchcock

更改.filter(a=>1/a[0])为,再节省3个字节.filter(a=>''+a)
Tomas Langkaas

很好,@ TomasLangkaas,谢谢。(保存2个字节。)
Rick Hitchcock

我不好(无法计数),但.filter(a=>a+a)会提供额外的字节。
Tomas Langkaas

1

V60,54个字节

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

在线尝试!

十六进制转储:

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个字节

只是快速刺入它:

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您可以删除System.Func<int[],int[][]>F=和尾随;。这不是这类lambda字节计数的一部分。
Kevin Cruijssen

@KevinCruijssen,我不知道。谢谢!
Hand-E-Food

1

R,66字节

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

在线尝试!

如果输出中的整数可以是字符串格式,则可以减少到48个字节(如@Giuseppe的答案所述)。


取消高尔夫:

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短了一个字节,它的工作原理与as.integer
Giuseppe

好吧,这取决于您要返回整数还是双精度数。如果可以使用double,那么字符也可以,而且我们都可以节省一些字节。
mb7744

1

PowerShell,77,70字节

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

注意:要查看这些结果是否正确分组(因为从视觉上看,每个数组的内容之间没有偏差),您不妨追加| write-host到上一行的末尾。

致谢

谢谢:


以前

77字节

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

很好,谢谢。我必须加入,()for分组(因为输出仅显示为一个连续数组)。这比我最初的尝试更具高尔夫风格。很棒的工作!
JohnLBevan

0

Groovy,71个字节

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

实际上,在创建了这个之后,我才刚刚了解了groupBy。我不知道收集不是我唯一的选择。


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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.