Jouez au golf un nombre plus grand que le nombre de Loader

18

En tant que suivi du programme de terminaison le plus court dont la taille de sortie dépasse le nombre de Graham et Golf un nombre plus grand que TREE (3) , je présente un nouveau défi.

Le nombre de Loader est un très grand nombre, ce qui est un peu difficile à expliquer (car il était lui-même le résultat d'un exercice de golf avec un objectif flexible). Il y a une définition et une explication ici , mais à des fins d'auto-confinement, je vais essayer de l'expliquer plus tard dans ce post également.

L'algorithme utilisé par Ralph Loader produit l'un des plus grands nombres d'algorithmes (calculables) jamais écrits! En effet, le numéro de Loader est le plus grand numéro «calculable» du Googology Wiki. (Par nombre "calculable", ils signifient un nombre défini en termes de calcul.) Cela signifie que si la réponse produit un nombre supérieur au nombre de Loader d'une manière intéressante (c'est-à-dire pas seulement le numéro de Loader + 1), vous pouvez descendre dans Histoire de la googologie! Cela étant dit, les programmes qui produisent quelque chose comme Loader number + 1 sont certainement des réponses valides et des candidats à cette question; ne vous attendez pas à la gloire.

Votre travail consiste à créer un programme de terminaison qui produit un nombre supérieur au nombre de Loader. C'est le , donc le programme le plus court gagne!

  • Vous n'êtes pas autorisé à prendre des commentaires.
  • Votre programme doit finalement se terminer de façon déterministe mais vous pouvez supposer que la machine a une mémoire infinie.
  • Vous pouvez supposer que le type de numéro de votre langue peut contenir n'importe quelle valeur finie mais devez expliquer comment cela fonctionne exactement dans votre langue (ex: un flotteur a-t-il une précision infinie?)
    • Les infinis ne sont pas autorisés en sortie.
    • Le dépassement de capacité d'un type de nombre lève une exception. Il ne s'enroule pas.
  • Vous devez fournir une explication de la raison pour laquelle votre numéro est si important et une version non golfée de votre code pour vérifier si votre solution est valide (car il n'y a pas d'ordinateur avec suffisamment de mémoire pour stocker le numéro de Loader).

Voici donc une explication du numéro de Loader. Voir http://googology.wikia.com/wiki/Loader%27s_number et les liens qui s'y trouvent pour des détails plus précis. En particulier, il contient un programme qui produit exactement le numéro de Loader (par définition).

Le calcul des constructions est essentiellement un langage de programmation aux propriétés très particulières.

Tout d'abord, chaque programme syntaxiquement valide se termine. Il n'y a pas de boucles infinies. Cela sera très utile, car cela signifie que si nous exécutons un programme de calcul arbitraire de constructions, notre programme ne restera pas bloqué. Le problème est que cela implique que le calcul des constructions n'est pas Turing complet.

Deuxièmement, parmi les langues complètes non-Turing, c'est l'un des plus puissants. Essentiellement, si vous pouvez prouver qu'une machine de Turing s'arrêtera à chaque entrée, vous pouvez programmer une fonction dans le calcul des constructions qui la simulera. (Cela ne rend pas le turing complet, car il existe des machines de turing à l'arrêt dont vous ne pouvez pas prouver qu'elles s'arrêtent.)

Le numéro du chargeur est essentiellement un numéro de castor occupé pour le calcul des constructions, qui est possible à calculer puisque tous les programmes coc se terminent.

En particulier, loader.c définit une fonction appelée D. Approximativement, D(x)itère moins que toutes les chaînes de bits x, les interprète comme des programmes coc, exécute les chaînes syntaxiquement valides et concatène les résultats (qui seront également des chaînes de bits). Il renvoie cette concaténation.

Le numéro du chargeur est D(D(D(D(D(99))))).

Une copie plus lisible du code du wiki de googolologie

int r, a;

P(y,x){return y- ~y<<x;}

Z(x){return r = x % 2 ? 0 : 1 + Z (x / 2 );}

L(x){return x/2 >> Z(x);}

S(v,y,c,t){
   int f = L(t);         
   int x = r;
   return f-2 ? f>2 ? f-v ? t-(f>v)*c : y : P(f,P(S(v,y,c,L(x)), S(v+2,t=S(4,13,-4,y),c,Z(x)))) : A(S(v,y,c,L(x)),S(v,y,c,Z(x)));
}

A(y,x){return L(y)-1 ? 5<<P(y,x) : S(4,x,4,Z(r));}

D(x) 
{
   int f;
   int d;
   int c=0;
   int t=7;
   int u=14;
   while(x&&D(x-1),(x/=2)%2&&(1)){
      d = L(L(D(x))),
      f = L(r),
      x = L(r),
      c - r||(L(u)||L(r)-f||(x/=2)%2&&(u=S(4,d,4, r),t=A(t,d)),f/2&(x/=2)%2&&(c=P(d,c),t=S(4,13,-4,t),u=S(4,13,-4,u))),
      c&&(x/=2)%2&&(t=P(~u&2|(x/=2)%2&&(u=1<<P(L(c),u)),P(L(c),t)),c=r)
      u/2&(x/=2)%2&&(c=P(t,c),u=S(4,13,-4,t),t=9);
    }
    return a = P( P( t, P( u, P( x, c)) ),a);
}

main(){return D(D(D(D(D(99)))));}
PyRulez
la source
6
Je déconseille de voter pour cette similitude avec la question TREE (3): le nombre de Loader est tellement plus grand que TREE (3) que de nouvelles approches intéressantes sont nécessaires.
lirtosiast
2
@ fəˈnɛtɪk Eh bien, imprimer le numéro du chargeur + 1 est toujours intéressant du point de vue du code de golf (par exemple, pouvez-vous battre les 512 octets d'origine?) Il existe également des généralisations naturelles du numéro du chargeur qui pourraient être plus faciles à implémenter (par exemple, en utilisant ZFC au lieu de CoC). En outre, des séquences de clique gourmandes ou des jeux à promesses finies pourraient être utilisés.
PyRulez
2
Malheureusement, comme je ne comprends pas la construction du nombre de Loader et qu'il ne semble pas y avoir de limites supérieures connues en termes de hiérarchie en croissance rapide, je ne peux pas donner de bonnes réponses ici. Je crois que la plupart des réponses seront des extensions du nombre de Loader ou des choses comme les séquences de clique gourmandes et les jeux de promesses finies ...
Simply Beautiful Art
1
@SimplyBeautifulArt Oh mon garçon, si vous ne le comprenez pas, cela n'augure rien de bon pour ce défi. : PI pourrait essayer de vous l'expliquer plus en détail dans le chat, mais je ne connais pas non plus de limites supérieures de hiérarchie.
PyRulez
1
@SimplyBeautifulArt En particulier, étant donné que la constante de Loader a été spécifiquement choisie pour essayer d'être le plus grand nombre généré par une certaine quantité de code (alors que le nombre de Graham et TREE (3) à des nombres mathématiquement intéressants qui se trouvent être gros), je pense que la plupart des réponses ne seront que le numéro du chargeur + 1.
PyRulez

Réponses:

9

JavaScript, D ^ 6 (9) ( 508 501 495 492 487 485 481 octets)

_='r=a=0,PN,yEx-~x<<y,ZNEr=x%2?0:1+ZC>>1@LNEx/2>>ZC@S=Bt,f=Ht@x=rEf-2?f>2?f-v?t-(f>v)*c:y:Ff,FSO(v+2,t8y@c,ZCMM:A(AOBZC)GAN,yELC)-1?5<<PC,y):Iy,4,Z(rGDN,f,dQ=0,t=7,u=14Eeval("whileC&&DC-1@61Md=HHDC)Gf=Hr@x=Hr@c-r||(Hu)||Hr)-f||6u=Id,4,r@t=A(t,dGfJdQ@t8t@u8u)Gc&&6t=F~u&2|6u=1<<FHc@uGFHc@tGc=r@uJtQ@u8t@t=9);a=FFt,Fu,PCQ)Ga)"@KKK9MMM6C>>=1)%2&&(8=I13,-4,G)@@),B(v,yQ,N=COBLCGSC(xE)=>J/2&6c=FFP(HL(IS(4,KD(D(M))Q,c';for(Y of $='QMKIHFJECONB@G86')with(_.split(Y))_=join(pop());eval(_)

Ceci est un code codé.

_='r=a=0,PN,yEx-~x<<y,ZNEr=x%2?0:1+ZC>>1@LNEx/2>>ZC@S=Bt,f=Ht@x=rEf-2?f>2?f-v?t-(f>v)*c:y:Ff,FSO(v+2,t8y@c,ZCMM:A(AOBZC)GAN,yELC)-1?5<<PC,y):Iy,4,Z(rGDN,f,dQ=0,t=7,u=14Eeval("whileC&&DC-1@61Md=HHDC)Gf=Hr@x=Hr@c-r||(Hu)||Hr)-f||6u=Id,4,r@t=A(t,dGfJdQ@t8t@u8u)Gc&&6t=F~u&2|6u=1<<FHc@uGFHc@tGc=r@uJtQ@u8t@t=9);a=FFt,Fu,PCQ)Ga)"@KKK9MMM6C>>=1)%2&&(8=I13,-4,G)@@),B(v,yQ,N=COBLCGSC(xE)=>J/2&6c=FFP(HL(IS(4,KD(D(M))Q,c'; //encoded code
for(Y of $='QMKIHFJECONB@G86')with(_.split(Y))_=join(pop()); //decoding algorithm
eval(_) //Evaluation of the string

Code décodé:

r=a=0,P=(x,y)=>x-~x<<y,Z=(x)=>r=x%2?0:1+Z(x>>1),L=(x)=>x/2>>Z(x),S=(v,y,c,t,f=L(t),x=r)=>f-2?f>2?f-v?t-(f>v)*c:y:P(f,P(S(v,y,c,L(x)),S(v+2,t=S(4,13,-4,y),c,Z(x)))):A(A(v,y,c,L(x)),S(v,y,c,Z(x))),A=(x,y)=>L(x)-1?5<<P(x,y):S(4,y,4,Z(r)),D=(x,f,d,c=0,t=7,u=14)=>eval("while(x&&D(x-1),(x>>=1)%2&&(1))d=L(L(D(x))),f=L(r),x=L(r),c-r||(L(u)||L(r)-f||(x>>=1)%2&&(u=S(4,d,4,r),t=A(t,d)),f/2&(x>>=1)%2&&(c=P(d,c),t=S(4,13,-4,t),u=S(4,13,-4,u))),c&&(x>>=1)%2&&(t=P(~u&2|(x>>=1)%2&&(u=1<<P(L(c),u)),P(L(c),t)),c=r),u/2&(x>>=1)%2&&(c=P(t,c),u=S(4,13,-4,t),t=9);a=P(P(t,P(u,P(x,c))),a)"),D(D(D(D(D(D(9))))))

Code décodé et non golfé (les conditions et les trucs sont conservés de loader.c):

var r=a=0;
function P(y,x){
  return y-~y<<x;
}
function Z(x){
  return r=x%2?0:1+Z(x>>1);
}
function L(x){
  return x/2>>Z(x);
}
function S(v,y,c,t){
  var f=L(t),x=r;
  return f-2?
           f>2?
             f-v?
               t-(f>v)*c
               :y
             :P(f,P(S(v,y,c,L(x)),S(v+2,t=S(4,13,-4,y),c,Z(x))))
           :A(S(v,y,c,L(x)),S(v,y,c,Z(x)))
}
function A(y,x){
  return L(y)-1?
         5<<P(y,x):
         S(4,x,4,Z(r));
}
function D(x){
  var f,
      d,
      c=0,
      t=7,
      u=14;
  while(x&&D(x-1),(x>>=1)%2&&(1))
    d=L(L(D(x))),
    f=L(r),
    x=L(r),
    c-r||(
      L(u)||L(r)-f||
      (x>>=1)%2&&(
        u=S(4,d,4,r),t=A(t,d)
      ),
      f/2&(x>>=1)%2&&(
        c=P(d,c),
        t=S(4,13,-4,t),
        u=S(4,13,-4,u)
      )
    ),
    c&&(x>>=1)%2&&(
      t=P(
        ~u&2|(x>>=1)%2&&(
          u=1<<P(L(c),u)
        ),
        P(L(c),t)
      ),
      c=r
    ),
    u/2&(x>>=1)%2&&(
      c=P(t,c),
      u=S(4,13,-4,t),
      t=9
    );
  return a=P(P(t,P(u,P(x,c))),a)
};
D(D(D(D(D(D(9))))))

En cela, il est supposé être:

  • Pile d'appel infinie
  • Mémoire infinie
  • Précision infinie Number
  • Magnitude infinie Number
  • Les opérateurs Bitshift et bitwise fonctionnent sur des entiers infinis au lieu de 53 bits. La négation au niveau du bit annule toujours le bit de signe.

Algorithme d'encodage / décodage:

L'encodage se fait comme suit:

  • Prenez une chaîne répétée, appelez-la S.
  • Remplacez tous les S du code par une clé K.
  • Mettez K et S à la fin.
  • Faites une liste de clés et mettez également un algorithme de décodage pour que le code s'exécute réellement.

L'algorithme de décodage:

  • Prenez la liste des clés.
  • Prenez la première clé K.
  • Divisez la chaîne pour chaque K.
  • Étant donné que le dernier du tableau est ce qu'il faut remplacer KS, éclatez-le et remplacez tout K en joignant le tableau avec la valeur sautée S.

La compression a été effectuée avec ce code , cochez uniquement la dernière case. Étant donné que cela encodera la plus grande sauvegarde en premier, ce n'est pas la compression la plus efficace, mais je ne sais pas non plus comment la rendre plus petite.

JavaScript, (339 caractères )

eval("_㴧爽愽〬偍ⱹ䕸⵾砼㱹ⱚ䵅爽砥㈿〺ㄫ婃㸾ㅀ䱍䕸⼲㸾婃䁓㵂琬昽䡴䁸㵲䕦ⴲ㽦㸲㽦⵶㽴⴨显瘩⩣㩹㩆昬䙓丨瘫㈬琸祀挬婃䭋㩁⡁乂婃⥇䅍ⱹ䕌䌩ⴱ㼵㰼偃ⱹ⤺匨㐬礬㐬娨片䑍ⱦⱤⱣ㴰ⱴ㴷Ⱶ㴱㑅敶慬⠢睨楬敃☦䑃ⴱ䀶ㅋ搽䡈䑃⥇昽䡲䁸㵈牀挭牼簨䡵⥼籈爩ⵦ籼㙵㵓⠴ⱤⰴⱲ䁴㵁⡴Ɽ䝦䥤Ᵽ䁴㡴䁵㡵⥇挦☶琽䙾甦㉼㙵㴱㰼䙈捀畇䙈捀瑇挽牀畉琬捀甸瑀琽㤩㭡㵆䙴ⱆ甬偃Ᵽ⥇愩≀䩊䨹䭋䬶䌾㸽ㄩ┲☦⠸㵓⠴ⰱ㌬ⴴⱇ⥀䀩ⱂ⡶ⱹⱣⱍ㵃乂䱃䝓䌨硅⤽㹉⼲☶挽䙆倨䡌⡊䐨䐨䬩⤧㭦潲⡙映␽❋䩈䙉䕃乍䉀䜸㘧⥷楴栨弮獰汩琨天⥟㵪潩渨灯瀨⤩㭥癡氨弩".split``.map(a=>(d=String.fromCharCode)((c=a.charCodeAt())>>8)+d(c&255)).join``.slice(1))

Ce code prendra la chaîne de 16 bits comme un, la convertira en chaîne de 8 bits avec le même binaire (BE), et evalce.

Le code décodé est le code codé ci-dessus.

Preuve que D ^ 6 (9)> D ^ 5 (99)

Pour cela, nous comparerions D (9) et 99.

En exécutant manuellement le code, D (9) est trouvé égal à (15*2^14849+1)*2^((15*2^14849+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^929+1)*2^((15*2^929+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^(15*2^59+1)))))))))))))))))))))))))))))))), et même D (0) est égal à 8646911284551352321.

