}0
--@2
@2/\=0MB
}0@1\/
&0/\>0!!
--
@1
00@0
--/\=0
\\@0&0
Marbelous est un langage 8 bits dont les valeurs ne sont représentées que par des billes dans une machine du type Rube Goldberg. Ce n'était donc pas très facile. Cette approche est à peu près équivalente au pseudo-code suivant:
function recursiveFunction(int i)
{
for(int j = i*512; j > 0; j--)
{
recursiveFunction(i - 1);
}
}
puisque la valeur maximale est 256, (représentée par 0 dans le programme Marbleous, qui est traité différemment à différents endroits), recursiveFunction (1) sera appelé un total 256!*512^256
égal à environ 10^1200
, assez facilement pour survivre à l'univers.
Marbelous n'a pas d'interprète très rapide, il semble pouvoir traiter les 10^11
appels de cette fonction chaque année, ce qui signifie que nous avons une durée d'exécution de plusieurs 10^1189
années.
Explications supplémentaires sur le tableau de Marbelous
00@0
--/\=0
\\@0&0
00
est un langage littéral (ou une bille), représenté en hexadécimal (donc 0). Cette bille tombe sur le --
, ce qui la réduit de 1 (00 s'enroule et se transforme en FF ou 255 en décimal). La bille avec maintenant la valeur FF tombe sur la \\
qui la pousse une colonne à droite, sur la partie inférieure @0
. Ceci est un portail et téléporte la bille sur l'autre @0
appareil. Là, la bille atterrit sur le /\
dispositif, qui est une duplicatrice, elle place une copie de la bille sur --
sa gauche (cette bille continuera à boucler entre les portails et sera décrémentée sur chaque boucle) et une =0
à droite.=0
compare la bille à la valeur zéro et laisse la bille tomber si elle est égale et la repoussera à droite sinon. Si la bille a la valeur 0, elle atterrit sur &0
un synchoniseur, que j'expliquerai plus tard.
Dans l’ensemble, cela commence simplement par une bille de valeur 0 dans une boucle et la décrémente jusqu’à atteindre 0, puis il met cette bille de valeur 0 dans un synchroniseur et continue à boucler en même temps.
}0@1
&0/\>0!!
--
@1
}0
est un périphérique d'entrée. Initialement, la nième entrée (base 0) de la ligne de commande lors de l'appel du programme est placée dans chaque }n
périphérique. Donc, si vous appelez ce programme avec l'entrée de ligne de commande 2, une bille de valeur 02 remplacera ceci }0
. Cette bille tombe ensuite dans l’ &0
appareil, un autre synchroniseur, les &n
synchroniseurs retenant les billes jusqu’à ce que tous les autres correspondants &n
soient également archivés. La bille est ensuite décrémentée, téléportée et dupliquée à peu près comme dans la boucle précédemment expliquée. La copie de droite est ensuite vérifiée pour l'inégalité avec zéro ( >0
) si ce n'est pas 0, elle tombe. Si la valeur est 0, il est poussé à droite et atterrit !!
, ce qui termine le tableau.
Jusqu'ici, nous avons une boucle qui compte en continu entre 255 et 0 et laisse une autre boucle similaire (alimentée par l'entrée de la ligne de commande) s'exécuter une fois à chaque fois qu'elle atteint 0. Lorsque cette deuxième boucle a été exécutée n fois (maximum 256 ) le programme se termine. Cela représente donc un maximum de 65 536 exécutions de la boucle. Pas assez pour survivre à l'univers.
}0
--@2
@2/\=0MB
Cela devrait commencer à paraître familier, l'entrée est décrémentée une fois, puis cette valeur est bouclée et copiée (notez que la bille n'est décrémentée qu'une fois, pas à chaque exécution de la boucle). Il est ensuite vérifié si l'égalité est égale à 0 et si ce n'est pas à zéro, atterrit MB
. Ceci est une fonction dans Marbelous, chaque fichier peut contenir plusieurs cartes et chaque carte est une fonction, chaque fonction doit être nommée en précédant la grille par :[name]
. Toutes les fonctions sauf la première fonction du fichier, qui porte un nom standard: MB. Ainsi, cette boucle appelle à nouveau la carte principale avec une valeur de n - 1
où n est la valeur avec laquelle cette instance de la fonction a été appelée.
Alors pourquoi n*512
?
Eh bien, la première boucle s'exécute en 4 ticks (et 256 fois) et la seconde boucle s'exécute n fois avant la fin du forum. Cela signifie que le conseil court environ pour les n*4*256
ticks. La dernière boucle (qui appelle la fonction récursive) est compacte et s’exécute en 2 ticks, ce qui signifie qu’elle parvient à appeler la fonction n*4*256/2 = n*512
fois.
Quels sont les symboles que vous n'avez pas mentionnés?
\/
est une corbeille qui supprime les billes du tableau, ce qui garantit que les billes découpées ne gênent pas les billes qui tournent en boucle et empêchent le programme de se terminer.
Prime
Étant donné que les billes tombant du bas d'une carte marbelous sont imprimées en sortie sur STDOUT, ce programme imprime une multitude de caractères ASCII pendant son exécution.