El caracol en el pozo


47

Antecedentes

Hay un acertijo común que dice algo como esto:

Un caracol está en el fondo de un pozo de 30 pies. Todos los días el caracol puede trepar hasta 3 pies. Por la noche, cuando duermen, se deslizan hacia abajo 2 pies. ¿Cuántos días le toma al caracol salir del pozo?

La respuesta intuitiva es

30 días, porque el caracol trepa a 1 pie por día durante 30 días para llegar a la cima,

pero en realidad la respuesta es

28 días, porque una vez que el caracol esté a 27 pies en el aire (después de 27 días), simplemente subirán los 3 pies restantes a la cima el día 28.

Desafío

Este desafío generaliza este acertijo. Dados tres enteros positivos como entrada, que representan la altura total, la altura de ascenso y la altura de caída, devuelve el número de días que tomará salir del pozo.

Si el caracol no puede salir del pozo, puede devolver 0, devolver un valor falso o lanzar una excepción. También puede escribir código que se detendrá si y solo si existe una solución.

Si lo desea, puede tomar la altura de caída como un entero negativo.

Casos de prueba

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

Puntuación

Este es el , por lo que gana la respuesta más corta en cada idioma.



8
Probablemente otorgaré una recompensa si alguien responde en Gray Snail. La página de Esolangs es solo un trozo vacío, pero hay información y un compilador en línea disponible , así como un programa de muestra para el problema de las 99 botellas de cerveza .
musicman523

44
Pensé que esto sería una fórmula simple, pero el trabajo de casos es sorprendentemente interesante.
xnor

Todavía tienes "cuántas horas ...". La respuesta es 27 * 24 + 12 (suponiendo un 'día' de 12 horas).
Francis Davey

2
@WheatWizard otorgaré la recompensa a la respuesta más breve de Gray Snail
musicman523

Respuestas:


21

Caracol gris , 1206 bytes para E / S numéricas, 149 bytes para E / S unarias

Por diversión. Composición del primer programa:

  • 451 bytes, convirtiendo el número en puntos
  • 121 bytes, función principal (a continuación se escribe una versión separada)
  • 634 bytes, convirtiendo puntos en número

Tomar entrada y salida numérica. De entrada es A, B, Crespectivamente. En comparación con otra O(1)respuesta (cercana) , el código tiene una complejidad de O(n). Pero para un gran número, puede consumir su memoria primero.

Cuelgue si no se encuentra una solución.

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]

fes una (quizás) función recursiva para convertir enteros en puntos. El argumento se guarda [p]y se genera [o].

Ues una prueba de función S1>=S2, almacenando parámetros B, Amientras se guarda A-Ben A.

El código a partir de Des un trozo que convierte puntos en números.

El principio subyacente es el mismo con mi respuesta C (estafando la salida falsa para soluciones imposibles).

Versión independiente, 149 156 157 167 170 230 bytes, solo admite E / S unarias

La entrada debe ser puntos, por ejemplo, ..........para 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]

Ucalcula A=A-By salta a Dcuando A<=0. De lo contrario $asigna A+Ca Ay llamada U.

Cuelgue si no se encuentra una solución.

Trucos: abusar de la capacidad del "compilador" para interpretar cadenas vacías. Puede extraer condiciones en la GOTOdeclaración para hacer saltos incondicionados y el mismo truco funciona POP.

Observación: puedo jugar más por 3 bytes, pero al hacerlo, la respuesta mía y de WheatWizard tendría exactamente la misma lógica. El resultado es probablemente la solución GraySnail más corta y estoy tratando de demostrarlo.


Lo hiciste primero
Евгений Новиков

Oye, pensé en hacerte saber que he hecho el mío más corto que el tuyo otra vez. Es solo un byte más corto y se inspira en su último golf.
Wheat Wizard

@WheatWizard Tengo una solución de 155 bytes basada en su respuesta anterior. Pero por espíritu deportivo, no lo veré como mi respuesta.
Keyu Gan

@KeyuGan No, adelante. No me importa el representante, todo se trata del juego. Estoy feliz de ser golpeado. Si mi código se puede jugar es mi culpa por no haberlo visto. :)
Wheat Wizard

@WheatWizard Me tampoco. Estoy seguro de que es el mejor momento que he tenido en PPCG.
Keyu Gan

20

Nota: Martin Ender cuestiona el recuento de bytes en los comentarios. Parece que no hay un consenso claro sobre qué hacer con las expresiones lambda nombradas y recursivas en las respuestas de C #. Así que hice una pregunta en Meta al respecto.

