ダイクストラの挑戦


23

今年50歳を迎えるインタラクティブなツールとしてAPLに敬意を表して発表

バックグラウンド

ケン[アイバーソン]は、1963年8月、ニュージャージー州プリンストンで開催された機械言語構造に関する作業会議で、論文「プログラミング言語の形式主義」を発表しました。(バッカス、カレー、ダイクストラ、フロイド、アイバーソン、ニューウェル、ペルリス、ウィルクス)。この論文はまた、プレゼンテーション後に行われた議論を記録し、最後にケンと[Edsger] Dijkstraの間のやり取りが行われました。

チャレンジ

たとえば、対応する行と列のインデックスの合計に等しい行列Mのすべての要素の合計など、より複雑な演算をどのように表現しますか?

スニペットまたは式(完全なプログラムまたは関数は不要)を記述して、インデックスの合計に等しい特定の整数行列の各要素の合計を計算します。または、FryAmTheEggmanが言うように、要素a ijの行列Mが与えられると、a ij = i + j であるa ijの合計を返します。

マトリックスが既に変数またはメモリの場所にあると仮定することも、引数または入力として受け取ることもできます。0または1ベースのインデックスを使用できます。

テストケース

 

0 空行列用

2

00ベースのインデックスまたは21 ベースのインデックス

1 5 2
9 4 2
5 9 6

20ベースまたは101ベース

 0 3  0  4
 0 4  1  4
 4 3  1  2
-2 4 -2 -1

11

3 -1 3 3
3 -1 3 1

60ベースまたは31ベース

逸話

アイバーソンの答えは++ /(だったM = ¹⨢ ¹)// M中にも有効で、アイバーソン表記法で定義されたAプログラミング言語、また最終的にはAPLになったものの中に。アイバーソン表記では、+ /(あったであろうM = ¹(μM))⨢ ¹(νM)))/ M。APLの最初のバージョンではそうでした+/(,M=(⍳1↑⍴M)∘.+⍳1↓⍴M)/,M


ダイクストラの質問に対するケンの返事はワンライナーでした。しかし、そのワンライナーは間違っていましたか?
ルイスメンドー

出力または印刷する必要がありますか、またはスニペットとして式を書き留めることができますか?
リーキー修道女

2
@LuisMendoいいえ、アイバーソンは積極的に言語を設計していましたが、その繰り返しで彼のワンライナーは正しかったです。「A PL」は、「A P rogramming L anguage」という本の出版で有名になりましたが、出版時には、2番目の表現が必要でした。これらの表記法のどちらも、マシンで実行できるように実装されたことはありません。
アダム

@LeakyNun 計算するスニペットまたは式
アダム

@Adámありがとう。今ではもっと理にかなっています
ルイスメンドー

回答:


9

APL、13 12バイト

@ jimmy23013のおかげで1バイト。

1インデックス付き。

配列は変数に格納されますm

+ /、m×m = + /¨⍳⍴m
+ / ∊m∩¨ + /¨⍳⍴m

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

APLに基づく言語であるJの回答に基づいています

TryAPLで、キー入力するには: +/m`em`c`1+/`1`i`rm

配列の場合: +/m`em`c`1+/`1`i`rm `[ 2 4 `r 3 `21 3 3 3 `21 3 1

説明

+/∊m∩¨+/¨⍳⍴m
           m    temp ← variable
          ⍴     temp ← shape of temp
         ⍳      temp ← a 2D array where each element is
                       the corresponding index. for the
                       example, this gives:
                       ┌───┬───┬───┬───┐
                       │1 1│1 2│1 3│1 4│
                       ├───┼───┼───┼───┤
                       │2 1│2 2│2 3│2 4│
                       └───┴───┴───┴───┘
      +/¨       each element in temp ← its sum
   m∩¨          temp ← intersect each element in temp with the variable
+/              temp ← sum of temp

最後に、私はこれを待っていました。
アダム

