O Caracol no Poço


47

fundo

Há um enigma comum que é mais ou menos assim:

Um caracol está no fundo de um poço de 30 pés. Todos os dias o caracol é capaz de subir 3 pés. À noite, quando dormem, deslizam de volta 2 pés. Quantos dias o caracol leva para sair do poço?

A resposta intuitiva é

30 dias, porque o caracol sobe 1 pé por dia durante 30 dias para chegar ao topo,

mas na verdade a resposta é

28 dias, porque uma vez que o caracol está a 27 pés no ar (após 27 dias), eles simplesmente subirão os 3 pés restantes até o topo no 28º dia.

Desafio

Esse desafio generaliza esse enigma. Dado três números inteiros positivos como entrada, representando a altura total, a altura de subida e a altura de queda, retorne o número de dias que levará para sair do poço.

Se o caracol não puder sair do poço, você pode retornar 0, retornar um valor falso ou lançar uma exceção. Você também pode escrever um código que interrompa se e somente se existir uma solução.

Se desejar, você pode considerar a altura da queda como um número inteiro negativo.

Casos de teste

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

Pontuação

Isso é , então a resposta mais curta em cada idioma vence.



8
Provavelmente eu recompensarei uma recompensa se alguém responder em Grey Snail. A página da Esolangs é apenas um esboço vazio, mas há algumas informações e um compilador disponível , além de um programa de amostra para o problema das 99 garrafas de cerveja .
musicman523

4
Eu pensei que isso seria apenas uma fórmula simples, mas o caso é surpreendentemente interessante.
Xnor

Você ainda tem "quantas horas ....". A resposta é 27 * 24 + 12 (assumindo um dia de 12 horas).
Francis Davey

2
@WheatWizard I premiará a recompensa para o mais curto Resposta Cinza Snail
musicman523

Respostas:


21

Caracol cinza , 1206 bytes para E / S numérica, 149 bytes para E / S unária

Para se divertir. Composição do primeiro programa:

  • 451 bytes, convertendo número em pontos
  • 121 bytes, função principal (uma versão separada está escrita abaixo)
  • 634 bytes, convertendo pontos em número

Tome entrada e saída numéricas. A entrada é A, B, Crespectivamente. Comparado com outra (quase) O(1)resposta, o código tem uma complexidade de O(n). Mas, para um grande número, ele pode consumir sua memória primeiro.

Trave se nenhuma solução for encontrada.

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é uma função (talvez) recursiva para converter números inteiros em pontos. O argumento é salvo [p]e produzido em [o].

Ué um teste de função S1>=S2, o armazenamento de parâmetro em B, Apoupando A-Bem A.

O código a partir de Dé um esboço que converte pontos em números.

O princípio subjacente é o mesmo com a minha resposta C (arrancando resultados falsos para soluções impossíveis).

Versão autônoma, 149 156 157 167 170 230 bytes, suportam apenas E / S unárias

A entrada precisa ser pontos, por exemplo, ..........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-Be pula para Dquando A<=0. Caso contrário, $atribui A+Cao Ae chamada U.

Trave se nenhuma solução for encontrada.

Truques: abusam da capacidade do "compilador" de interpretar uma string vazia. Você pode extrair condições na GOTOinstrução para fazer saltos incondicionados e o mesmo truque funciona POP.

Observação: eu posso jogar mais de 3 bytes, mas, ao fazê-lo, a resposta da minha e da WheatWizard teria exatamente a mesma lógica. O resultado é provavelmente a solução mais curta do GraySnail e estou tentando provar isso.


Você fez primeiro
Евгений Новиков

Ei, eu apenas pensei em deixar você saber que tornei o meu mais curto que o seu novamente. É apenas um byte mais curto e tira alguma inspiração do seu último golfe.
Assistente de trigo

@WheatWizard Eu tenho uma solução de 155 bytes com base na sua resposta antiga. Mas para o espírito esportivo, não vou vê-lo como minha resposta.
Keyu Gan

@KeyuGan Não, vá em frente. Eu não ligo para o representante, é tudo sobre o jogo. Estou feliz por ser derrotado. Se meu código pode ser jogado de golfe, a culpa é minha por não vê-lo. :)
Assistente de trigo

