一般化された配列の波紋


22

週を始める簡単なゴルフ!ベース配列 B値配列 Vインデックス配列の 3つの配列が与えられますI。で指定されたインデックスにから値Vが挿入される別の配列を作成する必要があります。以下に例を示します。BI

Base:    [5, 1, 4, 1, 3]
Values:  [0, 0, 7]
Indices: [5, 0, 3]

インデックスは、基本配列の次の位置を指します。

[ 5, 1, 4, 1, 3 ]
 ^        ^    ^
 0        3    5

したがって、値配列から対応する要素を挿入すると、結果は次のようになります。

[0, 5, 1, 4, 7, 1, 3, 0]

ルール

プログラムまたは関数を作成し、STDIN(または最も近い代替)、コマンドライン引数または関数引数を介して入力を取得し、STDOUT(または最も近い代替)、関数の戻り値、またはBパラメーターとして指定された配列を変更することで結果を出力できます。

送信が関数でIありV、何らかの方法で変更できる場合、およびB出力に使用されない場合。

入力について次のことを想定できます。

  • ベース配列および値配列のすべての要素は、負でない整数になります。
  • 値配列には、基本配列よりも多くても1つの要素しかありません。
  • 値配列とインデックス配列の要素数は同じになります。
  • インデックス配列には繰り返しインデックスが含まれず、すべてのインデックスが範囲内になります。
  • 基本配列と値配列に、繰り返される要素含まれる場合があります。
  • 配列の一部またはすべてが空の場合があります。
  • インデックスが特定の順序で与えられていると仮定してはなりません。
  • 入力を受け取り、便利で明確な文字列またはリスト形式で出力を生成できます。また、3つのアレイを異なる順序で受け取ることもできます。
  • 0ベースのインデックス付けと1ベースのインデックス付けを選択できます。

これはコードゴルフなので、最短の回答(バイト単位)が勝ちです。

テストケース

B V I => Result0ベースのインデックス付けの形式で指定されます。1から始まるインデックスを使用している場合、3番目の配列の要素を1増やします。

[] [] [] => []
[] [1] [0] => [1]
[1,2] [] [] => [1,2]
[1,2] [3] [0] => [3,1,2]
[1,2] [3] [1] => [1,3,2]
[1,2] [3] [2] => [1,2,3]
[0,0,0] [1,1,1,1] [0,1,2,3] => [1,0,1,0,1,0,1]
[5,1,4,1,3] [0,0,7] [5,0,3] => [0,5,1,4,7,1,3,0]
[1,2,3,4] [4,3,2,1] [4,0,3,1] => [3,1,1,2,3,2,4,4]

他の興味深いエッジケースに出会ったら教えてください。それらを追加します。

リーダーボード

これは、通常のリーダーボードと言語ごとの勝者の概要の両方を生成するスタックスニペットです。

回答が表示されるようにするには、次のマークダウンテンプレートを使用して、見出しから回答を開始してください。

# Language Name, N bytes

N提出物のサイズはどこですか。スコアを改善する場合、古いスコアを打つことで見出しに残すことができます。例えば:

# Ruby, <s>104</s> <s>101</s> 96 bytes


4
NULL空の配列がある言語の空の配列についてどう思いますNULLか?
アレックスA.

@AlexA。それは共通/なら言わ言語で空の配列(複数可)の表現、私はそれで大丈夫ですよ。
マーティンエンダー

3
シンプルなゴルフ?それは私がCJamで1週間ずっとやった最も難しいことです。:P
デニス

回答:


13

Pyth、14バイト

s.icFPQmedSCtQ

デモンストレーション。

このプログラムは、入力をベース、インデックス、値の順のリストの3タプルとして受け取ります。

例の説明[5, 1, 4, 1, 3], [5, 0, 3], [0, 0, 7]

  1. 入力を受け取ります:暗黙的、Qは入力です。

  2. インデックスと値のペアを作成します:CtQ=[(5, 0), (0, 0), (3, 7)]

  3. ペアをインデックスの昇順で並べ替えます:SCtQ=[(0, 0), (3, 7), (5, 0)]

  4. 各ペアから値を取り出します:medSCtQ=[0, 7, 0]

  5. インデックスの位置でベースリストを分割します。cFPQ=[[], [5, 1, 4], [1, 3], []]

  6. インターリーブ3および4:.icFPQmedSCtQ=[[], 0, [5, 1, 4], 7, [1, 3], 0, []]

  7. 1つのリストにまとめる:s.icFPQmedSCtQ=[0, 5, 1, 4, 7, 1, 3, 0]


