Алмазное Ката

Rate this post

Или Бриллиантовое Ката (Diamond kata). Такое ката как оказывается действительно есть — но оно не имеет совершенно никакого отношения к каратэ. Так на самом деле называется оригинальное упражнение в программировании — Diamond kata. (Видимо названное так одним из больших любителей каратэ.) К сожалению и большому разочарованию такое вот оказалось на самом деле алмазное ката — а название какое многообещающее и загадочное. Кажется — вершиной должно быть и каратэ и боевых искусств. (И что интересно, в каратэ в частности и в боевых искусствах в целом, часто так бывает, что за красивым и загадочным названием или историей скрывается самая что ни на есть обыденность, или еще хуже — вообще ничего.)

Для первого апреля хорошая статья, но не буду дожидаться.

Итак, оригинальное алмазное ката:

Подтверждения

Мортен Кромберг — другой соавтор этого текста, но программное обеспечение для ведения блогов предотвращает его перечисление в качестве такового.

Мы в долгу перед Джей Фоуд, Ником Николовым, Джоном Скоулзом и Фионой Смит за комментарии к последующим проектам MS.

Эта проблема

Алмазное ката — это упражнение по программированию, используемое в сообществах гибкой разработки, XP и TDD. [ 0 , 1 , 2 , 3 ]. Впервые он привлек наше внимание в 2012 году в ходе дискуссий с Джанфранко Алонги из Ericcson AB, Швеция, а также совсем недавно в [3] . Следующее описание проблемы взято из [2] (описание немного отличается в каждой из приведенных выше ссылок).

Мы собираемся написать программу, которая строит ромбовидную картинку, подобную этой, для некоторого набора букв от А до чего угодно:

--A--
-B-B-
C---C
-B-B-
--A--

Решения в Dyalog APL

На самом деле мы собираемся решить немного другую проблему: у функции будет два аргумента. Левый аргумент — это скаляр элемента фона; правильный аргумент — это вектор используемых «букв». Результат, описанный в первом разделе, может быть получен как:

'-' dia 'ABCD'
---A---
--B-B--
-C---C-
D-----D
-C---C-
--B-B--
---A---
(В сеансе APL то, что вы вводите, имеет отступ, и результирующий вывод выравнивается по левому полю. Кроме того, в этом тексте мы иногда представляем пары отступ / ввод / вывод по всей странице.)

Делая аргумент фактическими буквами, а не количеством букв или последней буквой, облегчается работа с «алфавитами», отличными от AZ. Например:

0 dia 3 1 4 2
0 0 0 3 0 0 0
0 0 1 0 1 0 0
0 4 0 0 0 4 0
2 0 0 0 0 0 2
0 4 0 0 0 4 0
0 0 1 0 1 0 0
0 0 0 3 0 0 0
Видно, что алмазный результат состоит из отражений одного из квадрантов. Например, (показано выше) состоит из отражений'-' dia 'ABCD'

A---
-B--
--C-
---D
Функции ⌽(обратная последняя ось) и ⊖(обратная первая ось) обеспечивают необходимые отражения. Если qквадрант показан выше, то:

⌽q q
---A A---
--B- -B--
-C-- --C-
D--- ---D

⌽⊖q ⊖q
D--- ---D
-C-- --C-
--B- -B--
---A A---
Существуют различные способы сшивания квадрантов (и удаления общего среднего ряда или столбца) для получения требуемого результата. Ниже приведен краткий способ:

f←{⍉⍵⍪1↓⊖⍵}

f ⌽q f f ⌽q f⍣2 ⌽q
---D--- ---A--- ---A---
--C-C-- --B-B-- --B-B--
-B---B- -C---C- -C---C-
A-----A D-----D D-----D
-C---C- -C---C-
--B-B-- --B-B--
---A--- ---A---
Же картина ( metakata ?) От вовлечения может быть использована для вычисления миноров матрицы [4] .f⍣2⍉