@WheatWizard Eu também não. Tenho certeza de que é o melhor momento que já tive no PPCG.
Keyu Gan

20

Nota: a contagem de bytes está sendo questionada por Martin Ender nos comentários. Parece que não há um consenso claro sobre o que fazer com expressões lambda recursivas nomeadas nas respostas C #. Então, eu fiz uma pergunta no Meta sobre isso.

C # (.NET Core) , 32 31 bytes

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

Experimente online!

Uma abordagem recursiva. Se o caracol não puder escapar, ele termina com a seguinte mensagem:Process is terminating due to StackOverflowException.

  • 1 byte salvo graças ao LiefdeWen!

1
Você pode salvar um byte byte mudando a<=bpara a>be trocar as seguintes peças
LiefdeWen

3
O mesmo código exato funciona no ES6f=(a,b,c)=>a<=b?1:1+f(a-b+c,b,c)
Tushar 07/07

Você terá que contar o código que atribui a função a um nome, se você confiar nesse nome fpara a chamada recursiva.
Martin Ender

4
Como não jogo golfe em C #, não tenho muita certeza de qual é o consenso, mas esperaria que isso exigisse uma declaração completa com uma declaração fe um ponto-e-vírgula, se esse nome for mencionado. A primeira coisa que encontrei é isso, mas não há consenso claro aqui.
Martin Ender

2
@MartinEnder Normalmente, eu apenas faço o que Carlos fez aqui, pois a declaração é f=...que não tenho certeza se devemos adicionar o ponto e vírgula no final.
TheLethalCoder 07/07

13

CARACOL CINZENTO, 219 206 169 167 159 156 146 bytes (IO unário)

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

Eu acho que posso jogar isso um pouco.


Parabéns!
Keyu Gan

11

JavaScript (ES6), 31 28 27 bytes

Guardou alguns bytes graças a @Arnauld

Eu não tinha percebido que poderíamos falhar com uma exceção. Certamente isso é ótimo:

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

Atribua a uma variável com f=, por exemplo , e chame como f(climb)(fall)(height). Lança InternalError: too much recursionse a subida for impossível.


JavaScript (ES6), 38 bytes

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

Uma função recursiva que retorna o número de dias ou NaNpara nunca.

Casos de teste


2
Isso é óbvio: se o caracol fizer muita recursão , a escalada é impossível. :)
Tushar

1
Talvez 27 com uma sintaxe de curry invertida? d=>u=>g=h=>h>u?1+g(h-u+d):1
Arnauld

Graças @Arnauld, que funciona surpreendentemente bem ...
ETHproductions

Estou confuso quanto à contagem de bytes - em uma variável que a função está atribuída t está incluída, a outra não?
Exibir nome

@ Laransandlemons na versão superior, você tem g=no meio, porque essa variável armazena a função intermediária necessária para a chamada recursiva. A resposta mais longa faz uma chamada recursiva f, que exige que o nome seja incluído na contagem de bytes.
musicman523

10

Excel, 51 46 bytes

-1 byte graças a @ Scarabee .

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

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

Entrada obtida das células A1, B1 e C1, respectivamente. Retorna FALSEpara cenários inválidos.


ceiling(x)é sempre igual a -floor(-x), então eu acho que você poderia economizar 1 byte substituindo CEILING((A1-B1)/(B1-C1)+1,1)por -FLOOR((B1-A1)/(B1-C1)+1,1).
Scarabee

7

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

Somente no GCC de 32 bits e todas as otimizações desativadas.

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

Retorne 0 quando a solução for impossível. Uma versão modificada da solução recursiva original.

Inspirado nas soluções @Jonah J e @CarlosAlejo C #.

Atualizarei a versão expandida mais tarde (depois de terminar minha resposta do Grey Snail).


Agradável! você poderia incluir a solução analítica (não compactada)?
31516 koita_pisw_sou #

1
@koita_pisw_sou Claro.
Keyu Gan

Não "devolve" nada. Você atribui a um parâmetro local, cujo valor evapora quando a função retorna. O caracol está preso no limbo eterno.
Cody Grey