Donc, D (9) >>> 99, et parce que D est strictement croissant, D ^ 6 (9)> D ^ 5 (99).

  • 508B-> 501B, -7B
    • -1B pour ... je ne sais pas pourquoi. J'ai changé D(D(D(D(D(99)))))pourD(D(D(D(D(D(9)))))) . Cela a également mélangé les lettres.
    • -6b pour re ajoutée &&(1)pour D(x)la condition de la boucle de.
  • 501B-> 495B, -6B
    • Correction de la plupart des /2s à >>1s carNumber
    • Sauvegarde de 6 octets quelque part
    • Vous pouvez voir ma tentative dans cette mise à jour ici
  • 495-> 492B, -3B
    • En changeant le décodeur de for...inà for...of.
  • 492-> 487B, -5B
    • Suppression des affectations inutiles
    • Modification des noms d'argument
  • 487-> 485B, -2B
    • 1 octet à utiliser evalpour D, supprimer return.
    • Compression de 1 octet combinant les parenthèses fermantes à une virgule.
  • 485-> 481B, -4B
    • En compressant différentes sous-chaînes.
Naruyoko
la source
Ou passez-le facilement avec une longueur égale en remplaçant 99 par M9, ce qui donne la valeur D ^ 6 (9).
Naruyoko
0

