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

Обновлено: 5 апреля 2019, в 15:12

Или Бриллиантовое Ката (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 (можете посмотреть, там действительно про алмазное (или даже бриллиантовое) ката)