頻度によるリストのグループ化


26

整数のリストが与えられたら、最も最初に出現する要素をグループ化し、次にリスト内の各一意の要素が一度グループ化されるまで、2番目に多くの要素をグループ化します。


例:

入力: [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

回答:



7

Mathematica、43バイト

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

オンラインでお試しください!(数学を使用。)

代わりに:

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

5
組み込みはありませんか?
魔法のタコUr

GatherBy私は言語がわからないので、オプションではありません。
魔法のタコUr

1
@carusocomputing元のリストの要素が最初に出現した順にグループを並べ替えるので、後でグループを並べ替える必要があります。リストを最初にソートすることで、バイトを保存できますSplitBy(最初SortByにやった場合、実際にはさらに複雑になりますGatherBy)。
マーティンエンダー

おもしろいので、「最大から最小まで順番に並べる必要があります」というのは、それを台無しにしますか?
魔法のタコUr

@carusocomputingまさに。
マーティンエンダー

5

パイソン2145の 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))]

オンラインでお試しください!

これは長年の読書の後の私の最初の提出です。

基本的には、すべての要素をカウンター(リスト内の各要素の数の辞書)に入れ、.most_common()は頻度の降順で項目を入れます。その後は、アイテムを正しいリストにフォーマットするだけです。

ovsのおかげで4バイト節約されました。


4
PPCGへようこそ:)。私のように中毒にならないでください。
魔法のタコUr

独自の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個の要素の異なるその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)正のインデックスを強制がです。

これにより、元のリストの一意の要素を含む配列の配列が得られ、頻度でグループ化され、頻度の高い順に並べられます。

ただし、外側の配列と内側の配列の両方に、除外する空のスロットが多数ある可能性があります。これを、関数Foとその各要素に適用して行います。

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

テストケース


で1 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これは、私の現在のアプローチとはまったく異なります。たぶん、あなたは新しい答えとしてそれを投稿すべきですか?
アーナルド

o[n]配列からセットに変更することはそれほど違うとは思いませんでしたが、とにかく@RickHitchcockの答えを既にゴルフしていたので、それほど意味はありません。
ニール



2

Clojure、74バイト

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

非常に冗長に見える:/


それに私を打ち負かします(そして、数バイト、私comp -を逆転させるために巧妙に使用してください!)。他の言語ほど短くはありませんが、Clojureには「グループバイ」と「周波数」が組み込まれているため、面白いと思いました
。– MattPutnam

タスクの説明を読んだとき、私は50バイトまたは60バイトを望んでいましたが、実際の実装は少し厄介であることがわかりました。
ニコニール

2

Perl 6バイト

*.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、素敵なものを忘れます!
魔法のタコUr


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/okkは、実際に何であるかを疑問に思う他の人のためにok。BA-DUM-tssss ...
マジックタコ壺


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、9、5、6、5、6、5、6、 5、6、-56}]

出力

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


GatherByマーティンに言及しました!私はこれがどのように行われるのだろうと思いました:)。
魔法のタコUr

Sort[...,...&]ただSortBy[...,-Last@#&]です。
マーティンエンダー

Length[f=...]。そしてFirst/@です#&@@@
マーティンエンダー

修正、修正、修正
-J42161217

2

R84 77バイト

mb7744のおかげで-7バイト

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

stdinから読み取ります。整数のサブベクトルのリストを昇順で返します。intの代わりに文字列を返すことができれば、11バイトをドロップできます(への呼び出しを削除します)as.double)が、です。Rのtable関数はここで面倒な処理を行い、入力の各メンバーの発生をカウントします。次に、それらをカウント(names)。もちろん、それは文字列なので、整数/倍精度に強制する必要があります。

オンラインでお試しください!


「which」を削除し、論理インデックスを使用して、7バイトを失う可能性があります
-mb7744

@ mb7744ああああ。
ジュゼッペ

1
Rでそれをもう一度突き刺しました。残念なことに、ラムダ構文がどれくらい長いのかを回避するために着手しました。代わりにlapply、ネストされたを使用する必要がありましたが、少なくともその場合は、に短い変数を割り当てることができます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をテストすることを知っていたはずです!あなたのコードはそれを修正し、さらに短いので、ありがとうございます:)
リックヒッチコック

に変更.filter(a=>1/a[0])して、さらに3バイト節約します.filter(a=>''+a)
トマスランカース

いいね、@ TomasLangkaas、ありがとう。(2バイトを保存します。)
リックヒッチコック

私の悪い(カウントに問題がある)が.filter(a=>a+a)、余分なバイトを提供します。
トマスランカース

1

V60、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バイト

それをちょっと突き刺してください:

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=と末尾は削除できますが;。これは、これらの種類のラムダのバイトカウントの一部ではありません。
ケビンCruijssen

@KevinCruijssen、私にはわからなかった。ありがとう!
ハンドEフード

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は1バイト短くなり、同じように動作するはずですas.integer
ジュゼッペ

まあ、それは整数を返すか、倍精度を返すかによって異なります。doubleが大丈夫なら、おそらく文字も同様になり、両方のバイトを節約できます。
mb7744

1

PowerShellの、77、 70のバイト

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

NB:これらの結果が正しくグループ化されていることを確認するには(視覚的に各配列の内容間にデリニエーションがないため)、追加することができます。 | write-host上記の行の最後する。

謝辞

おかげで:

  • TessellatingHecklerは、大幅にリファクタリング/リライトすることで7バイトを節約し、よりゴルフに近いアプローチにしています。

77バイト

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

よかった、ありがとう。,()グループ化を含める必要がありました(出力が1つの連続した配列として表示されていたため)。これは私の最初の試みよりもはるかにゴルフです。お見事!
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]]
}

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.