くそー。いつからインターリーブメソッドがありますか?ただ投稿したかった ssC,cFPQamedSCtQ]
ジャクベ

5
@Jakube isaacは6日前にこっそりコミットしました。
orlp


3
Pythはあらゆる問題を解決するために成長できるため、@ Jakube。それがゴルフ言語の問題です。難解な言語は、難解な言語のために存在します。*後に設計されるように。
センティオ

@sentiao公平を期すため、ホスト言語(Python)はしばらくの間、別の名前でインターリーブていました。
メゴ

16

Python 2、54

lambda B,*X:map(B.insert,*zip(*sorted(zip(*X))[::-1]))

入力をとして受け取りますB,I,VB呼び出されたときに入力を変更します(これが可能であることを思い出させてくれたMartinBüttnerに感謝します)。

を使用mapしてB.insert、各インデックス/要素のペアを呼び出します。要素の挿入時にリストのインデックスがシフトする問題を回避するために、pairsいzip / sort / unzipでインデックスの降順でペアをソートします。変化する問題がなければ、私たちはただやることができますmap(B.insert,*X)

古い方法(65):

B,V,I=input()
for i,v in sorted(zip(I,V))[::-1]:B[i:i]=v,
print B

5

Haskell、62バイト

import Data.List
f b v i=map snd$sort$zip[0.5,1.5..]b++zip i v

使用例:f [5,1,4,1,3] [0,0,7] [5,0,3]-> [0,5,1,4,7,1,3,0]

仕組み:(0.5たとえば[(0.5,5),(1.5,1),(2.5,4),(3.5,1),(4.5,3)])から始まる「半分」のインデックスでベースリストを拡張し、インデックスと値のペアで連結します。インデックスを並べ替えて破棄します。

備考:ここで不正行為をしているかどうかわかりません。数学的な観点からは問題ありませんが、プログラマーは、インデックス[5,0,3]のリストはIntegers要求されたリストではなく、Fractionals(正確には、型はポリモーフィックですが、Fractionalクラスに属している必要があります、FloatまたはDouble)。


5

ルビー、60 59 53バイト

->a,b,c{c.zip(b).sort.reverse.map{|i,v|a.insert i,v}}

そして、無料版

def riffle(array, values, indices)
    indices.zip(values).sort.reverse.each do |index, value|
        array.insert(index, value)
    end
end

2
代わりに名前のない関数にすることでこれを短縮できます->a,b,c{...}。また、insert括弧は必要ありません。
マーティンエンダー

@MartinBüttnerラムダを使用した名前のない関数については知っていましたが、それがチャレンジの精神にあるとは感じませんでした(通常は名前の付いた関数を要求します)。しかし、括弧を見つけてくれてありがとう。
ディランフレズ

チャレンジが名前付き関数を明確に要求しない限り、名前のない関数は常に受け入れられます。そして、名前付き関数を要求しませんでした(私は決してしません;))。
マーティンエンダー

5

CJam、34 23 18バイト

{.\2/\ee+{0=}$1f=}

私の最初のCJam提出。アドバイスは大歓迎です。ゴルフにはたくさんあると思います。

@MartinBüttnerと@Dennisの助けを借りて16バイトを節約しました。

スタック上の入力を順番に期待する関数B V I(私が最上位です)。

使用例:

[5 1 4 1 3] [0 0 7] [5 0 3] {.\2/\ee+{0=}$1f=}~

方法:

  • 配列のペア i th要素をしますi+0.5
  • 挿入値と挿入位置のペア
  • 結果の2つの配列をマージします
  • 位置要素に基づいて配列を並べ替える
  • 値要素を保持する

その浮動小数点アプローチは非常に賢く、(悲しいことに)私のものよりも優れています。あなたは、19のバイトまで取得することができますq~.5fm.\2/\ee+$1f=p匿名関数を使用して18バイトとする:{.5fm.\2/\ee+$1f=}
デニス

