J , 16 11 byte
(+$:)^:=1+?
Cobalah online!
Penjelasan
TL; DR 1+? melakukan die roll, (+$:)^:=hanya mengulangi ketika sama dengan input.
Fungsi ini adalah kereta dari 4 kata kerja:
┌─ +
┌───┴─ $:
┌─ ^: ─┴─ =
│
──┤ ┌─ 1
└──────┼─ +
└─ ?
Kereta adalah ketika 2 atau lebih kata kerja disatukan. Di sini, jawabannya adalah dalam bentuk f g h j:
(+$:)^:= 1 + ?
f g h j
Apa yang disebut "kereta 4" diurai sebagai kait dan garpu:
f g h j ⇔ f (g h j)
Dengan demikian, jawabannya setara dengan:
(+$:)^:= (1 + ?)
Hooks: (f g) xdanx (f g) y
Hook monadic (satu argumen) dari dua kata kerja, diberikan argumen x, persamaan berikut berlaku:
(f g) x ⇔ x f (g x)
Misalnya, (* -) 5mengevaluasi ke 5 * (- 5), yang mengevaluasi ke _25.
Ini berarti bahwa 4 kereta kami, sebuah kait dari fdan (g h j), setara dengan:
(f (g h j)) x ⇔ x f ((g h j) x)
Tetapi apa yang fdilakukan di sini? (+$:)^:=adalah konjungsi dari dua kata kerja menggunakan konjungsi Daya^: : hook lain ( (+$:)) dan kata kerja ( =). Perhatikan di sini bahwa fini adalah diadik — ada dua argumen ( xdan (g h j) x). Jadi kita harus melihat bagaimana ^:berperilaku. Konjungsi daya f^:omengambil kata kerja fdan kata kerja atau kata benda o(kata benda hanya sepotong data) dan berlaku f okali. Sebagai contoh, ambil o = 3. Persamaan berikut berlaku:
(f^:3) x ⇔ f (f (f x))
x (f^:3) y ⇔ x f (x f (x f y))
Jika oadalah kata kerja, konjungsi daya hanya akan mengevaluasi oargumen dan menggunakan hasil kata benda sebagai hitungan ulang.
Untuk kata kerja kami, oadalah =, kata kerja kesetaraan. Ini mengevaluasi 0untuk argumen yang berbeda dan 1untuk argumen yang sama. Kami mengulangi hook (+$:)sekali untuk argumen yang sama dan tidak ada waktu untuk yang berbeda. Untuk kemudahan notasi penjelasannya, mari y ⇔ ((g h j) x). Ingat bahwa kait awal kami setara dengan ini:
x (+$:)^:= ((g h j) x)
x (+$:)^:= y
Memperluas konjungsi, ini menjadi:
x ((+$:)^:(x = y)) y
Jika xdan ysama, ini menjadi:
x (+$:)^:1 y ⇔ x (+$:) y
Kalau tidak, ini menjadi:
x (+$:)^:0 y ⇔ y
Sekarang, kita telah melihat garpu monadik. Di sini, kami memiliki garpu diad:
x (f g) y ⇔ x f (g y)
Jadi, kapan xdan ysama, kita mendapatkan:
x (+$:) y ⇔ x + ($: y)
Apa $:? Ini merujuk ke seluruh kata kerja itu sendiri dan memungkinkan untuk rekursi. Ini berarti bahwa, ketika xdan y are the same, we apply the verb toy and addx` untuk itu.
Garpu: (g h j) x
Sekarang, apa yang dilakukan garpu dalam? Ini adalah ycontoh terakhir kami. Untuk fork monadik dengan tiga kata kerja, diberikan argumen x, persamaan kesetaraan berikut:
(g h j) x ⇔ (g x) h (j x)
Sebagai contoh berikut ini, misalkan kita telah verba bernama SUM, DIVIDE, dan LENGTH, yang melakukan apa yang Anda kira mereka mungkin. Jika kami menggabungkan ketiganya menjadi garpu, kami mendapatkan:
(SUM DIVIDE LENGTH) x ⇔ (SUM x) DIVIDE (LENGTH x)
Garpu ini mengevaluasi ke rata-rata x(dengan asumsi xadalah daftar angka). Di J, kami akan menulis ini sebagai contoh +/ % #.
Satu hal lagi tentang garpu. Ketika "tine" paling kiri (dalam kasus simbolis kami di atas, g) adalah kata benda, itu diperlakukan sebagai fungsi konstan mengembalikan nilai itu.
Dengan semua ini, kita sekarang dapat memahami garpu di atas:
(1 + ?) x ⇔ (1 x) + (? x)
⇔ 1 + (? x)
? di sini memberikan bilangan bulat acak dalam kisaran [ 0 , x ), jadi kita perlu mengubah rentang untuk mewakili dadu; incrementing menghasilkan rentang[ 1 , x ].
Menyatukan semuanya
Dengan semua hal ini, kata kerja kami setara dengan:
((+$:)^:=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
Ini mengekspresikan fungsi yang diinginkan.