O @CodyGray usa um comportamento estável, porém indefinido, no GCC. Eu poderia mostrar um link mais tarde.
Keyu Gan


7

Java (OpenJDK 8) , 35 bytes

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

Experimente online!

A matemática vence!

Créditos


1
Já faz um tempo, mas a-c-1a+~c.
Kevin Cruijssen 26/03

1
Graças @KevinCruijssen Tem sido um tempo, mas o golfe é golfe, não importa quando isso acontece :-)
Olivier Grégoire

Meus pensamentos exatamente. Em algumas ocasiões, joguei metade dos meus bytes originais quando olhei para algumas das minhas primeiras respostas. ;)
Kevin Cruijssen 26/03

5

Python 2 , 37 bytes

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

Experimente online!

Finalmente consegui minha versão recursiva abaixo do meu cálculo padrão (estava passando uma contagem para minha função em vez de adicionar uma antes de chamá-la).

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

Experimente online!

Raspou 3 bytes trocando "__ e 1" por "__> 0".

Usando truques booleanos, essencialmente executa:

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
Você deve colocar f=na frente do seu código (a primeira solução) e sua contagem de bytes se tornará 37, porque é recursiva, para que você não possa deixá-lo anônimo. f=pode ser descartado para um lambda apenas quando não for recusativo.
Mr. Xcoder

Anotado e endereçado. Obrigado por me avisar.
Coty Johnathan Saxman

4

R, 43 bytes

Empréstimos de outras respostas:

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

Dá erro se não houver solução.


Boa resposta. Bem-vindo ao PPCG!
musicman523

3

J, 25 bytes

Primeiro, uma boa solução, que é uma trapaça, pois assume que "qualquer coisa que não seja um resultado inteiro positivo" é igual a "Nenhum":

>.>:%/2-/\

explicação

  • 2-/\use janelas de comprimento 2 em nossa entrada de 3 itens, colocando um sinal de menos entre cada uma, o que para a entrada 30 3 2, por exemplo, retorna27 1
  • %/ coloque um símbolo de divisão entre cada elemento da lista; no nosso caso, a lista possui apenas dois itens; portanto, "divida 27 por 1"
  • >: incremento de 1
  • >. pegue o teto

solução oficial

Aqui está a solução oficial que converte negativos e infinito em 0, cuja parte i não foi capaz de encontrar uma solução satisfatoriamente concisa 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.Para escrever os casos de teste, simplesmente escolhi Noneindicar que não havia resposta. Você também consideraria adicionar uma explicação e um link Experimente Online?
musicman523

@ musicman523 corrigido e pronto.
Jonah



2

Mathematica, 47 40 39 bytes

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

-7 bytes de @KeyuGan


Você precisa lidar com a entrada como 69, 3, 8e é contado como 3 bytes, tanto quanto eu penso.
Keyu Gan

tudo consertado! experimentá-lo agora #
J42161217

você pode usar Maxpara substituir a Ifinstrução. If[#<=#2,1,Max[⌈(#-#3)/(#2-#3)⌉,0]]&
Keyu Gan 07/07

2

Ruby , 49 47 bytes

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

Lança exceção se o caracol não puder subir

Experimente online!


1
@Jonah o corrigiu
Alex

Qual é o raciocínio por trás do processo? h-a<1?1:(1.0*(h-a)/[a-b,0].max+1).ceilpassa nos casos de teste e salva 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%

O segundo último caso de teste não imprimiu nada e o último caso de teste realmente travou CMD.EXE...


2

05AB1E , 19 bytes

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

Explicação:

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 inválidos, isso pode retornar qualquer valor menor que 1. No entanto, em 05AB1E, apenas 1 é verdadeiro; portanto, ele atende ao requisito de que a saída para um valor inválido seja falsa.

Experimente online!


2

PHP, 60 bytes

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

imprime Npara None. Corra com -r.



2

Japonês , 12 bytes

@UµV-W §W}aÄ

Teste online!

Resultados undefinedpara nunca, depois de possivelmente congelar o navegador por um tempo, portanto, tenha cuidado.

Não estou convencido de que isso seja ótimo. oWV-W lfunciona em todos, exceto nos últimos três casos ...


Cheguei com isso por 11 bytes, alterando a ordem das entradas.
Shaggy

