Dijkstra'nın Mücadelesi


23

APL onuruna bu yıl 50 yaşına giren etkileşimli bir araç olarak sunuldu

Arka fon

Ken [Iverson] , 1963 Ağustos'unda Makine Dili Yapıları Çalışma Konferansında, Princeton, NJ’de Programlama Dilleri’nde Biçimcilik’i yayınladı. (Backus, Köri, Dijkstra, Floyd, Iverson, Newell, Perlis, Wilkes). Makalede ayrıca, Sun'ın ardından Ken ve [Edsger] Dijkstra arasında bir değişim ile sona eren tartışmalar kaydedildi .

Meydan okuma

Daha karmaşık bir işlemi, örneğin karşılık gelen satır ve sütun indekslerinin toplamına eşit olan bir M matrisinin tüm elemanlarının toplamını nasıl temsil edersiniz ?

Verilen bir tamsayı matrisindeki her bir öğenin toplamını, indekslerinin toplamına eşit olacak şekilde hesaplamak için bir snippet veya ifade yazın (tam bir program veya fonksiyona gerek yok). FryAmTheEggman koyar kadar veya, bir matrisi verilen M elemanları ile bir ij her toplamını geri bir ij burada bir ij = i + j.

Matrisin zaten değişken veya bellek konumunda olduğunu varsayabilir veya bir argüman veya giriş olarak kabul edebilirsiniz. 0 veya 1 tabanlı dizinleri kullanabilirsiniz.

Test durumları

 

0 boş matris için

2

00 tabanlı endeksler için veya 21 tabanlı

1 5 2
9 4 2
5 9 6

20 tabanlı veya 101 tabanlı

 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 tabanlı veya 31 tabanlı

anekdot

Iverson'ın cevabı ++ / ( M = ¹ ⨢ ¹) // M idi ; bu, ne bir Programlama Dili'nde tanımlandığı gibi Iverson Notasyonu'nda ne de sonunda APL olanında geçerli değildir. Iverson notasyonunda + / ( M = ¹ ( μ ( M )) ⨢ ¹ ( ν ( M ))) / M olurdu . APL'nin ilk sürümlerinde öyleydi .+/(,M=(⍳1↑⍴M)∘.+⍳1↓⍴M)/,M


Ken'in Dijkstra'nın sorusuna cevabını verdiği bir tek astardı. Ama o zaman bu bir astar yanlıştı?
Luis Mendo,

Çıktı yapmam veya yazdırmam gerekir mi, yoksa ifadeyi pasaj olarak yazabilir miyim?
Leaky Nun

2
@LuisMendo Hayır, Iverson dili aktif olarak tasarlıyordu ve bu yinelemede tek astarı doğruydu. "APL" kitabının yayınlanması ile ünlendi A P rogramming L anguage ama yayınlandığı tarihte, ikinci ifadesi ihtiyaç vardı. Bu notasyonların hiçbiri makinede çalıştırılabilir olmak için hiç uygulanmadı.
Adám

@LeakyNun Hesaplamak için bir pasaj veya ifade yazın
Adám

@ Adám Teşekkürler. Şimdi daha mantıklı geliyor
Luis Mendo,

Yanıtlar:


9

APL, 13 12 bayt

@ Jimmy23013 için 1 bayt teşekkürler.

1 endeksli.

Dizi değişkende saklanır m.

+ / M x m = + / ¨⍳⍴m
+ / Εm∩¨ + / ¨⍳⍴m

Çevrimiçi deneyin!

Göre J yanıt APL göre bir dildir.

TryAPL’de, aşağıdakileri girmek için: +/m`em`c`1+/`1`i`rm

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

açıklama

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

Sonunda bunu bekliyordum.
Adám