Python 3, D ^ 6 (9) ( 608 600 599 octets)

_='r=a=0?CM:#y-~y<<x?H6@r=0.EB1+HI)#r?Fx):#xI>>H)?8t6@TtNr#A(U8HG).f==2BCf,CUS(v+2,/yNc,HGG.f<2Bt-(f>v)*c.f-vBy?A(M:#5<<CM.Fy)-1BOx,4,Z(rG?Jx6,a@f=d=c=0@VW7,14@while 1:@.x:Jx-1)X~E:breakKd,TFJxGNFrNFr)@.c-r:K.not(Fu)or(Fr)-fGQ.E:WOd,4,rRA(Vd)K.fIQ.Yd,cR/t);W/u)@.c:@!.EQ q=~u&2|EK .q:W1<<CFuNu)K  Vc=Cq and u,CFcNtG,rXuI&YVc);W/tR9@a=CCVCu,Cx,cGNa)#a\nprint(JJJJJJ9GGG)X\n!if !  x=xIK#@return . if /O13,-4,6):@global r8S(v,y,c,?\ndef Q:K! K@ @\n B else CP(YE:c=CEx%2Tf,x=FFL(U8FxG,G))HZ(xI>>1JD(My,x)N),OS(4,R);t=Vt,Wu='
for Y in 'WVRONMJIHGUFTEYCB@KQ?86/.#!X':_=_.split(Y);_=_.pop().join(_)
exec(_)

