Tantangan Dijkstra

23

Disajikan untuk menghormati APL sebagai alat interaktif yang berusia 50 tahun tahun ini

Latar Belakang

Ken [Iverson] mempresentasikan makalahnya Formalisme dalam Bahasa Pemrograman pada Agustus 1963 pada Konferensi Kerja tentang Struktur Bahasa Mekanik, Princeton, NJ. (Backus, Kari, Dijkstra, Floyd, Iverson, Newell, Perlis, Wilkes). Makalah ini juga mencatat diskusi yang terjadi setelah presentasi, berakhir dengan pertukaran antara Ken dan [Edsger] Dijkstra , di mana jawaban Ken untuk pertanyaan Dijkstra adalah satu kalimat.

Tantangan

Bagaimana Anda mewakili operasi yang lebih kompleks, misalnya, jumlah semua elemen dari matriks M yang sama dengan jumlah dari indeks baris dan kolom yang sesuai?

Tulis cuplikan atau ungkapan (tidak perlu program atau fungsi penuh) untuk menghitung jumlah setiap elemen dalam matriks bilangan bulat yang diberikan yang sama dengan jumlah indeksnya. Atau, seperti dikatakan oleh FryAmTheEggman: diberi matriks M dengan elemen a ij kembalikan jumlah masing - masing a ij di mana a ij = i + j.

Anda dapat mengasumsikan matriks sudah berada di lokasi variabel atau memori, atau Anda dapat menganggapnya sebagai argumen atau input. Anda dapat menggunakan indeks berbasis 0 atau 1.

Uji kasus

 

0 untuk matriks kosong

2

0untuk 0 indeks berbasis atau 2untuk berbasis 1

1 5 2
9 4 2
5 9 6

2untuk 0 berbasis atau 101 berbasis

 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

6untuk 0 berbasis atau 31 berbasis

Anekdot

Jawaban Iverson adalah ++ / ( M = ¹ ⨢ ¹) // M , yang tidak valid dalam Notasi Iverson sebagaimana didefinisikan dalam Bahasa Pemrograman A , atau dalam apa yang akhirnya menjadi APL. Dalam notasi Iverson, itu akan menjadi + / ( M = ¹ ( μ ( M )) ⨢ ¹ ( ν ( M ))) / M . Dalam versi pertama APL itu +/(,M=(⍳1↑⍴M)∘.+⍳1↓⍴M)/,M.

Adm
sumber
di mana jawaban Ken untuk pertanyaan Dijkstra adalah satu kalimat. Tapi kemudian itu satu baris salah?
Luis Mendo
Apakah saya perlu menampilkan atau mencetaknya, atau bisakah saya menuliskan ekspresi sebagai cuplikan?
Leaky Nun
2
@LuisMendo Tidak, Iverson aktif mendesain bahasa, dan pada iterasi itu, one-liner-nya benar. "APL" menjadi terkenal dengan penerbitan buku A P rogramming L anguage , tetapi pada saat penerbitan, ekspresi kedua diperlukan. Tak satu pun dari notasi ini yang pernah diimplementasikan agar dapat dieksekusi mesin.
Adám
@LeakyNun Tulis cuplikan atau ungkapan untuk menghitung
Adám
@ Adam Terima kasih. Lebih masuk akal sekarang
Luis Mendo

Jawaban:

9

APL, 13 12 byte

1 byte terima kasih kepada @ jimmy23013.

1-diindeks.

Array disimpan dalam variabel m.

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

Cobalah online!

Berdasarkan jawaban dalam J , yang merupakan bahasa berdasarkan APL.

Di TryAPL, untuk memasukkan: +/m`em`c`1+/`1`i`rm

Dengan array: +/m`em`c`1+/`1`i`rm `[ 2 4 `r 3 `21 3 3 3 `21 3 1

Penjelasan

