J , 16 11 байт
(+$:)^:=1+?
Попробуйте онлайн!
объяснение
TL; DR 1+? выполняет бросок кубика, (+$:)^:=повторяется только тогда, когда он равен входу.
Функция представляет собой череду из 4 глаголов:
┌─ +
┌───┴─ $:
┌─ ^: ─┴─ =
│
──┤ ┌─ 1
└──────┼─ +
└─ ?
Поезд - это когда два или более глаголов соединяются. Здесь ответ имеет вид f g h j:
(+$:)^:= 1 + ?
f g h j
Так называемый «4-поезд» разбирается как крюк и вилка:
f g h j ⇔ f (g h j)
Таким образом, ответ эквивалентен:
(+$:)^:= (1 + ?)
Крючки: (f g) xиx (f g) y
Монадический (с одним аргументом) хук из двух глаголов, если задан аргумент x, имеет место следующая эквивалентность:
(f g) x ⇔ x f (g x)
Например, (* -) 5оценивает до 5 * (- 5), что оценивает до _25.
Это означает, что наш 4-поезд, крюк fи (g h j), эквивалентен:
(f (g h j)) x ⇔ x f ((g h j) x)
Но что fздесь делать? (+$:)^:=это соединение двух глаголов с использованием питания конъюнкции ^:: другой крюк ( (+$:)) и глагол ( =). Обратите внимание, что fэто двоично - у него есть два аргумента ( xи (g h j) x). Поэтому мы должны посмотреть, как ^:ведет себя. Силовое соединение f^:oпринимает глагол fи глагол или существительное o(существительное - просто часть данных) и применяет f oвремена. Например, взять o = 3. Имеются следующие эквивалентности:
(f^:3) x ⇔ f (f (f x))
x (f^:3) y ⇔ x f (x f (x f y))
Если oэто глагол, степенное соединение просто оценивает oаргументы и использует результат существительного в качестве числа повторений.
Для нашего глагола, oэто =глагол равенства. Он оценивает 0для различных аргументов и 1для равных аргументов. Мы повторяем хук (+$:)один раз для одинаковых аргументов, а не раз для разных. Для удобства обозначения для объяснения, позвольте y ⇔ ((g h j) x). Помните, что наш начальный хук эквивалентен этому:
x (+$:)^:= ((g h j) x)
x (+$:)^:= y
Расширяя соединение, это становится:
x ((+$:)^:(x = y)) y
Если xи yсовпадают, это становится:
x (+$:)^:1 y ⇔ x (+$:) y
В противном случае это становится:
x (+$:)^:0 y ⇔ y
Теперь мы видели монадические вилки. Здесь у нас есть диадическая вилка:
x (f g) y ⇔ x f (g y)
Итак, когда xи yсовпадают, мы получаем:
x (+$:) y ⇔ x + ($: y)
Что такое $:? Это относится ко всему самому глаголу и допускает рекурсию. Это означает, что, когда xи y are the same, we apply the verb toy and addx` к нему.
вилы: (g h j) x
Теперь, что делает внутренняя вилка? Это было yв нашем последнем примере. Для монадической вилки из трех глаголов с заданным аргументом имеет xместо следующая эквивалентность:
(g h j) x ⇔ (g x) h (j x)
Для следующего примера предположим, что мы глаголы с именем SUM, DIVIDEи LENGTH, что делать то , что вы думаете , что они могли бы. Если мы объединяем три в форк, мы получаем:
(SUM DIVIDE LENGTH) x ⇔ (SUM x) DIVIDE (LENGTH x)
Эта разветвленность оценивается как среднее x(предположим, xчто это список чисел). В J мы бы написали это как пример как +/ % #.
Еще одна вещь о вилках. Когда крайний левый «зубец» (в нашем символическом случае выше g) является существительным, он обрабатывается как постоянная функция, возвращающая это значение.
Имея все это на своем месте, теперь мы можем понять вышеупомянутый форк:
(1 + ?) x ⇔ (1 x) + (? x)
⇔ 1 + (? x)
?[ 0 , х )[ 1 , х ]
Собираем все вместе
Учитывая все эти вещи, наш глагол эквивалентен:
((+$:)^:=1+?) x ⇔ ((+$:)^:= 1 + ?) x
⇔ ((+$:)^:= (1 + ?)) x
⇔ x ((+$:)^:=) (1 + ?) x
⇔ x ((+$:)^:=) (1 + (? x))
⇔ x (+$:)^:(x = (1 + (? x))
(let y = 1 + (? x))
if x = y ⇒ x + $: y
otherwise ⇒ y
Это выражает желаемую функциональность.