Ceci est un code codé. Extrait:

r=a=0
def P(y,x):
 return y-~y<<x
def Z(x):
 global r
 r=0 if x%2 else 1+Z(x>>1)
 return r
def L(x):
 return x>>1>>Z(x)
def S(v,y,c,t):
 global r
 f,x=L(t),r
 return A(S(v,y,c,L(x)),S(v,y,c,Z(x))) if f==2 else P(f,P(S(v,y,c,L(x)),S(v+2,S(4,13,-4,y),c,Z(x)))) if f<2 else t-(f>v)*c if f-v else y
def A(y,x):
 return 5<<P(y,x) if L(y)-1 else S(4,x,4,Z(r))
def D(x):
 global r,a
 f=d=c=0
 t,u=7,14
 while 1:
  if x:D(x-1)
  x=x>>1
  if ~x%2:break
  d,f,x=L(L(D(x))),L(r),L(r)
  if c-r:
   if not(L(u)or(L(r)-f)):
    x=x>>1
    if x%2:u=S(4,d,4,r);t=A(t,d)
   if f>>1:
    x=x>>1
    if x%2:c=P(d,c);t=S(4,13,-4,t);u=S(4,13,-4,u)
  if c:
   x=x>>1
   if x%2:
    x=x>>1
    q=~u&2|x%2
    if q:u=1<<P(L(u),u)
    t,c=P(q and u,P(L(c),t)),r
  x=x>>1
  if u>>1&x%2:c=P(t,c);u=S(4,13,-4,t);t=9
 a=P(P(t,P(u,P(x,c))),a)
 return a
