The Snail in the Well

47

4

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?

The intuitive answer is

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

but actually the answer is

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.

musicman523

Posted 2017-07-07T05:41:35.993

Reputation: 4 472

Related – Not a tree – 2017-07-07T05:46:01.073

8

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.

– musicman523 – 2017-07-07T05:53:41.100

4I thought this would just be a simple formula, but the casework is surprisingly interesting. – xnor – 2017-07-07T06:02:08.147

You still have "how many hours....". The answer being 27*24 + 12 (assuming a 12 hour 'day'). – Francis Davey – 2017-07-07T10:14:00.753

@musicman523 To which answer did you intend to award the bounty? Both Keyu Gan and myself have made answers. Keyu Gan's was first but mine is quite a deal shorter. – Post Rock Garf Hunter – 2017-07-08T13:44:38.163

2@WheatWizard I will award the bounty to the shortest Gray Snail answer – musicman523 – 2017-07-08T15:50:45.747

Still waiting for that SnailBASIC answer... – 12Me21 – 2018-03-29T13:37:30.237

Answers

20

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 156 157 167 170 230 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.

Keyu Gan

Posted 2017-07-07T05:41:35.993

Reputation: 2 028

You made it first – Евгений Новиков – 2017-07-07T14:45:22.447

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. – Post Rock Garf Hunter – 2017-07-11T14:58:04.950

@WheatWizard I have a 155-byte solution based on your old answer. But for sportsmanship, I will not view it as my answer. – Keyu Gan – 2017-07-11T15:09:17.110

@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. :) – Post Rock Garf Hunter – 2017-07-11T15:11:37.160

@WheatWizard Me neither. I'm sure it is the best time I've ever had on PPCG. – Keyu Gan – 2017-07-11T15:16:05.053

I used your golf of my golf, to take of another 10 bytes. – Post Rock Garf Hunter – 2017-07-11T15:19:39.620

19

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!

Charlie

Posted 2017-07-07T05:41:35.993

Reputation: 11 448

1You can save a byte byte changing a<=b to a>b and swapping the following parts – LiefdeWen – 2017-07-07T09:03:22.607

3

Exact same code works in ES6 f=(a,b,c)=>a<=b?1:1+f(a-b+c,b,c)

– Tushar – 2017-07-07T09:09:56.103

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. – Martin Ender – 2017-07-07T09:12:16.573

@MartinEnder done! – Charlie – 2017-07-07T09:13:54.490

4

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.

– Martin Ender – 2017-07-07T09:15:14.677

(The usual rules are "either your submission is an expression that evaluates to a function object, or your submission is a statement that can stand on its own and results in a named function being defined".) – Martin Ender – 2017-07-07T09:17:43.573

@MartinEnder so, should I add the previous System.Func<int,int,int,int>f=null; and the trailing ; to the byte count? I don't think it adds anything to the code, but if I am to stick to the rules, so be it... – Charlie – 2017-07-07T09:23:35.593

@CarlosAlejo Well I guess you'd just put the expression where the null is to have it all in one statement. – Martin Ender – 2017-07-07T09:25:51.653

@MartinEnder if you mean System.Func<int,int,int,int>f=(a,b,c)=>a>b?1+f(a-b+c,b,c):1;, I can't do that because f is unassigned at the moment I try to call it recursively, hence the previous sentence to declare it as null. – Charlie – 2017-07-07T09:29:16.817

@CarlosAlejo Oh I see. In that case, I suppose you need to use the null version. But wouldn't a regular named method be shorter at that point? – Martin Ender – 2017-07-07T09:31:35.503

@MartinEnder yes, but then a non-recursive, anonymous lambda expression using a formula similar to other answers would be even shorter, losing the elegant, recursive approach. – Charlie – 2017-07-07T09:34:37.777

2@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. – TheLethalCoder – 2017-07-07T09:55:06.153

Thank Mathematica for having #0 – Keyu Gan – 2017-07-07T09:56:04.783

For the record, Scala has the same problem and I've never included the type declarations in my Scala answers, though those were mostly non-recursive. This C# consensus should probably apply to Scala as well. – musicman523 – 2017-07-07T14:03:59.263

I thought it required a runnable program with all the usings, class def etc – Ewan – 2017-07-08T08:52:59.997

I don't think anybody would argue int f(int a,int b,int c)=>a>b?1+f(a-b+c,b,c):1; is valid at 47 bytes. Not as cool as a recursive anonymous function thought :) – dana – 2019-01-28T11:39:17.107

13

GRAY SNAIL, 219 206 169 167 159 156 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.

Post Rock Garf Hunter

Posted 2017-07-07T05:41:35.993

Reputation: 55 382

Congratulations! – Keyu Gan – 2017-07-11T15:44:24.407

11

JavaScript (ES6), 31 28 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)))

