Pengurangan Gereja
Kalkulus Lambda selalu menjadi daya tarik saya dan perilaku yang muncul dari fungsi saling melintas sangat menyenangkan. Angka Gereja adalah representasi dari bilangan asli yang dibangun dari penerapan fungsi berulang (biasanya penambahan konstanta unary). Sebagai contoh, angka nol mengembalikan x dan "mengabaikan" fungsi input, satu adalah f(x)
, dua adalah f(f(x))
dan seterusnya:
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
Dari sini kita dapat dengan mudah melihat bahwa penambahan dilakukan dengan menerapkan fungsi pertama ke x kemudian menerapkan fungsi kedua ke x:
add = lambda m: lambda n: lambda f: lambda x: n(f)(m(f)(x))
print(to_int(add(one)(two)))
>>> 3
Selain itu relatif mudah dimengerti. Namun, bagi pendatang baru, mungkin tidak masuk akal untuk memikirkan seperti apa pengurangan dalam sistem angka Gereja yang dikodekan. Apa yang mungkin berarti membatalkan penerapan suatu fungsi?
Tantangan
Menerapkan fungsi pengurangan dalam sistem angka Gereja yang dikodekan. Di mana pengurangan melakukan operasi monus dan membatalkan penerapan fungsi n
kali jika hasilnya akan lebih besar dari nol atau nol sebaliknya. Ini adalah kode-golf sehingga kode terpendek menang.
Memasukkan
Dua angka Gereja yang telah dikodekan dalam pilihan bahasa Anda. Input dapat berupa posisi atau kari. Untuk membuktikan ini angka Gereja yang benar mereka akan harus mengambil di setiap fungsi dan menerapkannya berulang kali ( add1
diberikan dalam contoh tapi bisa add25
, mult7
, atau fungsi unary lainnya.)
Keluaran
Angka Gereja. Perlu dicatat bahwa jika m < n
demikian m - n
selalu sama dengan fungsi identitas.
Contoh:
minus(two)(one) = one
minus(one)(two) = zero
...
juga dapat diterima:
minus(two, one) = one
minus(one, two) = zero
Kredit:
Intisari github ini untuk memberi saya implementasi python Angka Gereja.
sumber
exp(m, n)
menghitungm^n
.)lambda m,n,f:apply f m-n times
(atau bahkanlambda m,n,f,x:apply f m-n times to x
), bukanlambda m,n:lambda f:...
? Atau apakah ini hanya berlaku untuk dua inputm
dann
?m
dann
dalam urutan lain? Ini akan membantu dengan kari.Jawaban:
Haskell , 35 byte
Cobalah online!
Katakan itu
r
dans
merupakan penyandian gereja darim
dann
. Kami inginr%s
menerapkanf
m-n
waktu pada beberapa nilai awalx
. Kami pertama-tama menghasilkan daftar tanpa bataslalu gunakan
s(x:)
untuk menambahkann
salinanx
, yaitu, menggeser setiapn
indeks nilai dengan benar:Kami kemudian menghitung
m
secara langsung sebagair(+1)0
, dan mengambilm
elemen ke-10 dari daftar itu sebagai!!r(+1)0
. Sebaliknyahead$r tail$...
, solusi pengindeksan bisa dilakukan , yaitu menjatuhkan elemenm
kali pertama dan kemudian mengambil elemen pertama, tetapi sintaks pengindeksan jauh lebih pendek.Perhatikan bahwa solusi klasik tidak berfungsi di Haskell tanpa ekstensi karena pengetikan yang kuat tidak dapat mewakili operasi pendahulunya.
sumber
Python 2 ,
8280 byteCobalah online!
2 byte thx untuk Nick Kennedy mencatat sepasang orangtua yang tidak dibutuhkan.
Fungsi anonim yang mengimplementasikan minus.
Sebagian besar ini hanya mengompresi definisi yang ditemukan di halaman Wikipedia; tidak seperti saya benar-benar mengerti kodenya. Tapi menarik!
sumber
!u:!v:v(!n:!f:!x:n(!g:!h:h(g(f)))(!y:x)(!x:x))(u)
tampaknya menghemat 2 byte, tapi saya tidak begitu mengerti kodenya!Python 2 , 77 byte
Cobalah online!
Kami melakukan pengurangan Gereja dengan melacak nilai sebelumnya untuk setiap iterasi dan menghasilkan yang pada akhirnya. 39% dari panjang kode adalah
"lambda"
...sumber
C ++ (dentang) , 112 byte
Cobalah online!
Sejauh ini ini adalah kode C ++ yang paling tidak bisa dipahami yang pernah saya tulis. Yang mengatakan, saya pikir bahwa melanggar kode ini hanya akan membuatnya lebih buruk.
sumber
Underload , 37 byte
Cobalah online!
Batin
(((!())~):*^(~!:(:)~*(*)*)~^^!)
adalahpred
fungsi, diimplementasikan melalui pasangan:sumber
R , 86 byte
Cobalah online!
Port R dari jawaban Python @ ChasBrown jadi pastikan untuk mengunggahnya juga.
sumber
JavaScript (Node.js) ,
8785817674 byteCobalah online! Tidak akan memenangkan penghargaan apa pun, tetapi saya pikir saya akan mencoba pendekatan yang berbeda.
a=>[h,a]
adalah tahap yang berlakuh
, sementara itua=>[x=>x,a]
adalah tahap yang tidak berlakuh
. Kami menerapkan waktu fungsi pertamaf
dan waktu fungsi keduag
. Kami kemudian menerapkan waktu fungsi terbalik([f,[g,a]])=>[g(x),a]
f
. Ini melompatig
tahap kedua dan melakukanf-g
tahap pertama seperti yang diinginkan. Kemudian tetap mengekstraksi nilai akhir.Tupel tentu saja dapat dikonversi ke fungsi lambda yang menghasilkan ekspresi berikut:
sumber
J , 56 byte
Cobalah online!
Catatan: -3 byte dari hitungan TIO untuk
m=.
Fungsi tingkat tinggi dalam J dicapai menggunakan kata keterangan dan kata sambung. Di sini angka gereja adalah bentuk gerund dari kata keterangan yang dibentuk dengan menggabungkan "kekuatan" konjungsi (yang berulang kali menggunakan kata kerja) dan bilangan bulat. Kata kerja berikut
c
(untuk "buat") menggunakan Representasi Atom J untuk mengubah bilangan bulat menjadi gerund seperti itu:Operator "minus" kami (yang merupakan gabungan) mengurangi angka gereja gerund kanan dari kiri. Namun, itu tidak mengasumsikan implementasi tertentu dari angka gereja, termasuk yang dari
c
kata kerja kami . Sebaliknya, hal itu bergantung pada definisi umum dan ternyata setiap gereja gerund angka kembali ke kata keterangan dengan membalik dengan5!:0
, dan kemudian menerapkan keterangan bahwa untuk kata kerja kenaikan>:
, dan kemudian menerapkan bahwa untuk 0.Itu kemudian mengurangi dan mengambil maksimum dengan 0, dan berlaku
c
untuk mendapatkan hasil akhir: angka gereja gerund baru.sumber
Bahasa Wolfram (Mathematica) ,
55484739 byte (33 karakter)Cobalah online!
Simbol adalah 0xF4A1, titik kode Mathematica khusus yang menunjukkan panah kanan untuk
\[Function]
. Lihat di sini untuk penjelasan lebih lanjut. Seperti apa kode ini di front end Mathematica:Kita dapat melakukannya dalam 40 byte / 32 karakter , yang mungkin lebih pendek tergantung pada skema pengukuran:
#2[n⟼f⟼x⟼n[g⟼#@g@f&][x&][#&]]@#&
Versi un-golfed adalah terjemahan literal dari definisi klasik dari pred :
yang terlihat seperti ini di bagian depan Mathematica:
Fungsi pengurangan ini berfungsi dengan angka-angka Gereja yang ditentukan dengan
(un-golfed:
c[0] = Identity &; c[n_] = Function[a, a@*c[n-1][a]]
)sehingga kita miliki
dan
sumber