Thử thách của Dijkstra


23

Được trình bày để vinh danh APL như một công cụ tương tác bước sang tuổi 50 trong năm nay

Lý lịch

Ken [Iverson] đã trình bày bài báo Chủ nghĩa hình thức về ngôn ngữ lập trình vào tháng 8 năm 1963 tại một hội nghị làm việc về cấu trúc ngôn ngữ cơ học, Princeton, NJ (Backus, Curry, Dijkstra, Floyd, Iverson, Newell, Perlis, Wilkes). Bài viết cũng ghi lại cuộc thảo luận xảy ra sau buổi thuyết trình, kết thúc bằng một cuộc trao đổi giữa Ken và [Edsger] Dijkstra , trong đó câu trả lời của Ken cho câu hỏi của Dijkstra là một vấn đề.

Thử thách

Làm thế nào bạn đại diện cho một hoạt động phức tạp hơn, ví dụ, tổng của tất cả các phần tử của ma trận M bằng tổng của các chỉ số hàng và cột tương ứng?

Viết một đoạn mã hoặc biểu thức (không cần chương trình hoặc hàm đầy đủ) để tính tổng của từng phần tử trong một ma trận số nguyên đã cho bằng với tổng chỉ số của nó. Hoặc, như FryAmTheEggman đặt nó: đưa ra một ma trận M với các phần tử a ij trả về tổng của mỗi a ij trong đó a ij = i + j.

Bạn có thể giả sử ma trận đã ở trong một vị trí biến hoặc bộ nhớ hoặc bạn có thể lấy nó làm đối số hoặc đầu vào. Bạn có thể sử dụng 0 hoặc 1 chỉ số dựa trên.

Các trường hợp thử nghiệm

 

0 cho ma trận trống

2

0cho 0 chỉ số dựa trên hoặc 2cho 1 dựa trên

1 5 2
9 4 2
5 9 6

2cho 0 dựa hoặc 10cho 1 dựa

 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

6cho 0 dựa hoặc 3cho 1 dựa

Giai thoại

Câu trả lời của Iverson là ++ / ( M = ¹) // M , không hợp lệ trong Ký hiệu Iverson như được định nghĩa trong Ngôn ngữ lập trình A , cũng không phải là thứ cuối cùng trở thành APL. Trong ký hiệu Iverson, nó đã có + / ( M = ¹ ( μ ( M )) ⨢ ¹ ( ν ( M ))) / M . Trong các phiên bản đầu tiên của APL, nó đã được +/(,M=(⍳1↑⍴M)∘.+⍳1↓⍴M)/,M.


trong đó câu trả lời của Ken cho câu hỏi của Dijkstra là một câu trả lời. Nhưng sau đó, một-liner đã sai?
Luis Mendo

Tôi có cần xuất nó ra hay in ra không, hoặc tôi có thể viết biểu thức dưới dạng đoạn trích không?
Nữ tu bị rò rỉ

2
@LuisMendo Không, Iverson đã tích cực thiết kế ngôn ngữ, và ở lần lặp đó, một lớp lót của anh ấy đã đúng. "APL" trở nên nổi tiếng với việc xuất bản cuốn sách A P rogramming L anguage , nhưng tại thời điểm xuất bản, biểu thức thứ hai là cần thiết. Cả hai ký hiệu này đều không được thực thi để có thể thực thi bằng máy.
Adám

@LeakyNun Viết đoạn trích hoặc biểu thức để tính toán
Adám

@ Adám Cảm ơn. Nó có ý nghĩa hơn bây giờ
Luis Mendo

Câu trả lời:


9

APL, 13 12 byte

1 byte nhờ @ jimmy23013.

1 chỉ mục.

Các mảng được lưu trữ trong biến m.

+ /, m × m = + / mm
+ / M∩¨ + / m

Hãy thử trực tuyến!

Dựa trên câu trả lời trong J , đây là ngôn ngữ dựa trên APL.

Trong TryAPL, để nhập vào: +/m`em`c`1+/`1`i`rm

Với mảng: +/m`em`c`1+/`1`i`rm `[ 2 4 `r 3 `21 3 3 3 `21 3 1

Giải trình

+/∊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

Cuối cùng, tôi đã chờ đợi điều này.
Adám

