Profundidade máxima de recursão [fechada]

15

Seu idioma possui uma profundidade de recursão máxima (MRD)?

Digamos que seu idioma tenha MRD = 500

Escreva um código que encontre a profundidade da recursão e produz o valor exato

Para o caso acima, seu programa (ou função) deve gerar 500

Code-Golf A resposta mais curta vence!


fonte
3
@cairdcoinheringaahing ... "que encontra a profundidade de recursão" significa hardcoding é inválido
6
Acho que o principal problema desse desafio é que não é permitido imprimir um valor codificado, mas a leitura de uma variável de sistema codificada é boa. Os dois realmente não parecem significativamente diferentes para mim.
DJMcMayhem
2
Os internos do @DJMcMayhem muitas vezes usam informações codificadas. Esse desafio permite embutidos.
7
Sim, esse é o meu ponto. Ambos estão simplesmente lendo um valor codificado, mas um é permitido e o outro não.
DJMcMayhem
3
O @DJMcMayhem embutido no mathematica também pode ter o sinalizador suíço (vi esse desafio aqui), mas postar o mesmo sinalizador que jpg é inválido.

Respostas:

49

Mathematica, 15 bytes

$RecursionLimit

¯ \ _ (ツ) _ / ¯

Experimente online!

J42161217
fonte
17
É claro que o Mathematica foi construído para isso! +1
caird coinheringaahing 31/08/17
1
Tenho que amar o Mathematica +1
JungHwan Min
Emacs Lisp na mesma linha (19): máx-cicio-EVAL profundidade
Caterpillar
19

Python 3 , 40 bytes

def f(x=2):
 try:f(x+1)
 except:print(x)

Experimente online!

Sem apenas ler a partir do builtin. Começamos com 2 em vez de 1 porque a cláusula de exceção é executada um nível antes de ocorrer um erro. Este é um byte mais curto no python 2, é claro.

FryAmTheEggman
fonte
1
Você não precisa de 3 bytes a chamada f
8bitwide
Os envios no @ 8bitwide como uma função são aceitos por padrão. A menos que a pergunta os proíba especificamente, você pode enviar uma função reutilizável como solução. Você notará que muitas outras respostas sobre essa pergunta fazem a mesma coisa.
FryAmTheEggman
15

JavaScript (Babel) , 35 33 29 bytes

f=_=>do{try{-~f()}catch(e){}}
  • 2 bytes salvos graças a Neil.

Experimente aqui ou use o Snippet abaixo para testá-lo em evalvez de do.

console.log((f=_=>eval(`try{-~f()}catch(e){}`))())


JaptPorta , 24 bytes

Não vale a pena postar isso como uma solução separada, pois é essencialmente idêntico.