print(D(D(D(D(D(D(9)))))))

En cela, il est supposé être:

  • Pile d'appel infinie
  • Mémoire infinie

Il s'agit essentiellement d'un portage de ma réponse JavaScript . Pour plus de détails, vérifiez celui-là.

La compression a été effectuée avec cela .

Je ne connais pas très bien Python, donc il y a certainement des endroits pour économiser des octets. Je pense que le sous-600 est possible. sous-600 a été prouvé.

  • 608-> 600B, -8B
    • Regroupé certaines affectations
    • Conditions inversées Spour réduire les parenthèses
  • 600-> 599B, ​​-1B
    • Changer u/2dans l'avant-dernière ligne de la définition de Dto u>>1, sauver un octet de le compresser en un caractère avec d'autres >>1s.
Naruyoko
la source
0

Ruby, D ^ 6 (9) (553 octets)

_='F=$a=0TEK#y-~yUx.Z@#F=x%2G1?0R1+Z(x/2).L@#x/2>>[email protected])VHt);x=F#fG2?A(8L@C8Z@IRf>2?fGv ?yRt-(f>v ?1R0)*cREf,E8L@CS(v+2,t6yCc,Z@I).A(K#Hy)G1?Mx,4,Z(FIR5UEK.D@;$>UxVd=c=0;t=7;u=14;while[xNOx-1CB>0][1];d=HHD@IVW;x=W;cGF&&[Hu)G0&&WGf&&![u=Md,4,FCt=A(t,d)],fJd,cCt6tCu6u)]];cNB&&[t=E~u&2|!(u=1UEHcCu)CEHcCt)Cc=F];uJt,cCu6tCt=9]Q#$a=EEt,Eu,Ex,cIC$a)Q;$>UOOOOOO9III!BN#;return .QT6=M13,-4,8S(v,y,c,@(x)B(x/=2)%2C),J/2&![c=EEP(F$rNG0||G==WHF)HL(I))Ky,x)MS(4,OD(Q;endR: T;def U<<V;f=VUTRQOMKIHWGNFEJCB@86.#!'.each_char{|Y|_=_.split(Y);_=_.join(_.pop())};eval(_)