Tôi không chắc chắn "To key in:" là một ý tưởng hay. Nó chỉ áp dụng cho TryAPL và RIDE, nhưng không áp dụng cho sản phẩm chính. Ít nhất bạn có thể giải thích điều đó `có nghĩa là "khóa APL".
Adám

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

@ jimmy23013 Điều đó thực sự tốt!
Adám

9

MATL , 15 14 10 byte

3#fbb+y=*s

Đầu vào có các hàng cách nhau bởi ;. Ví dụ : [1 5 2; 9 4 2; 5 9 6]. Lập chỉ mục dựa trên 1 được sử dụng.

Hãy thử trực tuyến! Hoặc xác minh tất cả các trường hợp thử nghiệm .

Giải trình

Tôi sẽ sử dụng ví dụ với đầu vào [3 -1 3 3; 3 -1 3 1]trong phần giải thích.

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

Chỉnh sửa: Đã lưu 3 byte nhờ @MartinEnder chỉ ra rằng các đoạn được cho phép.


5

Võng mạc , 46 byte

Số lượng byte giả định mã hóa ISO 8859-1.

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

Đầu vào sử dụng dấu cách và dấu cách dòng để thể hiện ma trận. Các chỉ số dựa trên 0.

Hãy thử trực tuyến!

Giải trình

Không hẳn là loại thử thách mà Retina đã thực hiện, nhưng nó đang hoạt động rất tốt ... :)

Giai đoạn 1: Thay thế

\d+
$*

Điều này chỉ đơn giản là mở rộng tất cả các số nguyên trong chuỗi dưới dạng số đơn nguyên sử dụng 1làm chữ số đơn. Số âm như -3sẽ đơn giản trở thành những thứ như -111.

Giai đoạn 2: Trận đấu

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

Do !tùy chọn, điều này in tất cả các trận đấu của regex đã cho. Regex cho biết sử dụng các nhóm cân bằng để kiểm tra xem số hiện tại có giống với tổng các chỉ số của nó hay không.

Để làm điều đó, trước tiên, chúng tôi xác định tổng các chỉ số với giao diện (?<=(\S* |.*¶)*) . Điều này thêm một lần chụp cho mỗi số ở phía trước số hiện tại trên cùng một dòng (thông qua \S* ) cũng như một lần chụp cho mỗi dòng trước số hiện tại (thông qua .*¶) vào nhóm 1. Do đó, chúng tôi nhận được tổng số chỉ số dựa trên không.

Sau đó, chúng tôi cố gắng khớp toàn bộ số tiếp theo trong khi xóa các ảnh chụp từ ngăn xếp này với (?<-1>1)+\b . Và sau đó chúng tôi làm cho trận đấu thất bại nếu bất kỳ sự bắt giữ nào được để lại trên nhóm 1với (?(1)1)để đảm bảo sự bình đẳng.

Lưu ý rằng các số âm không bao giờ được khớp, bởi vì giao diện không thể vượt qua - phía trước danh sách 1s và (?<-1>1)+không thể khớp với số đó.

Điều này cung cấp cho chúng tôi một danh sách tất cả các số đơn vị bằng tổng các chỉ số của chúng.

Giai đoạn 3: Trận đấu

1

Chúng tôi kết thúc với một giai đoạn trận đấu khác, nhưng không có !tùy chọn, điều này chỉ đếm số lượng trận đấu, cả hai tổng hợp tất cả các số đơn vị từ kết quả trước đó và cũng chuyển đổi tổng đó thành số thập phân.


Bạn có thể sử dụng unary làm đầu vào?
Rò rỉ Nun

@LeakyNun Đừng biết, tôi đã cố gắng tránh nó. Có vẻ như quá hack, đặc biệt là khi Retina không gặp rắc rối với việc chuyển đổi nữa.
Martin Ender


4

Con trăn 2 - 60 57 byte

Đó là một đoạn mã, vì vậy nó sẽ là một vài byte nữa nếu tôi thực sự trả về giá trị, tôi đoán vậy. e=enumerate;sum(i*(x+y==i)for x,r in e(a)for y,i in e(r))

Cảm ơn sự giúp đỡ Leaky Num :-)

Giải thích nhanh. alà một mảng giữ số. Đơn giản chỉ cần lặp qua các chỉ mục và tổng hợp tất cả các giá trị trong đó giá trị bằng tổng của chỉ mục.



oh nó đã không làm việc vì vậy, 57 byte của nó bây giờ: (Tôi đã thêm một lời giải thích nhanh
Jeremy

Bạn có thể muốn bao gồm các liên kết tôi vừa đưa cho bạn.
Rò rỉ Nun

4

R, 24 byte

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

1 dựa.
Các trường hợp thử nghiệm:

> 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

Sử dụng lập chỉ mục dựa trên zero và giả sử ma trận đã được lưu trữ trong biến M .

Giải trình

+/,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
Không chỉ ngắn nhất cho đến bây giờ; +1 để thực hiện bằng ngôn ngữ Iverson.
Adám

3

CJam, 23 21 20 byte

Cảm ơn Peter Taylor đã tiết kiệm 3 byte.

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

Dự kiến ​​ma trận sẽ nằm trên ngăn xếp và thay vào đó là tổng. Các chỉ số là không dựa trên trong cả hai trường hợp.

Kiểm tra nó ở đây.


Bạn có thể lưu một cặp đôi _,,thay vì bên trong ee.cho vòng lặp bên trong:ee{~_,,@f+1$.=.*~}%1b
Peter Taylor

@PeterTaylor Ah gọn gàng, cảm ơn bạn. :)
Martin Ender

Trên thực tế, có thêm một người nữa, bằng cách thực hiện một cuộc gặp gỡ giữa chừng:ee{~_@f-_,,.=.*~}%1b
Peter Taylor

3

k4, 24 byte

Giả sử ma trận được lưu trữ trong m.

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

Đây là một trong những câu đố trong đó các đơn giản hóa liên quan đến việc thiết kế k từ APL (và J) thực sự làm tổn thương của K k !tương đương với APL nhưng chỉ hoạt động trên các vectơ, vì vậy tôi phải tự lắp ráp ma trận các chỉ số; sản phẩm bên trong là một ký tự trong APL nhưng năm ký tự k; và tôi mất ba ký tự để xử lý ma trận trống đúng cách vì k không có ma trận được gõ mạnh.


2
Mặt khác, bạn có một ngôn ngữ mạnh mẽ, phù hợp hơn nhiều, và với ít nguyên thủy hơn để học.
Adám


2

PowerShell v2 +, 43 byte

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

Như một đoạn trích. Cách sử dụng là dẫn đường rõ ràng ma trận đến đây (xem ví dụ bên dưới). Giả sử rằng $i, và $olà null hoặc 0 khi bắt đầu (Tôi đã đặt rõ ràng chúng như vậy trong các ví dụ bên dưới) và sử dụng 0-index.

Có một vòng lặp foreach trên mỗi hàng của ma trận. Chúng tôi đặt $jthành 0, và sau đó đi qua từng phần tử của hàng trong một vòng lặp khác $_|%{...}. Mỗi vòng lặp bên trong, chúng ta tăng $otheo phần tử hiện tại nhân với Boolean ($_-eq$i+$j++), nghĩa là nếu Boolean $TRUEđó 1, thì ngược lại 0. Sau đó, chúng tôi thoát khỏi vòng lặp bên trong, tăng$i và bắt đầu hàng tiếp theo. Cuối cùng, chúng tôi rời khỏi $ođường ống ở cuối.

Ví dụ

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

Với z là một dãy số hai chiều:

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

Không thú vị lắm đâu.

Nếu z là một mảng dẹt với x và y có kích thước của các mảng, chẳng hạn như:

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

Sau đó, chúng ta có sự quái dị này - có lẽ nhiều ruby-ish với các sản phẩm và khóa kéo lạ mắt của nó, nhưng thực sự lớn hơn:

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

Có lẽ có một mảng fancier hoặc phương pháp liệt kê sẽ rút ngắn nó, tôi chưa tìm thấy nó, nhưng tôi rất muốn thấy nó.
David Ljung Madison Stellar

2

Trên thực tế, 21 byte

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

Hãy thử trực tuyến!

Cảm ơn Leaky Nun vì đã khiến tôi ngừng lười biếng và cuối cùng viết bài này.

Điều này sử dụng ma trận 0 chỉ mục và lấy đầu vào làm danh sách lồng nhau.

Giải trình:

ñ`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 byte

