Виклик Дейкстри


23

Презентований на честь APL як інтерактивний інструмент, яким виповнилося 50 років цього року

Фон

Кен [Іверсон] представив свою працю « Формалізм в мовах програмування» в серпні 1963 р. На робочій конференції з механічних структур мови, Прінстон, штат Нью-Джерсі, Список учасників переповнений відомими і скоро відомими іменами та кількома майбутніми лауреатами премії Тьюрінга (Backus, Curry, Dijkstra, Floyd, Iverson, Newell, Perlis, Wilkes). Документ також фіксує дискусію, яка відбулася після презентації, закінчуючи обміном між Кеном та [Едсгером] Дійкстра , в якому відповідь Кена на питання Дікстра була однолінійною.

Виклик

Як би ви представляли більш складну операцію, наприклад, суму всіх елементів матриці M, які дорівнюють сумі відповідних індексів рядків і стовпців?

Напишіть фрагмент або вираз (не потрібно повною програмою чи функцією), щоб обчислити суму кожного елемента в заданій цілій матриці, яка дорівнює сумі його індексів. Або, як стверджує FryAmTheEggman: задана матриця M з елементами a ij повертає суму кожного a ij, де a ij = i + j.

Ви можете припустити, що матриця вже знаходиться у змінній або пам'яті, або ви можете взяти її як аргумент або вхід. Ви можете використовувати індекс на основі 0 або 1.

Тестові кейси

 

0 для порожньої матриці

2

0для 0 індексів на основі або 2для 1 на основі

1 5 2
9 4 2
5 9 6

2для 0 на основі або 10для 1 на основі

 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

6для 0 на основі або 3для 1 на основі

Анекдот

Відповідь Айверсон був ++ / ( M = ¹ ⨢ ¹) // М , яка НЕ є ні дійсним в Айверсон нотації , як це визначено в мовою програмування , ні в тому, що в кінцевому підсумку став APL. У позначеннях Айверсон, було б + / ( М = ¹ ( μ ( М )) ⨢ ¹ ( ν ( М ))) / М . У перших версіях APL це було +/(,M=(⍳1↑⍴M)∘.+⍳1↓⍴M)/,M.


в якому відповідь Кена на питання Діккстра була однозначною. Але тоді той однокласник помилявся?
Луїс Мендо

Чи потрібно мені виводити його чи роздруковувати, чи я можу просто записати вираз як фрагмент?
Leaky Nun

2
@LuisMendo Ні, Іверсон активно розробляв мову, і на цій ітерації його однолінійний текст був правильним. "APL" прославився з виданням книги A P rogramming L anguage , але на момент видання друку вираз був потрібний. Жодне з цих позначень ніколи не було реалізовано як машинне виконання.
Адам

@LeakyNun Напишіть фрагмент або вираз для обчислення
Adám

@ Adám Дякую Зараз має більше сенсу
Луїс Мендо

Відповіді:


9

APL, 13 12 байт

1 байт завдяки @ jimmy23013.

1-індексований.

Масив зберігається у змінній m.

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

Спробуйте в Інтернеті!

На основі відповіді в J , яка є мовою на основі APL.

У 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

Нарешті я чекав цього.
Адам

