Profondità massima di ricorsione [chiuso]


15

La tua lingua ha una profondità massima di ricorsione (MRD)?

Supponiamo che la tua lingua abbia MRD = 500

Scrivi un codice che trova la profondità di ricorsione e genera il valore esatto

Nel caso sopra il tuo programma (o funzione) dovrebbe produrre 500

Code-Golf La risposta più breve vince!


3
@cairdcoinheringaahing ... "che trova la profondità di ricorsione" significa che la

6
Penso che il problema principale con questa sfida sia che la stampa di un valore hardcoded non è consentita, ma la lettura di una variabile di sistema hardcoded va bene. I due non mi sembrano molto diversi.
DJMcMayhem

2
Le funzioni integrate di @DJMcMayhem utilizzano molte volte informazioni codificate. Questa sfida consente incorporati.

7
Sì, questo è il mio punto. Entrambi stanno semplicemente leggendo un valore codificato, ma uno è permesso e l'altro no.
DJMcMayhem

3
@DJMcMayhem integrato in matematica può anche avere la bandiera svizzera (ho visto questa sfida qui), ma pubblicare la stessa bandiera come jpg non è valido.

Risposte:



19

Python 3 , 40 byte

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

Provalo online!

Senza solo leggerlo dall'integrato. Iniziamo da 2 invece di 1 perché la clausola exception viene eseguita a un livello prima di errori. Questo è un byte più breve in Python 2, ovviamente.


1
Non hai bisogno di 3 byte per chiamare f
bit wide

@ Le presentazioni a 8 bit in tutto il mondo sono accettate per impostazione predefinita. A meno che la domanda non li proibisca specificamente, è possibile inviare una funzione riutilizzabile come soluzione. Noterai che molte altre risposte su questa domanda fanno la stessa cosa.
FryAmTheEggman,

15

JavaScript (Babele) , 35 33 29 byte

f=_=>do{try{-~f()}catch(e){}}
  • 2 byte salvati grazie a Neil.

Provalo qui o usa lo snippet qui sotto per testarlo evalinvece di do.

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


Porta Japt , 24 byte

Non vale davvero la pena pubblicarlo come soluzione separata in quanto sostanzialmente identico.

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

Provalo


Spiegazione

