順序付けられていないリストから2つの整数を見つけて、合計して入力します


13

これはGoogleのインタビューの質問です。YouTubeリンクについてはこちらをご覧ください。

タスク:

合計が指定された整数になる順不同リストから2つの整数を見つけます。

  1. 整数の順序付けられていないリストが与えられた場合、合計が指定された値になる2つの整数を見つけ、これら2つの整数を出力し、成功を示します(終了0)。特定の数値(つまり、最初の2つの整数が正しい数値に加算される)である必要はありません。値に加算されるペアはすべて機能します。
  2. 整数は正でゼロより大きい。
  3. 整数のリストは、整数のファイル(1行に1つの整数)を含む任意のデータ構造にできます。
  4. 整数が見つからない場合は、失敗を示します(終了1)。
  5. リスト内の異なる位置にある2つの整数を返す必要があります。(つまり、同じ位置から同じ番号を2回返すことはできません)

(注:ビデオでは、これらは厳密には要件ではありません。「インタビュアー」は彼を複数回変更しました。)

例えば。

sum2 8 <<EOF
1
7
4
6
5
3
8
2
EOF

印刷3および5終了ステータスは0 です。これ1,72,6は結果も許可されることに注意してください。

sum2 8 <<EOF
1
2
3
4

可能なコンボがないため、終了ステータス1を返します。4,4ルール5に従って許可されていません。


15
これは、最初にSandboxのルーズエンドの一部を揺るがす機会があった場合、大きな疑問でした。たとえば、このようなものについては、偽の値または数値のペアのいずれかを返す関数を作成する予定です。
ニール

2
この例では、返されるペアは(3,5)であり、(1,7)ではないのはなぜですか?
ロッド

4
順序付けられていないリストに「最初の」ペアがあるのはどうしてですか?それは本質的に矛盾しています。
ピーターテイラー

23
exit 0 / exit 1のことは良い考えではないと思います。多くの言語は、そのように簡単には存在しないことができ、そしてそれはだ(つまりはSTDERRを無視する)は、一般的にエラーで終了するには許可され、私が考える多くのゴルフの言語でも終了コードで終了する簡単な方法を持っていない
Rɪᴋᴇʀ

2
考え直して、いくつかの答えは終了コード1を生成するための努力を行ったため、今は要件を変更しない方が良いかもしれません
ルイスメンドー

回答:


5

Bash、84バイト

(大体)Googleのエンジニアのソリューションの実装ですが、bashと入力ストリームを使用します-私のソリューションではないため、これは考慮されません。

while read V;do((V<$1))&&{ ((T=R[V]))&&echo $T $V&&exit;((R[$1-V]=V));};done;exit 1

方法

一方、入力ストリームから整数Vを読み取ることができます。ターゲット$ 1未満の場合は、すでに$ 1-Vが表示されている場合は、$ 1-VとVを出力し、0(else)を入力します。


4

Brachylog、9バイト

h⊇Ċ.+~t?∧

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

課題を正しく理解したと仮定すると…

説明

h⊇Ċ          Ċ ('couple') has two elements, and is a subset of the head of the input
  Ċ.         Output = Ċ
   .+~t?     The sum of the elements of the Output is the tail of the Input
        ∧    (disable implicit unification)

4

Perl 6、59バイト

$_=get;put lines().combinations(2).first(*.sum==$_)//exit 1

試してみてください結果なし試してみて
ください

拡張:

$_ = get;            # get one line (the value to sum to)

put                  # print with trailing newline
    lines()          # get the rest of the lines of input
    .combinations(2) # get the possible combinations
    .first(          # find the first one
      *.sum == $_    # that sums to the input
    )
  //                 # if there is no value (「Nil」)
    exit 1           # exit with a non-zero value (「put」 is not executed)

4

JavaScript ES6、58 70 68 64バイト

a=>b=>{for(i in a)if(a.includes(b-a[i],i+1))return[a[i],b-a[i]]}

見つかった場合は配列の形式で数値のペアを返し、見つからない場合はundefined偽の値を返します。

f=a=>b=>{for(i in a)if(a.includes(b-a[i],i+1))return[a[i],b-a[i]]}

console.log(f([1,7,4,6,5,3,8,2])(8));
console.log(f([1,2,3,4,5,6,7,8])(8));
console.log(f([1,2,3,4])(8));
console.log(f([2,2])(4));


例でした3, 5が、この出力1, 7...
ニール

