Latar Belakang
Ada teka-teki umum yang berbunyi seperti ini:
Seekor siput berada di dasar sumur 30 kaki. Setiap hari siput mampu memanjat 3 kaki. Pada malam hari ketika mereka tidur, mereka meluncur turun 2 kaki. Berapa hari yang dibutuhkan siput untuk keluar dari sumur?
Jawaban intuitifnya adalah
30 hari, karena siput naik 1 kaki per hari selama 30 hari untuk mencapai puncak,
tetapi sebenarnya jawabannya adalah
28 hari, karena begitu siput 27 kaki di udara (setelah 27 hari), mereka hanya akan memanjat 3 kaki yang tersisa ke atas pada hari ke 28.
Tantangan
Tantangan ini menggeneralisasikan teka-teki ini. Diberikan tiga bilangan bulat positif sebagai input, mewakili tinggi total, tinggi pendakian, dan tinggi jatuh, kembalikan jumlah hari yang diperlukan untuk keluar dari sumur.
Jika siput tidak dapat keluar dari sumur, Anda dapat mengembalikan 0, mengembalikan nilai palsu, atau melemparkan pengecualian. Anda juga dapat menulis kode yang akan berhenti jika dan hanya jika ada solusi.
Jika mau, Anda dapat menganggap tinggi jatuh sebagai bilangan bulat negatif.
Uji Kasus
(30, 3, 2) -> 28 (84, 17, 15) -> 35 (79, 15, 9) -> 12 (29, 17, 4) -> 2 (13, 18, 8) -> 1 (5, 5, 10) -> 1 (7, 7, 7) -> 1 (69, 3, 8) -> Tidak ada (81, 14, 14) -> Tidak ada
Mencetak gol
Ini adalah kode-golf , jadi jawaban tersingkat di setiap bahasa menang.
sumber
Jawaban:
Grey Snail , 1206 byte untuk I / O numerik, 149 byte untuk I / O unary
Untuk kesenangan. Komposisi program pertama:
Ambil input dan output numerik. Input adalah
A
,B
,C
masing-masing. Dibandingkan denganO(1)
jawaban lain (dekat) , kode ini memiliki kompleksitasO(n)
. Tetapi untuk jumlah yang besar, itu mungkin menghabiskan memori Anda terlebih dahulu.Tunggu jika tidak ada solusi yang ditemukan.
f
adalah fungsi (mungkin) rekursif untuk mengubah bilangan bulat menjadi titik-titik. Argumen disimpan dalam[p]
dan output dalam[o]
.U
adalah pengujian fungsiS1>=S2
, menyimpan parameterB, A
sementara menyimpanA-B
keA
.Kode mulai dari
D
adalah sebuah rintisan yang mengubah titik menjadi angka.Prinsip dasarnya adalah sama dengan jawaban C saya (merobek output palsu untuk solusi yang tidak mungkin).
Versi mandiri, 149
156157167170230byte, hanya mendukung I / O unaryInput harus berupa titik, misalnya
..........
untuk10
.U
menghitungA=A-B
, dan melompat keD
kapanA<=0
. Jika tidak$
memberikanA+C
keA
dan panggilanU
.Tunggu jika tidak ada solusi yang ditemukan.
Trik: menyalahgunakan kemampuan "kompiler" untuk menafsirkan string kosong. Anda dapat merobek kondisi dalam
GOTO
pernyataan untuk membuat lompatan tanpa syarat dan trik yang sama berhasilPOP
.Catatan: Saya dapat golf lebih dari 3 byte tetapi dengan melakukannya, jawaban saya dan WheatWizard akan memiliki logika yang sama persis. Hasilnya mungkin solusi GraySnail terpendek dan saya mencoba untuk membuktikannya.
sumber
C # (.NET Core) ,
3231 byteCobalah online!
Pendekatan rekursif. Jika siput tidak dapat melarikan diri, itu berakhir dengan pesan berikut:
Process is terminating due to StackOverflowException.
sumber
a<=b
kea>b
dan menukar bagian-bagian berikutf=(a,b,c)=>a<=b?1:1+f(a-b+c,b,c)
f
untuk panggilan rekursif.f
dan tanda titik koma jika namanya. Hal pertama yang saya temukan adalah ini tetapi tidak ada konsensus yang jelas di sini.f=...
saya tidak yakin apakah atau tidak kita harus menambahkan titik koma pada akhirnya.GREY SNAIL,
219206169167159156146 byte (IO unary)Saya pikir saya bisa bermain golf ini sedikit.
sumber
JavaScript (ES6),
312827 byteDisimpan beberapa byte berkat @Arnauld
Saya tidak menyadari kita bisa gagal kecuali. Cukup yakin ini optimal:
Tetapkan ke variabel dengan misalnya
f=
, lalu panggil likef(climb)(fall)(height)
. MelemparInternalError: too much recursion
jika pendakian tidak mungkin.JavaScript (ES6), 38 byte
Fungsi rekursif yang mengembalikan jumlah hari, atau
NaN
untuk tidak pernah.Uji kasus
Tampilkan cuplikan kode
sumber
d=>u=>g=h=>h>u?1+g(h-u+d):1
g=
di tengah karena variabel ini menyimpan fungsi perantara yang diperlukan untuk panggilan rekursif. Jawaban yang lebih lama melakukan panggilan rekursiff
, yang mengamanatkan bahwa nama tersebut dimasukkan dalam jumlah byte.Excel,
5146 byte-1 byte terima kasih kepada @ Scarabee .
-4 karena INT (x) = LANTAI (x, 1)
Input diambil dari Sel A1, B1 dan C1 masing-masing. Pengembalian
FALSE
untuk skenario yang tidak valid.sumber
ceiling(x)
selalu sama untuk-floor(-x)
, jadi saya pikir Anda bisa menyimpan 1 byte dengan menggantiCEILING((A1-B1)/(B1-C1)+1,1)
dengan-FLOOR((B1-A1)/(B1-C1)+1,1)
.C (gcc), 39
434446475860byteHanya pada GCC 32-bit dan semua optimizaiton dimatikan.
Kembalikan 0 ketika solusi tidak mungkin. Versi modifikasi dari solusi rekursif asli.
Terinspirasi oleh solusi @Jonah J dan solusi @CarlosAlejo C #.
Saya akan memperbarui versi yang diperluas nanti (setelah saya menyelesaikan jawaban Gray Snail saya).
sumber
Assign instead of return
Java (OpenJDK 8) , 35 byte
Cobalah online!
Matematika menang!
Kredit
sumber
a-c-1
→a+~c
.Python 2 , 37 byte
Cobalah online!
Akhirnya mendapatkan versi rekursif saya di bawah perhitungan standar saya (saya melewati hitungan ke fungsi saya daripada menambahkannya sebelum memanggilnya).
Python 2 , 43
46byteCobalah online!
Dicukur 3 byte dengan berdagang "__ dan 1" untuk "__> 0".
Menggunakan tipuan boolean, pada dasarnya mengeksekusi:
sumber
f=
di depan kode Anda (solusi pertama), dan jumlah byte Anda menjadi 37, karena itu bersifat rekursif, sehingga Anda tidak dapat membiarkannya tanpa nama.f=
dapat dijatuhkan untuk lambda hanya jika tidak recusive.R, 43 byte
Meminjam dari jawaban lain:
Memberikan kesalahan jika tidak ada solusi.
sumber
J, 25 byte
Pertama solusi yang bagus, yang merupakan cheat, karena mengasumsikan bahwa "apa pun selain hasil bilangan bulat positif" sama dengan "Tidak ada":
penjelasan
2-/\
gunakan jendela panjang 2 di 3 input item kami, menempatkan tanda minus di antara masing-masing, yang untuk input30 3 2
, misalnya, kembali27 1
%/
letakkan simbol pembagian di antara setiap elemen daftar, dalam kasus kami daftar hanya memiliki dua item, jadi itu berarti "membagi 27 dengan 1">:
selisih dengan 1>.
ambil langit-langitsolusi resmi
Berikut ini adalah solusi resmi yang mengubah negatif dan tak terhingga menjadi 0, yang bagian saya tidak dapat menemukan solusi singkat yang memuaskan untuk:
TIO
sumber
If the snail cannot climb out of the well, you may return 0, return a falsy value, or throw an exception.
Untuk keperluan penulisan kasus-kasus tes, saya hanya memilihNone
untuk menunjukkan bahwa tidak ada jawaban. Apakah Anda juga mempertimbangkan untuk menambahkan penjelasan dan tautan Cobalah Online?Perl 5 , 37 byte
35 byte kode +2 untuk
-pa
.Cobalah online!
sumber
PHP> = 7.1, 60 byte
mencetak 0 tanpa melarikan diri
PHP Sandbox Online
PHP> = 7.1, 67 byte
tidak mencetak apapun tanpa melarikan diri
PHP Sandbox Online
sumber
Mathematica,
474039 byte-7 byte dari @KeyuGan
sumber
69, 3, 8
dan⌈
dihitung sebagai 3 byte sejauh yang saya pikir.Max
untuk menggantiIf
pernyataan.If[#<=#2,1,Max[⌈(#-#3)/(#2-#3)⌉,0]]&
Ruby ,
4947 byteMelempar pengecualian jika siput tidak bisa keluar
Cobalah online!
sumber
h-a<1?1:(1.0*(h-a)/[a-b,0].max+1).ceil
melewati test case, dan menyimpan 9 byte.Batch, 66 byte
Kasing uji terakhir kedua tidak mencetak apa pun, dan kasing tes terakhir benar-benar jatuh
CMD.EXE
...sumber
05AB1E , 19 byte
Penjelasan:
Untuk nilai yang tidak valid, ini dapat mengembalikan nilai kurang dari 1. Namun, pada 05AB1E, hanya 1 yang benar sehingga memenuhi persyaratan bahwa output untuk nilai yang tidak valid harus palsu.
Cobalah online!
sumber
PHP, 60 byte
mencetak
N
untukNone
. Jalankan dengan-r
.sumber
05AB1E , 12 byte
Cobalah online!
Mencetak
0
jika tidak mungkin.Masukkan format:
sumber
Japt , 12 byte
Uji secara online!
Output
undefined
untuk tidak pernah, setelah mungkin membekukan browser Anda untuk sementara waktu, jadi harap berhati-hati.Saya tidak yakin ini optimal.
oWV-W l
bekerja pada semua kecuali tiga kasus terakhir ...sumber
Haskell ,
3029 byteCobalah online!
Lebih pendek dari jawaban Haskell yang ada. Mungkin orang lain bisa mengalahkan saya.
Ini menggunakan pendekatan rekursif untuk memecahkan masalah. Setiap rekursi pada dasarnya adalah hari pergerakan untuk siput. Jika jarak yang tersisa ke ujung kurang dari jarak yang masih dibutuhkan, kami mengakhiri rekursi kami.
sumber
(b#c)a=1+sum[(b#c)$a+c-b|a>b]
.b!c
dalam daftar pemahaman.QBIC ,
3123 byteHanya memperhatikan persyaratan berubah. Versi ini tidak memeriksa apakah siput akan mencapai bagian atas sumur.
Penjelasan di bawah ini, untuk versi asli yang memeriksa apakah ada solusi, juga mencakup semua bagian yang relevan dari kode ini.
Asli, jawaban 31 byte:
Penjelasan
Cobalah online! (Oke, tidak juga: ini adalah terjemahan dari QBIC ke QBasic code dijalankan di repl.it (agak kurang) lingkungan QBasic)
sumber
Excel VBA, 47 Bytes
Fungsi jendela langsung VBE anonim yang mengambil input dari rentang
[A1:C1]
dariActiveSheet
objek output ke jendela langsung VBESolusi berbasis rumus Excel ini tampaknya lebih kecil daripada solusi VBA murni yang bisa saya buat :(
sumber
Haskell, 47
55byte (48 jika diperlukan tuple)variasi tuple
Penjelasan
sumber
d>c||c<s
hanya dengan0<1
, seperti yang sudah Anda lakukan secara implisit dalam penjelasan Anda, karenaotherwise
hanya sinonim dariTrue
. 2. Panggilan rekursif dalam versi tuple Anda masih dalam proses. 3. Anda dapat mendefinisikan fungsi Anda sebagai(d#c)s
gantif d c s
menyimpan dua byte lagi.c<=s
bukanc<s
.0
alih-alih-1
sebagaimana diizinkan oleh OP menghasilkan 38 byte: Cobalah secara online!Python 3, 41 Bytes
Kesalahan untuk Tidak Pernah
Outgolf @veganaiZe
sumber
int(b>=a)
ke1-(b<a)
untuk menyimpan 2 byte?APL (Dyalog) , 13 byte
Cobalah online!
Kesalahan pembagian dengan nol jika siput tidak bisa keluar dari sumur.
sumber
C # (.NET Core) , 37 byte
Lambda non-rekursif. Formula penggunaan ditemukan di sini . Dapat dipersingkat 6 byte jika "hasil negatif" adalah cara yang valid untuk mengembalikan kegagalan; saat ini mengembalikan 0 sebagai gantinya.
sumber
h-f-1
bisah+~f
.Python v2 & v3, 44 Bytes
^ Rekursi tak terbatas (kesalahan) untuk Tidak ada kasus.
sumber
(x-z-1)//(y-z)+1
. Saya tidak melakukan banyak Python, jadi saya mungkin salah ...f=
dari jumlah byte, menghapus beberapa spasi di sekitar ifs dan elses, dan beralih ke Python 2 di mana pembagian integer adalah tunggal/
Kalkulator yang Dapat Diprogram HP-15C, 26 Bytes
Tiga angka dimuat ke dalam tumpukan sebelum menjalankan program. Tinggi jatuh dimasukkan sebagai angka negatif. Jika siput tidak dapat keluar dari sumur, hasilnya adalah angka negatif atau kesalahan # 0 (zero Divide error).
Kode op dalam hex:
Makna instruksi:
Anda dapat mencoba program dengan simulator HP-15C ini .
sumber
Gangguan Umum, 49 byte
Cobalah online!
Fungsi rekursif, stack overflow jika tidak ada solusi yang ditemukan.
sumber
PowerShell ,
9594 byteCobalah online!
sumber