配列を列挙し、重複をグループ化します


24

この課題の目的は、正の整数の配列を取得し、そのインデックスを列挙して、要素のようにグループ化することです。

重複のない列挙は(value, index)、たとえば[3, 4, 13, 9, 2]=>のようなペアの配列を出力するだけで行われ[[3,1],[4,2],[13,3],[9,4],[2,5]]ます。

ただし、特定の要素が2回目に出現した場合、その要素には独自のペアが与えられるのではなく、最初に出現するグループに追加されます。私たちの上の例では、我々は3と9を交換した場合、出力には、我々は削除します[9,4]と交換してください[3,1][3,1,4]

出力では、グループは最初に出現する順に並べる必要があり、インデックスは昇順である必要があります。要素は、インデックスの前にグループの最初になければなりません。出力には、0または1のインデックスが付けられます。配列に少なくとも1つの要素があると仮定できます。

テストケース:

Input           | Output (One-indexed)
[3, 2, 2, 3]    | [[3, 1, 4], [2, 2, 3]]
[17]            | [[17, 1]]
[1, 1]          | [[1, 1, 2]]
[1, 1, 2]       | [[1, 1, 2], [2, 3]]
[1, 2, 3, 4]    | [[1, 1], [2, 2], [3, 3], [4, 4]]
[1, 1, 1, 1]    | [[1, 1, 2, 3, 4]]

これは、最少バイトが勝ちます!


たとえば、インデックスが文字列として出力されることは許容され[[17,"1"]]ますか?(そのようにバイトを保存できるかどうかまだわからない、まだ作業中!)
シャギー

@シャギー確かに、それは大丈夫
パベル


1
[[3, [1, 4]], [2, [2, 3]]]代わりに何かを出力できますか?
コナーオブライエン

1
@Pavelそれは理由ではありません:pしかし確かです
コナーオブライエン

回答:


9

Dyalog APL、5バイト

(⊂,)⌸

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

,⌸2バイトはほとんど動作しますが、末尾にゼロがあります:/


世界では何をしていますか?
Xcoder氏18年

@ Mr.Xcoderは各モノのインデックスを取得し、モノと存在するインデックスを使用して左演算子を呼び出します
-dzaima

isue ,⌸は後続のゼロであり、ゼロが入力に含まれることはないため、3バイト未満ですべてのゼロをドロップすることは可能でしょうか?
パベル

@Pavelゼロが存在する理由は、結果が正確な次元を持たなければならない行列であるため、バイトゲインのためにゼロをドロップするのに1バイトしかないことです。しかし、これはゴルフに適していると思います。
dzaima


7

J、12バイト

~.,&.><@I.@=

ゼロインデックス。

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

ボックスで行っているすべての作業を削除できる場合は、バイト数をかなり減らすことができます。私はそれを理解できるかどうかを確認します。

説明

これはおそらく説明するには時期尚早です(もっとゴルフがあるはずです)。

