# Background

There's a common riddle that goes something like this:

A snail is at the bottom of a 30 foot well. Every day the snail is able to climb up 3 feet. At night when they sleep, they slide back down 2 feet. How many days does it take for the snail to get out of the well?

30 days, because the snail climbs at 1 foot per day for 30 days to reach the top,

28 days, because once the snail is 27 feet in the air (after 27 days), they will simply climb the remaining 3 feet to the top on the 28th day.

# Challenge

This challenge generalizes this riddle. Given three positive integers as input, representing the total height, the climb height, and the fall height, return the number of days it will take to climb out of the well.

If the snail cannot climb out of the well, you may return 0, return a falsy value, or throw an exception. You may also write code that will halt if and only if a solution exists.

If you wish, you may take the fall height as a negative integer.

# Test Cases

(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) -> None
(81, 14, 14) -> None


# Scoring

This is , so the shortest answer in each language wins.

• Related Jul 7, 2017 at 5:46
• I'll probably award a bounty if someone answers in Gray Snail. The Esolangs page is just an empty stub, but there is some information and an online compiler available, as well as a sample program for the 99 bottles of beer problem. Jul 7, 2017 at 5:53
• I thought this would just be a simple formula, but the casework is surprisingly interesting.
– xnor
Jul 7, 2017 at 6:02
• You still have "how many hours....". The answer being 27*24 + 12 (assuming a 12 hour 'day'). Jul 7, 2017 at 10:14
• @WheatWizard I will award the bounty to the shortest Gray Snail answer Jul 8, 2017 at 15:50

# Gray Snail, 1206 bytes for numeric I/O, 149 bytes for unary I/O

For fun. Composition of first program:

• 451 bytes, converting number into dots
• 121 bytes, core function (a separated version is written below)
• 634 bytes, converting dots into number

Take numeric input and output. Input is A, B, C respectively. Compared to other (near) O(1) answer, the code has a complexity of O(n). But for large number, it may eat up your memory first.

Hang if no solution is found.

INPUT p
POP Z r .!
f
POP Z o .
q
POP Z p [p]
GOTO [Z]
0
POP Z n .
GOTO w
1
POP Z n ..
GOTO w
2
POP Z n ...
GOTO w
3
POP Z n ....
GOTO w
4
POP Z n .....
GOTO w
5
POP Z n ......
GOTO w
6
POP Z n .......
GOTO w
7
POP Z n ........
GOTO w
8
POP Z n .........
GOTO w
9
POP Z n ..........
GOTO w
w
POP Z o .[o][o][o][o][o][o][o][o][o][o][n]
GOTO [r] [p]
GOTO q
!
POP Z A .[o]
INPUT p
POP Z r .@
GOTO f
@
POP Z B .[o]
INPUT p
POP Z r .#
GOTO f
#
POP Z C .[o]
POP H N .[B]
U
POP Z A [A]
POP Z B [B]
GOTO D [A]
GOTO $[B] GOTO U$
POP Z A .[A][C]
POP Z H ..[H]
POP Z B .[N]
GOTO U
D
POP Z r .
POP Z M .
POP Z N ...........
POP Z z .[N]
POP Z V .[H]
+
GOTO l[V] [H]
POP Z H [H]
POP Z z [z]
GOTO ( [z]
GOTO +
(
GOTO ) [H]
POP Z z .[N]
POP Z M ..[M]
POP Z V .[H]
GOTO +
)
POP Z r .0[r]
POP Z M ..[M]
POP Z H .[M]
POP Z M .
POP Z V .[H]
POP Z z .[N]
GOTO +
l
POP Z r .0[r]
GOTO -
l.
POP Z r .1[r]
GOTO -
l..
POP Z r .2[r]
GOTO -
l...
POP Z r .3[r]
GOTO -
l....
POP Z r .4[r]
GOTO -
l.....
POP Z r .5[r]
GOTO -
l......
POP Z r .6[r]
GOTO -
l.......
POP Z r .7[r]
GOTO -
l........
POP Z r .8[r]
GOTO -
l.........
POP Z r .9[r]
GOTO -
-
GOTO / [M]
POP Z H .[M]
POP Z M .
POP Z V .[H]
POP Z z .[N]
GOTO +
/
OUTPUT [r]


