インデックスと値を交換する


29

タスク

入力が整数のリスト/配列Xであり、出力が整数Yのセットのリストであるプログラムまたは関数を記述します。これにより、各セットY [ i ]の各要素eに対して、X [ e ] = iYのセットの要素の総数がXの要素の数と等しくなるようにします。

(これは基本的にハッシュテーブル/辞書を逆にするのと同じ操作ですが、代わりに配列に適用されます。)

これらの例では1ベースのインデックス付けを想定していますが、必要に応じて0ベースのインデックス付けを代わりに使用できます。

X             Y
[4]           [{},{},{},{1}]
[1,2,3]       [{1},{2},{3}]
[2,2,2]       [{},{1,2,3}]
[5,5,6,6]     [{},{},{},{},{1,2},{3,4}]
[6,6,5,5]     [{},{},{},{},{3,4},{1,2}]

明確化

  • 必要に応じて、セットをリストとして表すことができます。その場合、要素の順序は重要ではありませんが、要素を繰り返すことはできません。
  • 妥当な明確なI / O形式を使用できます。たとえば、セットの要素をスペースで区切り、セット自体を改行で区切ることができます。
  • Yは有限長で、少なくともXのすべての要素を配列インデックスとして持つのに十分な長さでなければなりません。ただし、Xの最大要素よりも長くなる場合があります(余分な要素は空のセットになります)。
  • Xの要素はすべて有効な配列インデックスになります。つまり、0ベースのインデックスを使用する場合は負でない整数、1ベースのインデックスを使用する場合は正の整数になります。

勝利条件

の挑戦、短い方が良いです。


関連。でサンドボックスポスト(今削除していますが、評判を持っている場合、あなたはそれを見ることができる)、我々はそれはおそらく重複していないと判断しましたが、あなたは同意しない場合は近くに投票して自由に感じます。

「要素の順序は重要ではありません」とは、出力が同一で[5,5,6,6]あり[6,6,5,5]得ることを意味しますか?
リーキー修道女

1
@LeakyNun出力リスト内のセットの要素の順序は関係ありません。だから、[5,5,6,6]および[6,6,5,5]同一の出力を持つことはできませんが、のための出力は[5,5,6,6]、例えば、もあったかもしれません[{},{},{},{},{2,1},{4,3}]
-ngenisis

Xにインデックスの想定可能な最大値はありますか?また、空のセットに実際に空の代わりに0を含めることはできますか?たとえば[{0},{0},{0},{0},{1,2},{3,4}][5,5,6,6]
Skidsdev

@Mayube:最初の答えはノーです(ただし、整数の範囲が制限されている言語を使用している場合、整数が無限に大きくなる可能性があるようにプログラムを記述できます。入力として範囲外の整数)。2番目の質問に関しては、1ベースのインデックスを使用している場合、それは明確な(奇妙な場合)構文なので、その場合はい(明らかに、0ベースのインデックスを使用している場合は0ですその他。)

回答:


9

MATL、8バイト

tn:IXQ&D

入力は、;セパレータとしての列ベクトルです(例:)[2;2;2]。出力は、行ベクトルのセル配列の文字列表現です(例:){[]; [1 2 3]}。単一要素の行ベクトルは数値と同じです(そのため、の{1; 2; 3}代わりに出力されます{[1]; [2]; [3]})。

オンラインでお試しください!または、すべてのテストケースを確認します

説明

