Вычитание церкви
Лямбда-исчисление всегда было моим увлечением, и возникающее поведение передачи функций друг другу восхитительно сложно. Церковные цифры - это представления натуральных чисел, полученные из многократного применения функции (обычно это одинарное сложение константы). Например, нулевое число возвращает x и «игнорирует» входную функцию, one is f(x)
, two is f(f(x))
и так далее:
ident = lambda x: x
zero = lambda f: ident
succ = lambda n: lambda f: lambda x: f(n(f)(x))
one = succ(zero)
add1 = lambda x: x + 1
to_int = lambda f: f(add1)(0)
print(to_int(one))
>>> 1
Из этого легко увидеть, что добавление выполняется путем применения первой функции к x, а затем применения второй функции к x:
add = lambda m: lambda n: lambda f: lambda x: n(f)(m(f)(x))
print(to_int(add(one)(two)))
>>> 3
Дополнение относительно легко понять. Однако для новичка было бы немыслимо подумать о том, как выглядит вычитание в зашифрованной церковной системе счисления. Что это может означать, чтобы не применять функцию?
Вызов
Реализуйте функцию вычитания в системе счисления, закодированной Церковью. Где вычитание выполняет операцию monus и отменяет функцию n
раз, если результат будет больше нуля или ноль в противном случае. Это код-гольф, поэтому выигрывает самый короткий код.
вход
Две церковные цифры, которые были закодированы на выбранном вами языке. Ввод может быть позиционным или карри. Для того, чтобы доказать этот являются истинным Чёрчем они должны будут принимать в любой функции и применять их повторно ( add1
дано в примерах , но это может быть add25
, mult7
или любой другая одноместный функция) .
Выход
Церковная цифра. Следует отметить, что если m < n
тогда m - n
всегда то же самое, что и функция тождества.
Примеры:
minus(two)(one) = one
minus(one)(two) = zero
...
также приемлемо:
minus(two, one) = one
minus(one, two) = zero
Кредит:
Это GitHub суть для того, чтобы дать мне реализацию Python церковных цифр.
источник
exp(m, n)
подсчитывает,m^n
конечно.)lambda m,n,f:apply f m-n times
(или дажеlambda m,n,f,x:apply f m-n times to x
) вместоlambda m,n:lambda f:...
? Или это относится только к двум входамm
иn
?m
иn
в другом порядке? Это поможет с карри.Ответы:
Haskell , 35 байт
Попробуйте онлайн!
Скажи это
r
иs
есть церковные кодировкиm
иn
. Мы хотимr%s
применитьf
m-n
времена к некоторому начальному значениюx
. Сначала мы генерируем бесконечный списокзатем используйте
s(x:)
для добавленияn
копийx
, то есть сдвиг каждогоn
индекса значения вправо:Затем мы вычисляем
m
непосредственно какr(+1)0
и принимаемm
ый элемент этого списка как!!r(+1)0
. Вместо этого можно было бы использовать решение без индексацииhead$r tail$...
, то есть отбрасывать первый элементm
раз, а затем брать первый элемент, но синтаксис индексации намного короче.Обратите внимание, что классическое решение не работает в Haskell без расширений, потому что его строгая типизация не может представлять предшествующую операцию.
источник
Python 2 ,
8280 байтПопробуйте онлайн!
2 байта спасибо Нику Кеннеди, отмечая ненужную пару паренов.
Анонимная функция, которая реализует минус.
В основном это просто сжатие определения, найденного на странице Википедии; не так, как я действительно понимаю код еще. Но интересно!
источник
!u:!v:v(!n:!f:!x:n(!g:!h:h(g(f)))(!y:x)(!x:x))(u)
похоже, экономит 2 байта, но я не совсем понимаю код!Python 2 , 77 байт
Попробуйте онлайн!
Мы делаем церковный декремент, отслеживая предыдущее значение для каждой итерации и выводя его в конце. 39% длины кода это
"lambda"
...источник
C ++ (лязг) , 112 байт
Попробуйте онлайн!
Это, безусловно, самый непостижимый код C ++, который я когда-либо писал. Тем не менее, я думаю, что разглашение этого кода только ухудшит его.
источник
Недогрузка , 37 байт
Попробуйте онлайн!
Внутренняя
(((!())~):*^(~!:(:)~*(*)*)~^^!)
являетсяpred
функция, осуществляемая с помощью пар:источник
R 86 байт
Попробуйте онлайн!
R-порт ответа @ ChasBrown's на Python, так что не забудьте также его подтвердить.
источник
JavaScript (Node.js) ,
8785817674 байтаПопробуйте онлайн! Не собираюсь выигрывать никаких наград, но я решил попробовать другой подход.
a=>[h,a]
это этап, который применяетсяh
, в то времяa=>[x=>x,a]
как это этап, который не применяетсяh
. Мы применяем первыйf
раз функции и второйg
раз функции . Затем мы применяем обратную функцию([f,[g,a]])=>[g(x),a]
f
времени. Это пропускаетg
вторые этапы и выполняетf-g
первые этапы по желанию. Затем остается извлечь окончательное значение.Конечно, кортежи могут быть преобразованы в лямбда-функции, что приводит к следующему выражению:
источник
J , 56 байт
Попробуйте онлайн!
Примечание: -3 байта от счета TIO для
m=.
Функции высшего порядка в J достигаются с помощью наречий и союзов. Здесь церковное число - это герундовая форма наречий, образованного сочетанием «силы» соединения (которое многократно применяет глагол) и целого числа. Следующий глагол
c
(для «создания») использует атомарное представление J, чтобы преобразовать целое число в такой герундий:Наш оператор «минус» (который является конъюнкцией) вычитает правую цифру церковного герунда слева. Однако он не предполагает какой-либо конкретной реализации церковных цифр, в том числе из нашего
c
глагола. Вместо этого он полагается на общем определении и превращает каждую герундий Чёрч обратно в наречие, переворачивая его5!:0
, а затем применять эти наречия с глаголом приращения>:
, а затем применяя , что 0.Затем он вычитает и принимает максимум с 0 и применяется
c
для получения окончательного результата: новой церковной цифры герунды.источник
Wolfram Language (Mathematica) ,
55484739 байт (33 символа)Попробуйте онлайн!
Символ is - это 0xF4A1, специальная кодовая точка Mathematica, обозначающая стрелку вправо
\[Function]
. Смотрите здесь для большего количества объяснений. Вот как выглядит код в интерфейсе Mathematica:Мы можем сделать это в 40 байтах / 32 символа , которые могут быть короче в зависимости от схемы измерения:
#2[n⟼f⟼x⟼n[g⟼#@g@f&][x&][#&]]@#&
Версия без гольфа - буквальный перевод классического определения pred :
который выглядит так в интерфейсе Mathematica:
Эта функция вычитания работает с церковными цифрами, определенными с
(ип-golfed:
c[0] = Identity &; c[n_] = Function[a, a@*c[n-1][a]]
)так что у нас есть
и
источник