Scala: 110
type B=BigInt
def r(a:B,b:B,f:(B,B)=>B):B=if(b>1)f(a,r(a,b-1,f))else a
def h(a:B,b:B)=r(a,b,r(_,_,r(_,_,(_+_))))
non golfé:
type B=BigInt
def recursive (a:B, b:B, f:(B,B)=>B): B =
if (b>1) f (a, recursive (a, b-1, f))
else a
recursive (2, 3, recursive (_, _, recursive (_, _, (_ + _))))
explication:
type B=BigInt
def p (a:B, b:B):B = a+b
def m (a:B, b:B):B = if (b>1) p (a, m (a, b-1)) else a
def h (a:B, b:B):B = if (b>1) m (a, h (a, b-1)) else a
def t (a:B, b:B):B = if (b>1) h (a, t (a, b-1)) else a
plus, mul, high (: = pow), tetration fonctionnent tous de la même manière. Le modèle commun peut être extrait en tant que méthode récursive, qui prend deux BigInts et une fonction de base:
def r (a:B, b:B, f:(B,B)=>B):B =
if (b>1) f(a, r(a, b-1, f)) else a
r (4, 3, r (_,_, r(_,_, (_+_))))
Les soulignements sont réservés pour quelque chose qui est appelé dans cette séquence, par exemple l'addition plus (a, b) = (a + b); donc ( + ) est une fonction qui prend deux arguments et les ajoute (a + b).
malheureusement, j'ai des problèmes avec la taille de la pile. Cela fonctionne pour de petites valeurs pour 4 (par exemple: 2) ou si je réduis la profondeur pour une étape:
def h(a:B,b:B)=r(a,b,r(_,_,(_*_))) // size -7, penalty + 5
def h(a:B,b:B)=r(a,b,r(_,_,r(_,_,(_+_))))
Le code d'origine est de 112 caractères et marquerait, s'il était valide, 107. Peut-être que je trouverai comment augmenter la pile.
L'algorithme étendu peut être transformé en appels récursifs:
type B=BigInt
def p(a:B,b:B):B=a+b
import annotation._
@tailrec
def m(a:B,b:B,c:B=0):B=if(b>0)m(a,b-1,p(a,c))else c
@tailrec
def h(a:B,b:B,c:B=1):B=if(b>0)h(a,b-1,m(a,c))else c
@tailrec
def t(a:B,b:B,c:B=1):B=if(b>0)t(a,b-1,h(a,c))else c
L'appel tailrecursive est plus long que la méthode d'origine, mais n'a pas déclenché de stackoverflow dans la version longue - mais il ne donne pas de résultat dans un délai raisonnable. t (2,4) est bien, mais t (3,3) a déjà été arrêté par moi après 5 min. Mais c'est très élégant, non?
// 124 = 119-5 bonus
type B=BigInt
def r(a:B,b:B,c:B,f:(B,B)=>B):B=if(b>0)r(a,b-1,f(a,c),f)else c
def t(a:B,b:B)=r(a,b,1,r(_,_,1,r(_,_,0,(_+_))))
Et maintenant la même chose que ci-dessus: utilisez la multiplication puante (nous profitons même en rejetant le bonus de 5, car nous économisons 7 caractères: win = 4 caractères :)
// 115 without bonus
type B=BigInt
def r(a:B,b:B,c:B,f:(B,B)=>B):B=if(b>0)r(a,b-1,f(a,c),f)else c
def t(a:B,b:B)=r(a,b,1,r(_,_,1,(_*_)))
invocation:
timed ("t(4,3)")(t(4,3))
t(4,3): 1
scala> t(4,3)
res89: B = 13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084096
durée d'exécution: 1 ms.
*
c'est la multiplication dans certains contextes, mais c'est aussi l'opérateur de bouclage simple:{block}N*
est équivalent au style Cfor(i=0;i<N;i++){block}
. Le cas délicat est la multiplication chaîne / tableau ('a'3*
donne'aaa'
), mais il est peu probable que ce soit un problème étant donné qu'un tableau d'4***3
éléments débordera de RAM.