t     % Implicit input, say x. Duplicate
n     % Number of elements, say N
:     % Range: [1 2 ... N]
IXQ   % accumarray(x, [1 2 ... N], [], @(x){sort(x).'})
&D    % String representation

ほとんどの作業は、Matlabの高次関数によって行われますaccumarray。これは、最初の入力の一致する値に従って2番目の入力の要素をグループ化し、指定された関数を各グループに適用します。この場合の関数は@(x){sort(x).'}、各グループのソートされた要素を出力し、すべてのグループの結果をセル配列にパックします。


7

Python、69バイト

lambda s:[[j for j,x in enumerate(s)if x==i]for i in range(max(s)+1)]

0ベースのインデックスを使用します。


7

ゼリー7 5バイト

=þṀT€

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

使い方

=þṀT€  Main link. Argument: A (array)

  Ṁ    Yield m, the maximum of A.
=þ     Equals table; for each t in [1, ..., m], compare all elemnts of A with t,
       yielding a 2D Boolean array.
   T€  Truth each; for each Boolean array, yield all indices of 1.

5

ゼリー、8バイト

Jẋ"Ṭ€;"/

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

使い方

Jẋ"Ṭ€;"/  argument: z           eg. [6,6,4,4]
J         [1 .. len(z)]             [1,2,3,4]
   Ṭ€     untruth each of z         [[0,0,0,0,0,1],
                                     [0,0,0,0,0,1],
                                     [0,0,0,1],
                                     [0,0,0,1]]
 ẋ"       repeat each of ^^         [[[],[],[],[],[],[1]],
          as many times as           [[],[],[],[],[],[2]],
          each of ^                  [[],[],[],[3]],
                                     [[],[],[],[4]]]
       /  reduce by...
     ;"   vectorized concatenation  [[],[],[],[3,4],[],[1,2]]

4

Mathematica、36バイト

Join@@@#~Position~n~Table~{n,Max@#}&

説明

ここに画像の説明を入力してください

n{1, 2, ..., Max@#}Max@#入力リスト内の最大の整数であり、計算PositionSをここでn入力されたリストに表示されます#。以降Position[{6,6,5,5},5](例えば)戻り{{3},{4}}、我々は、次にApply Joinレベルのすべての要素に{1}結果。


3

Haskell、45バイト

s整数のリストを取り、リストのリストを返します。テストケースの入力が変更されないように1インデックスが付けられます(ただし、出力には余分な空のリストが追加されます)。

s l=[[i|(i,y)<-zip[1..]l,y==x]|x<-[1..sum l]]

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

これらは非常に簡単なネストされたリスト内包表記です。わずかな微調整は、のsum代わりにを使用してより長いリストを作成するオプションを利用することですmaximum


3

PHP、55バイト

<?while($i<=max($_GET))print_r(array_keys($_GET,$i++));

0インデックス。


3

R、68 49 47バイト

lapply(1:max(x<-scan()),function(y)which(y==x)) 

驚いたことに、長いソリューションよりもずっと簡単です。xSTDINからベクトルを取得し、1to からベクトルを作成しmax(x)、暗黙的にlengthのリストを生成し、max(x)どのインデックスがx新しいリストのインデックスと一致するかをチェックします。暗黙的に出力を印刷します。

古いバージョン:

o=vector('list',max(x<-scan()));for(i in x)o[[i]]=c(o[[i]],F<-F+1);o

他のRの回答に対する若干異なるアプローチ。STDINへのベクトルを取得し、入力の最大値に等しい長さのリストを作成します。入力をループし、適切な場所にインデックスを追加します。

1ベースのインデックスを使用します。



2

ゼリー、9 バイト

Ṭ+\ịĠȧ@"Ṭ

として表される1インデックス付きの空のセット、として0表されるN複数のアイテムのセットとして表される1つのアイテムのセット[M,N,...]

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

どうやって?

Ṭ+\ịĠȧ@"Ṭ - Main link: list a        e.g. [6,6,4,4]
Ṭ         - untruth a                     [0,0,0,1,0,1]
  \       - cumulative reduce with:
 +        -   addition                    [0,0,0,1,1,2]
    Ġ     - group indices of a by value   [[3,4],[1,2]]
   ị      - index into                    [[1,2],[1,2],[1,2],[3,4],[3,4],[1,2]]
        Ṭ - untruth a                     [0,0,0,1,0,1]
       "  - zip with:
     ȧ@   -   and with reversed @rguments [0,0,0,[3,4],0,[1,2]]

2

JavaScript(ES6)、64 62バイト

@SteveBennettのおかげで2バイト節約


0インデックス付き入力を受け取ります。セットのコンマ区切りリストを返します。

a=>a.map((n,i)=>o[n]=[i,...o[n]||[]],o=[])&&`{${o.join`},{`}}`

テストケース


代替バージョン、53バイト

などの単純化された出力'||||3,2|1,0'が受け入れられる場合、次のようにします。

a=>a.map((n,i)=>o[n]=[i,...o[n]||[]],o=[])&&o.join`|`

ワオ。私は、`{${o.join`},{`}}`ES2015の合法性がとても混乱しています。
スティーブベネット

@SteveBennett、それはテンプレートリテラルです。JSの古いバージョンでは、それが"{" + o.join("},{") + "}"明確になれば、になります。
シャギー

いいえ、私はそれらについて知っています-私を混乱させるのは、単語joinの後のバッククォートです。それは文字列を閉じていますか(この場合はwtf)、または閉じ括弧をエスケープする方法ですか?
スティーブベネット

うーん、わかりましたので、このコンテキストでjoin`はと同等join('です。それができるとは思いもしませんでした。
スティーブベネット

ああ、今は見える。タグ付きテンプレートリテラルです。1つの文字列引数を取る(および他の文字列引数を無視する)関数を呼び出すたびに、いくつかの文字を保存するために悪用できる:array.join` `。テンプレート文字列内にそれを埋め込んでいるので、ここで非常に混乱します。さらに複雑なことに、結合文字列は},{、偶然にもテンプレート文字列の一部のように見えました...とにかく奇妙でいです。:)
スティーブベネット


1

Mathematica 62バイト

(Y={}~Table~Max@#;Y[[#[[j]]]]~AppendTo~j~Table~{j,Tr[1^#]};Y)&

私はあなたのためにそれを実行します

(Y={}~Table~Max@#;Y[[#[[j]]]]~AppendTo~j~Table~{j,Tr[1^#]};Y)&[{4,5,2,3,3,8,6,3}]

{{}、{3}、{4、5、8}、{1}、{2}、{7}、{}、{6}}

オンラインで試してみてください(ctrl-vでコードを貼り付け、shift + enterを押します)。
上記の例のように入力リストを最後に貼り付けることを忘れないでください


PPCGへようこそ!の挿入記法を使用して、バイトを保存できますAppendTo。また、{j,1,Length[#1]}単に{j,Length@#}、またはさらに短くすることもでき{j,Tr[1^#]}ます。Tr[1^#]は、を使用してバイトを節約する非常に一般的なトリックLengthです。
-ngenisis

1

Perl 6の 36の32  29バイト

->\a{map {a.grep(*==$_):k},1..a.max}

それを試してみてください

{map {.grep(*==$^a):k},1.. .max}

それを試してみてください

{map {.grep($^a):k},1.. .max}

それを試してみてください


拡張:

{  # bare block lambda with implicit parameter 「$_」

  map

    {  # bare block lambda with placeholder parameter 「$a」

      .grep(  # grep for the values in 「$_」
        $^a   # that are equal to the currently tested value (and declare param)
      ) :k    # return the key (index) rather than the value
    },

    1 .. .max # Range from 1 to the maximum value in 「$_」

}

ゼロベースのインデックスを返します。1を使用するにはX+op と組み合わせてクロス演算子()使用します。(33バイト)

{1 X+.grep($^a):k}

Setを返すようにするにsetは、そこに追加するだけです(合計37バイト)

{set 1 X+.grep($^a):k}

1

R、80 72バイト

1インデックス付き、Xstdinから取得。NULL空のセットとして、インデックスのベクトルのリストを返します。

X=scan();Y=vector('list',max(X));Y[X]=lapply(X,function(x)which(X==x));Y

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

古いバージョン:

X=scan();Y=vector('list',max(X));for(i in 1:length(X))Y[[X[i]]]=c(Y[[X[i]]],i);Y

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


私もそれがY=list();うまくいくと思う
-rturnbull

few私の答えでバイトを削った:) codegolf.stackexchange.com/a/120024/59530
JAD




0

GNUのメイク214の 213 208 204バイト

X=$(MAKECMDGOALS)
M=0
P=$(eval N=$(word $1,$X))$(if $N,$(if $(shell dc -e$Nd$Mds.\>.p),$(eval M=$N),)$(eval A$N+=$1$(call $0,$(shell expr $1 + 1))),)
$(call P,1)$(foreach K,$(shell seq $M),$(info $(A$K)))

I / O:引数を介した入力配列、stdoutへの出力、行ごとに1つ、スペースで区切られます。

$ make -f swap.mk 2 2 2

3 2 1
make: *** No rule to make target `2'.  Stop.

説明

X=$(MAKECMDGOALS)     # Input array
M=0                   # Max value encountered in X
P=$(eval
    N=$(word $1,$X))  # Get next word from X
  $(if $N,$(if $(shell dc -e$Nd$Mds.\>.p),
    $(eval M=$N),)    # Update M
    $(eval A$N+=$1    # Append index to a variable named after value
      $(call $0,      # Recurse (call returns empty string)
        $(shell expr $1 + 1))),)
$(call P,1)           # Initial call to P. 1 is the first index
$(foreach K,          # Print all values of A* variables
  $(shell seq $M),
  $(info $(A$K)))     # Uninitialized ones default to empty strings

セット内のインデックスの順序は、P更新の前に再帰的にA$2呼び出されるため、逆になります(呼び出しは右側の評価で実行されます)。


make自体算術行うにはどのような方法がありますか?それを行うために外部プログラムを呼び出すことは、おそらくそれらのプログラムにより多くのアルゴリズムを入れて、より短いプログラムで終わる可能性があるので、少し不正行為のように感じます。

@ ais523ありません。以前のバージョンが使用されbcgrep。私はまた、使用することができますtest$?dc構文は簡潔ですが、率直に言ってこれらはすべて同じように感じます。
-eush77


0

k、13バイト

{(=x)@!1+|/x}

これは0インデックスです。

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

{           } /function(x)
 (=x)         /make a map/dictionary of values to their indices
         |/x  /get maximum value in x
      !1+     /make a range from 0 to the value, inclusive
     @        /get map value at each of the values in the range
              /    0N is given where there is no result
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.