+/∊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
Biarawati Bocor
sumber
Akhirnya, saya menunggu yang ini.
Adám
Saya tidak yakin "Untuk memasukkan:" adalah ide yang bagus. Ini hanya berlaku untuk TryAPL dan RIDE, tetapi tidak untuk produk utama. Setidaknya Anda bisa menjelaskan itu `berarti "kunci APL".
Adám
1
+/∊m∩¨+/¨⍳⍴m.
jimmy23013
@ jimmy23013 Itu benar-benar bagus!
Adám
9

MATL , 15 14 10 byte

3#fbb+y=*s

Input memiliki baris yang dipisahkan oleh ;. Sebagai contoh: [1 5 2; 9 4 2; 5 9 6]. Pengindeksan berbasis 1 digunakan.

Cobalah online! Atau verifikasi semua kasus uji .

Penjelasan

Saya akan menggunakan contoh dengan input [3 -1 3 3; 3 -1 3 1]dalam penjelasan.

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
Luis Mendo
sumber
6

JavaScript, 49 46 byte

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

Sunting: Disimpan 3 byte berkat @MartinEnder menunjukkan bahwa snippet diperbolehkan.

Neil
sumber
5

Retina , 46 byte

Hitungan byte mengasumsikan penyandian ISO 8859-1.

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

Input menggunakan pemisah spasi dan linefeed untuk merepresentasikan matriks. Indeks berbasis 0.

Cobalah online!

Penjelasan

Bukan jenis tantangan yang dibuat untuk Retina, tapi ternyata berhasil dengan baik ... :)

Tahap 1: Substitusi

\d+
$*

Ini hanya memperluas semua bilangan bulat dalam string sebagai angka unary menggunakan 1sebagai digit unary. Angka negatif seperti -3hanya akan menjadi hal-hal seperti -111.

Tahap 2: Cocokkan

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

Karena !opsi, ini mencetak semua kecocokan dari regex yang diberikan. Regex tersebut menggunakan grup penyeimbang untuk memeriksa apakah angka saat ini sama dengan jumlah indeksnya.

Untuk melakukan itu, pertama-tama kita menentukan jumlah indeks dengan tampilan di belakang (?<=(\S* |.*¶)*). Ini menambahkan satu tangkapan untuk setiap angka di depan yang sekarang pada baris yang sama (via \S* ) serta satu tangkapan untuk setiap baris di depan yang saat ini (via .*¶) ke grup 1. Karenanya, kami mendapatkan jumlah indeks berbasis nol sebagai hasilnya.

Kemudian kami mencoba mencocokkan seluruh nomor berikutnya sambil menghapus tangkapan dari tumpukan ini (?<-1>1)+\b. Dan kemudian kami membuat pertandingan gagal jika ada tangkapan tersisa di grup 1dengan (?(1)1)untuk memastikan kesetaraan.

Perhatikan bahwa angka negatif tidak pernah cocok, karena tampilan di belakang tidak dapat melewati bagian -depan daftar 1dan (?<-1>1)+tidak dapat mencocokkannya juga.

Ini memberi kita daftar semua angka unary yang sama dengan jumlah indeks mereka.

Tahap 3: Cocokkan

1

Kami mengakhiri dengan tahap pertandingan lain, tetapi tanpa !opsi, ini hanya menghitung jumlah pertandingan, yang keduanya menjumlahkan semua angka unary dari hasil sebelumnya dan juga mengkonversi jumlah itu kembali ke desimal.

Martin Ender
sumber
Bisakah Anda menggunakan unary sebagai input?
Leaky Nun
@ LeakyNun Tidak tahu, saya agak berusaha menghindarinya. Sepertinya terlalu hacky, terutama karena Retina tidak memiliki masalah dengan konversi lagi.
Martin Ender
4

Jelly, 15 14 10 byte

4 byte terima kasih kepada Adnan.

1-diindeks.

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

Cobalah online!

Verifikasi semua testcans sekaligus. (Sedikit dimodifikasi.)

Biarawati Bocor
sumber
Saya tidak yakin jika bekerja, tetapi Anda dapat melakukan J€bukan L€R€?
Adnan
1
Ya Tuhan, kau jenius.
Leaky Nun
4

Python 2 - 60 57 byte

Ini adalah potongan kode, jadi itu akan menjadi beberapa byte lagi jika saya benar-benar mengembalikan nilainya, saya kira. e=enumerate;sum(i*(x+y==i)for x,r in e(a)for y,i in e(r))

Terima kasih atas bantuan Leaky Num :-)

Penjelasan cepat. aadalah nomor memegang array. Lakukan iterate melalui indeks dan jumlahkan semua nilai yang nilainya sama dengan jumlah indeks.

Jeremy
sumber
oh itu tidak berhasil. jadi 57 byte sekarang: (saya menambahkan penjelasan cepat
Jeremy
Anda mungkin ingin memasukkan tautan yang baru saja saya berikan kepada Anda.
Leaky Nun
4

R, 24 byte

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

Berbasis 1.
Kasus uji:

> 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
plannapus
sumber
3

J, 15 byte

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

Menggunakan nol berbasis pengindeksan dan mengasumsikan matriks sudah tersimpan dalam variabel M .

Penjelasan

+/,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
mil
sumber
3
Tidak hanya terpendek sampai sekarang; +1 untuk melakukannya dalam bahasa Iverson.
Adám
3

CJam, 23 21 20 byte

Terima kasih kepada Peter Taylor untuk menghemat 3 byte.

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

Mengharapkan matriks berada di tumpukan dan meninggalkan jumlah sebagai gantinya. Indeks berdasarkan nol dalam kedua kasus.

Uji di sini.

Martin Ender
sumber
Anda dapat menyimpan pasangan dengan _,,alih - alih bagian dalam eedan .untuk loop dalam:ee{~_,,@f+1$.=.*~}%1b
Peter Taylor
@PeterTaylor Ah rapi, terima kasih. :)
Martin Ender
Bahkan, ada satu lagi, dengan melakukan semacam meet-in-the-middle:ee{~_@f-_,,.=.*~}%1b
Peter Taylor
3

k4, 24 byte

Mengasumsikan matriks disimpan di m.

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

Ini adalah salah satu teka-teki di mana penyederhanaan yang terlibat dalam merancang k dari APL (dan J) benar-benar menyakitkan — k's !adalah setara dengan APL tetapi hanya bekerja pada vektor, jadi saya harus merakit sendiri matriks indeks; produk dalam adalah satu karakter dalam APL tetapi lima dalam k; dan saya kehilangan tiga karakter untuk menangani matriks kosong dengan benar karena k tidak memiliki matriks yang sangat diketik.

Aaron Davies
sumber
2
Di sisi lain, Anda memiliki bahasa yang kuat yang jauh lebih konsisten, dan dengan primitif yang lebih sedikit untuk dipelajari.
Adám
2

PowerShell v2 +, 43 byte

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

Sebagai cuplikan. Penggunaan adalah untuk secara eksplisit menyalurkan matriks ke ini (lihat contoh di bawah). Asumsikan itu $i, dan $onol atau nol di awal (saya sudah secara eksplisit mengaturnya seperti pada contoh di bawah), dan menggunakan 0-index.

Apakah loop foreach pada setiap baris matriks. Kami menetapkan $jke 0, dan kemudian pergi melalui setiap elemen dari baris di loop lain $_|%{...}. Setiap loop dalam, kita bertambah $odengan elemen saat ini dikalikan dengan Boolean ($_-eq$i+$j++), artinya jika Boolean itu $TRUE, itu akan menjadi 1, sebaliknya 0. Kemudian kita keluar dari lingkaran dalam, kenaikan $i, dan mulai baris berikutnya. Akhirnya, kami meninggalkan $ojalur pipa di akhir.

Contohnya

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
AdmBorkBork
sumber
2

Ruby, 63 byte

Dengan z sebagai susunan angka dua dimensi:

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

Sama sekali tidak mengasyikkan.

Jika z adalah array yang diratakan dengan x dan y yang memiliki ukuran array, seperti:

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

Lalu kita memiliki monster ini - mungkin lebih ruby-ish dengan produk mewah dan resletingnya, tetapi sebenarnya lebih besar:

(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)}
David Ljung Madison Stellar
sumber
Mungkin ada array yang lebih menarik atau metode enumerator yang akan mempersingkatnya, saya belum menemukannya, tapi saya ingin melihatnya.
David Ljung Madison Stellar
2

Sebenarnya, 21 byte

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

Cobalah online!

Terima kasih kepada Leaky Nun karena membuatku berhenti malas dan akhirnya menulis ini.

Ini menggunakan matriks 0-diindeks, dan mengambil input sebagai daftar bersarang.

Penjelasan:

ñ`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
Mego
sumber
2