~. ,&.> <@I.@=
             =  Self-classify (comparison of each unique element to array)
            @   Composed with
          I.    Indices of ones (where it's equal)
         @      Composed with
        <       Boxed (how we deal with arrays of unequal length)
   ,&.>         Joined with
      >          Unbox each
   ,             Concatenate
    &.           Box again
~.              Unique elements

2
その配列の出力形式は空想的です
Pavel

それはまた、Π.Πバイトをたくさん取って@Pavel
コール




5

アタッシュ、15バイト

Flat=>Positions

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

これはの興味深いケースであり=>、の演算子形式ですMap。2つの関数引数fとが与えられるとg、上Mapの関数f => g[x]を返しますx。つまり、RHSが入力に適用され、LHSがマッピングされます。

組み込み関数Positionsは、インデックスによるエントリのグループ化を表す配列を生成します。デフォルトでは、2番目の引数が指定されていないPositions場合、最初の引数が使用されます。Flat質問に必要なものであるため、各アイテムにマッピングされます。

代替ソリューション

31バイト

MapArgs[Concat#~Indices,Unique]

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

非常に短い、組み込みなしの代替。MapArgsに似た関数ですMap。ただし、追加の引数を渡すことができます。たとえば、MapArgs[{_1 + _2}, 1..3, 3]です[4, 5, 6]。のようにMap、2つの関数引数を指定するとカリーになります。マッピングされる関数はですConcat#~Indices、これはフォークです。このフォークはUnique、入力の項目と入力自体に適用されます。これはConcat[_, Indices[_2, _]]Indicesswapped through の引数で~)に変換され、マッピングさ_れる要素()を_入力配列内の当該要素のインデックスと_2ペアにしMapArgsます。

43バイト

{Flat=>Zip[Unique[_],Indices[_,Unique[_]]]}

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

これは、ソリューション#1と#2の単なるより冗長な(まだ少し読みやすい)組み合わせです。


4

ゼリー、6バイト

Q;"ĠṢ$

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

説明:

Q;"ĠṢ$
Q      Keep the first occurrence of each element
     $ Last two links as a monad
   Ġ    Group indices of equal elements, then sort the resulting list of groups by the element they point to
    Ṣ   Sort; used to re-order the list of groups based on first occurrence instead
  "    Vectorize link between two arguments (the first occurrences and the group list)
 ;      Concatenate

最後のテストケース機能しません。配列は別のレイヤーにネストする必要があり、出力は常に2次元です。
パベル

@Pavel はい、そうです、フッターを追加するのを忘れました(答えは関数です)
エリック・ザ・アウトゴルファー

OK すぐに説明しますか?:P
パベル


4

Pyth、7バイト

0インデックス。

{+VQxRQ

ここで試してみてください! 代替。

どうやって?

{+ VQxRQ –完全なプログラム。

     RQ –各要素について...
    x –すべてのインデックスを取得します。
 + V –ベクトル化された連結を適用します。
   Q –入力あり。
{–重複排除。

4

MATL、8バイト

u"@tG=fh

MATL Online試しください

説明

        # Implicitly get the input
u       # Compute the unique values
"       # For each unique value, N
  @     # Push the value N to the stack
  t     # Duplicate N
  G     # Grab the input
  =f    # Get the 1-based indices of the elements that equal N
  h     # Horizontally concatenate N with the indices
        # Implicitly display the result

ああ、それは賢い!使用しようとしている18バイト&fがありましたが、機能しませんでした。
ジュゼッペ

3

実際には、24バイト

;;╗⌠╝╜r⌠╜E╛=⌡░⌡M@Z⌠♂i⌡M╔

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

説明:

;;╗⌠╝╜r⌠╜E╛=⌡░⌡M@Z⌠♂i⌡M╔
;;                        make two copies of input
  ╗                       save a copy to register 0
   ⌠╝╜r⌠╜E╛=⌡░⌡M          map over input:
    ╝                       save the element in register 1
     ╜r                     indices for input
       ⌠╜E╛=⌡░              filter:
        ╜E                    element in input at index
          ╛=                  equals element for outer map (from register 1)
                @Z        swap, zip input with map result
                  ⌠♂i⌡M   flatten each element in zipped list
                       ╔  uniquify

3

R、56バイト

function(x)lapply(unique(x),function(y)c(y,which(x==y)))

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


これはcodegolfでの私の最初の試みなので、どんなフィードバックでも歓迎です!


3
PPCGへようこそ!いい最初の答え。
パベル

1
おいフローリアン!とてもいい答えです。これは実際にはプログラムや関数ではなくスニペットです。入力はにハードコーディングされていると想定していますが、入力xを読み取る方法がscan必要です。通常、関数を使用または定義します。さらに、出力する必要があるため、これをa printまたはa でラップする必要がありcatます。
ジュゼッペ

1
より便利なRゴルフトリックについては、この質問を参照してください:)
ジュゼッペ

1
みんなありがとう!そして、rヒントへのリンクは確かに便利です!
フロリアン

2
@Florian Rは、他のRゴルファーとゴルフをしていることを覚えている限り、あなたが思うほど悪くありません(ストリングチャレンジを除く...)。ご質問がある場合は、チャットでお気軽にお問い合わせください。アクティブなRゴルファーが数人います。彼らは間違いなく提案を提供し、あなたにも感謝します!ゴルフへようこそ:)
ジュゼッペ

3

Wolfram言語(Mathematica)、40バイト

Martin Enderのおかげで1バイト節約できました。

KeyValueMap[{#,##&@@#2}&]@*PositionIndex

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


どのように機能し@*PositionIndexますか?
パベル

@Pavel @*は関数の構成です。PositionIndex基本的にすべての仕事をしますが、リストの代わりに関連付けを返します。
アレフアルファ

1
{#,##&@@#2}&バイトを保存します。
マーティンエンダー

3

JavaScript(ES6)、64バイト

0インデックス付き

a=>a.map((v,i)=>a[-v]?a[-v].push(i):a[-v]=[v,i]).filter(x=>x[0])

注、これは入力値が正であると仮定しているため、v> 0

テストケースに一致するようにテストをわずかに変更(1インデックス)

var F=
a=>a.map((v,i)=>a[-v]?a[-v].push(i+1):a[-v]=[v,i+1]).filter(x=>x[0])

test = [ // output 1 indexed
  [3, 2, 2, 3],//    | [[3, 1, 4], [2, 2, 3]]
  [17], //           | [[17, 1]]
  [1, 1], //         | [[1, 1, 2]]
  [1, 1, 2], //      | [[1, 1, 2], [2, 3]]
  [1, 2, 3, 4], //   | [[1, 1], [2, 2], [3, 3], [4, 4]]
  [1, 1, 1, 1] //    | [[1, 1, 2, 3, 4]] 
]

test.forEach(t => {
  x = F(t)
  console.log(JSON.stringify(t)+ ' -> ' + JSON.stringify(x))
})


3

APL NARS、24バイト、12文字

{∪⍵,¨⍸¨⍵=⊂⍵}

Adamテストのおかげで-4バイト:

  f←{∪⍵,¨⍸¨⍵=⊂⍵}

  ⎕fmt f 3 2 2 3
┌2────────────────┐
│┌3─────┐ ┌3─────┐│
││ 3 1 4│ │ 2 2 3││
│└~─────┘ └~─────┘2
└∊────────────────┘
  ⎕fmt f 17
┌1──────┐
│┌2────┐│
││ 17 1││
│└~────┘2
└∊──────┘
  ⎕fmt f 1 1
┌1───────┐
│┌3─────┐│
││ 1 1 2││
│└~─────┘2
└∊───────┘
  ⎕fmt f 1 2 3 4
┌4──────────────────────────┐
│┌2───┐ ┌2───┐ ┌2───┐ ┌2───┐│
││ 1 1│ │ 2 2│ │ 3 3│ │ 4 4││
│└~───┘ └~───┘ └~───┘ └~───┘2
└∊──────────────────────────┘
  ⎕fmt f 1 1 1 1
┌1───────────┐
│┌5─────────┐│
││ 1 1 2 3 4││
│└~─────────┘2
└∊───────────┘

4バイト/ 2文字を剃る:{∪⍵,¨⍸¨⍵=⊂⍵}
アダム

3

SWI-Prolog165 117バイト

Prologゴルフのヒントのおかげで-48バイト。

h(I):-I+[]-1.
[H|T]+R-N:-(select([H|A],R,[H|L],S),!,append(A,[N],L);append(R,[[H,N]],S)),O is N+1,(T+S-O,!;write(S)).

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

説明

% The predicate that prints the grouped duplicates. It's a wrapper because we
% need some extra arguments to keep state:
enumerate_duplicates(Input) :- enumerate(Input, [], 1).

% In the golfed code, operators are used to represent this predicate.
% See /codegolf//a/153160
% Go through the input, build up the result on the way and print it.
enumerate([Head|Tail], Result, Index) :-
    (
        % If our current Result already contains a list that starts with the
        % current first element in our input, Head, NewIndexes will become the
        % new "tail" of that list in our next result list:
        select([Head|OldIndexes], Result, [Head|NewIndexes], NextResult),
        % Don't backtrack before this if goals below this fail:
        !,
        % The as-yet-unknown NewIndexes above should in fact be the same as
        % OldIndexes with our current Index appended:
        append(OldIndexes, [Index], NewIndexes)
    % Use ; instead of separate predicate rules.
    % See /codegolf//a/67032
    ;
        % If our current Result did not already contain Head, append a new list
        % for it with the current index:
        append(Result, [[Head, Index]], NextResult)
    ),
    % Increment our index counter:
    NextIndex is Index + 1,
    (
        % And continue with the rest of our input:
        enumerate(Tail, NextResult, NextIndex),
        % Don't backtrack if the above succeeded:
        !
    ;
        % If Tail is no longer a multi-element list, we're done. Print:
        write(NextResult)
    ).

3

K(oK)、10バイト

溶液:

(!x),'.x:=

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

例:

(!x),'.x:=,17
,17 0
(!x),'.x:=1 1
,1 1 2
(!x),'.x:=1 0 1
(1 1 2
2 3)
(!x),'.x:=1 2 3 4
(1 0
2 1
3 2
4 3)

説明:

評価は右から左に実行されます。私はまだこれがさらにゴルフできると思います...

(!x),'.x:= / the solution
         = / group input into dictionary, item!indices
       x:  / save as variable x
      .    / value of x (the indices)
    ,'     / concatenate (,) each-both (') with
(  )       / do this together
 !x        / the key of x (i.e. the items)

ノート:

  • 14バイト宣言しなくてもx(,/)'+(!;.)@'=このアプローチをあきらめました...

1
0のインデックスが付けられた結果を返す場合があるため、をスキップできると思います1+
アダム


2

JavaScript(ES6)、68バイト

0インデックス。

a=>a.map(p=(x,i)=>1/p[x]?b[p[x]].push(i):b.push([x,p[x]=i]),b=[])&&b

テストケース


入力番号は= 0、つまり、1 / xのトリックを避けるために役立つことができる!
edc65

2

PHP 4.1、88バイト

ええ、かなり長いです。

これは、デフォルトの php.iniファイル(short_open_tag = Onおよびregister_globals = On)を想定してます。

<?foreach($A as$k=>$v){!$b[$v]&&$b[$v]=array($v);$b[$v][]=$k;}print_r(array_values($b));

これにより、人間が判読できる方法で配列が表示されます。
値は、キー「A」内のPOST、GET、およびCOOKIEによって渡すことができます。


最新バージョンでは、次を使用できます(90バイト):

<?foreach($_GET[A]as$k=>$v){if(!$b[$v])$b[$v]=[$v];$b[$v][]=$k;}print_r(array_values($b));

結果は同じですが、キー「A」内のすべての値をGETパラメーターで渡す必要があります。


2

Perl 6の 63の  61バイト

*.pairs.classify(*.value).map({.key,|.value».key}).sort(*.[1])

テスト(0ベース)

{sort *.[1],map {.key,|.value».key},classify *.value,.pairs}

テスト(0ベースの同じアルゴリズム)

拡張:

# WhateverCode lambda (this is the parameter) 
*\                                            # [3,2,2,3]

# get a list of Pairs (zero based index => value)
.pairs                                        # (0=>3,1=>2,2=>2,3=>3)

# classify based on the values (unordered result)
.classify(*.value)                            # {2=>[1=>2,2=>2],3=>[0=>3,3=>3]}

# simplify the structure
.map({
  .key,         # the value
  |.value».key  # slip in the indexes
})                                            # ((3,0,3),(2,1,2))

# sort based on first index
.sort(*.[1])


2

PHP 7.4+、71バイト

* $_GETキーを引用し、警告を避けるための73バイト。

スニペット:(デモ

<?foreach($_GET[A]as$k=>$v){$b[$v][0]=$v;$b[$v][]=$k;}print_r([...$b]);

担当者に基づいて、IsmaelMiguelはこのコミュニティにphpコードを投稿する最良の方法を知っていると思いますので、私は彼の基礎から構築しています。がスニペットに含まれるかカウントされる<?明確ではありません。これは私の最初の投稿なので、不必要な構文があるかどうかを説明できる人がいることを嬉しく思います。psまた、PHPでのゴルフのヒントも読んでいます。これは、Metaへの移行の素晴らしい候補のように思えます。です。

Ismaelのスニペットに加えられた改善は次のとおりです。

  1. 各サブ配列の最初の要素の無条件の割り当て(値の上書き)
  2. array_values()出力のインデックスを再作成する代わりに、スプラットパッキング


1

Kotlin、83バイト

{it.mapIndexed{i,c->c to i}.groupBy({(a,b)->a},{(a,b)->b}).map{(a,b)->listOf(a)+b}}

美化

{
    it.mapIndexed { i, c -> c to i }
        .groupBy({ (a, b) -> a }, { (a, b) -> b })
        .map { (a, b) -> listOf(a) + b }
}

テスト

var f: (List<Int>) -> List<List<Int>> =
{it.mapIndexed{i,c->c to i}.groupBy({(a,b)->a},{(a,b)->b}).map{(a,b)->listOf(a)+b}}

data class Test(val input: List<Int>, val output: List<List<Int>>)

val tests = listOf(
        Test(listOf(3, 2, 2, 3), listOf(listOf(3, 0, 3), listOf(2, 1, 2))),
        Test(listOf(17), listOf(listOf(17, 0))),
        Test(listOf(1, 1), listOf(listOf(1, 0, 1))),
        Test(listOf(1, 1, 2), listOf(listOf(1, 0, 1), listOf(2, 2))),
        Test(listOf(1, 2, 3, 4), listOf(listOf(1, 0), listOf(2, 1), listOf(3, 2), listOf(4, 3))),
        Test(listOf(1, 1, 1, 1), listOf(listOf(1, 0, 1, 2, 3)))
)

fun main(args: Array<String>) {
    for (c in tests) {
        val o = f(c.input)
        if (o != c.output) {
            throw AssertionError("${c.input} -> $o != ${c.output}")
        }
    }
}

TIO

TryItOnline


このソリューションはスニペットであり、完全な機能やプログラムではありません。変数iを事前定義する必要があります。パラメータを受け取るラムダに変換することにより、これを有効にすることができますi
パベル

@Pavelによって提起された問題を解決するために修正されました
jrtapsell

1

Swift 4、107バイト

...いや。

{a in Dictionary(grouping:a.enumerated()){$0.1}.sorted{$0.1.first!.0<$1.1.first!.0}.map{[$0]+$1.flatMap{$0.0}}}

ゴルフをしていない:

let f = { (input: [Int]) -> [[Int]] in
    return Dictionary(grouping: input.enumerated(), by: { $0.element })
        .sorted { pairA, pairB in // Sort by order of first appearence (lowest offset)
            return pairA.value.first!.offset < pairB.value.first!.offset
        }.map { element, pairs in
            return [element] + pairs.map{ $0.offset /* +1 */} // add 1 here for 1 based indexing
        }
}

辞書が順序付けを失うのはあまりにも悪いので、再びソートする際に非常に多くの文字を無駄にしなければなりません。暗黙の閉鎖の引数(の虐待のこの種の$0$1、...)と暗黙のタプルメンバーは(.0.1、...)uhhhhhきれいではありません。



1

ルビー54 52バイト

->a{a.map{|i|[i]+(0..a.size).select{|j|a[j]==i}}|[]}

このバージョンでは、nil(53バイト)が許可されます。

->a{a.map{|i|[i]+(0...a.size).select{|j|a[j]==i}}|[]}

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


チャレンジは、配列に正の整数のみが含まれ、少なくとも1つの要素があることを指定します。nil正の整数ではありません。
パベル

@Pavelおかげで、私を確認したが、何とかそれを逃しました
アソーントゥヒッド
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.