JavaScript stesso non ha un limite di ricorsione di per sé, piuttosto il limite è imposto dall'interprete (cioè dal browser) - buona cosa definiamo le lingue dal loro interprete qui intorno! Tra gli altri fattori, il limite può variare in base al browser e alla memoria disponibile, influenzata dalle operazioni eseguite. Il seguente frammento illustra l'ultimo punto, utilizzando le 5 diverse versioni di questa soluzione che ho esaminato. Come puoi vedere dagli ultimi 2 test, almeno in Chrome, anche l'ordine delle operazioni può fare la differenza.

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}`))())

Detto questo, non abbiamo quindi la comodità di una costante o di un metodo con cui lavorare. Invece, creeremo una funzione che si chiama continuamente prima, eventualmente, di rompersi. Nella sua forma più semplice che è:

f=_=>f()

Ma non ci è molto utile per questa sfida in quanto genera solo un errore di overflow senza alcuna indicazione di quante volte si è fchiamato. Possiamo evitare l'errore trying di chiamare fcontinuamente e catching quando fallisce:

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

Nessun errore, ma ancora nessun valore di ritorno di quante volte la funzione è riuscita a chiamare se stessa prima di fallire, perché in catchrealtà non sta facendo nulla. Proviamo a valutare l' try / catchaffermazione:

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

Ora abbiamo un valore che viene restituito (e, poiché si tratta di codice golf, ci siamo risparmiati qualche byte usando un valore reale return). Il valore restituito, tuttavia, è undefined, ancora una volta perché catchnon sta facendo nulla. Fortunatamente per noi -~undefined==1e -~n==n+1così, facendo scoppiare un -~davanti alla chiamata f, abbiamo essenzialmente -~-~ ... -~-~undefined, con un altro -~anteposto ad ogni chiamata, dandoci il numero di volte che è fstato chiamato.

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

Bella soluzione, dato che suppongo che tu non abbia accesso a una profondità di ricorsione integrata in JS!
Zacharý,

3
33 byte:f=_=>eval('try{-~f()}catch(e){}')
Neil,

@Neil: ho visto la tua versione da 34 byte mentre stavo andando a letto e mi sono preso a calci per non pensarci. Quella versione da 33 byte è ispirata. Grazie.
Shaggy

13

Mathematica (non integrato), 20 byte

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

Omettendo il ;calcolo verrà calcolato 1+$IterationLimit(probabilmente perché Mathematica ottimizza la coda della funzione). In alternativa, 0 //. x_ -> x + 1calcola ReplaceRepeatedil valore predefinito MaxIteration, ovvero 65536(che è maggiore di entrambi i valori sopra).

(Questo è uno snippet di codice che valuta il risultato. Comunque è anche l'altra soluzione Mathematica)


10

J, 8 byte

1+$: ::]

Provalo online!

Quindi, in realtà non so come eseguire un verbo senza alcun input e una breve ricerca (così come l'intuizione personale) fa sembrare che non sia possibile. Se lo è, per favore fatemi sapere come fare e cancellerò o aggiornerò la mia risposta. Tuttavia, non ha davvero senso che un verbo non riceva alcun input. Alla luce di ciò, la funzione fornita si aspetta0 l'input "vuoto" predefinito per gli interi. Probabilmente posso cambiarlo per usare l'array vuoto ( 0$0) se pensi che sia più adatto.

Modifica: l'OP ha consentito alla funzione di accettare 0.

Spiegazione

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

Questo si chiama ricorsivamente, aggiungendo 1 all'input (0 previsto) fino a quando non si verifica un errore di stack. Quando sbaglia, chiama il contrario (] l'input -right identity) sull'input, che è solo 0.

A proposito, lo spazio è necessario .


1
produce 6000 sulla mia macchina. prima penso che questo dovrebbe essere un gioco equo, ma puoi sempre solo dare la tua risposta(1+$: ::]) 0
Giona

@Jonah punto giusto, sono abituato a presentare funzioni. Sulla mia macchina, 6666 è stranamente abbastanza.
Cole

6660 su un iPad pro. Freddo!
Aganju,

Il modo in cui gestisce la massima profondità di ricorsione sembra dipendere dalla versione - sul mio telefono ottengo 5999 (che sembra essere spento da 1). Sul mio iPad (sinceramente non ricordo quale modello), si blocca e basta.
Cole

9

Python 3 , 41 32 byte

import sys
sys.getrecursionlimit

Provalo online!

Salvato 9 byte grazie a @FryAmTheEggman!

34 byte

from sys import*
getrecursionlimit

35 byte

__import__('sys').getrecursionlimit

Gli ultimi 2 sono grazie a @totallyhuman


32 byte , 34 byte e 35 byte . Fai la tua scelta. : P
totalmente umano

@FryAmTheEggman si posso, grazie!
caird coinheringaahing

Ricevo un errore (almeno su TIO) quando provo a eseguire il primo 2.
Shaggy

@Shaggy dovrai scambiare le righe con la prima, l'importazione segue per consentire l'assegnazione di un nome al file incorporato. Aggiornerò il link.
caird coinheringaahing

8

C (gcc, Linux x64), 180 133 byte

-4 byte grazie 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)));}

Provalo online!

Installa un gestore SIGSEGV (segnale 11) con uno stack di segnali alternativo (la dimensione minima MINSIGSTKSZè 2 KB, flagSA_ONSTACK è 0x08000000), quindi chiama una funzione senza argomenti e nessuna variabile locale ricorsivamente fino a quando lo stack non trabocca. È interessante notare che la profondità massima di ricorsione varia tra le serie, probabilmente a causa dell'ASLR.

La profondità massima di ricorsione in C dipende ovviamente da molti fattori. Su un tipico sistema Linux a 64 bit la dimensione dello stack predefinita è 8 MB e l'allineamento dello stack è di 16 byte, quindi si ottiene una profondità di ricorsione di circa 512 KB per funzioni semplici.

Si noti inoltre che il programma sopra non funziona a -O2causa dell'ottimizzazione delle chiamate di coda.


1
+1! È possibile salvare 4 byte incrementando ce chiamando exite sigactioncome parametri. Ciò non fa alcuna differenza sul risultato: collegamento TIO
scottinet,

6

Java 8, 131 51 48 47 43 byte

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

-80 byte grazie a @Nevay . Ho provato un metodo al posto del programma, ma ho fatto un errore, quindi ho finito con un programma completo .. Ora è un metodo.
-3 byte grazie a @Neil usando finallyinvece di catch(Error e).
-5 byte grazie di nuovo a @Nevay .

Spiegazione:

Provalo qui.

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

1
51 byte:int c(){try{return-~c();}catch(Error e){return 1;}}
Nevay,

2
@Nevay Spesso pubblichi risposte eccellenti nei commenti. Potresti pubblicarli come risposte e ottenere una reputazione. Nulla impedisce a qualsiasi domanda di avere diverse risposte Java. ;-)
Olivier Grégoire,

2
int c(){int n=1;try{n=-~c();}finally{return n;}}salva 3 byte ma mi dà una risposta diversa?
Neil,

2
47 byte:int c(){int n=1;try{n+=c();}finally{return n;}}
Nevay,

1
43 byte:int d;int c(){try{c();}finally{return++d;}}
Nevay,

4

Ottava, 19 byte

max_recursion_depth

Uso:

octave:1> max_recursion_depth
ans =  256

4

R , 32 26 18 byte

-8 byte grazie a Sven Hohenstein : $eseguirà una corrispondenza parziale, quindi possiamo semplicemente usare al expposto del pieno expressions.

cat(options()$exp)

Il optionscomando può anche essere usato per impostare la profondità di ricorsione, cioè options(expressions=500)per 500.

Provalo online!


1
È possibile salvare sette byte rimuovendoli a ressionscausa della corrispondenza parziale con $.
Sven Hohenstein,

1
Più per riferimento futuro che come contributo; è il consenso che è necessario racchiudere in cat ()? R produrrà qualcosa nella maggior parte dei casi, quindi c'è un post da qualche parte che chiarisce le buone pratiche / la logica da seguire?
CriminallyVulgar

@SvenHohenstein dang, me ne dimentico sempre dopo aver scritto il codice R in buon stile ... Grazie!
Giuseppe,

1
@CriminallyVulgar vedi ad esempio questo post in meta; c'è sicuramente qualche incertezza al riguardo.
Giuseppe,

4

Ottava , 25 22 20 byte

2 byte rimossi grazie a un suggerimento di Sanchises

@max_recursion_depth

Funzione anonima che genera il valore.

Provalo online!


Non è necessario (), poiché max_recursion_depthè anche una funzione.
Sanchises,

@Sanchising Grazie! Hai ragione: anche se il documento dice che è una variabile, in realtà è una funzione
Luis Mendo,

La tua modifica ha trasformato questo in un duplicato dell'altra risposta di Ottava, quindi il mio trattenuto @per tenerlo distinto (definendo una funzione piuttosto che REPL'e il risultato).
Sanchises,

@Sanchise In realtà l'ho appena cambiato, anche se per un motivo diverso (il codice dovrebbe effettivamente definire una funzione)
Luis Mendo,

Sì, l'altra risposta è più simile a un programma; Non sono sicuro se ciò dovrebbe effettivamente richiedere disp(l'avrei incluso, ma questa è la mia opinione personale su Octave REPL, e non sono sicuro di alcun meta consenso al riguardo)
Sanchises,

3

zsh, 24 byte

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

Provalo online!(Vedi sotto debug)

bash, 24 byte

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

Provalo online!(Vedi sotto debug)

ksh93, 27 byte

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

Provalo online!(Vedi sotto debug)

trattino, 27 byte

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

Provalo online! (Supera l'output di tio debug, eseguilo nella tua shell)


1
Dovrebbero i=0e echonon essere inclusi nel conteggio dei byte?
Shaggy

@Shaggy: Forse l'ho cambiato in una soluzione più autonoma
Thor

1

Lua , 52 byte

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

Provalo online!


@Shaggy in questo caso sì, perché uso il nome f. Se questo non fosse ricorsivo, potrei
cavarmela

Ah, non ho posto l' fin pcall.
Shaggy

perché il tuo programma si ferma a 200? qui puoi vedere che in quella semplice funzione va oltre 200. se lo rimuovi --puoi confermare che è ancora una chiamata ricorsiva senza ottimizzazioni
Felipe Nardi Batista

1

q / kdb +, 16 byte

Soluzione:

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

Esempio:

/ 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

Spiegazione:

Prova a ricorrere, aumenta x di uno ogni volta, se l'errore restituisce 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

1

Excel-VBA, 26 byte

?Application.MaxIterations

Non una profondità di ricorsione di per sé, ciò genera effettivamente il numero massimo di iterazioni per una cella in un foglio di lavoro di Excel. Dato che l'output appartiene a una lingua diversa dalla lingua in cui è scritto, forse questo è più appropriato:

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

Function f:f=Application.MaxIterations

Come può essere chiamato da una cella con

=f(

Per VBA senza built-in:

Excel-VBA, 53 44 40 byte

-9 poiché la variabile non deve più essere inizializzata o stampata

-4 poiché l'esecuzione del codice non deve più essere terminata per evitare stampe multiple

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

Chiama con s nella finestra immediata, visualizza la cella A1 del foglio di lavoro

(l'avviso richiede un po 'di tempo per essere eseguito ora, aggiungi Application.ScreenUpdating = Falseprima)



1

Clojure, 72 55 48 byte

-23 byte eliminando l'atomo

-7 byte grazie a @madstap. Passato a usare fnover defe #(), e prover println.

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

Scritto e testato sul mio telefono. L'app Clojure REPL mi ha dato una profondità di 13087.

Soluzione di base. Recurse fino a quando non viene generata una SO, incrementando un contatore per ogni recurse. Quando viene lanciato, viene stampato il valore del contatore.


È possibile salvare 5 byte utilizzando prinvece di println. Anche -2 byte rendendo il fn in questo modo: ((fn f[x](,,,))0)invece di (def f #(,,,))(f 0).
Madstap,

@madstap Grazie. Apporterò le modifiche tra un po '.
Carcigenicato

1

VBA, qualsiasi tipo, 41 39 byte

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

Chiama utilizzando ?A()nella finestra immediata o come funzione del foglio di lavoro.

Nota: Returns 4613 in Excel-VBA, while the answer by @Greedo returns 3666 on my system (highest should be the max). Apparently also varies between Office programs (Access-VBA returns 4622, Word-VBA 4615)

Modifica: indovina VBA aggiunge automaticamente le parentesi, quindi rimuovile.


0

Pyth - 9 byte

L.xyhbbyZ

If I can run it like the J answer above, this is 7 bytes because you can take out the last yZ.

Try it online here.


5
This doesn't work for me. Offline, I get a segmentation fault. Online, I get no output at all. You can't catch a segfault.
isaacg

@isaacg wait this is really weird. Online, it rarely gives 764, but you're right most of the time it gives no output.
Maltysen




0

Ruby, 39 bytes

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

Suppressing the error message is a little shorter than rescuing it, since by default rescue doesn't catch SystemStackError.

There's a cheesier answer if I can output in unary, representing n with n consecutive newline characters:

Ruby, 35 bytes

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

0

Jelly, 18 bytes

:( *

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

Try it online!

How?

* Since Jelly as far as I am aware:
(1) sets the Python recursion limit prior to setting up much of its own interpreter and parsing the code to be run; and
(2) has no way of catching Python errors
I'm not sure if there is a way to either reliably evaluate the recursion limit or to print it out as it is discovered other than to actually ask Python what the value was set to (I'd love to see if it can be done though!) so that's what the code here does:

“¡ż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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.