@ニール、ごめんなさい、私は台無しにしたので、私はルールを修正しました。1,7は大丈夫です。
フィルコルボーン

1
それはうまくいきませんf([2,2] 4)か?
クリフルート

1
@cliffrootは現在、そのような場合のために働く必要があります
トム・

1
ナイスincludesトリック。
ニール

4

JavaScript(ES6)、61 57 56バイト

カリー化構文で整数の配列aと期待される合計sを取ります(a)(s)。一致する整数のペアを配列として返すかundefined、そのようなペアが存在しない場合。

a=>s=>(r=a.find((b,i)=>a.some(c=>i--&&b+c==s)))&&[r,s-r]

フォーマットおよびコメント

a =>                      // given an array of integers (a)
  s => (                  // and an expected sum (s)
    r = a.find((b, i) =>  // look for b at position i in a such that:
      a.some(c =>         //   there exists another c in a:
        i-- &&            //     - at a different position
        b + c == s        //     - satisfying b + c == s
      )                   //   end of some()
    )                     // end of find(): assign the result to r
  ) &&                    // if it's not falsy:
  [r, s - r]              // return the pair of integers

テスト


3

ゼリー、14バイト

ŒcS=⁹$$ÐfḢṄo⁶H

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

これは、標準出力に出力する関数です(完全なプログラムではありません)。(TIOリンクには、関数を実行し、その戻り値を無視するラッパーがあります。)

このプログラムは、終了コードの要件でない場合、4バイト短くなる可能性があります。Jellyで終了コード1を返すのはかなり難しいです。(私が見逃した、これを行うためのより簡単な方法がある可能性があります。)

説明

ŒcS=⁹$$ÐfḢṄo⁶H
Œc                All pairs of values from {the first argument}
       Ðf         Take only those which
  S=⁹               sum to {the second argument}
     $$           Parse the preceding three builtins as a group
         Ḣ        Take the first result (0 if there are no results)

          Ṅ       Output this result (plus a newline) on standard output
           o⁶     If this value is falsey, replace it with a space character
             H    Halve every element of the value

ペアのすべての整数をo⁶H適切に半分にすることができるため、結果が見つかった場合、関係のない無駄な戻り値を返す以外は何もしません(関数の戻り値を決定する便利なシングルバイトメソッドとして機能します) PPCGルールの下で、早期に価値があります)。ただし、結果が見つからなかった場合、スペース文字を半分にしようとすることになります。これは、Jellyインタープリターがクラッシュするほど無意味な操作です。幸いなことに、このクラッシュは終了コード1を生成します。


3

Perl 5、51バイト

46バイトのコード+ -pliフラグ用の5バイト

$\="$_ $v"if$h{$v=$^I-$_};$h{$_}=1}{$\||exit 1

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

アイデアは、入力リストで反復することです:数値x$_)で、以前にn-x$^I-$_)を見た場合、探していたものを見つけ、$\これら2つの値に設定します("$_ $v")。最後に、$\が設定されていない場合、we exit 1、そうでない場合は暗黙的に出力されます。


2つの文字の代わりにリテラルタブが機能します^Iか?

@ ais523できないようです。たぶんそれは古いバージョンのPerlでも可能でした。
ダダ

3

ローダ60 56バイト

f s,a{seq 1,s|{|x|[[x,s-x]]if[x in a,s-x in a-x]}_|pull}

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

応答がない場合、このコードはエラーをスローします。sumを形成できるすべての可能なペアを生成しますs1, s-12, s-23, s-3、...そして、それは両方の数が配列であるかどうかをチェックaし、もしそうなら、ストリームにプッシュします。pullストリームから1つの値を読み取り、それを返します。ストリームに値がない場合、エラーがスローされます。削除されa-xた配列aを返しますx


3

Python 2、60バイト

コード1で終了するルールが明確になるまで、この短い。何も見つからない場合、エラーで終了します。

@Peilonrayzのおかげで-5バイト

@Rodのおかげで-4バイト

オンラインで試す

a,s=input()
while a:
 x=a.pop()
 if s-x in a:r=s-x,x
print r

@Peilonrayz気づかなかった、ありがとう!
デッドポッサム

@Peilonrayzこれは適合規則に違反します。リスト内の異なる位置にある2つの整数を返す必要があります。(つまり、同じ位置から同じ番号を2回返すことはできません)
デッドポッサム