「To key in:」が良いアイデアかどうかわかりません。これはTryAPLとRIDEにのみ適用され、メイン製品には適用されません。少なくとも`「APLキー」を意味すると説明できます。
アダム

1
+/∊m∩¨+/¨⍳⍴m
jimmy23013

@ jimmy23013それは本当に良いです!
アダム

9

MATL15 14 10バイト

3#fbb+y=*s

入力には、で区切られ;た行があります。例:[1 5 2; 9 4 2; 5 9 6]。1ベースのインデックスが使用されます。

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

説明

[3 -1 3 3; 3 -1 3 1]説明の入力を使用して例を使用します。

3#f    % Three-output find: for all nonzero values of implicit input matrix, pushes
       % three column vectors with row indices, column indices, and values
       %   Stack contains: [1;2;1;2;1;2;1;2], [1;1;2;2;3;3;4;4], [3;3;-1;-1;3;3;3;1]
bb     % Bubble up twice: move vectors of row and column indices to top
       %   Stack contains: [3;3;-1;-1;3;3;3;1], [1;2;1;2;1;2;1;2], [1;1;2;2;3;3;4;4]
+      % Element-wise sum of top two arrays
       %   Stack contains: [3;3;-1;-1;3;3;3;1], [2;3;3;4;4;5;5;6]
y      % Duplicate the vector of nonzero values onto the top of the stack
       %   Stack contains: [3;3;-1;-1;3;3;3;1], [2;3;3;4;4;5;5;6], [3;3;-1;-1;3;3;3;1] 
=      % Element-wise equality test of top two arrays
       %   Stack contains: [3;3;-1;-1;3;3;3;1], [0;1;0;0;0;0;0;0]
*      % Element-wise multiply of top two arrays
       %   Stack contains: [0;3;0;0;0;0;0;0]
s      % Sum of array
       %   Stack contains: 3

6

JavaScript、49 46バイト

a.map((b,i)=>b.map((c,j)=>r+=c==i+j&&c),r=0)|r

編集:スニペットが許可されていることを指摘している@MartinEnderのおかげで3バイト保存されました。


5

網膜、46バイト

バイトカウントはISO 8859-1エンコードを前提としています。

\d+
$*
M!`(?<=(\S* |.*¶)*)(?<-1>1)+\b(?(1)1)
1

入力では、スペースとラインセパレータを使用してマトリックスを表します。インデックスは0から始まります。

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

説明

Retinaが行ったようなチャレンジではありませんが、驚くほどうまくやっています... :)

ステージ1:置換

\d+
$*

これは、単項数字として文字列内のすべての整数を単項数として単純に展開します1。のような負の数-3は、単にのようなものになり-111ます。

ステージ2:試合