Я не впевнений, що "Ввести:" це гарна ідея. Це стосується лише TryAPL та RIDE, але не до основного продукту. Принаймні, ви можете пояснити, що `означає "ключ APL".
Адам

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

@ jimmy23013 Це справді добре!
Адам

9

MATL , 15 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

Редагувати: збережено 3 байти завдяки @MartinEnder, який вказує, що фрагменти дозволені.


5

Сітківка , 46 байт

Кількість байтів передбачає кодування ISO 8859-1.

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

Вхід використовує простір та розділювачі передачі ліній для представлення матриці. Індекси базуються на 0.

Спробуйте в Інтернеті!

Пояснення

Не зовсім подібний виклик, з яким була зроблена Ретіна, але це на диво добре ... :)

Етап 1: Заміна

\d+
$*

Це просто розширює всі цілі числа в рядку як одинарні числа, використовуючи 1як одинарну цифру. Негативні числа, подібні -3, просто стануть подібними -111.

2 етап: Матч

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

Завдяки !опції, це друкує всі збіги даного регулярного виразів. Згаданий регулярний вираз використовує балансуючі групи, щоб перевірити, чи є поточне число таким, як сума його індексів.

Для цього ми спочатку визначаємо суму індексів з оглядом (?<=(\S* |.*¶)*). Це додає один захоплення для кожного номера перед поточним на тому ж рядку (через \S* ), а також один захоплення для кожного рядка перед поточним (через .*¶) групою 1. Отже, в результаті ми отримуємо нульову суму індексів.

Тоді ми намагаємось зіставити весь наступний номер, видаляючи з цього стека фіксації (?<-1>1)+\b. І тоді ми робимо матч потерпіти невдачу , якщо якісь - або захоплення залишені на групи 1з (?(1)1)метою забезпечення рівності.

Зауважте, що від'ємні числа ніколи не узгоджуються, тому що огляд за спиною не може пройти повз -списку 1s і (?<-1>1)+не може також відповідати.

Це дає нам список усіх одиничних чисел, які дорівнюють сумі їх індексів.

Етап 3: Матч

1

Ми закінчуємо ще одним етапом поєдинку, але без цього !варіанту, це просто підраховує кількість збігів, яке обидва підсумовує всі одинакові числа попереднього результату, а також перетворює цю суму назад у десяткову.


Чи можете ви використовувати Ury як вхід?
Leaky Nun

@LeakyNun Не знаю, я якось намагався цього уникнути. Це здається занадто хитким, тим більше, що у Retina більше не виникає проблем з конвертацією.
Мартін Ендер

4

Желе, 15 14 10 байт

4 байти завдяки Аднану.

1-індексований.

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

Спробуйте в Інтернеті!

Перевірте всі тести одразу. (Трохи модифікований.)


Я не впевнений, чи працює він, але чи можна це зробити J€замість L€R€?
Аднан

1
О Боже, ти геній.
Leaky Nun

4

Пітон 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 байт зараз: (Я додав швидке пояснення
Джеремі

Ви можете включити посилання, яке я вам щойно дав.
Leaky Nun

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
Не тільки найкоротший дотепер; +1 за те, що це робиться мовою Іверсона.
Адам

3

CJam, 23 21 20 байт

Дякую Пітеру Тейлору за збереження 3 байтів.

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

Очікує, що матриця буде в стеці, і замість цього залишить суму. В будь-якому випадку показники нульові.

Перевірте це тут.


Можна зберегти пару, _,,замість внутрішньої eeта .внутрішньої петлі:ee{~_,,@f+1$.=.*~}%1b
Пітер Тейлор

@PeterTaylor Ак акуратний, дякую. :)
Мартін Ендер

Насправді є ще один, роблячи своєрідну зустріч у середині:ee{~_@f-_,,.=.*~}%1b
Пітер Тейлор

3

k4, 24 байти

Припускає, що матриця зберігається в m.

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

Це одна з тих головоломок, де спрощення, пов'язані з проектуванням k з APL (і J), дуже боляче - k's !еквівалент APL, але працює лише на векторах, тому я повинен сам зібрати матрицю індексів; внутрішній продукт - це один символ в APL, але п’ять в k; і я втрачаю три символи для правильної обробки порожньої матриці, оскільки k не має сильно набраних матриць.


2
З іншого боку, у вас є потужна мова, яка набагато послідовніша і з набагато меншою кількістю примітивів для вивчення.
Адам


2

PowerShell v2 +, 43 байти

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

Як фрагмент. Використання полягає в тому, щоб явно передати матрицю цьому (див. Приклади нижче). Мається на увазі , що $i, і $oє або нульовий або нуль на початку (я явно встановити їх в якості таких в прикладах нижче), і використовує 0-індекс.

Чи робить петлю передбачення на кожному рядку матриці. Ми встановили , $jщоб 0, а потім пройти через кожен елемент рядка в іншому циклі $_|%{...}. Кожен внутрішній цикл ми збільшуємо $oна поточний елемент, помножений на булевий ($_-eq$i+$j++), тобто якщо цей булевий $TRUE, то 1інакше буде 0. Потім виходимо з внутрішньої петлі, з кроком $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 як двовимірний масив чисел:

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

Можливо, є більш химерний масив або метод перерахування, який би скоротив його, я його ще не знайшов, але мені б хотілося його побачити.
Девід Люнг Медісон Зоряний

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

Матлаб / Октава, 48 байт

1-індексований.

Перший тестовий випадок не обробляється, оскільки [1:0]з якихось причин має розмір 1x0

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

Випробуваний в Октаві 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! В Октаві можна зробити sum((M.*(M-[1:size(M,1)]'-[1:size(M,2)]==0))(:)). Крім того, я думаю, ви можете змінити ==0на початковий рівень, ~щоб зменшити кількість байтів. Нарешті, зауважте, що вам потрібно розглянути всі тестові справи, інакше питання слід видалити
Луїс Мендо

1

Луа, 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;

очікує масив $ визначений; має бути порожнім або двовимірним, 0-індексованим.
обчислює суму до $ s (раніше 0 або невизначено - 0 дорівнює NULL),
вставити +2перед фіналом )для 1-індексованої поведінки

З днем ​​народження 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));
}


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.