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];
Probieren Sie es online!
Es ist an der Zeit, dass ich wieder Rutger benutze. Leider ist es möglicherweise nicht die beste Sprache für die Aufgabe, da es keine Form von hateval , die mich zwingt, vier if-Anweisungen zu verwenden
Wie es funktioniert
Wie funktioniert Rutger?
Ein kurzes Vorwort zur Funktionsweise der Sprache: Alles ist entweder eine Aufgabe oder eine Funktion, und jede Funktion benötigt genau ein Argument. Für Operationen, die mehr als ein Argument erfordern (z. B. Multiplikation), gibt der erste Aufruf eine Teilfunktion zurück, die bei erneutem Aufruf mit dem zweiten Argument das erwartete Ergebnis zurückgibt. Beispielsweise:
left = Times[5];
Print[left[6]];
druckt 30 aus: Online ausprobieren! . Während dies normalerweise länger ist als die übliche Alternative, kann es manchmal Bytes sparen, wenn eine Funktion wiederholt mit einem konstanten Argument und einem sich ändernden Argument aufgerufen wird, beispielsweise beim Ausdrucken von Zeittabellen.
Diese Regel mit einem Argument gilt für alles, was keine Konstante oder Variable ist, einschließlich Schleifen und Bedingungen. Allerdings Schleifen und Bedingungen ( For, Each, While, DoWhile, Ifund IfElse) sind machbar , dass im Hinblick auf Bedeutung , die sie tatsächlich läuft, dieDo muß Funktion (siehe die letzte Zeile in der Antwort) aufgerufen werden. Dies kann wiederum Byte sparen, wenn dieselbe Schleife wiederholt ausgeführt wird, oder Sie können beliebigen Code zwischen der Definition und der Ausführung von Schleifen ausführen.
Schließlich gibt es drei Möglichkeiten, auf Variablen zu verweisen, die alle in diesem Programm verwendet werden. Die erste ist die direkte Referenzierung , bei der dem Variablennamen ein $Symbol vorangestellt wird . Dies greift direkt auf den Wert der Variablen zu und gibt ihn zurück. Die zweite ist die Funktionsreferenzierung , die keinen Präfixcharakter hat. Auf diese Weise kann der Code zwischen (potenziell partiellen) Funktionen, die Variablen zugewiesen sind, und tatsächlichen Variablen, die einen bestimmten Wert enthalten, unterscheiden. Schließlich indirekte Referenzierung mit einem Präfix @Symbol, wird eine Variable (falls es nicht bereits vorhanden ist ) und gibt das variable Objekt innerhalb eines bestimmten Bereichs. Auf diese Weise können Sie eine Schleifenvariable erstellen (z . B. iin for i in range(...)).
Wie die eigentliche Lösung funktioniert
Hier ist der ungolfed Code:
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];
Probieren Sie es online!
Wie man sehen kann, beginnt sie , indem sie die drei Variablen zuweisen n, eund a, die die Eingabe des Änderungselement in der Sequenz repräsentieren, und die Änderungszahl für jedes jeweils neues Element. Wir erstellen dann eine while-Schleife:
w=While[{m=Modulo[$e];Not[m[1]];}];
Die geschweiften Klammern ( {und }) definieren einen Codeblock , wobei die letzte Anweisung im Block die Bedingung für die while-Schleife ist. In diesem Fall definieren wir zunächst eine partielle Modulo-Funktion, die ein zweites Argument aufnimmt mund zurückgibt e % m. Wir nennen diese Teilfunktion dann mit1 als zweites Argument zurückkehren 0für ganze Zahlen und eine ganze Zahl ungleich Null für Gleitkommazahlen. Wir berechnen dann das logische Nicht davon, Mapping0 → 1 und n → 0 , n ≤ 0.
Als nächstes kommen wir zu der absoluten Monstrosität, die aus dem Körper der while-Schleife besteht:
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];}];
Der primäre Teil dieser Schleife ist eine for-Schleife, die iteriert 4mal jede Iteration der while-Schleife, hat eine Iterationsvariable von xund besteht aus:
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]];
Die erste Anweisung druckt jede Iteration der Sequenz aus, bevor sie geändert wird. Wir erstellen dann eine Teilfunktion, um die Gleichheit mit der Schleifenvariablen zu überprüfen x, und treffen auf vier if-Anweisungen. Jede Anweisung überprüft , ob xgleich 1, 2, 3 oder 4 ist, und weist dann kjede Funktion in *, +, -und /dann wird es in eine Teilfunktion eals Argument. Schließlich weisen wir eauf kmit laufen aals zweites Argument und Zuwachs a.