1 chỉ mục.

Sẽ không xử lý trường hợp thử nghiệm đầu tiên vì [1:0]có kích thước 1x0 vì một số lý do

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

Đã thử nghiệm trong Octave 3.

Chương trình đầy đủ:

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

Chào mừng đến với PPCG! Trong Octave bạn có thể làm sum((M.*(M-[1:size(M,1)]'-[1:size(M,2)]==0))(:)). Ngoài ra, tôi nghĩ rằng bạn có thể thay đổi ==0và ban đầu ~để giảm thêm số byte. Cuối cùng, lưu ý rằng bạn cần xử lý tất cả các trường hợp kiểm tra nếu không câu hỏi sẽ bị xóa
Luis Mendo

1

Lua, 70 byte

1 chỉ mục.

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

Tiền thưởng: nó hoạt động cho các mảng rách rưới!

Đầu vào được lưu trữ trong a, đầu ra được lưu trữ trongs .

Chương trình đầy đủ:

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;

mong đợi mảng $ a được xác định; phải trống hoặc 2 chiều, 0 chỉ mục.
tính tổng thành $ s (trước đó là 0 hoặc không xác định - 0 bằng NULL)
chèn +2trước khi kết thúc) cho hành vi được lập chỉ mục 1

Chúc mừng sinh nhật APL!

chức năng và bộ kiểm tra

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}ᶠ+

Hãy thử trực tuyến!

              +    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.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.