Осталось произвести квадрант q. Отметим, что это диагональная матрица, напоминающая матрицу тождеств, для которой известно множество методов. Мы используем два из 34 различных методов в [5] .

Первый способ: Для вектора с nбуквами, если каждый вектор сопровождается nкопиями фонового элемента, то Reshape из что вращает каждую строка дополнительного шаг вправо, и результат является искомой диагональной матрицей.2⍴n

n←≢v←'ABCD'

v,'-'⍴⍨s←2⍴n s ⍴ v,'-'⍴⍨s←2⍴n
A---- A---
B---- -B--
C---- --C-
D---- ---D
Второй способ: для предлагаемого слияния оператора [6] представляет собой массив , как с в положениях , выбранных . Таким образом, это функциональная версия выборочного назначения. Слияние с операндом делает трюк.⍺ f merge ⍵⍵⍺f1 1∘⍉

4 4⍴⍳16 1 1∘⍉ 4 4⍴⍳16
1 2 3 4 1 6 11 16
5 6 7 8
9 10 11 12
13 14 15 16

'-'⍴⍨2⍴n 'ABCD' (1 1∘⍉merge) '-'⍴⍨2⍴n
---- A---
---- -B--
---- --C-
---- ---D
Собираем это вместе:

dia ← {{⍉⍵⍪1↓⊖⍵}⍣2⌽s⍴⍵,⍺⍴⍨s←2⍴≢⍵}
diam ← {{⍉⍵⍪1↓⊖⍵}⍣2⌽⍵(1 1∘⍉merge)⍺⍴⍨2⍴≢⍵}

'-' dia 'ABCD' 0 dia 3 1 4 2
---A--- 0 0 0 3 0 0 0
--B-B-- 0 0 1 0 1 0 0
-C---C- 0 4 0 0 0 4 0
D-----D 2 0 0 0 0 0 2
-C---C- 0 4 0 0 0 4 0
--B-B-- 0 0 1 0 1 0 0
---A--- 0 0 0 3 0 0 0

'-' diam 'ABCD' 0 diam 3 1 4 2
---A--- 0 0 0 3 0 0 0
--B-B-- 0 0 1 0 1 0 0
-C---C- 0 4 0 0 0 4 0
D-----D 2 0 0 0 0 0 2
-C---C- 0 4 0 0 0 4 0
--B-B-- 0 0 1 0 1 0 0
---A--- 0 0 0 3 0 0 0
Дальнейшие примеры
↑∘⎕a¨ 0 1 5 3 ⍝ four prefixes of the alphabet
┌┬─┬─────┬───┐
││A│ABCDE│ABC│
└┴─┴─────┴───┘
'.' dia¨ ↑∘⎕a¨ 0 1 5 3 ⍝ apply dia to each prefix
┌┬─┬─────────┬─────┐
││A│...A...│...A...│
││ │...B.B...│.B.B.│
││ │...C...C...│C...C│
││ │.D...D.│.B.B.│
││ │E.......E│...A...│
││ │.D...D.│ │
││ │...C...C...│ │
││ │...B.B...│ │
││ │...A...│ │
└┴─┴─────────┴─────┘
'.' {{⍉⍵⍪1↓⊖⍵}⍣2⌽s⍴⍵,⍺⍴⍨s←2⍴≢⍵}¨ ↑∘⎕a¨ 0 1 5 3
┌┬─┬─────────┬─────┐
││A│...A...│...A...│
││ │...B.B...│.B.B.│
││ │...C...C...│C...C│
││ │.D...D.│.B.B.│
││ │E.......E│...A...│
││ │.D...D.│ │
││ │...C...C...│ │
││ │...B.B...│ │
││ │...A...│ │
└┴─┴─────────┴─────┘
Последнее входное выражение является автономным (заменяет diaпредпоследнее входное выражение его определением), и вы можете попробовать его в сеансе.

Алмазное ката готово, надеюсь вы тоже совершенно ничего не поняли...

Источник: Dialog.com (можете посмотреть, там действительно про алмазное (или даже бриллиантовое) ката)