Cubix, 33 32 bytes
u*.$s.!(.01I^<W%NW!;<,;;q+p@Opus
Forma neta:
u * .
$ s .
! ( .
0 1 I ^ < W % N W ! ; <
, ; ; q + p @ O p u s .
. . . . . . . . . . . .
. . .
. . .
. . .
Pruébalo en línea!
Notas
- Funciona con entradas de hasta 170 inclusive, las entradas más altas dan como resultado un bucle infinito, porque su factorial produce
Infinity
número (técnicamente hablando, es una propiedad no escribible, no enumerable y no configurable del objeto de ventana).
- La precisión se pierde para las entradas 19 y superiores, porque los números superiores a 2 53 (= 9 007 199 254 740 992) no se pueden almacenar con precisión en JavaScript.
Explicación
Este programa consta de dos bucles. El primero calcula el factorial de la entrada, el otro divide el resultado en sus dígitos y los suma. Luego se imprime la suma y finaliza el programa.
comienzo
Primero, necesitamos preparar la pila. Para esa parte, usamos las primeras tres instrucciones. La IP comienza en la cuarta línea, apuntando hacia el este. La pila está vacía.
. . .
. . .
. . .
0 1 I . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . .
. . .
. . .
Mantendremos la suma en la parte inferior de la pila, por lo que debemos comenzar 0
siendo la suma almacenando eso en la parte inferior de la pila. Luego, debemos presionar a 1
, porque la entrada se multiplicará inicialmente por el número anterior. Si esto fuera cero, el factorial siempre daría cero también. Por último, leemos la entrada como un entero.
Ahora, la pila está [0, 1, input]
y la IP está en la cuarta línea, la cuarta columna, apuntando hacia el este.
Bucle factorial
Este es un bucle simple que multiplica los dos elementos superiores de la pila (el resultado del bucle anterior y la entrada - n, y luego disminuye la entrada. Se rompe cuando la entrada llega a 0. La $
instrucción hace que la IP omita el u
- gire. El bucle es la siguiente parte del cubo. La IP comienza en la cuarta línea, cuarta columna.
u * .
$ s .
! ( .
. . . ^ < . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . .
. . .
. . .
Debido al ^
carácter, la IP comienza a moverse hacia el norte de inmediato. Luego, u
gira la IP y la mueve una hacia la derecha. En la parte inferior, hay otra flecha: <
apunta la IP de nuevo al ^
. La pila comienza como [previousresult, input-n]
, donde n
es el número de iteraciones. Los siguientes caracteres se ejecutan en el bucle:
*s(
* # Multiply the top two items
# Stack: [previousresult, input-n, newresult]
s # Swap the top two items
# Stack: [previousresult, newresult, input-n]
( # Decrement the top item
# Stack: [previousresult, newresult, input-n-1]
Luego, la parte superior de la pila (entrada disminuida) se compara 0
con la !
instrucción, y si es así 0
, u
se omite el carácter.
Suma los dígitos
La IP se envuelve alrededor del cubo, terminando en el último carácter en la cuarta línea, inicialmente apuntando hacia el oeste. El siguiente bucle consta de prácticamente todos los caracteres restantes:
. . .
. . .
. . .
. . . . . W % N W ! ; <
, ; ; q + p @ O p u s .
. . . . . . . . . . . .
. . .
. . .
. . .
El ciclo primero elimina el elemento superior de la pila (que es 10
o 0
) y luego comprueba lo que queda del resultado del factorial. Si eso se ha reducido a 0
, se imprime la parte inferior de la pila (la suma) y el programa se detiene. De lo contrario, se ejecutan las siguientes instrucciones (la pila comienza como[oldsum, ..., factorial]
):
N%p+q;;,s;
N # Push 10
# Stack: [oldsum, ..., factorial, 10]
% # Push factorial % 10
# Stack: [oldsum, ..., factorial, 10, factorial % 10]
p # Take the sum to the top
# Stack: [..., factorial, 10, factorial % 10, oldsum]
+ # Add top items together
# Stack: [..., factorial, 10, factorial % 10, oldsum, newsum]
q # Send that to the bottom
# Stack: [newsum, ..., factorial, 10, factorial % 10, oldsum]
;; # Delete top two items
# Stack: [newsum, ..., factorial, 10]
, # Integer divide top two items
# Stack: [newsum, ..., factorial, 10, factorial/10]
s; # Delete the second item
# Stack: [newsum, ..., factorial, factorial/10]
Y el ciclo comienza de nuevo, hasta que sea factorial/10
igual a 0.
n>21