ETHproductions

Posted 2017-07-07T05:41:35.993

Reputation: 47 880

2That's obvious: If snail does too much recursion, then climb is impossible. :) – Tushar – 2017-07-07T11:25:09.413

1Maybe 27 with a reversed currying syntax? d=>u=>g=h=>h>u?1+g(h-u+d):1 – Arnauld – 2017-07-07T11:36:54.990

@Arnauld Thanks, that works surprisingly well... – ETHproductions – 2017-07-07T11:38:50.550

I'm a it confused re the byte count- in one the variable the function is assigned t is included, the other not? – None – 2017-07-07T15:39:39.713

@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. – musicman523 – 2017-07-07T18:11:35.260

10

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.

Wernisch

Posted 2017-07-07T05:41:35.993

Reputation: 2 534

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). – Scarabee – 2017-07-08T22:29:17.743

7

C (gcc), 39 43 44 46 47 58 60 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).

Keyu Gan

Posted 2017-07-07T05:41:35.993

Reputation: 2 028

Nice one! could u please include the analytical (non-compressed) solution? – koita_pisw_sou – 2017-07-07T07:15:25.250

1@koita_pisw_sou Sure. – Keyu Gan – 2017-07-07T07:22:16.690

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. – Cody Gray – 2017-07-08T00:51:09.593

@CodyGray it uses a stable but undefined behavior in GCC. I could show you a link later. – Keyu Gan – 2017-07-08T03:27:13.140

@CodyGray https://codegolf.stackexchange.com/questions/2203/tips-for-golfing-in-c Assign instead of return

– Keyu Gan – 2017-07-08T04:56:40.523

Sigh, more bad advice given out to code golfers by people who don't know the language. If it's undefined behavior, it isn't valid code. This doesn't work reliably. For example, it doesn't work here. (And yes, CodePad uses GCC as the C compiler.) It doesn't work on my machine, either.

– Cody Gray – 2017-07-08T07:24:09.663

@CodyGray btw, it requires all optimizations turned off – Keyu Gan – 2017-07-08T07:27:23.710

Codepad uses -O to compile code, which may alter undefined behavior. As discussed in https://codegolf.meta.stackexchange.com/questions/5486/is-an-answer-allowed-to-use-undefined-but-consistent-behaviour , it is acceptable to utilize consistent undefined behavior. I should mention it more clearly in the title.

– Keyu Gan – 2017-07-08T07:35:37.650

7

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

Olivier Grégoire

Posted 2017-07-07T05:41:35.993

Reputation: 10 647

1It's been a while, but a-c-1a+~c. – Kevin Cruijssen – 2018-03-26T15:00:23.520

1Thanks @KevinCruijssen It's been a while, but golf is golf, no matter when it happens :-) – Olivier Grégoire – 2018-03-26T15:03:31.130

My thoughts exactly. On a few occasions I golfed about halve my original bytes when I looked at some of my first answers. ;) – Kevin Cruijssen – 2018-03-26T15:12:03.237

5

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)

Coty Johnathan Saxman

Posted 2017-07-07T05:41:35.993

Reputation: 280

2You 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. – Mr. Xcoder – 2017-07-07T09:09:09.557

Noted and addressed. Thanks for letting me know. – Coty Johnathan Saxman – 2017-07-07T09:20:19.030

4

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.

r2evans

Posted 2017-07-07T05:41:35.993

Reputation: 141

Nice answer. Welcome to PPCG! – musicman523 – 2017-07-09T06:09:17.667

3

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

Jonah

Posted 2017-07-07T05:41:35.993

Reputation: 8 729

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? – musicman523 – 2017-07-07T06:45:21.787

@musicman523 fixed and done. – Jonah – 2017-07-07T07:06:52.787

3

Perl 5, 37 bytes

35 bytes code +2 for -pa.