f is a (maybe) recursive function to convert integers into dots. Argument is saved in [p] and output in [o].

U is a function testing S1>=S2, storing parameter in B, A while saving A-B into A.

Code starting from D is a stub converting dots into numbers.

The underlying principle is the same with my C answer (ripping off falsy output for impossible solutions).

## Standalone version, 149 156157167170230 bytes, only support unary I/O

Input needs to be dots, e.g. .......... for 10.

INPUT A
INPUT B
INPUT C
POP N H .
GOTO U
$POP N A .[A][C] POP Z H ..[H] U POP Z A [A] POP Z N ..[N] GOTO D [A] GOTO$ .[B] [N]
GOTO U
D
OUTPUT .[H]


U calculates A=A-B, and jumps to D when A<=0. Otherwise $ assigns A+C to A and call U. Hang if no solution is found. Tricks: abuse the "compiler"'s ability to interpret empty string. You can rip off conditions in GOTO statement to make unconditioned jumps and the same trick works for POP. Remark: I may golf it more by 3 bytes but by doing so, mine and WheatWizard's answer would have the exact same logic. The result is probably the shortest GraySnail solution and I'm trying to prove it. • You made it first Jul 7, 2017 at 14:45 • Hey I just thought I'd let you know that I've made mine shorter than yours again. Its only a byte shorter and it draws some inspiration from your latest golf. Jul 11, 2017 at 14:58 • @WheatWizard I have a 155-byte solution based on your old answer. But for sportsmanship, I will not view it as my answer. Jul 11, 2017 at 15:09 • @KeyuGan No, go ahead. I don't care about the rep its all about the game. I'm happy to be beaten. If my code can be golfed is my fault for not seeing it. :) Jul 11, 2017 at 15:11 • @WheatWizard Me neither. I'm sure it is the best time I've ever had on PPCG. Jul 11, 2017 at 15:16 Note: the byte count is being questioned by Martin Ender in the comments. It seems there is no clear consensus about what to do with named, recursive lambda expressions in C# answers. So I have asked a question in Meta about it. # C# (.NET Core), 32 31 bytes f=(a,b,c)=>a>b?1+f(a-b+c,b,c):1  Try it online! A recursive approach. If the snail cannot escape, it ends with the following message: Process is terminating due to StackOverflowException. • 1 byte saved thanks to LiefdeWen! • You can save a byte byte changing a<=b to a>b and swapping the following parts Jul 7, 2017 at 9:03 • Exact same code works in ES6 f=(a,b,c)=>a<=b?1:1+f(a-b+c,b,c) Jul 7, 2017 at 9:09 • You'll have to count the code that assigns the function to a name if you're relying on that name being f for the recursive call. Jul 7, 2017 at 9:12 • I don't golf in C# so I'm not entirely sure what the consensus is, but I would've expected this to require a full statement with a declaration of f and a semicolon if it's named. The first thing I found is this but there's no clear consensus here. Jul 7, 2017 at 9:15 • @MartinEnder I usually just do as Carlos has done here, as the declaration is only f=... I'm unsure as to whether or not we should add the semi-colon on the end though. Jul 7, 2017 at 9:55 # GRAY SNAIL, 219206169167159156 146 bytes (unary IO) INPUT a INPUT u INPUT d POP U c GOTO 1 3 POP f a [a][d] POP U c ..[c] 1 GOTO 2 [a] GOTO 3 [U] [u] POP f U ..[U] POP f a [a] GOTO 1 2 OUTPUT [c].  I think I can golf this down a bit. • You can save a few bytes by using the empty string as one of your variables and also as one of your line labels. Apr 22 at 5:21 ## JavaScript (ES6), 3128 27 bytes Saved a few bytes thanks to @Arnauld I hadn't realized we could fail with an exception. Pretty sure this is optimal: u=>d=>g=h=>h>u?1+g(h-u+d):1  Assign to a variable with e.g. f=, then call like f(climb)(fall)(height). Throws InternalError: too much recursion if the climb is impossible. ## JavaScript (ES6), 38 bytes f=(h,u,d=0)=>h>u?u>0?1+f(h-u,u-d):+f:1  A recursive function that returns the number of days, or NaN for never. ### Test cases let f=(h,u,d=0)=>h>u?u>0?1+f(h-u,u-d):+f:1; [ [30, 3, 2], [84, 17, 15], [79, 15, 9], [29, 17, 4], [13, 18, 8], [ 5, 5, 10], [ 7, 7, 7], [69, 3, 8], [81, 14, 14] ].map(x => console.log(x + '', '->', f.apply(null, x))) • That's obvious: If snail does too much recursion, then climb is impossible. :) Jul 7, 2017 at 11:25 • Maybe 27 with a reversed currying syntax? d=>u=>g=h=>h>u?1+g(h-u+d):1 Jul 7, 2017 at 11:36 • @Arnauld Thanks, that works surprisingly well... Jul 7, 2017 at 11:38 • I'm a it confused re the byte count- in one the variable the function is assigned t is included, the other not? – user69654 Jul 7, 2017 at 15:39 • @Orangesandlemons in the top version, you have g= in the middle because this variable stores the intermediate function needed for the recursive call. The longer answer does a recursive call on f, which mandates that the name be included in the byte count. Jul 7, 2017 at 18:11 # Excel, 51 46 bytes -1 byte thanks to @Scarabee. -4 because INT(x) = FLOOR(x,1) =IF(B1<A1,IF(C1<B1,-INT((B1-A1)/(B1-C1)-1)),1)  Input taken from Cells A1, B1 and C1 respectively. Returns FALSE for invalid scenarios. • ceiling(x) is always equal to -floor(-x), so I think you could save 1 byte by replacing CEILING((A1-B1)/(B1-C1)+1,1) with -FLOOR((B1-A1)/(B1-C1)+1,1). Jul 8, 2017 at 22:29 # C (gcc), 39 434446475860 bytes Only on 32-bit GCC and all optimizaitons turned off. f(a,b,c){a=a>b?b>c?1+f(a-b+c,b,c):0:1;}  Return 0 when solution is impossible. A modified version of original recursive solution. Inspired by @Jonah J solution and @CarlosAlejo C# solution. I'll update the expanded version later (after I finish my Grey Snail answer). • Nice one! could u please include the analytical (non-compressed) solution? Jul 7, 2017 at 7:15 • @koita_pisw_sou Sure. Jul 7, 2017 at 7:22 • It doesn't "return" anything at all. You assign to a local parameter, whose value evaporates once the function returns. The snail is stuck in eternal limbo. Jul 8, 2017 at 0:51 • @CodyGray it uses a stable but undefined behavior in GCC. I could show you a link later. Jul 8, 2017 at 3:27 • @CodyGray codegolf.stackexchange.com/questions/2203/tips-for-golfing-in-c Assign instead of return Jul 8, 2017 at 4:56 # Java (OpenJDK 8), 35 bytes (a,b,c)->b<a?c<b?(a+~c)/(b-c)+1:0:1  Try it online! Math wins! ### Credits • It's been a while, but a-c-1a+~c. Mar 26, 2018 at 15:00 • Thanks @KevinCruijssen It's been a while, but golf is golf, no matter when it happens :-) Mar 26, 2018 at 15:03 • My thoughts exactly. On a few occasions I golfed about halve my original bytes when I looked at some of my first answers. ;) Mar 26, 2018 at 15:12 # Python 2, 37 bytes f=lambda x,y,z:x-y<1or 1+f(x-y+z,y,z)  Try it online! Finally got my recursive version below my standard calculation (I was passing a count to my function instead of adding one before calling it). # Python 2, 43 46 bytes #43 bytes lambda x,y,z:y/x>0 or[1-(x-y)/(z-y),0][z/y] #46 bytes lambda x,y,z:y/x and 1or[1-(x-y)/(z-y),0][z/y]  Try it online! Shaved 3 bytes by trading "__ and 1" for "__>0". Using boolean trickery, essentially executes: if floor(y/x) > 0: return True # == 1 elif floor(z/y) == 1: return 0 elif floor(z/y) == 0: return 1-floor((x-y)/(z-y)) # Python 2 implicitly treats integer division as floor division # equivalent: 1 + math.ceil((y-x)/(z-y)) # because: -floor(-x) == ceil(x)  • You have to put f= in front of your code (the first solution), and your byte count becomes 37, because it is recursive, so you can't leave it anonymous. f= can be dropped for a lambda only when it is not recusive. Jul 7, 2017 at 9:09 • Noted and addressed. Thanks for letting me know. Jul 7, 2017 at 9:20 • 36 bytes, elminitating a space by using -~x instead of 1+x Mar 13, 2020 at 3:59 ## Perl 5, 37 bytes 35 bytes code +2 for -pa. $i-=$F[2]while++$\,($i+=$F[1])<$_}{  Try it online! # R, 43 bytes Borrowing from other answers: g=function(a,b,c)if(b<a,1+g(a-b+c,b,c),1)  Gives error if no solution. • Nice answer. Welcome to PPCG! Jul 9, 2017 at 6:09 # Haskell, 3029 27 bytes (b!c)a=1+sum[b!c$a+c-b|a>b]


