Cubix, 33 32 bytes
u*.$s.!(.01I^<W%NW!;<,;;q+p@Opus
Formulário líquido:
u * .
$ s .
! ( .
0 1 I ^ < W % N W ! ; <
, ; ; q + p @ O p u s .
. . . . . . . . . . . .
. . .
. . .
. . .
Experimente online!
Notas
- Funciona com entradas de até 170 entradas, inclusive superiores, resultando em um loop infinito, porque seu fatorial produz o
Infinity
número (tecnicamente falando, é uma propriedade não gravável, não enumerável e não configurável do objeto de janela).
- A precisão é perdida para as entradas 19 e superiores, porque números maiores que 2 53 (= 9 007 199 254 740 992) não podem ser armazenados com precisão em JavaScript.
Explicação
Este programa consiste em dois loops. O primeiro calcula o fatorial da entrada, o outro divide o resultado em seus dígitos e os soma. A soma é impressa e o programa termina.
Começar
Primeiro, precisamos preparar a pilha. Para essa parte, usamos as três primeiras instruções. O IP começa na quarta linha, apontando para o leste. A pilha está vazia.
. . .
. . .
. . .
0 1 I . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . .
. . .
. . .
Manteremos a soma no final da pilha, portanto, precisamos começar 0
sendo a soma armazenando-a no final da pilha. Então precisamos pressionar um1
, porque a entrada será multiplicada inicialmente pelo número antes dela. Se fosse zero, o fatorial sempre produziria zero também. Por fim, lemos a entrada como um número inteiro.
Agora, a pilha está [0, 1, input]
e o IP está na quarta linha, na quarta coluna, apontando para leste.
Laço fatorial
Este é um loop simples que multiplica os dois principais elementos da pilha (o resultado do loop anterior e da entrada - n, e depois diminui a entrada. Ele interrompe quando a entrada atinge 0. A $
instrução faz com que o IP pule a u
- O loop é a seguinte parte do cubo: O IP começa na quarta linha, quarta coluna.
u * .
$ s .
! ( .
. . . ^ < . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . .
. . .
. . .
Por causa do ^
personagem, o IP começa a se mover para o norte imediatamente. Em seguida, ele u
gira o IP e o move um para a direita. Na parte inferior, há outra seta: <
aponta o IP de volta para o ^
. A pilha começa como [previousresult, input-n]
, onde n
está o número de iterações. Os seguintes caracteres são executados no loop:
*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]
Em seguida, a parte superior da pilha (entrada reduzida) é comparada 0
pela !
instrução e, se estiver 0
, au
caractere é ignorado.
Soma os dígitos
O IP envolve o cubo, terminando no último caractere da quarta linha, inicialmente apontando para o oeste. O loop a seguir consiste em praticamente todos os caracteres restantes:
. . .
. . .
. . .
. . . . . W % N W ! ; <
, ; ; q + p @ O p u s .
. . . . . . . . . . . .
. . .
. . .
. . .
O loop primeiro exclui o item superior da pilha (que é um 10
ou 0
) e, em seguida, verifica o que resta do resultado do fatorial. Se isso foi reduzido para 0
, a parte inferior da pilha (a soma) é impressa e o programa para. Caso contrário, as seguintes instruções serão executadas (a pilha começa 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]
E o loop começa novamente, até factorial/10
igual a 0.
n>21