3
あなたができ、混合インデント用スペース+タブを使用する 2バイトまたは低減するようにスイッチをinput() 4つのバイトを低減する
ロッド

@ロッドあり​​がとう!入力は良く見える
デッドポッサム

2
@Eric Duminilうん。それはeval(raw_input())(私が思うに)同等です。
イッツィー

2

C ++ 133バイト(clang 4およびgcc 5.3でコンパイル-std = c ++ 14)

#include <set>
auto f=[](auto s,int v,int&a,int&b){std::set<int>p;for(auto i:s)if(p.find(i)==end(p))p.insert(v-i);else{a=v-i;b=i;}};

C 108バイト

void f(int*s,int*e,int v,int*a,int*b){do{int*n=s+1;do if(v-*s==*n){*a=*s;*b=*n;}while(++n<e);}while(++s<e);}

1
サイトへようこそ!残念ながら、私はあなたが15個のバイトを追加する必要があると思う#include <set>し、のためのいくつかのより多くをstd::set。あなたが周りにカッコを削除する場合にも、いくつかのバイトを保存することができますがp.insert(v-i);
ジェームズ

@DJMcMayhemああ、ありがとう。main()を含める必要がありますか?
em2er

@ em2erいいえ、を含める必要はありませんmain。関数が有効な提出であると(チャレンジで特に明記されていない限り)考慮します。(サイトにようこそ!)
ダダ

いいえ、関数の送信は問題ありません。(入力を引数として受け取ることができるため、はるかに短くなります)送信に必要なインクルードをカウントするだけです。
ジェームズ

1
@DJMcMayhem @Dadaどうもありがとう!私はわからないend、あまりにも、それはせずに、GCCでコンパイルstd::(ともちろんそうではない場合に設定)
em2er

2

Haskell、34バイト

(n:v)#s|elem(s-n)v=(n,s-n)|1<2=v#s

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

リストの各要素について、この関数は(sum-element)がリストの次の部分にあるかどうかを確認します。見つかった最初のカップルを返します。関数がリストの最後に到達すると、「非網羅的なパターン」エラーがスローされ、コード1で終了します。


このアプローチはのような入力では機能しないのではないかと心配してい[2,2]#4ます。
ライコニ

@Laikoniありがとうございます、このチャレンジを十分に読んでいませんでした。この新しいバージョンは正しい(より短い^^)
レオ

2

PowerShell、109 97バイト

param($i,$a)($c=0..($a.count-1))|%{$c-ne($f=$_)|%{if($a[$f]+$a[$_]-eq$i){$a[$f,$_];exit}}};exit 1

AdmBorkBorkが提供する12バイトの取引を取りました

説明

# Get the parameter passed where $i is the addition target from the array of numbers in $a
param($i,$a)

($c=0..($a.count-1))|%{
    # We are going to have two loops to process the array elements.
    # The first loop element will be held by $f
    $f=$_
    # Create a second loop that will be the same as the first except for the position of $f to
    # prevent counting the same number twice. 
    $c|?{$_-ne$f}|%{
        # Check if the number at the current array indexes add to the target value. If so print and exit.
        if($a[$f]+$a[$_]-eq$i){$a[$f],$a[$_];exit}        
    }

}
# If nothing was found in the loop then we just exit with error.
exit 1

現在のルールは、これが行う終了コードを探します。それらを削除して、返された数字と偽物をチェックするだけです。

サンプルの使用法

上記のコードが関数として保存された場合 s

s 8 @(1,2,3,4)
s 8 @(1,7,4,6,5,3,8,2) 