C # (.NET Core) , 32 31 bytes

f=(a,b,c)=>a>b?1+f(a-b+c,b,c):1

Pruébalo en línea!

Un enfoque recursivo. Si el caracol no puede escapar, termina con el siguiente mensaje:Process is terminating due to StackOverflowException.

  • ¡1 byte guardado gracias a LiefdeWen!

1
Puede guardar un byte byte de cambiar a<=ba a>be intercambiando las siguientes partes
LiefdeWen

3
El mismo código funciona exactamente en ES6f=(a,b,c)=>a<=b?1:1+f(a-b+c,b,c)
Tushar

Tendrá que contar el código que asigna la función a un nombre si confía en que ese nombre sea fpara la llamada recursiva.
Martin Ender

44
No juego golf en C #, así que no estoy completamente seguro de cuál es el consenso, pero hubiera esperado que esto requiriera una declaración completa con una declaración fy un punto y coma si se nombra. Lo primero que encontré es esto, pero no hay un consenso claro aquí.
Martin Ender

2
@MartinEnder Por lo general, solo hago lo que Carlos ha hecho aquí, ya que la declaración es f=...que no estoy seguro de si debemos agregar el punto y coma al final.
TheLethalCoder

13

GRAY caracol, 219 206 169 167 159 156 146 bytes (unario 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].

Creo que puedo jugar un poco con esto.


¡Felicidades!
Keyu Gan

11

JavaScript (ES6), 31 28 27 bytes

Guardado algunos bytes gracias a @Arnauld

No me había dado cuenta de que podíamos fallar con una excepción. Bastante seguro de que esto es óptimo:

u=>d=>g=h=>h>u?1+g(h-u+d):1

Asigne a una variable con f=, por ejemplo , luego llame como f(climb)(fall)(height). Lanza InternalError: too much recursionsi la escalada es imposible.


JavaScript (ES6), 38 bytes

f=(h,u,d=0)=>h>u?u>0?1+f(h-u,u-d):+f:1

Una función recursiva que devuelve el número de días, o NaNpara nunca.

Casos de prueba


2
Eso es obvio: si el caracol hace demasiada recursión , entonces escalar es imposible. :)
Tushar

1
¿Quizás 27 con una sintaxis curry invertida? d=>u=>g=h=>h>u?1+g(h-u+d):1
Arnauld

@Arnauld Gracias, eso funciona sorprendentemente bien ...
ETHproductions

Estoy confundido con el recuento de bytes: en uno, la variable a la que se le asigna la función está incluida, ¿y la otra no?
Nombre para mostrar

@Orangesandlemons en la versión superior, tiene g=en el medio porque esta variable almacena la función intermedia necesaria para la llamada recursiva. La respuesta más larga hace una llamada recursiva f, que exige que el nombre se incluya en el recuento de bytes.
musicman523

10

Excel, 51 46 bytes

-1 byte gracias a @ Scarabee .

-4 porque INT (x) = PISO (x, 1)

=IF(B1<A1,IF(C1<B1,-INT((B1-A1)/(B1-C1)-1)),1)

Entrada tomada de las Celdas A1, B1 y C1 respectivamente. Devoluciones FALSEpara escenarios no válidos.


ceiling(x)siempre es igual a -floor(-x), por lo que creo que podría guardar 1 byte reemplazando CEILING((A1-B1)/(B1-C1)+1,1)con -FLOOR((B1-A1)/(B1-C1)+1,1).
Scarabee

7

C (gcc), 39 43 44 46 47 58 60 60 bytes

Solo en GCC de 32 bits y todas las optimizaciones desactivadas.

f(a,b,c){a=a>b?b>c?1+f(a-b+c,b,c):0:1;}

Devuelve 0 cuando la solución es imposible. Una versión modificada de la solución recursiva original.

Inspirado en la solución @Jonah J y la solución @CarlosAlejo C #.

Actualizaré la versión ampliada más tarde (después de que termine mi respuesta de Gray Snail).


¡Buena esa! ¿podría incluir la solución analítica (no comprimida)?
koita_pisw_sou

1
@koita_pisw_sou Claro.
Keyu Gan

No "devuelve" nada en absoluto. Se asigna a un parámetro local, cuyo valor se evapora una vez que la función regresa. El caracol está atrapado en el limbo eterno.
Cody Gray

@CodyGray utiliza un comportamiento estable pero indefinido en GCC. Podría mostrarte un enlace más tarde.
Keyu Gan