Ceci est un code codé. Extrait:

$r=$a=0;def P(y,x);return y-~y<<x;end;def Z(x);return $r=x%2==1?0: 1+Z(x/2);end;def L(x);return x/2>>Z(x);end;def S(v,y,c,t);f=L(t);x=$r;return f==2?A(S(v,y,c,L(x)),S(v,y,c,Z(x))): f>2?f==v ?y: t-(f>v ?1: 0)*c: P(f,P(S(v,y,c,L(x)),S(v+2,t=S(4,13,-4,y),c,Z(x))));end;def A(y,x);return L(y)==1?S(4,x,4,Z($r)): 5<<P(y,x);end;def D(x);$><<x;f=d=c=0;t=7;u=14;while[x==0||D(x-1),(x/=2)%2>0][1];d=L(L(D(x)));f=L($r);x=L($r);c==$r&&[L(u)==0&&L($r)==f&&(x/=2)%2==0||[u=S(4,d,4,$r),t=A(t,d)],f/2&(x/=2)%2==0||[c=P(d,c),t=S(4,13,-4,t),u=S(4,13,-4,u)]];c==0||(x/=2)%2&&[t=P(~u&2|(x/=2)%2==0||(u=1<<P(L(c),u)),P(L(c),t)),c=$r];u/2&(x/=2)%2==0||[c=P(t,c),u=S(4,13,-4,t),t=9];end;return $a=P(P(t,P(u,P(x,c))),$a);end;$><<D(D(D(D(D(D(9))))))

Ce code est le numéro du chargeur avec D 6 (9) à la place.

En cela, il est supposé être:

  • Pile d'appel infinie
  • Mémoire infinie

Il s'agit essentiellement d'un portage de ma réponse JavaScript et de ma réponse Python 3 . Pour plus de détails, vérifiez-les.

La compression a été effectuée avec cela (peut apparaître car elle n'existe pas).

Je suis un débutant chez Ruby, donc peut-être moins de 512 est possible, mais j'en doute.

Naruyoko
la source