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.


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

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

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.


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.


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

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.



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

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

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.


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.


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

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)}

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


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)))

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}})

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));
}

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.

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*)
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.