7

Java (OpenJDK 8) , 35 bytes

(a,b,c)->b<a?c<b?(a+~c)/(b-c)+1:0:1

Pruébalo en línea!

Matemáticas gana!

Créditos


1
Ha pasado un tiempo, pero a-c-1a+~c.
Kevin Cruijssen

1
Gracias @KevinCruijssen Ha pasado un tiempo, pero el golf es golf, no importa cuándo suceda :-)
Olivier Grégoire

Mis pensamientos exactamente. En algunas ocasiones jugué a la mitad mis bytes originales cuando miré algunas de mis primeras respuestas. ;)
Kevin Cruijssen

5

Python 2 , 37 bytes

f=lambda x,y,z:x-y<1or 1+f(x-y+z,y,z)

Pruébalo en línea!

Finalmente obtuve mi versión recursiva por debajo de mi cálculo estándar (estaba pasando un conteo a mi función en lugar de agregar uno antes de llamarlo).

Pitón 2 , 4346 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]

Pruébalo en línea!

Afeitó 3 bytes cambiando "__ y 1" por "__> 0".

Usando trucos booleanos, esencialmente ejecuta:

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)

2
Debe poner f=delante de su código (la primera solución), y su recuento de bytes se convierte en 37, porque es recursivo, por lo que no puede dejarlo en el anonimato. f=se puede descartar para una lambda solo cuando no es recusiva.
Sr. Xcoder

Anotado y dirigido. Gracias por hacérmelo saber.
Coty Johnathan Saxman

4

R, 43 bytes

Préstamo de otras respuestas:

g=function(a,b,c)`if`(b<a,1+g(a-b+c,b,c),1)

Da error si no hay solución.


Buena respuesta. Bienvenido a PPCG!
musicman523

3

J, 25 bytes

Primero, una buena solución, que es una trampa, ya que supone que "cualquier cosa que no sea un resultado entero positivo" es igual a "Ninguno":

>.>:%/2-/\

explicación

  • 2-/\use ventanas de longitud 2 en nuestra entrada de 3 elementos, colocando un signo menos entre cada una, que para la entrada 30 3 2, por ejemplo, devuelve27 1
  • %/ ponga un símbolo de división entre cada elemento de la lista, en nuestro caso la lista tiene solo dos elementos, por lo que significa "dividir 27 por 1"
  • >: incrementar en 1
  • >. tomar el techo

solución oficial

Aquí está la solución oficial que convierte los negativos y el infinito a 0, cuya parte no pude encontrar una solución satisfactoriamente breve para:

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.Con el propósito de escribir los casos de prueba, simplemente elegí Noneindicar que no había respuesta. ¿Consideraría también agregar una explicación y un enlace Pruébelo en línea?
musicman523

@ musicman523 arreglado y listo.
Jonás



2

Mathematica, 47 40 39 bytes

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

-7 bytes de @KeyuGan


Necesito lidiar con la entrada como 69, 3, 8y se cuenta como 3 bytes por lo que creo.
Keyu Gan

¡todo arreglado! pruébelo ahora
J42161217

puede usar Maxpara reemplazar la Ifdeclaración. If[#<=#2,1,Max[⌈(#-#3)/(#2-#3)⌉,0]]&
Keyu Gan

2

Ruby , 49 47 bytes

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

Lanza una excepción si el caracol no puede salir

Pruébalo en línea!


1
@Jonah lo arregló
Alex

¿Cuál es el razonamiento detrás del proceso? h-a<1?1:(1.0*(h-a)/[a-b,0].max+1).ceilpasa los casos de prueba y guarda 9 bytes.
Galen

2

Lote, 66 bytes

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

El segundo último caso de prueba no imprimió nada, y el último caso de prueba realmente se bloqueó CMD.EXE...


2

05AB1E , 19 bytes

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

Explicación:

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

Para valores no válidos, esto puede devolver cualquier valor menor que 1. Sin embargo, en 05AB1E, solo 1 es verdadero, por lo que cumple con el requisito de que la salida de un valor no válido sea falsa.

Pruébalo en línea!


2

PHP, 60 bytes

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

impresiones Npara None. Corre con -r.



2

Japt , 12 bytes

@UµV-W §W}aÄ

¡Pruébelo en línea!

Salidas undefinedpara nunca, después de posiblemente congelar su navegador por un tiempo, así que tenga cuidado.

No estoy convencido de que esto sea óptimo. oWV-W lfunciona en todos menos los últimos tres casos ...