Matlab / Oktaf, 48 byte

1-diindeks.

Tidak akan menangani test case pertama karena [1:0]memiliki ukuran 1x0 untuk beberapa alasan

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

Diuji dalam Oktaf 3.

Program lengkap:

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)))
SpamBot
sumber
Selamat datang di PPCG! Di Octave bisa Anda lakukan sum((M.*(M-[1:size(M,1)]'-[1:size(M,2)]==0))(:)). Juga, saya pikir Anda dapat mengubah ==0dan menginisialisasi ~untuk lebih mengurangi jumlah byte. Akhirnya, perhatikan bahwa Anda harus menangani semua kasus uji atau pertanyaan itu harus dihapus
Luis Mendo
1

Lua, 70 byte

1-diindeks.

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

Bonus: berfungsi untuk array yang tidak rata!

Input tersimpan a, keluaran disimpan s.

Program lengkap:

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}})
Biarawati Bocor
sumber
1

PHP, 59 byte

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

mengharapkan array $ a didefinisikan; harus kosong atau 2 dimensi, diindeks 0.
menghitung jumlah $ s (sebelumnya 0 atau tidak terdefinisi - 0 sama dengan NULL)
masukkan +2sebelum akhir )untuk perilaku 1-diindeks

Selamat Ulang Tahun APL!

fungsi dan test suite

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));
}
Titus
sumber
1

Brachylog , 15 byte

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

Cobalah online!

              +    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.
String yang tidak terkait
sumber
1

Bahasa Wolfram (Mathematica) , 42 byte

ArrayRules/*Cases[p_~_~v_/;Tr@p==v:>v]/*Tr

Cobalah online!

1-diindeks.

ArrayRules                                  (*Convert into a list of (position->value) Rules*)
          /*Cases[p_~_~v_/;Tr@p==v          (*select those where sum(position)==value*)
                                  :>v]/*Tr  (*and find the sum of those values*)
attinat
sumber