Try it online!

Shorter than the existing Haskell answer. Perhaps someone else can beat me.

This uses a recursive approach to solving the problem. Each recursion is essentially a day of movement for the snail. If the distance left to the end is less than the distance still required we end our recursion.

• Save 1 byte with infix notation: (b#c)a=1+sum[(b#c)$a+c-b|a>b]. Jul 7, 2017 at 22:04 • @Laikoni Didn't know that could be done. Thanks for the tip. Jul 7, 2017 at 22:23 • You can drop the parens around b!c in the list comprehension. Jul 9, 2017 at 9:22 # J, 25 bytes First a nice solution, which is a cheat, since it assumes that "anything other than a positive integer result" equals "None": >.>:%/2-/\  ## explanation • 2-/\ use windows of length 2 across our 3 item input, placing a minus sign between each one, which for the input 30 3 2, eg, returns 27 1 • %/ put a division symbol between each element of the list, in our case the list has only two items, so it means "divide 27 by 1" • >: increment by 1 • >. take the ceiling ## official solution Here is the official solution that converts negatives and infinity to 0, which part i was not able to find a satisfyingly terse solution for: 0:[@.(>&0*<&_)>.>:%/2-/\  TIO • If the snail cannot climb out of the well, you may return 0, return a falsy value, or throw an exception. For the purpose of writing the test cases, I simply chose None to indicate that there was no answer. Would you also consider adding an explanation and a Try it Online link? Jul 7, 2017 at 6:45 • @musicman523 fixed and done. Jul 7, 2017 at 7:06 # PHP>=7.1, 60 bytes prints 0 for no escape [,$h,$u,$d]=$argv;echo$h>$u?$u>$d?ceil(($h-$d)/($u-$d)):0:1;  PHP Sandbox Online # PHP>=7.1, 67 bytes prints nothing for no escape for([,$h,$u,$d]=$argv;($u>$d?:$h<=$u)&&0<$h+$t*$d-$u*++$t;);echo$t;  PHP Sandbox Online # PowerShell, 95 94 bytes $g=$args[0]$c=$args[1]$f=$args[2]$p=0
$d=0 1..$g|%{$d+=1;$p+=$c;if($p-ge$g){$d;exit}$p-=$f}


Try it online!

# Mathematica, 4740 39 bytes

If[#==#2,1,⌈(#-#3)/(#2-#3)⌉~Max~0]&


-7 bytes from @KeyuGan

• You need to deal with input as 69, 3, 8 and ⌈ is counted as 3 bytes as far as I think. Jul 7, 2017 at 7:39
• all fixed! try it now Jul 7, 2017 at 7:44
• you may use Max to replace If statement. If[#<=#2,1,Max[⌈(#-#3)/(#2-#3)⌉,0]]& Jul 7, 2017 at 7:47

# Ruby, 49 47 bytes

->h,a,b{h-a<1?1:(1.0*(h-a)/[a-b,0].max+1).ceil}


Throws exception if snail can't climb out

Try it online!

• @Jonah fixed it
– Alex
Jul 7, 2017 at 7:26
• What's the reasoning behind the proc? h-a<1?1:(1.0*(h-a)/[a-b,0].max+1).ceil passes the test cases, and saves 9 bytes. Jul 11, 2017 at 19:08

## Batch, 66 bytes

@set/an=%4+1,a=%1-%2+%3
@if %1 gtr %2 %0 %a% %2 %3 %n%
@echo %n%


The second last test case printed nothing, and the last test case actually crashed CMD.EXE...

# 05AB1E, 19 bytes

0[¼²+D¹<›i¾q}³-D1‹#


Explanation:

0                   Initialise stack with 0
[                  while(true)
¼                   increment the counter variable
²+                 add the second input to the top of the stack
D¹<›i            if it is greater than or equal to the first input
¾             push the counter variable
q            terminate the program
}        end if
³-      subtract the third input from the top of the stack
D     duplicate top of stack
1‹   if it is less than 1
#  break the loop


For invalid values, this may return any value less than 1. However, in 05AB1E, only 1 is truthy so this meets the requirement that the output for an invalid value should be falsy.

Try it online!

# PHP, 60 bytes

[,$h,$v,$d]=$argv;echo$h>$v?$v>$d?ceil(($h-$d)/($v-$d)):N:1;


prints N for None. Run with -r.

# 05AB1E, 12 bytes

.×ηO<²›1k2÷>


Try it online!

Prints 0 if impossible.

Input format:

[climb, -fall]
height


# Japt, 12 bytes

@UµV-W §W}aÄ


Test it online!

Outputs undefined for never, after possibly freezing your browser for a while, so please be careful.

I'm not convinced this is optimal. oWV-W l works on all but the last three cases...

• Came up with this for 11 bytes by changing the order of the inputs. Mar 26, 2018 at 15:51

# Python v2 & v3, 44 Bytes

f=lambda x,y,z:1+f(x-(y-z),y,z)if x>y else 1


^Infinite recursion (error) for None case.

• You can use lambda. Also, this seems similar to my (Java) answer so allow me to suggest an improvement in the formula: (x-z-1)//(y-z)+1. I don't do much Python, so I might be wrong... Jul 7, 2017 at 11:11
• You can eliminate f= from the byte count, remove some spaces around ifs and elses, and switch to Python 2 where integer division is a single / Jul 7, 2017 at 19:28
• Thanks @musicman523. I ended up taking all of your advice. Jul 7, 2017 at 20:25
• I realized that my "clean" (no infinite recursion) code had lots of corner-case issues when used with other inputs (ie. 4, 3, 8). @musicman523 I think I'm starting to see the "proofs" that you speak of. Jul 7, 2017 at 23:50

# HP-15C Programmable Calculator, 26 Bytes

The three numbers are loaded into the stack in order before running the program. The fall height is entered as a negative number. If the snail cannot climb out of the well, the result is either a negative number or error #0 (zero divide error).

Op codes in hex:

C5 C1 B4 C5 FB 74 1A C4 FA B4 C5 FD C1 C1 A3 70 C6 F0 B4 FA EB F1 FA B2 0A F1


Instruction meanings:

x↔y
ENTER
g R⬆
x↔y
−
g TEST x≤0
GTO A
R⬇
+
g R⬆
x↔y
÷
ENTER
ENTER
f FRAC
TEST x≠0
EEX
0
g R⬆
+
g INT
1
+
g RTN
f LBL A
1


You can try the program with this HP-15C simulator.

• This is awesome! Welcome to PPCG :) Jul 9, 2017 at 6:06

# Common Lisp, 49 bytes

(defun f(a b c)(if(> a b)(1+(f(+(- a b)c)b c))1))


Try it online!

Recursive function, stack overflow if no solution found.

# QBIC, 31 23 bytes

Just noticed the requirements changed. This version doesn't check if the snail will ever reach the top of the well.

≈:-:>0|q=q+1┘a=a-b+:]?q