M!`(?<=(\S* |.*¶)*)(?<-1>1)+\b(?(1)1)

!オプションにより、これは指定された正規表現のすべての一致を出力します。この正規表現は、バランシンググループを使用して、現在の数がインデックスの合計と同じかどうかを確認します。

そのためには、最初にlookbehindを使用してインデックスの合計を決定し(?<=(\S* |.*¶)*)ます。これにより、同じ行(via \S* )の現在の行の前にある各番号の1つのキャプチャと.*¶、groupの現在の行(via )の前の各行の1つのキャプチャが追加され1ます。したがって、結果としてインデックスのゼロベースの合計を取得します。

次に、このスタックからキャプチャを削除しながら、次の番号全体を一致させようとします(?<-1>1)+\b。そして、我々は、任意のキャプチャがグループに残っている場合、一致は失敗させる1(?(1)1)平等を確保するために。

負の数は一致しないことに注意してください。これは、後読みがs -のリストの前を通過できず、どちらも一致しないためです。1(?<-1>1)+

これにより、インデックスの合計に等しいすべての単項数のリストが得られます。

ステージ3:試合

1

別の一致ステージで終了し!ますが、オプションがない場合、これは一致の数をカウントするだけで、前の結果からのすべての単項数を合計し、その合計を10進数に変換します。


入力として単項式を使用できますか?
リーキー修道女

@LeakyNunわからない、私はちょっとそれを避けようとしている。特にRetinaが変換に問題を起こさないため、あまりにもハックが多いようです。
マーティンエンダー

4

ゼリー、15 14 10バイト

Adnanのおかげで4バイト。

1インデックス付き。

L€R€+ "LR $ =³×³FSL 
€R€+" LR $ =׳FS
J€+ "J =×⁸FS

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

すべてのテストケースを一度に検証します。 (少し変更されています。)


うまくいくかどうかはわかりませんが、J€代わりにできますL€R€か?
アドナン

1
なんてこった、あなたは天才だ。
リーキー修道女

4

Python 2- 60 57バイト

これはコードスニペットなので、実際に値を返した場合はさらに数バイトになると思います。 e=enumerate;sum(i*(x+y==i)for x,r in e(a)for y,i in e(r))

助けてくれてありがとうLeaky Num :-)

簡単な説明。a数値を保持する配列です。単純にインデックスを反復処理し、値がインデックスの合計と等しいすべての値を合計します。



ああ、うまくいきませんでした。57バイトになりました:(簡単な説明を追加しました
ジェレミー

私があなたに与えたリンクを含めたいかもしれません。
リーキー修道女

4

R、24バイト

sum(M[M==row(M)+col(M)])

1ベース。
テストケース:

> M<-matrix(nrow=0,ncol=0)
> M
<0 x 0 matrix>
> sum(M[M==row(M)+col(M)])
[1] 0
> M<-matrix(2,nrow=1,ncol=1)
> M
     [,1]
[1,]    2
> sum(M[M==row(M)+col(M)])
[1] 2
> M<-matrix(c(1,9,5,5,4,9,2,2,6),nrow=3)
> M
     [,1] [,2] [,3]
[1,]    1    5    2
[2,]    9    4    2
[3,]    5    9    6
> sum(M[M==row(M)+col(M)])
[1] 10
> M<-matrix(c(0,0,4,-2,3,4,3,4,0,1,1,-2,4,4,2,-1),nrow=4)
> M
     [,1] [,2] [,3] [,4]
[1,]    0    3    0    4
[2,]    0    4    1    4
[3,]    4    3    1    2
[4,]   -2    4   -2   -1
> sum(M[M==row(M)+col(M)])
[1] 11
> M<-matrix(c(3,3,-1,-1,3,3,3,1),nrow=2)
> M
     [,1] [,2] [,3] [,4]
[1,]    3   -1    3    3
[2,]    3   -1    3    1
> sum(M[M==row(M)+col(M)])
[1] 3

3

J、15バイト

+/,M*M=+/&i./$M

ゼロベースのインデックスを使用し、マトリックスが既に変数Mに格納されていると仮定します。

説明

+/,M*M=+/&i./$M
             $a  Get the shape of M
            /    Insert between the shape
         &i.     Create a range from 0 to each end exclusive
       +/        Forms a table which is the sum of each row and column index
     M=          1 if the element is equal to its index sum else 0
   M*            Multiply by their values
  ,              Flatten
+/               Reduce using addition to get the sum

3
これまでの最短時間だけではありません。Iverson言語で行うための+1。
アダム

3

CJam、23 21 20バイト

3バイトを節約してくれたPeter Taylorに感謝します。

ee{~_@f-_,,.=.*~}%1b

マトリックスがスタック上にあることを期待し、代わりに合計を残します。どちらの場合も、インデックスはゼロベースです。

ここでテストしてください。


あなたがカップルを救うことができる_,,代わりに、内側のee.内側のforループ:ee{~_,,@f+1$.=.*~}%1b
ピーター・テイラー

@PeterTaylor Ahきちんとした、ありがとう。:)
マーティンエンダー

実際には、出会い・イン・ザ・ミドルの種類を実行して、もう一つは、あります:ee{~_@f-_,,.=.*~}%1b
ピーター・テイラー

3

k4、24バイト

行列がに保存されてmいると仮定します。

+//7h$m*m=(!#m)+/:\:!#*m

これは本当に傷つける-Kさんは、単純化は、APL(およびJ)からKを設計する際に関係者のパズルの一つである!APLのと同等ですが、私はインデックスの行列を自分で組み立てるために持っているだけなので、ベクトルに動作します。内積はAPLでは1文字ですが、kでは5文字です。kには厳密に型指定された行列がないため、空の行列を適切に処理すると3文字が失われます。


2
一方、より一貫性があり、学習するプリミティブがはるかに少ない強力な言語があります。
アダム


2

PowerShell v2 +、43バイト

%{$j=0;$_|%{$o+=$_*($_-eq$i+$j++)};$i++};$o

スニペットとして。使用法は、これを明示的にマトリックスにパイプすることです(以下の例を参照)。と仮定し$i、そして$oが開始時にnullまたはゼロである(以下の例で明示的に設定しています)、0インデックスを使用します。

マトリックスの各行でforeachループを実行します。に設定して$jから0、別のループで行の各要素を調べます$_|%{...}。各内側のループは、我々はインクリメント$oブールを乗じた現在の要素によって($_-eq$i+$j++)ブールであることを意味している場合、$TRUEそれはなります1それ以外の場合は、0。。次に、内側のループを終了し、incrementして$i、次の行を開始します。最後に、私たちは去ります$oパイプラインに残ります。

PS C:\Tools\Scripts\golfing> $o=0;$i=0;$j=0;@(@(3,-1,3,3),@(3,-1,3,1))|%{$j=0;$_|%{$o+=$_*($_-eq$i+$j++)};$i++};$o
6

PS C:\Tools\Scripts\golfing> $o=0;$i=0;$j=0;@(@(0,3,0,4),@(0,4,1,4),@(4,3,1,2),@(-2,4,-2,-1))|%{$j=0;$_|%{$o+=$_*($_-eq$i+$j++)};$i++};$o
11

2

ルビー、63バイト

zを数値の2次元配列として:

s=0;z.each_index{|i|z[i].each_index{|j|s+=i+j if z[i][j]==i+j}}

まったくエキサイティングではありません。

zが、次のようなxとyが配列のサイズを持つ平坦化された配列の場合:

x=z.size
y=z[0].size
z=z.flatten

次に、この怪物があります-おそらくそれは派手な製品とジッパーでよりルビーっぽいですが、実際にはもっと大きくなります:

(1..x).to_a.product((1..y).to_a).zip(z).inject(0){|s,n|s+(n[0][0]+n[0][1]==n[1]+2?n[1]:0)}

おそらく、それを短縮する手の込んだ配列または列挙子メソッドがありますが、まだ見つかりませんでしたが、見たいです。
デイビッドLjungマディソンステラ

2

実際には、21バイト

ñ`i╗ñ"i╜+@;(=*"£Mi`MΣ

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

Leaky Nunに私を怠け者にして、最終的にこれを書いてくれてありがとう。

これは、インデックスが0のマトリックスを使用し、ネストされたリストとして入力を受け取ります。

説明:

ñ`i╗ñ"i╜+@;(=*"£Mi`MΣ
ñ                      enumerate input
 `i╗ñ"i╜+@;(=*"£Mi`M   for each (i, row) pair:
  i╗                     flatten, store i in register 0
    ñ                    enumerate the row
     "i╜+@;(=*"£M        for each (j, val) pair:
      i╜+                  flatten, add i to j
         @;(               make an extra copy of val, bring i+j back to top
            =              compare equality of i+j and val
             *             multiply (0 if not equal, val if they are)
                 i       flatten the resulting list
                    Σ  sum the values


2

Matlab / Octave、48バイト

1インデックス付き。

[1:0]何らかの理由でサイズが1x0であるため、最初のテストケースを処理しません。

sum(sum(M.*(M-[1:size(M,1)]'-[1:size(M,2)]==0)))

Octave 3でテスト済み。

完全なプログラム:

M = [2]
sum(sum(M.*(M-[1:size(M,1)]'-[1:size(M,2)]==0)))
M = [1 5 2; 9 4 2; 5 9 6]
sum(sum(M.*(M-[1:size(M,1)]'-[1:size(M,2)]==0)))
M = [ 0 3  0  4; 0 4  1  4; 4 3  1  2;-2 4 -2 -1]
sum(sum(M.*(M-[1:size(M,1)]'-[1:size(M,2)]==0)))
M = [ 3 -1 3 3; 3 -1 3 1]
sum(sum(M.*(M-[1:size(M,1)]'-[1:size(M,2)]==0)))

PPCGへようこそ!Octaveでできますsum((M.*(M-[1:size(M,1)]'-[1:size(M,2)]==0))(:))。また、バイトカウントをさらに減らすために==0、最初~に変更することもできると思います。最後に、あなたはすべてのテストケースを処理する必要があるか、他の質問がされなければならないことに注意してください削除
ルイスMendo

1

Lua、70バイト

1インデックス付き。

s=0 for i=1,#a do for j=1,#a[i]do s=i+j==a[i][j]and s+i+j or s end end

ボーナス:不規則な配列に対して機能します!

入力はに保存されa、出力はに保存されsます。

完全なプログラム:

function Dijkstras_Challenge(a)
    s=0 for i=1,#a do for j=1,#a[i]do s=i+j==a[i][j]and s+i+j or s end end
    print(s)
end

Dijkstras_Challenge({})
Dijkstras_Challenge({{2}})
Dijkstras_Challenge({{1,5,2},{9,4,2},{5,9,6}})
Dijkstras_Challenge({{0,3,0,4},{0,4,1,4},{4,3,1,2},{-2,4,-2,-1}})
Dijkstras_Challenge({{3,-1,3,3},{3,-1,3,1}})

1

PHP、59バイト

foreach($a as$y=>$r)foreach($r as$x=>$v)$s+=($v==$x+$y)*$v;

定義された配列$ aが必要です。空または2次元、0インデックスが必要です。
合計を$ sに計算します(以前は0または未定義-0はNULLに等しい)
1インデックス付き動作の+2最終の前に 挿入し)

ハッピーバースデーAPL!

関数とテストスイート

function f0($a) { foreach($a as$y=>$r)foreach($r as$x=>$v)$s+=($v==$x+$y)*$v;return $s|0; }
function f1($a) { foreach($a as$y=>$r)foreach($r as$x=>$v)$s+=($v==$x+$y+2)*$v;return $s|0;}
$samples = [
    [], 0, 0,
    [[2]], 0, 2,
    [[1,5,2],[9,4,2],[5,9,6]], 2, 10,
    [[0,3,0,4],[0,4,1,4],[4,3,1,2],[-2,4,-2,-1]],11,11,
    [[3,-1,3,3],[3,-1,3,1]],6,3
];
function test($x,$e,$y){static $h='<table border=1><tr><th>input</th><th>output</th><th>expected</th><th>ok?</th></tr>';echo"$h<tr><td>",out($x),'</td><td>',out($y),'</td><td>',out($e),'</td><td>',cmp($e,$y)?'N':'Y',"</td></tr>";$h='';}
while($samples)
{
    $a=array_shift($samples);
    test($a,'B0:'.array_shift($samples),'B0:'.f0($a));
    test($a,'B1:'.array_shift($samples),'B1:'.f1($a));
}

1

Brachylog、15バイト

{iiʰI-ʰ=∧Ihh}ᶠ+

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

              +    The output is the sum of
{           }ᶠ     all possible results of
 i                 taking a row from the input with its index,
  i                taking an element with its index
   ʰ               from that row,
    I    Ihh       and outputting the element
       =∧          so long as the index of the row is equal to
     -ʰ            the value of the element minus its index within the row.

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