2

Haskell , 30 29 bytes

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

Experimente online!

Mais curto que a resposta Haskell existente. Talvez alguém possa me derrotar.

Isso usa uma abordagem recursiva para resolver o problema. Cada recursão é essencialmente um dia de movimento para o caracol. Se a distância restante até o final for menor que a distância ainda necessária, encerramos nossa recursão.


Guardar 1 byte com a notação infix: (b#c)a=1+sum[(b#c)$a+c-b|a>b].
Laikoni 7/07

@Laikoni Não sabia que isso poderia ser feito. Obrigado pela dica.
Assistente de trigo

Você pode soltar os parênteses b!cna compreensão da lista.
Zgarb

2

QBIC , 31 23 bytes

Só notei que os requisitos foram alterados. Esta versão não verifica se o caracol chegará ao topo do poço.

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

A explicação abaixo, para a versão original que verifica se existe uma solução, também abrange todas as partes relevantes deste código.


Resposta original de 31 bytes:

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

Explicação

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

Experimente online! (OK, na verdade não: esta é uma tradução do código QBIC para QBasic executado no ambiente QBasic de repl.it (um pouco ausente))


2

Excel VBA, 47 bytes

Função de janela imediata VBE anônima que recebe entrada do intervalo [A1:C1]das ActiveSheetsaídas do objeto para a janela imediata VBE

Esta solução baseada principalmente na fórmula do Excel parece ser menor do que qualquer solução puramente VBA que eu possa apresentar :(

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

1

Haskell, 47 55 bytes (48 se necessário, tupla)

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

variação da tupla

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

Explicação

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. Você pode substituir d>c||c<sjustamente por 0<1, como já implicitamente faz na sua explicação, porque otherwiseé apenas um sinônimo de True. 2. A chamada recursiva na sua versão de tupla ainda está ativa. 3. Você pode definir sua função como em (d#c)svez de f d c ssalvar mais dois bytes.
Laikoni 7/07

1
Você também precisa em c<=svez de c<s.
Laikoni 7/07

1
Reordenar e usar em 0vez do -1permitido pelo OP gera 38 bytes: Experimente online!
Laikoni 07/07

1
Você pode usar um identificador de infixo para salvar bytes?
musicman523

Eu não sei, se eu deveria postar anser editado uma vez que é esentialy @ resposta 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 não recursiva. Usa a fórmula encontrada aqui . Pode ser reduzido em 6 bytes se "qualquer resultado negativo" for uma maneira válida de retornar falha; atualmente retorna 0.


Já faz um tempo, mas h-f-1pode ser h+~f.
Kevin Cruijssen 26/03

1

Python v2 e v3, 44 bytes

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

^ Recursão infinita (erro) para Nenhum caso.


Você pode usar lambda. Além disso, este parece semelhante à minha resposta (Java) para que permita-me sugerir uma melhora na fórmula: (x-z-1)//(y-z)+1. Eu não faço muito Python, por isso posso estar errado ...
Olivier Grégoire

Você pode eliminar f=a partir da contagem de bytes, remover alguns espaços em torno de ifs e elses, e mudar para Python 2, onde a divisão inteira é uma única/
musicman523

Obrigado @ musicman523. Acabei seguindo todos os seus conselhos.
precisa saber é o seguinte

1
Percebi que meu código "limpo" (sem recursão infinita) apresentava muitos problemas de maiúsculas quando usado com outras entradas (ou seja, 4, 3, 8). @ musicman523 Acho que estou começando a ver as "provas" de que você fala.
precisa saber é o seguinte

1

Calculadora programável HP-15C, 26 bytes

Os três números são carregados na pilha em ordem antes de executar o programa. A altura da queda é inserida como um número negativo. Se o caracol não puder sair do poço, o resultado será um número negativo ou um erro # 0 (erro de divisão zero).

Códigos op em 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

Significado das instruções:

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

Você pode experimentar o programa com este simulador HP-15C .


Isso é incrível! Bem-vindo ao PPCG :)
musicman523

1

Lisp comum, 49 bytes

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

Experimente online!

Função recursiva, estouro de pilha se nenhuma solução encontrada.


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.