"Girmek için:" iyi bir fikir olduğundan emin değilim. Sadece TryAPL ve RIDE için geçerlidir, fakat ana ürün için geçerli değildir. En azından `"APL anahtarı" anlamına geldiğini açıklayabilirsin .
Adám

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

@ jimmy23013 Bu gerçekten iyi!
Adám

9

MATL , 15 14 10 bayt

3#fbb+y=*s

Girdi ile ayrılmış satırlar var ;. Örneğin: [1 5 2; 9 4 2; 5 9 6]. 1 tabanlı indeksleme kullanılır.

Çevrimiçi deneyin! Veya tüm test durumlarını doğrulayın .

açıklama

Örneği [3 -1 3 3; 3 -1 3 1]açıklamadaki girdiyle kullanacağım .

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 bayt

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

Düzenleme: @MartinEnder sayesinde snippet'lere izin verildiğini belirten 3 bayt kaydedildi.


5

Retina , 46 bayt

Bayt sayısı, ISO 8859-1 kodlamasını varsayar.

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

Girdi, matrisi temsil etmek için boşluk ve satır besleme ayırıcılarını kullanır. Endeksler 0 tabanlıdır.

Çevrimiçi deneyin!

açıklama

Retina’nın yaptığı bu tür bir zorluk değil, ama şaşırtıcı derecede iyi gidiyor ... :)

Aşama 1: Değiştirme

\d+
$*

Bu sadece dizedeki tüm tamsayıları 1, tekli basamak olarak kullanan tekli sayılar olarak genişletir . Gibi negatif sayılar -3sadece gibi şeyler haline gelecektir -111.

2. Aşama: Maç

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

!Bu seçenek nedeniyle , verilen regex'in tüm eşleşmelerini yazdırır. Bahsedilen regex , mevcut sayının indekslerinin toplamı ile aynı olup olmadığını kontrol etmek için dengeleme grupları kullanır .

Bunu yapmak için, ilk önce indekslerin toplamını lookbehind ile belirleriz (?<=(\S* |.*¶)*). Bu (aracılığıyla aynı hat üzerinde mevcut birinin önünde her numara için bir yakalama ekler \S* ) ve aynı zamanda mevcut birinin önünde, her hat için bir yakalama (yoluyla .*¶grubuna bağlı olarak) 1. Dolayısıyla, sonuç olarak sıfır temelli endeks toplamını elde ederiz.

Ardından, bu yığından yakalamaları kaldırırken bir sonraki sayının tamamını eşleştirmeye çalışırız (?<-1>1)+\b. Sonra herhangi yakalar grubuna kalması durumunda maç başarısız kılmak 1ile (?(1)1)eşitlik sağlayacak.

Negatif sayıların hiçbir zaman eşleşmediğini unutmayın; çünkü gözbebeki s -listesinin önünden geçemez 1ve (?<-1>1)+eşleşemez.

Bu bize endekslerinin toplamına eşit olan bütün unary sayıların bir listesini verir.

Aşama 3: Eşleşme

1

Başka bir eşleşme aşamasıyla sona ereriz, ancak bu !seçenek olmadan , bu sadece önceki sonuçtan gelen tüm birleşik sayıları toplayan ve bu toplamı ondalık basamağa dönüştüren eşleşme sayısını sayar.


Giriş olarak unary kullanabilir misiniz?
Leaky Nun

@LeakyNun Bilmiyorum, bundan kaçınmaya çalışıyorum. Sadece Retina artık dönüşümle ilgili bir sorun yaşamadığı için çok tehlikeli görünüyor.
Martin Ender


4

Python 2 - 60 57 bayt

Bu bir kod pasajı, bu yüzden aslında değeri döndürürsem birkaç bayt daha olur, sanırım. e=enumerate;sum(i*(x+y==i)for x,r in e(a)for y,i in e(r))

Leaky Num :-) yardımınız için teşekkürler

Hızlı açıklama asayı tutan bir dizidir. Dizinler arasında yineleme yapın ve değerin dizinin toplamına eşit olduğu tüm değerleri toplayın.



oh işe yaramadı. bu yüzden şimdi 57 baytı: (hızlı bir açıklama ekledim
Jeremy

Size verdiğim bağlantıyı dahil etmek isteyebilirsiniz.
Leaky Nun

4

R, 24 bayt

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

1 tabanlı.
Test durumları:

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

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

Sıfır tabanlı dizinlemeyi kullanır ve matrisin zaten M değişkeninde depolandığını varsayar .

açıklama

+/,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
Şimdiye kadar sadece en kısa değil; Iverson dilinde bunu yapmak için +1.
Adám

3

CJam, 23 21 20 bayt

Peter Taylor'a 3 bayt kaydettiği için teşekkürler.

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

Matrisin yığında olmasını bekler ve bunun yerine toplamı bırakır. Endeksler her iki durumda da sıfır tabanlıdır.

Burada test et.


_,,İçsel eeve .içsel döngü yerine bir çifti kurtarabilirsiniz :ee{~_,,@f+1$.=.*~}%1b
Peter Taylor

@PeterTaylor Ah düzgün, teşekkür ederim. :)
Martin Ender

Aslında, bir çeşit ortada buluşma yaparak:ee{~_@f-_,,.=.*~}%1b
Peter Taylor

3

k4, 24 bayt

Matrisin depolandığını varsayar m.

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

Bu, APL (ve J) 'den k tasarımında yer alan basitleştirmelerin gerçekten incittiği bulmacalardan biridir - k, APL'lerin !eşdeğeridir, ancak sadece vektörler üzerinde çalışır, bu yüzden indeks matrisini kendim oluşturmam gerekiyor; iç ürün APL'de bir karakter, beş de k cinsindendir; ve boş matrisi düzgün bir şekilde kullanabilmek için üç karakter kaybediyorum, çünkü k güçlü şekilde yazılmış matrislere sahip değil.


2
Öte yandan, daha tutarlı ve öğrenmesi gereken çok daha az ilkeli olan güçlü bir dile sahipsiniz.
Adám


2

PowerShell v2 +, 43 bayt

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

Bir snippet olarak. Kullanım, matrisi bu şekilde açıkça belirtmektir (aşağıdaki örneklere bakınız). Varsayar $ive $ostart (açıkça aşağıdaki örneklerde gibi bunları kurdum) de ya boş veya sıfır olup, 0-indeksi kullanır.

Matrisin her satırında bir foreach döngüsü yapar. Biz set $jiçin 0, ve sonra başka döngü içinde sıranın her öğe geçmesi $_|%{...}. Her iç döngü, biz artırır $obir Boole ile çarpılır akım elemanı tarafından ($_-eq$i+$j++)Boole olduğunu eğer yani $TRUE, bu olacak 1, aksi takdirde 0. Sonra iç döngüden çıkarız, artar $ive bir sonraki satıra başlar. Sonunda, $osonunda boru hattından ayrılıyoruz .

Örnekler

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 bayt

İki boyutlu bir sayı dizisi olarak z ile:

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

Hiç de heyecan verici değil.

Z, x ve y gibi dizilerin boyutlarına sahip düzleştirilmiş bir dizi ise:

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

Öyleyse bu canavarlığa sahibiz - belki de süslü ürünleri ve fermuarlarıyla daha yakut gibi, ama aslında daha büyük:

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

Belki de onu kısaltacak bir meraklı dizisi veya numaralandırıcı yöntemi var, henüz bulamadım, ama görmeyi çok isterim.
David Ljung Madison Stellar,

2

Aslında, 21 bayt

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

Çevrimiçi deneyin!

Beni tembel kılmayı bıraktığım ve sonunda bunu yazdığım için teşekkür ederim.

Bu, 0 dizinli matrisler kullanır ve girişi yuvalanmış bir liste olarak alır.

Açıklama:

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

1 endeksli.

İlk test durumuyla başa [1:0]çıkmayacak, çünkü bazı nedenlerden dolayı 1x0 boyutunda

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

Octave 3'te test edilmiştir.

Tam program:

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'ye Hoşgeldiniz! Octave'da yapabilirsin sum((M.*(M-[1:size(M,1)]'-[1:size(M,2)]==0))(:)). Ayrıca, bayt sayısını daha da azaltmak için ==0tarafından değiştirilip ilk değiştirilebileceğini düşünüyorum ~. Son olarak, tüm test durumlarını ele almanız gerektiğine dikkat edin, aksi takdirde sorunun silinmesi
Luis Mendo

1

Lua, 70 bayt

1 endeksli.

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: düzensiz diziler için çalışıyor!

Giriş saklandı a, çıkış saklandı s.

Tam program:

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 bayt

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

$ a dizisinin tanımlı olmasını bekliyor; boş veya 2 boyutlu, 0 indeksli olmalıdır. 1-indeksli davranış için finalden önce
$ s (daha önce 0 veya daha önce tanımlanmamış - 0 eşittir NULL)
ekini toplamı hesaplar+2)

İyi ki doğdun APL!

fonksiyonlar ve test takımı

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 bayt

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

Çevrimiçi deneyin!

              +    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

Wolfram Dili (Mathematica) , 42 bayt

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

Çevrimiçi deneyin!

1 endeksli.

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*)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.