The explanation below, for the original version that does check if a solution exists, covers all relevant parts of this code too.

~:>:|≈:-a>0|q=q+1┘c=c-a+b]?q\?0


## Explanation

~           IF
:          cmd line arg 'a'  (the increment of our snail)
>         is greater than
:        cmd line arg 'b'  (the decrement, or daily drop)
|       THEN
≈           WHILE
:          cmd line arg 'c'  (the height of the well)
-a        minus the increment (we count down the hieght-to-go)
>0|     is greater than 0 (ie while we haven't reached the top yet)
q=q+1       Add a day to q (day counter, starts at 1)
┘           (syntactic linebreak)
c=c-a+b     Do the raise-and-drop on the height-to-go
]           WEND
?q          PRINT q (the number of days)
\?0         ELSE (incrementer <= decrementer) print 0 (no solution)


Try it online! (OK, not really: this is a translation of QBIC to QBasic code run in repl.it 's (somewhat lacking) QBasic enviroment)

# Excel VBA, 47 Bytes

Anonymous VBE immediate window function that takes input in from the range [A1:C1] from the ActiveSheet object outputs to the VBE immediate window

This primarily Excel formula based solution appears to be smaller than any purely VBA solution that I can come up with :(

?[If(B1>C1,-Int((B1-A1)/(B1-C1)-1),Int(A1=B1))]


Haskell, 47 55 bytes (48 if tuple required)

f d c s|d<=c=1|c<s= -1|d>c||c<s=1+(f(d-c+s)c s)


tuple variation

f(d,c,s)|d<=c=1|c<s= -1|d>c||c<s=1+(f(d-c+s)c s)


Explanation

f d c s       function that does all the heavy lifting =)
d - depth
c - climb per day
s - slide per night

|d<=c=1             recursion terminator. 1 day of climbing
|c<s= -1            possibility check. top can't be reached
|otherwise=1+(f(d-c+s)c s)  1 day plus the rest of the distance

• 1. You can replace d>c||c<s just with 0<1, as you already implicitly do in your explanation, because otherwise is just a synonym of True. 2. The recursive call in your tuple version is still curried. 3. You can define your function as (d#c)s instead of f d c s to save two more bytes. Jul 7, 2017 at 13:16
• You also need c<=s instead of c<s. Jul 7, 2017 at 13:17
• Reordering and using 0 instead of -1 as allowed by the OP yields 38 bytes: Try it online! Jul 7, 2017 at 13:21
• Can you use an infix identifier to save any bytes? Jul 7, 2017 at 18:14
• I don't know, if I should post edited anser since it is esentialy @Laikoni's answer Jul 7, 2017 at 18:33

# Python 3, 41 Bytes

f=lambda a,b,c:int(b>=a)or 1+f(a-b+c,b,c)


Error for Never

Outgolf @veganaiZe

• Welcome to PPCG! Nice first answer :) Jul 7, 2017 at 15:46
• I don't know much Python, but could you change int(b>=a) to 1-(b<a) to save 2 bytes? Jul 7, 2017 at 16:45

# APL (Dyalog), 13 bytes

(⌈+÷⊢)/0⌈2-/⊢


Try it online!

Errors on division by zero if the snail cannot climb out of the well.

# C# (.NET Core), 37 bytes

(h,c,f)=>h>c?f<c?1+(h-f-1)/(c-f):0:1;


Non-recursive lambda. Uses formula found here. Could be shortened by 6 bytes if "any negative result" is a valid way to return failure; currently returns 0 instead.

• It's been a while, but h-f-1 can be h+~f`. Mar 26, 2018 at 15:01