Se me ocurrió esto por 11 bytes cambiando el orden de las entradas.
Shaggy

2

Haskell , 30 29 bytes

(b!c)a=1+sum[(b!c)$a+c-b|a>b]

Pruébalo en línea!

Más corto que la respuesta Haskell existente. Quizás alguien más pueda vencerme.

Esto utiliza un enfoque recursivo para resolver el problema. Cada recursión es esencialmente un día de movimiento para el caracol. Si la distancia que queda hasta el final es menor que la distancia aún requerida, finalizamos nuestra recursión.


Guardar 1 byte con notación infija: (b#c)a=1+sum[(b#c)$a+c-b|a>b].
Laikoni

@Laikoni no sabía que se podía hacer. Gracias por el consejo.
Wheat Wizard

Puede colocar los parens b!cen la lista de comprensión.
Zgarb

2

QBIC , 31 23 bytes

Acabo de notar que los requisitos cambiaron. Esta versión no verifica si el caracol llegará a la parte superior del pozo.

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

La explicación a continuación, para la versión original que verifica si existe una solución, también cubre todas las partes relevantes de este código.


Original, respuesta de 31 bytes:

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

Explicación

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

Pruébalo en línea! (OK, en realidad no: esta es una traducción de QBIC al código QBasic ejecutado en el entorno QBasic de repl.it (algo deficiente))


2

Excel VBA, 47 Bytes

Función de ventana inmediata anónima de VBE que toma la entrada desde el rango [A1:C1]de las ActiveSheetsalidas del objeto a la ventana inmediata de VBE

Esta solución basada principalmente en fórmulas de Excel parece ser más pequeña que cualquier solución puramente VBA que se me ocurra :(

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

1

Haskell, 47 55 bytes (48 si se requiere tupla)

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

variación de tupla

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

Explicación

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
1. Puede reemplazar d>c||c<ssolo con 0<1, como ya lo hace implícitamente en su explicación, porque otherwisees solo un sinónimo de True. 2. La llamada recursiva en tu versión de tupla todavía está al curry. 3. Puede definir su función como en (d#c)slugar de f d c sguardar dos bytes más.
Laikoni

1
También necesitas en c<=slugar de c<s.
Laikoni

1
Reordenar y usar en 0lugar de -1lo permitido por el OP produce 38 bytes: ¡ Pruébelo en línea!
Laikoni

1
¿Puedes usar un identificador infijo para guardar los bytes?
musicman523

No sé, si debo publicar una respuesta editada, ya que es esencialmente la respuesta de @ Laikoni
Sergii Martynenko Jr



1

C # (.NET Core) , 37 bytes

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

Lambda no recursiva. Utiliza la fórmula que se encuentra aquí . Podría acortarse en 6 bytes si "cualquier resultado negativo" es una forma válida de devolver la falla; actualmente devuelve 0 en su lugar.


Ha pasado un tiempo, pero h-f-1puede ser h+~f.
Kevin Cruijssen

1

Python v2 y v3, 44 bytes

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

^ Recurrencia infinita (error) para el caso Ninguno.


Puedes usar lambda. Además, esto parece similar a mi respuesta (Java) por lo que me permito sugerir una mejora en la fórmula: (x-z-1)//(y-z)+1. No hago mucho Python, así que podría estar equivocado ...
Olivier Grégoire

Puede eliminar f=del conteo de bytes, eliminar algunos espacios alrededor de ifs y elses, y cambiar a Python 2, donde la división de enteros es única/
musicman523

Gracias @ musicman523. Terminé tomando todos tus consejos.
veganaiZe

1
Me di cuenta de que mi código "limpio" (sin recursión infinita) tenía muchos problemas de mayúsculas y minúsculas cuando se usaba con otras entradas (es decir, 4, 3, 8). @ musicman523 Creo que estoy empezando a ver las "pruebas" de las que hablas.
veganaiZe

1

Calculadora programable HP-15C, 26 bytes

Los tres números se cargan en la pila en orden antes de ejecutar el programa. La altura de caída se ingresa como un número negativo. Si el caracol no puede salir del pozo, el resultado es un número negativo o un error n. ° 0 (error de división cero).

Códigos operativos en hexadecimal:

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

Significado de las instrucciones:

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

Puede probar el programa con este simulador HP-15C .


¡Esto es asombroso! Bienvenido a PPCG :)
musicman523

1

Lisp común, 49 bytes

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

Pruébalo en línea!

Función recursiva, desbordamiento de pila si no se encuentra una solución.


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.