$i-=$F[2]while++$\,($i+=$F[1])<$_}{

Try it online!

Dom Hastings

Posted 2017-07-07T05:41:35.993

Reputation: 16 415

3

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

Jörg Hülsermann

Posted 2017-07-07T05:41:35.993

Reputation: 13 026

2

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!

Alex

Posted 2017-07-07T05:41:35.993

Reputation: 371

1@Jonah fixed it – Alex – 2017-07-07T07:26:01.983

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. – Galen – 2017-07-11T19:08:50.117

2

Mathematica, 47 40 39 bytes

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

-7 bytes from @KeyuGan

J42161217

Posted 2017-07-07T05:41:35.993

Reputation: 15 931

You need to deal with input as 69, 3, 8 and is counted as 3 bytes as far as I think. – Keyu Gan – 2017-07-07T07:39:59.653

all fixed! try it now – J42161217 – 2017-07-07T07:44:07.537

you may use Max to replace If statement. If[#<=#2,1,Max[⌈(#-#3)/(#2-#3)⌉,0]]& – Keyu Gan – 2017-07-07T07:47:37.480

2

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.


Original, 31 byte answer:

~:>:|≈:-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)

steenbergh

Posted 2017-07-07T05:41:35.993

Reputation: 7 772

2

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...

Neil

Posted 2017-07-07T05:41:35.993

Reputation: 95 035

2

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!

Okx

Posted 2017-07-07T05:41:35.993

Reputation: 15 025

2

05AB1E, 12 bytes

.×ηO<²›1k2÷>

Try it online!

Prints 0 if impossible.

Input format:

[climb, -fall]
height

Erik the Outgolfer

Posted 2017-07-07T05:41:35.993

Reputation: 38 134

2

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.

Titus

Posted 2017-07-07T05:41:35.993

Reputation: 13 814

2

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...

ETHproductions

Posted 2017-07-07T05:41:35.993

Reputation: 47 880

Came up with this for 11 bytes by changing the order of the inputs.

– Shaggy – 2018-03-26T15:51:01.870

2

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))]

Taylor Scott

Posted 2017-07-07T05:41:35.993

Reputation: 6 709

2

Haskell, 30 29 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.

Post Rock Garf Hunter

Posted 2017-07-07T05:41:35.993

Reputation: 55 382