Ox`try\{-~rp()}¯t®(e)\{}

Teste-o


Explicação

O próprio JavaScript não possui um limite de recursão propriamente dito, mas o limite é imposto pelo intérprete (ou seja, pelo navegador) - é bom definirmos idiomas pelo intérprete deles 'por aqui! Entre outros fatores, o limite pode variar de acordo com o navegador e a memória disponível, impactada pelas operações que estão sendo executadas. O Snippet a seguir ilustra esse último ponto, usando as 5 versões diferentes desta solução pelas quais passei. Como você pode ver nos dois últimos testes, no Chrome, pelo menos, até a ordem das operações pode fazer a diferença.

console.log((f=(i=0)=>eval(`try{f(i+1)}catch(e){i}`))())
console.log((f=i=>eval(`try{f(-~i)}catch(e){i}`))())
console.log((f=(i=0)=>eval(`try{f(++i)}catch(e){i}`))())
console.log((f=_=>eval(`try{-~f()}catch(e){}`))())
console.log((f=_=>eval(`try{f()+1}catch(e){0}`))())
console.log((f=_=>eval(`try{1+f()}catch(e){0}`))())

Sendo assim, não temos a conveniência de uma constante ou método para trabalhar. Em vez disso, vamos criar uma função que se autodenomina continuamente antes, eventualmente, de exagerar. Na sua forma mais simples, é:

f=_=>f()

Mas isso não nos serve muito para esse desafio, pois gera apenas um erro de estouro, sem indicação de quantas vezes se fchamou. Podemos evitar o erro trying ao chamadof continuamente e catching quando ele falhar:

f=_=>{try{f()}catch(e){}}

Sem erro, mas ainda sem valor de retorno de quantas vezes a função conseguiu se chamar antes de falhar, porque na catchverdade não está fazendo nada. Vamos tentar avaliar a try / catchdeclaração:

f=_=>eval(`try{f()}catch(e){}`)

Agora temos um valor a ser devolvido (e, porque este é o golfe código, salvo se estabeleceu alguns bytes sobre o uso de um real return). O valor retornado, no entanto, é undefinednovamente porque catchnão está fazendo nada. Felizmente para nós, -~undefined==1e -~n==n+1assim, pressionando um -~na frente da chamada f, basicamente recebemos -~-~ ... -~-~undefineduma outra -~anexada a cada chamada, fornecendo o número de vezes que ela ffoi chamada.

f=_=>eval(`try{-~f()}catch(e){}`)
Shaggy
fonte
Solução agradável, já que estou assumindo que você não tem acesso a uma profundidade de recursão embutida no JS!
Zacharý 31/08/19
3
33 bytes:f=_=>eval('try{-~f()}catch(e){}')
Neil
@ Neil: Eu vi sua versão de 34 bytes quando estava indo para a cama e me chutei por não ter pensado nisso. Essa versão de 33 bytes é inspirada. Obrigado.
Shaggy
13

Mathematica (sem embutido), 20 bytes

#0[#+1];&@1
%[[1,1]]

Omitir o ;cálculo 1+$IterationLimit(provavelmente porque o Mathematica otimiza a função da cauda). Como alternativa, 0 //. x_ -> x + 1calcule ReplaceRepeatedo padrão MaxIteration, ou seja, 65536(que é maior que os dois valores acima).

(Este é um trecho de código que avalia o resultado. No entanto, a outra solução Mathematica também é)

user202729
fonte
10

J, 8 bytes

1+$: ::]

Experimente online!

Portanto, eu realmente não sei como executar um verbo sem nenhuma entrada e algumas pesquisas breves (além de intuição pessoal) fazem parecer que isso não é possível. Se for o caso, informe-me como fazê-lo e excluirei ou atualizarei minha resposta. Realmente não faz sentido que um verbo não dê entrada. Em vista disso, a função fornecida espera 0, a entrada "vazia" padrão para números inteiros. Provavelmente posso alterá-lo para usar a matriz vazia ( 0$0) se você achar que isso é mais adequado.

Editar: o OP permitiu que a função assumisse 0.

Explicação

1+$: ::]
     ::]  Assign adverse: if an error occurs, call ] (the identify function)
1+        Add one to
  $:      Recursive call to self

Isso se chama recursivamente, adicionando 1 à entrada (0 esperado) até encontrar um erro de pilha. Quando erra, chama o adverso ( ]-right identity) na entrada, que é apenas 0.

A propósito, o espaço é necessário .

Cole
fonte
1
produz 6000 na minha máquina. fwiw eu acho que isso deve ser um jogo justo, mas você sempre pode dar sua resposta(1+$: ::]) 0
Jonah
@Jonah fair point, estou acostumado a enviar funções. Na minha máquina, é 6666 por incrível que pareça.
Cole
6660 em um iPad profissional. Legal!
Aganju 01/09
A maneira como ele lida com a profundidade máxima de recursão parece dependente da versão - no meu telefone, recebo 5999 (que parece estar desativado em 1). No meu iPad (sinceramente não me lembro de qual modelo), ele simplesmente trava.
Cole
9

Python 3 , 41 32 bytes

import sys
sys.getrecursionlimit

Experimente online!

Guardado 9 bytes graças a @FryAmTheEggman!

34 bytes

from sys import*
getrecursionlimit

35 bytes

__import__('sys').getrecursionlimit

Os últimos 2 são graças a @totallyhuman

caird coinheringaahing
fonte
32 bytes , 34 bytes e 35 bytes . Faça sua escolha. : P
totallyhuman
@FryAmTheEggman sim eu posso, obrigado!
caird coinheringaahing
Estou recebendo um erro (na TIO, pelo menos) ao tentar executar o primeiro 2.
Shaggy
@ Shaggy, você terá que trocar as linhas pela primeira, a importação será posterior para permitir que um nome seja atribuído ao builtin. Vou atualizar o link.
caird coinheringaahing 01/09/17
8

C (gcc, Linux x64), 180 133 bytes

-4 bytes graças a @scottinet

c;f(){f(++c);}h(){exit(printf("%d",c));}main(){int b[512];f(sigaction(11,(int*[]){h,[17]=1<<27},sigaltstack((int*[]){b,0,2048},0)));}

Experimente online!

Instala um manipulador SIGSEGV (sinal 11) com uma pilha de sinal alternativa (o tamanho mínimo MINSIGSTKSZé 2 KB, sinalizadorSA_ONSTACK é 0x08000000) e chama uma função sem argumentos e nenhuma variável local recursivamente até a pilha estourar. É interessante que a profundidade máxima da recursão varie entre as execuções, provavelmente devido ao ASLR.

A profundidade máxima de recursão em C depende de muitos fatores, é claro. Em um sistema Linux típico de 64 bits, o tamanho padrão da pilha é 8 MB e o alinhamento da pilha é 16 bytes; portanto, você obtém uma profundidade de recursão de cerca de 512K para funções simples.

Observe também que o programa acima não funciona -O2devido à otimização da chamada de cauda.

Nwellnhof
fonte
1
+1! Você pode salvar 4 bytes incrementando ce chamando exite sigactioncomo parâmetros. Isso não faz nenhuma diferença perceptível no resultado: link TIO
scottinet
6

Java 8, 131 51 48 47 43 bytes

int d;int c(){try{c();}finally{return++d;}}

-80 bytes graças a @Nevay . Eu tentei um método em vez de programa também, mas cometi um erro e acabei com um programa completo .. Agora é um método.
-3 bytes graças a @Neil , usando em finallyvez de catch(Error e).
-5 bytes graças a @Nevay novamente.

Explicação:

Experimente aqui.

int d;                 // Depth-integer `d` on class-level (implicit 0)
int c(){               // Method without parameter and integer return-type
  try{c();}            //  Recursive call
  finally{return++d;}  //  Increase depth-integer `d` and always return it,
                       //   whether a StackOverflowError occurs or not
}                      // End of method
Kevin Cruijssen
fonte
1
51 bytes: int c(){try{return-~c();}catch(Error e){return 1;}}
Nevay
2
@Nevay You often post excellent answers in comments. You could post them as answers, and get some reputations. Nothing forbids any question from having several Java answers. ;-)
Olivier Grégoire
2
int c(){int n=1;try{n=-~c();}finally{return n;}} saves 3 bytes but gives me a different answer?
Neil
2
47 bytes: int c(){int n=1;try{n+=c();}finally{return n;}}
Nevay
1
43 bytes: int d;int c(){try{c();}finally{return++d;}}
Nevay
4

Octave, 19 bytes

max_recursion_depth

Usage:

octave:1> max_recursion_depth
ans =  256
Ilya
fonte
4

R , 32 26 18 bytes

-8 bytes, graças a Sven Hohenstein : $fará a correspondência parcial, para que possamos usar em expvez da totalidade expressions.

cat(options()$exp)

O optionscomando também pode ser usado para definir a profundidade da recursão, ou seja, options(expressions=500)para 500.

Experimente online!

Giuseppe
fonte
1
Você pode salvar sete bytes removendo ressionsdevido à correspondência parcial com $.
Sven Hohenstein
1
Mais para referência futura do que como contribuição; é o consenso de que você precisa envolver isso em cat ()? R produzirá algo na maioria das circunstâncias, então existe um post em algum lugar esclarecendo boas práticas / lógicas a seguir?
CriminallyVulgar
@SvenHohenstein dang, I always forget about that after I write R code in good style...Thank you!
Giuseppe
1
@CriminallyVulgar veja, por exemplo, este post na meta; certamente há alguma incerteza sobre isso.
Giuseppe
4

Oitava , 25 22 20 bytes

2 bytes removidos graças a uma sugestão de Sanchises

@max_recursion_depth

Função anônima que gera o valor.

Experimente online!

Luis Mendo
fonte
Você não precisa do (), como max_recursion_depthtambém é uma função.
Sanchises
@Sanchises Thanks! Você está certo: mesmo que o documento diga que é uma variável, na verdade é uma função
Luis Mendo
Sua edição transformou isso em uma duplicata da outra resposta da Oitava, portanto, eu retive @para mantê-la distinta (definindo uma função em vez de REPL'ing o resultado).
Sanchises 02/09
@Sanchises Na verdade, eu só mudou que, embora por um motivo diferente (o código deve realmente definir uma função)
Luis Mendo
Sim, a outra resposta é mais como um programa; Eu não tenho certeza se isso realmente necessitam disp(I teria incluído, mas essa é a minha opinião pessoal sobre Octave REPL, e eu não estou certo de qualquer consenso meta nisso)
Sanchises
3

zsh, 24 bytes

f(){f $[++i];f};set -x;f

Experimente online! (Veja em debug)

bash, 24 bytes

f(){ f $[++i];};set -x;f

Experimente online!(Veja em debug)

ksh93, 27 bytes

f(){ f $(($1+1));};set -x;f

Experimente online!(Veja em debug)

traço, 27 bytes

f(){ f $(($1+1));};set -x;f

Experimente online! (Excede a saída de depuração, execute-a em seu próprio shell)

Thor
fonte
1
Deve i=0e echonão deve ser incluído na sua contagem de bytes?
Shaggy
@Shaggy: Talvez, eu tenha alterado para uma solução mais auto-contida
Thor
1

Lua , 52 bytes

f=load"b,e=pcall(f,(...or 3)+1)return b and e or..."

Experimente online!

ATaco
fonte
@ Shaggy, neste caso, sim, porque eu uso o nome f. Se isso não foi recursivo eu poderia fugir com não tê-la
Ataco
Ah, eu não manchar o fem pcall.
Shaggy
por que seu programa para em 200? aqui você pode ver que nessa função simples que vai além de 200. Se você remover o --que você pode confirmar que ele ainda é uma chamada recursiva sem otimizações
Felipe Nardi Batista
1

q / kdb +, 16 bytes

Solução:

{@[.z.s;x+1;x]}0

Exemplo:

/ solution
q){@[.z.s;x+1;x]}0
2000

/ without apply (try/catch)
q){.z.s x+1}0
'stack
@
{.z.s x+1}
2001

Explicação:

Tente recuar, aumente x em um a cada vez, se houver erro, retorne x.

{@[.z.s;x+1;x]}0 / the solution
{             }0 / call lambda function with 0
 @[    ;   ; ]   / @[function;argument;catch]
   .z.s          / call self (ie recurse)
        x+1      / increment x
            x    / return x if function returns error
rua
fonte
1

Excel-VBA, 26 bytes

?Application.MaxIterations

Não a profundidade da recursão propriamente dita, na verdade, gera o número máximo de iterações para uma célula em uma planilha do Excel. Dado que a saída pertence a um idioma diferente daquele em que está escrito, talvez isso seja mais apropriado:

Excel + Excel-Vba, 3 + 38 = 41 bytes

Function f:f=Application.MaxIterations

Como isso pode ser chamado de uma célula com

=f(

Para VBA sem construído em:

Excel-VBA, 53 44 40 bytes

-9 como variável não precisa mais ser inicializada ou impressa

-4, já que a execução do código não precisa mais ser finalizada para evitar várias impressões

Sub s:[A1]=[A1]+1:On Error Resume Next:s

Chame com s na janela imediata, para a célula A1 da planilha

(o aviso demora um pouco para ser executado agora, adicione Application.ScreenUpdating = Falseprimeiro)

Greedo
fonte
1

Lua , 45 37 bytes

x=2
f=load"x=x+1;f()"pcall(f)print(x)

Experimente online!

Não sei com qual valor inicializar, xpois não sei o número de chamadas intermediárias que existem ...

Felipe Nardi Batista
fonte
1

Clojure, 72 55 48 bytes

-23 bytes, livrando-se do átomo

-7 bytes graças a @madstap. Passou a usar fnmais defe #(), e prmais println.

((fn f[i](try(f(inc i))(catch Error e(pr i))))0)

Escrevi e testei no meu telefone. O aplicativo REPL Clojure me deu uma profundidade de 13087.

Solução básica. Recursar até que uma SO seja lançada, incrementando um contador a cada recursão. Quando é lançado, o valor do contador é impresso.

Carcinigenicado
fonte
Você pode salvar 5 bytes usando em prvez de println. Também -2 bytes, tornando o fn assim: em ((fn f[x](,,,))0)vez de (def f #(,,,))(f 0).
madstap 02/09
@madstap Thanks. Farei as alterações daqui a pouco.
Carcigenicate
1

VBA, qualquer tipo, 41 39 bytes

Function A:On Error Resume Next:A=A()+1

Ligue usando ?A() na janela Imediata ou como função da planilha.

Nota: Retorna 4613 no Excel-VBA, enquanto a resposta de @Greedo retorna 3666 no meu sistema (o mais alto deve ser o máximo). Aparentemente, também varia entre os programas do Office (o Access-VBA retorna 4622, o Word-VBA 4615)

Editar: acho que o VBA adiciona automaticamente parênteses, então as removeu.

Erik A
fonte
0

Pitão - 9 bytes

L.xyhbbyZ

Se eu puder executá-lo como a resposta J acima, isso significa 7 bytes, porque você pode remover o último yZ .

Experimente online aqui .

Maltysen
fonte
5
Isso não funciona para mim. Off-line, recebo uma falha de segmentação. Online, não recebo nenhuma saída. Você não pode pegar um segfault.
Isaacg 01/09
@isaacg espera, isso é realmente estranho. On-line, raramente dá 764, mas você está certo na maioria das vezes não dá saída.
Maltysen
0

Quarto, 48 bytes

Loops até atingir o limite.

: m 1+ recurse ;
: f 0 ['] m catch drop ; f .

Experimente online

mbomb007
fonte
0

Tcl , 49 bytes

proc R {i\ 1} {if [catch {R [incr i]}] {puts $i}}

Experimente online!

sergiol
fonte
0

Ruby, 39 bytes

END{p$.}
$stderr=$<
f=->{$.+=1;f[]}
f[]

Suprimir a mensagem de erro é um pouco menor do que resgatá-la, pois, por padrão, rescuenão é detectada SystemStackError.

Há uma resposta mais brega se eu puder imprimir em unário, representando n n caracteres de nova linha consecutivos:

Ruby, 35 bytes

$stderr=$<
f=->{puts;$.+=1;f[]}
f[]
histocrata
fonte
0

Gelatina , 18 bytes

:( *

“¡żuẋ×HẒpƙ7"8!ƭ»ŒV

Experimente online!

Quão?

* Desde o Jelly que eu saiba:
(1) define o limite de recursão do Python antes de configurar grande parte de seu próprio intérprete e analisar o código a ser executado; e
(2) não tem como detectar erros do Python.
Não tenho certeza se existe uma maneira de avaliar com segurança o limite de recursão ou imprimi-lo, pois ele é descoberto, exceto para perguntar ao Python qual foi o valor definido ( Eu adoraria ver se isso pode ser feito!) E é isso que o código aqui faz:

“¡żuẋ×HẒpƙ7"8!ƭ»ŒV - Link: no arguments
“¡żuẋ×HẒpƙ7"8!ƭ»   - compression of "sys."+"get"+"recursion"+"limit"+"()"
                ŒV - evaluate as Python code
Jonathan Allan
fonte