Rutger , 310 octets
n=e=$Input;
a=0;
w=While[{m=Modulo[$e];Not[m[1]];}];
w=w[{f=For[4];f=f[@x];f=f[{Print[$e];q=Equal[$x];i=If[{q[1];}];i=i[{k=Times[$e];}];Do[$i];i=If[{q[2];}];i=i[{k=Add[$e];}];Do[$i];i=If[{q[3];}];i=i[{k=Subtract[$e];}];Do[$i];i=If[{q[4];}];i=i[{k=Divide[$e];}];Do[$i];e=k[a=Increment[$a]];}];Do[$f];}];
Do[$w];
Essayez-le en ligne!
Il est temps que j'utilise à nouveau Rutger. Malheureusement, ce n'est peut-être pas le meilleur langage pour la tâche, car il n'a aucune forme eval
, ce qui m'oblige à utiliser quatre instructions if
Comment ça marche
Comment fonctionne Rutger
Un bref avant-propos sur le fonctionnement du langage: tout est soit une affectation, soit une fonction, et chaque fonction prend exactement un argument. Pour les opérations qui nécessitent plus d'un argument (par exemple la multiplication), le premier appel renvoie une fonction partielle qui, lorsqu'elle est appelée à nouveau avec le deuxième argument, renvoie le résultat attendu. Par exemple:
left = Times[5];
Print[left[6]];
imprimera 30: Essayez-le en ligne!. Bien que cela soit généralement plus long que l'alternative habituelle, il peut parfois économiser des octets, si une fonction est appelée à plusieurs reprises avec un argument constant et un argument changeant, par exemple lors de l'impression de tables de temps.
Cette règle à un argument s'applique à tout ce qui n'est pas une constante ou une variable, y compris les boucles et les conditions. Cependant, les boucles et conditionals ( For
, Each
, While
, DoWhile
, If
et IfElse
) sont faisables , ce qui signifie que pour les exécuter en fait, laDo
fonction doit être appelée (voir la dernière ligne dans la réponse). Encore une fois, cela peut économiser des octets lors de l'exécution répétée de la même boucle, ou vous permettre d'exécuter du code arbitraire entre la définition et l'exécution des boucles.
Enfin, il existe trois façons de se référer aux variables, qui sont toutes utilisées dans ce programme. Le premier est le référencement direct , où le nom de la variable est préfixé par un $
symbole. Cela accède directement à la valeur de la variable et la renvoie. Le second est le référencement fonctionnel , qui n'a pas de caractère de préfixe. Cela permet au code de faire la distinction entre les fonctions (potentiellement partielles) attribuées aux variables et les variables réelles contenant une valeur spécifique. Enfin, le référencement indirect , préfixé d'un @
symbole, crée une variable (si elle n'existe pas déjà) et renvoie l'objet variable dans une portée donnée. Cela vous permet de créer une variable de boucle (par exemple i
dans for i in range(...)
).
Fonctionnement de la solution réelle
Voici le code non golfé:
n = elem = $Input;
var = 0;
while = While[{
mod = Modulo[$elem];
Not[mod[1]];
}];
while = while[{
for = For[4];
for = for[@index];
for = for[{
Print[$elem];
equal = Equal[$index];
if = If[{ equal[1]; }];
if = if[{ func = Times[$elem]; }];
Do[$if];
if = If[{ equal[2];}];
if = if[{ func = Add[$elem];}];
Do[$if];
if = If[{ equal[3];}];
if = if[{ func = Subtract[$elem];}];
Do[$if];
if=If[{ equal[4];}];
if=if[{ func = Divide[$elem];}];
Do[$if];
elem = func[var = Increment[$var]];
}];
Do[$for];
}];
Do[$while];
Essayez-le en ligne!
Comme vous pouvez le voir, il commence par attribuer des trois variables n
, e
et a
qui représentent l'entrée, l'élément de modification de la séquence, et le numéro de modification pour chaque nouvel élément , respectivement. Nous créons ensuite une boucle while:
w=While[{m=Modulo[$e];Not[m[1]];}];
{
}
m
e % m
100 → 1n → 0 , n ≠ 0
Nous arrivons ensuite à la monstruosité absolue constituée du corps de la boucle while:
w=w[{f=For[4];f=f[@x];f=f[{Print[$e];q=Equal[$x];i=If[{q[1];}];i=i[{k=Times[$e];}];Do[$i];i=If[{q[2];}];i=i[{k=Add[$e];}];Do[$i];i=If[{q[3];}];i=i[{k=Subtract[$e];}];Do[$i];i=If[{q[4];}];i=i[{k=Divide[$e];}];Do[$i];e=k[a=Increment[$a]];}];Do[$f];}];
La partie principale de cette boucle est une boucle for, qui itère 4x
Print[$e];
q=Equal[$x];
i=If[{q[1];}];i=i[{k=Times[$e] ;}];Do[$i];
i=If[{q[2];}];i=i[{k=Add[$e] ;}];Do[$i];
i=If[{q[3];}];i=i[{k=Subtract[$e] ;}];Do[$i];
i=If[{q[4];}];i=i[{k=Divide[$e] ;}];Do[$i];
e=k[a=Increment[$a]];
La première instruction imprime chaque itération de la séquence avant de la modifier. Nous créons ensuite une fonction partielle pour vérifier l'égalité avec la variable de boucle x
et rencontrons quatre instructions if. Chaque instruction suivante vérifie si x
est égal à 1, 2, 3 ou 4 respectivement, puis attribue k
à chacune des fonctions dans *
, +
, -
et /
, puis le transforme en une fonction partielle avec e
comme argument. Enfin, nous assignons e
à k
exécuter avec a
comme deuxième argument, et à incrémenter a
.