Save 1 byte with infix notation: (b#c)a=1+sum[(b#c)$a+c-b|a>b]. – Laikoni – 2017-07-07T22:04:09.857

@Laikoni Didn't know that could be done. Thanks for the tip. – Post Rock Garf Hunter – 2017-07-07T22:23:36.083

You can drop the parens around b!c in the list comprehension. – Zgarb – 2017-07-09T09:22:05.107

1

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.

veganaiZe

Posted 2017-07-07T05:41:35.993

Reputation: 191

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... – Olivier Grégoire – 2017-07-07T11:11:47.213

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 / – musicman523 – 2017-07-07T19:28:53.743

Thanks @musicman523. I ended up taking all of your advice. – veganaiZe – 2017-07-07T20:25:21.370

1I 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. – veganaiZe – 2017-07-07T23:50:11.313

1

Jelly, 10 bytes

ẋ;\m2S€<i0

Try it online!

Erik the Outgolfer

Posted 2017-07-07T05:41:35.993

Reputation: 38 134

1

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

Sergii Martynenko Jr

Posted 2017-07-07T05:41:35.993

Reputation: 213

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.
  • < – Laikoni – 2017-07-07T13:16:13.497

    1You also need c<=s instead of c<s. – Laikoni – 2017-07-07T13:17:54.003

    1

    Reordering and using 0 instead of -1 as allowed by the OP yields 38 bytes: Try it online!

    – Laikoni – 2017-07-07T13:21:43.210

    1Can you use an infix identifier to save any bytes? – musicman523 – 2017-07-07T18:14:42.713

    I don't know, if I should post edited anser since it is esentialy @Laikoni's answer – Sergii Martynenko Jr – 2017-07-07T18:33:51.733

    Feel free to use it, it's still the same approach based on your answer. – Laikoni – 2017-07-07T21:57:50.140

    1

    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

    Alix Eisenhardt

    Posted 2017-07-07T05:41:35.993

    Reputation: 111

    1Welcome to PPCG! Nice first answer :) – musicman523 – 2017-07-07T15:46:30.200

    2I don't know much Python, but could you change int(b>=a) to 1-(b<a) to save 2 bytes? – ETHproductions – 2017-07-07T16:45:55.173

    1

    Google Sheets, 43 Bytes

    Worksheet cell function that takes input from cells A1:C1 and outputs to the calling cell

    =if(B1>C1,-int((B1-A1)/(B1-C1)-1),int(A1=B1
    

    Excel, 45 Bytes

    Same as above, but formatted for MS Excel

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

    Taylor Scott

    Posted 2017-07-07T05:41:35.993

    Reputation: 6 709

    Excel solution does not seem to handle cases where climb distance = well depth. (5,5,10) (7,7,7) – Wernisch – 2017-07-10T10:59:07.043

    @Wernisch, good catch! I've corrected this by replacing 0 in the if statement with a INT(A1=B1) call – Taylor Scott – 2017-07-10T12:18:22.743

    1

    APL (Dyalog), 13 bytes

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

    Try it online!


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

    TwiNight

    Posted 2017-07-07T05:41:35.993

    Reputation: 4 187

    1

    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.

    Kamil Drakari

    Posted 2017-07-07T05:41:35.993

    Reputation: 3 461

    It's been a while, but h-f-1 can be h+~f. – Kevin Cruijssen – 2018-03-26T15:01:21.267

    1

    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.

    Ryan

    Posted 2017-07-07T05:41:35.993

    Reputation: 31

    This is awesome! Welcome to PPCG :) – musicman523 – 2017-07-09T06:06:43.610

    1

    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!

    root

    Posted 2017-07-07T05:41:35.993

    Reputation: 241

    1

    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.

    Renzo

    Posted 2017-07-07T05:41:35.993

    Reputation: 2 260

    1

    Kotlin, 70 bytes

    fun s(h:Int,c:Int,f:Int):Int=if(h>c)if(c>f)1+s(h-c+f,c,f)else 0 else 1
    

    Try it online!

    JohnWells

    Posted 2017-07-07T05:41:35.993

    Reputation: 611

    1

    @yBASIC, 45 bytes

    @__
    _=_+_%-_#__=__+!.GOTO(@_)+"_"*(_>_%)@_?__
    

    The language has no support for input so you have to set variables _, _%, and _# to the well depth, fall distance, and climb distance, respectively. (Is this allowed?)

    Try it online! (Experimental)

    12Me21

    Posted 2017-07-07T05:41:35.993

    Reputation: 6 110

    0

    R, 50 bytes

    f=function(x,y,z)`if`(y>z,ceiling((x-z)/(y-z)),0)
    

    Similar logic to others, let down by ceiling and function being such long words..

    Usage:

    > f(30,3,2)
    [1] 28
    
    > f(30,3,20)
    [1] 0
    

    Andrew Haynes

    Posted 2017-07-07T05:41:35.993

    Reputation: 311

    f(5, 5, 10) should be 1. – Scarabee – 2017-07-08T22:37:17.150

    0

    Clojure - 80 70 bytes

    (defn snail[x y z](cond(>= y x)1(> y z)(Math/ceil(/(- x z)(- y z))):else false))
    

    Ungolfed version:

    (defn snail [x y z]
      (cond
        (>= y x) 1
        (> y z)  (Math/ceil (/ (- x z) (- y z)))
        :else    false))
    

    As a (shorter) anonymous function:

    #(cond(<= %2 %1)1(> %2 %3)(Math/ceil(/(- %1 %3)(- %2 %3))):else false)
    

    My original thinking (without checking, naturally) was that the % chars in the substitution markers would outweigh the benefit of getting rid of defn snail [x y z]. Apparently NOT! :-)

    Bob Jarvis - Reinstate Monica

    Posted 2017-07-07T05:41:35.993

    Reputation: 544

    This is great! Since the function is not recursive, can you define it as an anonymous function instead to save bytes? – musicman523 – 2017-07-09T22:28:56.163

    I'd originally glanced at it and thought that the % chars on all the parameter references would outweigh the benefit of getting rid of defn snail [x y z]. Thanks for prodding me to reconsider this. :-) – Bob Jarvis - Reinstate Monica – 2017-07-10T03:07:57.510

    0

    Jelly, 8 bytes

    ẋ+\<i0HĊ
    

    Try it online!

    How it Works

    ẋ+\<i0HĊ - main link. The inputs are a list and an int, e.g. 3,-2 and 30
    ẋ          - repeat the first input a number of times equal to the second input
                   e.g. 3,-2,3,-2,3,-2,3,-2,...3,-2 (60 elements total)
     +\        - cumulative sum, e.g. 3,1,4,2,5,3,6,4,7,5,8,...32,30
       <       - less than (the second element)
        i0     - get the index of the first 0
          HĊ   - halve and round up
    

    fireflame241

    Posted 2017-07-07T05:41:35.993

    Reputation: 7 021

    0

    bash, 39 bytes

    echo $((d=$2-$3,d>0?$1/d-$3/d:$2/$1%2))
    

    Try it online!

    Gerhard

    Posted 2017-07-07T05:41:35.993

    Reputation: 161

    0

    Add++, 31 bytes

    D,f,@@@,¿@>,@$_+abRbUp${f}1+,1¿
    

    Try it online!

    First ever use of the ternary expression! Raises an Exception on invalid inputs

    How it works

    D,f,@@@,		; Declare a triadic function
    			; Example arguments: 		[30 3 2]. Labelled [A B C] here
    	¿		; If...
    		@>	; 	A > B
    	,		; Then...
    		@	; 	Reverse;	STACK = [2 3 30]
    		$_	; 	Swap subtract;	STACK = [2 27]
    		+	; 	Add;		STACK = [29]
    		abRbU	; 	Reversed args;	STACK = [29 2 3 30]
    		p$	; 	Pop and swap;	STACK = [29 3 2]
    		{f}	; 	Call 'f';	STACK = [27]
    		1+	; 	Add 1;		STACK = [28]
    	,		; Else...
    	1		; 	Push 1;
    	¿		; Endif
    			;			Returns  28
    

    Try it online!

    caird coinheringaahing

    Posted 2017-07-07T05:41:35.993

    Reputation: 13 702