あなたは排除することによって、さらにいくつかのバイトを保存することができます$cし、下方向にループ-($a.count-1)..1|%{$f=$_;--$_..0|%{if...
AdmBorkBork

2

R、49バイト

function(x,y){r=combn(x,2);r[,colSums(r)==y][,1]}

これにより、すべての2の組み合わせが検索されx、行列が返されます。次に、列ごとに合計し、等しいすべての合計を見つけますy(したがって[,1]、最後の部分がないと、合計がに等しいすべての組み合わせが出力されますy


2

Japt、9バイト

@ETHproductionsのおかげで多くのバイトを節約

à2 æ_x ¥V

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

説明

à2 æ_x ¥V
à2         // Creates all combinations of the input, length 2
   æ       // Returns the first item where:
    _x     //     The sum of the two items in each set
       ¥V  //     == Second input   

Input:        [1,2,3], 4
à2         // [[1,2],[1,3],[2,3]]
   æ_x     // [3,    4,    5    ]
       ¥V  //  3!=4, 4==4 ✓
Output:    //  1,3

2

Javascript、114 96 86 84バイト

a=>b=>{c=b.length;for(x=0;x<c;x++)for( y=x;++y<c;)if(b[x]+b[y]==a)return[b[x],b[y]]}

@Cyoceのおかげで1バイト、@ ETHProductionsのおかげでさらに8バイト節約

これは、指定された入力を合計するリスト要素の最初の組み合わせを持つタプルを返します。一致しない場合は何も返しません。var関数のs を削除しました。REPL.itはそれらなしでクラッシュしますが、Chrome Dev Consoleはこれをうまく処理します...

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


チャレンジは特に無効な入力を要求するため、コード1は終了しません。今のところそれは無効な答えですが、私はそれを簡単にできない言語のこの要件についてOPに尋ねました。
Rɪᴋᴇʀ

@Mattはい、そのルールが守られています:それy=x+1を処理します。
steenbergh

1
a=>b=>...バイトを保存するために使用することができます
チョイス

1
でさらに3バイト節約できますfor(y=x;++y<b.length;){。また、最も外側のブレースを除くすべてのブレースのセットを削除し、その後にスペースを削除することができますreturn
ETHproductions

1

Clojure、77バイト

#(first(mapcat(fn[i a](for[b(drop(inc i)%):when(=(+ a b)%2)][a b]))(range)%))

そのような最初のペアまたはを返しますnil


1

Haskell、62バイト

r=return;s#[]=r 1;s#(a:b)|elem(s-a)b=print(a,s-a)>>r 0|1<2=s#b

チャレンジによって何が許可され、何が許可されないのかはまだわかりません。数値のペアを出力し、解決策がある場合は0を返し、解決策がない場合は1を返す関数を使用します。印刷はI / Oなので、戻り値をIO-Monadに持ち上げる必要があります(経由してreturn)あり、関数の実際の型はNum a => IO aです。

使用例(replによって返される戻り値付き):

*Main> 4 # [2,2]
(2,2)
0

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

例外の発生が許可されている場合、failいくつかのバイト(合計51)を節約します。

s#[]=fail"";s#(a:b)|elem(s-a)b=print(a,s-a)|1<2=s#b

1

ゼリー、9バイト

ŒcS=¥ÐfḢZ

Jellyには終了コードを任意の値に設定する方法がないため、有効な解決策がないと入力に対してTypeErrorが生成され、親インタープリターは終了コード1で終了します。

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

使い方

ŒcS=¥ÐfḢZ  Main link. Argument: A (array of integers), n (integer)

Œc         Yield all 2-combinations of different elements of A.
     Ðf    Filter by the link to the left.
    ¥        Combine the two links to the left into a dyadic chain.
  S            Take the sum of the pair.
   =           Compare the result with n.
       Ḣ   Head; extract the first pair of the resulting array.
           This yields 0 if the array is empty.
        Z  Zip/transpose the result.
           This doesn't (visibly) alter pairs, but it raise a TypeError for 0.

1

Nova、101バイト

q(Int[] a,Int x)=>a{if(Int y=a.firstWhere({a.contains(x-a.remove(0))}))return [y,x-y];System.exit(1)}

コードゴルフの良い点の1つは、言語のバグを見つけるのに役立つことです。例えば、間に必要なスペースreturn[y,x-y]

プッシュ/ポップ関数をArray.novaに追加して戻り値を修正すると、96バイトになります。

q(Int[] a,Int x)=>a{if(Int y=a.firstWhere({a.contains(x-a.pop())}))return[y,x-y];System.exit(1)}

使用法:

class Test {
    static q(Int[] a,Int x)=>a{if(Int y=a.firstWhere({a.contains(x-a.remove(0))}))return [y,x-y];System.exit(1)}

    public static main(String[] args) {
        Console.log(q([1, 2, 3, 4, 5], 8)) // [5, 3]
        Console.log(q([1, 2, 3, 4, 5], 5)) // [1, 4]
        Console.log(q([1, 2, 3, 4], 8)) // exit code 1
    }
}

編集:また、73バイト(ポップを使用して69)でこの方法もあります:

q(Int[] a,Int x)=>[Int y=a.firstOrThrow({a.contains(x-a.remove(0))}),x-y]

firstOrThrowは例外をスローします。例外はキャッチされないため、最終的に終了コード1でプログラムを終了します。;)

この方法も読みやすいようです。


0

Pyth、12バイト

hfqsThQ.ceQ2

説明

       .ceQ2   Get all pairs from the second input
 fqsThQ        Find the ones whose sum is the first input
h              Take the first (exits with error code 1 if there aren't any)

0

PHP、88バイト

for($i=1;$a=$argv[$k=++$i];)for(;$b=$argv[++$k];)if($a+$b==$argv[1])die("$a $b");die(1);

コマンドライン引数から入力を受け取り、最初に合計します。で実行し-nrます。

幸いなことに、パラメータとして文字列を指定するとdie/ exitは終了し0ます。

ループを1つにマージしようとしました。しかし、今回はより長い初期化とテストが必要です。


付いてない日?for($i=1;$a=$argv[$k=++$i];)for(;$b=$argv[++$k];)$a+$b!=$argv[1]?:die(!0);あなたがこの上を見ている必要がありcodegolf.stackexchange.com/questions/120803/...を
イェルクHülsermann

0

Mathematica、76バイト

f::e="1";If[(l=Cases[#~Subsets~{2},x_/;Tr@x==#2])=={},Message@f::e,First@l]&

かなり簡単:#~Subsets~{2}リストのすべての2要素サブセットを取得しCases[...,x_/;Tr@x==#2]、合計が必要な数であるもののみを選択します。これらのいずれも存在しない場合はIf[l=={}, Message@f::e,First@l]、エラーメッセージを出力しますf::e : 1以前に定義しを(Mathematicaにとって「終了ステータス1」が他に何を意味するかわからないため)。それ以外の場合は、合計が正しいものになるペアのリストの最初のエントリを返します。

奇妙な終了ステータスを実行する代わりにfalsey値を返すことが許可されている場合、次のコードは58バイトです。

If[(l=Cases[#~Subsets~{2},x_/;Tr@x==#2])=={},1<0,First@l]&

0

Scala、55 41バイト

(l,n)=>l combinations 2 find(_.sum==n)get

2つの数値が存在する場合はそれらのリストを返し、存在しない場合はエラーをスローします。キャッチされないため、このエラーは終了ステータス1になります。


0

ルビー、53 48バイト

->a,s{p(a.combination(2).find{|x,y|x+y==s})?0:1}

入力:aはリスト、sは予想される合計です。

2つの数値が見つかった場合、それらを出力して0を返します。それ以外の場合は、仕様のように1を返します。


0

TI-Basic、59バイト

Prompt L1
Prompt X
While 1
L1(1→B
seq(L1(C),C,2,dim(L1→L1
If sum(not(X-L1-B
Then
Disp B,X-B
Return
End
End

説明:

Prompt L1               # 4 bytes, input array like "{1, 2, 3}"
Prompt X                # 3 bytes, Input target sum
While 1                 # 3 bytes, until the list is empty
L1(1→B                  # 7 bytes, try the first element (now B)
seq(L1(C),C,2,dim(L1→L1  # 18 bytes, remove first element from list
If sum(not(X-L1-B       # 10 bytes, if any element in the list plus B is the target
Then                    # 2 bytes, then...
Disp B,X-B              # 7 bytes, print it and it's "complement"
Return                  # 2 bytes, and exit gracefully
End                     # 2 bytes
End                     # 1 byte

プログラムが正常に終了しなかった場合、リスト内に続行するための十分な要素がないときにエラーが発生します。


0

CJam、23バイト

l~_,1>{e!2f<::+#)}{;;}?

入力はsum numbersです。例えば:6 [3 2 3]。真実の場合は正の数、空の場合は0、偽の場合は0を残します。

説明:

l~    e# Read input and evaluate:  | 7 [3 2 3]
_     e# Duplicate:                | 7 [3 2 3] [3 2 3]
,     e# Take the length:          | 7 [3 2 3] 3
1>{   e# If more than 1:           | 7 [3 2 3]
  e!  e#   Unique permutations:    | 7 [[2 3 3] [3 2 3] [3 3 2]]
  2f< e#   Slice each to length 2: | 7 [[2 3] [3 2] [3 3]]
  ::+ e#   Some each:              | 7 [5 5 6]
  #   e#   Index:                  | -1
  )   e#   Increment:              | 0
}{    e# Else:                     | 7 [3 2 3]
  ;   e#   Pop                     | 7
  ;   e#   pop                     |
}?    e# Endif
e# Implicit output: 0
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.