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];
Pruébalo en línea!
Ya es hora de que vuelva a usar Rutger. Desafortunadamente, puede que no sea el mejor lenguaje para la tarea, ya que no tiene forma de evalobligarme a usar cuatro declaraciones if
Cómo funciona
¿Cómo funciona Rutger?
Un breve prólogo sobre cómo funciona el lenguaje: todo es una asignación o una función, y cada función toma exactamente un argumento. Para operaciones que requieren más de un argumento (por ejemplo, multiplicación), la primera llamada devuelve una función parcial que, cuando se llama nuevamente con el segundo argumento, devuelve el resultado esperado. Por ejemplo:
left = Times[5];
Print[left[6]];
imprimirá 30: ¡ Pruébelo en línea!. Si bien esto suele ser más largo que la alternativa habitual, a veces puede guardar bytes, si se llama a una función repetidamente con un argumento constante y un argumento cambiante, por ejemplo, al imprimir tablas de tiempos.
Esta regla de argumento se aplica a todo lo que no es una constante o una variable, incluidos los bucles y condicionales. Sin embargo, los bucles y condicionales ( For, Each, While, DoWhile, Ify IfElse) son factibles , lo que significa que con el fin de ejecutar de hecho ellos, elDo función debe ser llamada (véase la última línea de la respuesta). Nuevamente, esto puede ahorrar bytes cuando se ejecuta repetidamente el mismo bucle, o le permite ejecutar código arbitrario entre la definición y la ejecución de bucles.
Finalmente, hay tres formas de referirse a las variables, todas las cuales se utilizan en este programa. El primero es la referencia directa , donde el nombre de la variable tiene como prefijo un $símbolo. Esto accede al valor de la variable directamente y lo devuelve. El segundo es la referencia funcional , que no tiene un carácter de prefijo. Esto permite que el código distinga entre funciones (potencialmente parciales) asignadas a variables y variables reales que contienen un valor específico. Finalmente, la referencia indirecta , con el prefijo de un @símbolo, crea una variable (si aún no existe) y devuelve el objeto variable dentro de un ámbito determinado. Esto le permite crear una variable de bucle (por ejemplo, ien for i in range(...)).
Cómo funciona la solución real
Aquí está el código sin 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];
Pruébalo en línea!
Como se puede ver, se inicia mediante la asignación de las tres variables n, ey a, lo que representa la entrada, el elemento de cambio en la secuencia, y el número de modificación para cada nuevo elemento, respectivamente. Luego creamos un ciclo while:
w=While[{m=Modulo[$e];Not[m[1]];}];
Las llaves ( {y }) definen un bloque de código, donde la declaración final en el bloque es la condición para el ciclo while. En este caso, comenzamos definiendo una función de módulo parcial, que tomará un segundo argumento my regresará e % m. Luego llamamos a esta función parcial con1 como segundo argumento, volviendo 0 0para enteros y un entero distinto de cero para flotantes. Luego calculamos el no lógico de esto, mapeo0 → 1 y n → 0 , n ≠ 0.
Luego llegamos a la monstruosidad absoluta que consiste en el cuerpo del bucle 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 parte principal de este ciclo es un ciclo for, que itera 4 4veces cada iteración del ciclo while, tiene una variable de iteración de xy consiste en:
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 primera declaración imprime cada iteración de la secuencia antes de modificarla. Luego creamos una función parcial para verificar la igualdad con la variable de bucle x, y encontramos cuatro declaraciones if. Cada uno de los estados comprueba si xes igual a 1, 2, 3 o 4, respectivamente, y entonces asigna ka cada función en *, +, -y /, a continuación, lo hace en una función parcial con ecomo su argumento. Finalmente, se asigna ea kcorrer con acomo segundo argumento, y el incremento a.