浮動小数点トリックを使用しない同じアイデア:({.\2/\ee+{0=}$1f=}まだ18バイト)
デニス

@Dennisありがとう、のget array element演算子が見つかりませんでした1f=。ただし、完全なプログラムのままにします。
randomra

あなたの電話。関数を投稿することに反対する理由を尋ねても構いませんか?
デニス

@Dennis CJamを始めたばかりで、関数の使い方がわかりませんでした。今、私はそれを理解したので、その答えを変えました。
ランダラ

5

K、22 21バイト

{,//+(y@<z;(z@<z)_ x)}

私たちは、3引数の関数を定義し{…}、暗黙の変数でxyそしてzそれぞれ、始まるリスト、値リストとインデックスリストを表します。「カット」演算子(_)は、指定されたインデックス((z@<z))のソート済みリストで開始リストを分割するために使用されます。リスト((a;b))を作成し、その転置(+)および結果を平坦化(,//)することにより)。

使用例:

  f:{,//+(y@<z;(z@<z)_ x)}
{,//+(y@<z;(z@<z)_ x)}

  f[1 2 3 4;4 3 2 1;4 0 3 1]
3 1 1 2 3 2 4 4

  f[5 1 4 1 3;0 0 7;5 0 3]
0 5 1 4 7 1 3 0

Kでは識別子にアンダースコアを使用できるため、アンダースコアの前後にスペースが必要です。K5はこの潜在的なあいまいさを取り除きます。昇順のインデックスを期待でき、アンダースコアが有効な識別子ではなかった場合は、はるかに優れた13バイトのプログラムを使用できます。

{,//+(y;z_x)}

(ため息。)

編集:

{,//+(y@<z;(z@<z)_ x)} / before
{,//+(y@<z;z[<z]_ x)}  / after

対称性を破り[…]ますが、中置@インデックス演算子の代わりにブラケットインデックス()を使用することでバイトを節約できます。通常、これによりプログラムが長くなりますが、この場合z、カットを実行する前にソートするためにとにかく括弧が必要でした。


4

Pyth、17バイト

ssC,cFPQamedSCtQ]

@isaacgはすでに私のソリューションを打ち負かしました。しかし、ドキュメントが完成したので、とにかく投稿するだけです。

これは、形式で入力を受け取りますB, I, V。ここで試すことができます:デモンストレーションまたはテストスイート

説明:

B = [5,1,4,1,3], I = [5,0,3], V = [0,0,7]OP の例を使用しています。

                    implicit: Q = input()
      PQ            all elements but last of Q   => [[5,1,4,1,3], [5,0,3]]
    cF              split B it the indices in I  => [[], [5,1,4], [1,3], []]

              tQ    all elements but first of Q  => [[5,0,3], [0,0,7]]
             C      zip                          => [(5,0), (0,0), (3,7)]
            S       sort                         => [(0,0), (3,7), (5,0)]
         med        extract the end of each pair => [0,7,0]
        a       ]   append an empty list         => [0,7,0,[]]

   ,                create a pair => ([[], [5,1,4], [1,3], []], [0,7,0,[]])
  C                 zip           => [([],0), ([5,1,4],7), ([1,3],0), ([],[])]
 s                  sum           => ([],0,[5,1,4],7,[1,3],0,[],[])
s                   sum           => [0,5,1,4,7,1,3,0]

4

JavaScript(ES6)、75

配列を返す3つの配列パラメーターを持つ関数。奇妙なことに、この関数はそのiパラメーターを変更します(OPによって親切に許可されているように)

スニペットの実行をテストします。Firefoxは通常どおりのみです。

f=(b,v,i,j=0)=>b.concat(v).map(p=>(p=i.indexOf(j))<0?b[j++]:(i[p]=-1,v[p]))

// TEST
out=x=>O.innerHTML+=x+'\n'

test=[
{ b:[], v:[], i:[], k:[] },
{ b:[], v:[1], i:[0], k:[1] },
{ b:[1,2], v:[], i:[], k:[1,2] },
{ b:[1,2], v:[3], i:[0], k:[3,1,2] },
{ b:[1,2], v:[3], i:[1], k:[1,3,2] },
{ b:[1,2], v:[3], i:[2], k:[1,2,3] },
{ b:[0,0,0], v:[1,1,1,1], i:[0,1,2,3], k:[1,0,1,0,1,0,1] },
{ b:[5,1,4,1,3], v:[0,0,7], i:[5,0,3], k:[0,5,1,4,7,1,3,0] },
{ b:[1,2,3,4], v:[4,3,2,1], i:[4,0,3,1], k:[3,1,1,2,3,2,4,4] }
];

test.forEach(x=>{
  r = f(x.b,x.v,x.i.slice(0)) // pass a copy of i, as the function will alter it
  ok = ''+r==''+x.k
  s='Test ' + (ok?'OK':'FAIL')
  +'\n B ['+x.b
  +']\n V ['+x.v
  +']\n I ['+x.i
  +']\n Result ['+r
  +']\n Check  ['+x.k
  +']\n'
  out(s)
  
})
<pre id=O></pre>


好奇心から、コードはFirefoxに固有のものですか?ES6だからでしょうか?
アレックスA.

@ AlexA.itはES6だからです。はい。特に、fat arrow functionChrome(AFAIK)の開発者バージョンでも実装されていません
-edc65

実際、ChromeのCanaryビルドでさえサポートしていません。
DocMax

4

Mathematica、52 51バイト

Last/@(Tr@#2->#&~MapIndexed~#⋃Thread[#3+.5->#2])&

例:

In[1]:= f = Last/@(Tr@#2->#&~MapIndexed~#⋃Thread[#3+.5->#2])&;

In[2]:= f[{5, 1, 4, 1, 3}, {0, 0, 7}, {5, 0, 3}]

Out[2]= {0, 5, 1, 4, 7, 1, 3, 0}

説明:

上記の例を使用します。

  • Tr@#2->#&~MapIndexed~# => {1 -> 5, 2 -> 1, 3 -> 4, 4 -> 1, 5 -> 3}
  • Thread[#3+.5->#2] => {5.5 -> 0, 0.5 -> 0, 3.5 -> 7}
  • 次に、これら2つのリストの(ソートされた)結合を取ります。(=>{0.5 -> 0, 1 -> 5, 2 -> 1, 3 -> 4, 3.5 -> 7, 4 -> 1, 5 -> 3, 5.5 -> 0}
  • そして、各ペアの最後の要素を取得します。(=> {0, 5, 1, 4, 7, 1, 3, 0}


3

R、75バイト

function(b,v,i){n=b;j=0;for(g in v)n=append(n,g,i[j<-j+1]+sum(i<i[j])-1);n}

これにより、名前のない関数が作成されます。呼び出すには、名前を付けf=function...ます。配列は1インデックスである必要があることに注意してください。これは、Rがロールする方法だからです。

Ungolfed +説明:

f <- function(b, v, i) {
    # Initialize the output vector to b
    n <- b

    # Initialize an index over the indices
    j <- 0

    # Loop over the values to insert
    for(g in v) {
        # Get the index of the next given insertion index
        j <- j + 1

        # Insert g into n.
        # The position at which to insert the value is determined by
        # adding the number of indices less than the current one and
        # subtracting 1. The subtraction is because we're using the
        # `after` argument in the `append` function.

        n <- append(n, g, i[j] + sum(i < i[j]) - 1)
    }

    # Return n
    n
}

例:

> f(c(), c(), c())
[1] NULL

> f(c(0, 0, 0), c(1, 1, 1, 1), c(1, 2, 3, 4))
[1] 1 0 1 0 1 0 1

> f(c(5, 1, 4, 1, 3), c(0, 0, 7), c(6, 1, 4))
[1] 0 5 1 4 7 1 3 0

いつものように提案を歓迎します!


2

CJam、19バイト

l~_,)N*q~.{t}~.\N-p

これは、STDINから配列BI、およびV(行ごとに1つ)読み取る完全なプログラムです。

CJamインタープリターでオンラインで試してください。

使い方

l~    e# Evaluate the first line of input.
_,)   e# Compute the array length and add 1.
N*    e# Push a string of that many linefeeds.
q~    e# Evaluate the remaining input.
.{t}~ e# Vectorized array set: for each index in the array from line 2, replace the
      e# LF at that index by the corresponding element of the array from line 3.
.\    e# Interleave the two arrays on the stack.
N-    e# Remove the linefeeds.
p     e# Print.

CJam、20バイト

{Qa+@@.{a2$2$=+t}e_}

これは、スタックからBV、およびI(上から下)をポップし、代わりにスタック上に単一の配列を残す匿名関数です。

CJamインタープリターでオンラインで試してください。

使い方

Qa+      e# Append [[]] to B.
@@       e# Rotate V and I on top of B.
.{       e# For each v in V and the corresponding i in I:
   a     e#     Push [v].
   2$2$= e#     Retrieve b := B[i].
   +     e#     Append to push [v b].
         e#     The stack now consists of: B i [v b]
   t     e#     Set B[i] := [v b].
}        e#
e_       e# Flatten B.

1

ルビー、48バイト

これはルールに準拠していると思いますが、確認してください。

->b,v,i{l=-1;i.map{|j|b[j]=[v[l+=1],b[j]]};b*?:}

入力として3つの配列を使用する名前のない関数。ruby式を使用して数値の配列に明確に解析できる文字列を出力しますx.split(/:+/).map(&:to_i)

イデオンのテストケース

さらに3バイトを節約できましたが、出力形式[1,2,[nil,5]]は明確ではありませんが、ルールを少し広げすぎています。


現在のフォーマットは大丈夫だと思います。インターリーブnil値を持つネストされた配列は少し伸びます。しかし、どちらの場合でも、これはコンテストに勝っていないので、私はどちらの方法でもそれについて本当に心配していません。
マーティンエンダー

1

R、60

b、v、iを取る名前のない関数として

function(b,v,i){e=c(NA,rbind(b,NA));e[i*2+1]=v;e[!is.na(e)]}

NAでbを展開vで必要なギャップを埋めるNAなしのベクトルを返します

> f=function(b,v,i){e=c(NA,rbind(b,NA));e[i*2+1]=v;e[!is.na(e)]}
> f(c(), c(), c())
logical(0)
> f(c(0, 0, 0), c(1, 1, 1, 1), c(0, 1, 2, 3))
[1] 1 0 1 0 1 0 1
> f(c(5, 1, 4, 1, 3), c(0, 0, 7), c(5, 0, 3))
[1] 0 5 1 4 7 1 3 0

1

Java(登録商標)、253、226、219、 209

勝者ではありませんが、まあです。

B、V、およびIがヌルではないと仮定します。v(小文字のv)は、Values / Indicies配列の長さです。Rは返される配列です。rは、返される配列の長さです。x、y、およびiはすべて一時的なintです。

int[]f(int[]B,int[]V,int[]I){int v=V.length,r=B.length+v,x,y,i;int[]R=java.utils.Arrays.copyOf(B,r);for(x=0;x<v;x++){i=I[x];for(y=0;y<x;y++)if(I[x]>I[y])i++;for(y=r-2;y>=i;y--)R[y+1]=R[y];R[i]=V[x];}return R;}

拡張:

int[]f( int[] B, int[] V, int[] I ) {
    int v = V.length, //length of Values
        r = B.length + v, //length of the result
        x, y, i; //temps
        int[] R = java.utils.Arrays.copyOf( B, r );       
        for( x = 0; x < v; x++ ) {
        i = I[x];
        for( y = 0; y < x; y++ )
            if( I[x] > I[y] )
                i++;
        for( y = r - 2; y >= i; y-- )
            R[y+1] = R[y];
        R[i] = V[x];
    }
    return R;
}

1

APL、22バイト

{(∊⌽2↑⍵)[⍋(2⊃⍵),⍳≢⊃⍵]}

casesIO←0では、テストケースに一致します。

これは標準のアルゴリズムです。最初の引数のインデックスベクトルは、指定されたインデックス(3番目の引数)に追加されます。インデックスを昇順に並べ替える順列を計算します。APLのソートアルゴリズムは定義上安定しているため、計算される置換は、2番目と1番目の引数の連結の要素を正しい場所に配置します。

例えば

    {(∊⌽2↑⍵)[⍋(2⊃⍵),⍳≢⊃⍵]}(5 1 4 1 3)(0 0 7)(5 0 3)
0 5 1 4 7 1 3 0
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.