[S S S N
_Push_0][S N
S _Duplicate_0][S N
S _Duplicate_0][T N
T T _Read_STDIN_as_number][T T T _Retrieve][N
S S S N
_Create_Label_OUTER_LOOP][S N
S _Duplicate][S S S T S N
_Push_2][T S T T _Modulo][S S S T N
_Push_1][T S S S _Add][S N
T _Swap][S S S T S N
_Push_2][T S T S _Integer_division][S N
S _Duplicate][N
T S N
_If_0_jump_to_Label_INNER_LOOP][N
S N
S N
_Jump_to_Label_OUTER_LOOP][N
S S N
_Create_Label_INNER_LOOP][S S S T T N
_Push_3][T S S N
_Multiply][T S S S _Add][S N
T _Swap][S N
S _Duplicate][N
T S T N
_If_0_jump_to_Label_PRINT_AND_EXIT][S N
T _Swap][N
S N
N
_Jump_to_Label_INNER_LOOP][N
S S T N
_Create_Label_PRINT_AND_EXIT][S N
T _Swap][T N
S T _Output_integer_to_STDOUT]
Letras S
(espaço), T
(tabulação) e N
(nova linha) adicionadas apenas como destaque.
[..._some_action]
adicionado apenas como explicação.
Experimente online (apenas com espaços brutos, guias e novas linhas).
Explicação em pseudo-código:
Primeiro converti a função recursiva int f(int n){return n<1?0:n%2+1+3*f(n/2);}
para sua forma iterativa (em pseudo-código):
Integer n = STDIN as integer
Add starting_value 0 to the stack
function OUTER_LOOP:
while(true){
Add n%2+1 to the stack
n = n/2
if(n == 0):
Jump to INNER_LOOP
Else:
Jump to next iteration OUTER_LOOP
function INNER_LOOP:
while(true){
n = 3*n
n = n + Value at the top of the stack (the ones we calculated with n%2+1)
Swap top two items
Check if the top is now 0 (starting value):
Jump to PRINT_AND_EXIT
Else:
Swap top two items back
Jump to next iteration INNER_LOOP
function PRINT_AND_EXIT:
Swap top two items back
Print top to STDOUT as integer
Exit program with error: Exit not defined
Em seguida, implementei essa abordagem iterativa na linguagem Whitespace baseada em pilha, usando sua pilha padrão.
Exemplo é executado:
Entrada: 1
Command Explanation Stack Heap STDIN STDOUT STDERR
SSSN Push 0 [0]
SNS Duplicate top (0) [0,0]
SNS Duplicate top (0) [0,0,0]
TNTT Read STDIN as integer [0,0] {0:1} 1
TTT Retrieve [0,1] {0:1}
NSSSN Create Label OUTER_LOOP [0,1] {0:1}
SNS Duplicate top (1) [0,1,1] {0:1}
SSSTSN Push 2 [0,1,1,2] {0:1}
TSTT Modulo top two (1%2) [0,1,1] {0:1}
SSSTN Push 1 [0,1,1,1] {0:1}
TSSS Add top two (1+1) [0,1,2] {0:1}
SNT Swap top two [0,2,1] {0:1}
SSSTSN Push 2 [0,2,1,2] {0:1}
TSTS Int-divide top two (1/2) [0,2,0] {0:1}
SNS Duplicate top (0) [0,2,0,0] {0:1}
NTSN If 0: Go to Label INNER_LOOP [0,2,0] {0:1}
NSSN Create Label INNER_LOOP [0,2,0] {0:1}
SSSTTN Push 3 [0,2,0,3] {0:1}
TSSN Multiply top two (0*3) [0,2,0] {0:1}
TSSS Add top two (2+0) [0,2] {0:1}
SNT Swap top two [2,0] {0:1}
SNS Duplicate top (0) [2,0,0] {0:1}
NTSTN If 0: Jump to Label PRINT [2,0] {0:1}
NSSTN Create Label PRINT [2,0] {0:1}
SNT Swap top two [0,2] {0:1}
TNST Print top to STDOUT [0] {0:1} 2
error
Experimente online (apenas com espaços brutos, guias e novas linhas).
Para com erro: Saída não definida.
Entrada: 4
Command Explanation Stack Heap STDIN STDOUT STDERR
SSSN Push 0 [0]
SNS Duplicate top (0) [0,0]
SNS Duplicate top (0) [0,0,0]
TNTT Read STDIN as integer [0,0] {0:4} 4
TTT Retrieve [0,4] {0:4}
NSSSN Create Label OUTER_LOOP [0,4] {0:4}
SNS Duplicate top (4) [0,4,4] {0:4}
SSSTSN Push 2 [0,4,4,2] {0:4}
TSTT Modulo top two (4%2) [0,4,0] {0:4}
SSSTN Push 1 [0,4,0,1] {0:4}
TSSS Add top two (0+1) [0,4,1] {0:4}
SNT Swap top two [0,1,4] {0:4}
SSSTSN Push 2 [0,1,4,2] {0:4}
TSTS Int-divide top two (4/2) [0,1,2] {0:4}
SNS Duplicate top (2) [0,1,2,2] {0:4}
NTSN If 0: Go to Label INNER_LOOP [0,1,2] {0:4}
NSNSN Jump to Label OUTER_LOOP [0,1,2] {0:4}
SNS Duplicate top (2) [0,1,2,2] {0:4}
SSSTSN Push 2 [0,1,2,2,2] {0:4}
TSTT Modulo top two (2%2) [0,1,2,0] {0:4}
SSSTN Push 1 [0,1,2,0,1] {0:4}
TSSS Add top two (0+1) [0,1,2,1] {0:4}
SNT Swap top two [0,1,1,2] {0:4}
SSSTSN Push 2 [0,1,1,2,2] {0:4}
TSTS Int-divide top two (2/2) [0,1,1,1] {0:4}
SNS Duplicate top (1) [0,1,1,1,1] {0:4}
NTSN If 0: Go to Label INNER_LOOP [0,1,1,1] {0:4}
NSNSN Jump to Label OUTER_LOOP [0,1,1,1] {0:4}
SNS Duplicate top (1) [0,1,1,1,1] {0:4}
SSSTSN Push 2 [0,1,1,1,1,2] {0:4}
TSTT Modulo top two (1%2) [0,1,1,1,1] {0:4}
SSSTN Push 1 [0,1,1,1,1,1] {0:4}
TSSS Add top two (1+1) [0,1,1,1,2] {0:4}
SNT Swap top two [0,1,1,2,1] {0:4}
SSSTSN Push 2 [0,1,1,2,1,2] {0:4}
TSTS Int-divide top two (1/2) [0,1,1,2,0] {0:4}
SNS Duplicate top (0) [0,1,1,2,0,0] {0:4}
NTSN If 0: Go to Label INNER_LOOP [0,1,1,2,0] {0:4}
NSSN Create Label INNER_LOOP [0,1,1,2,0] {0:4}
SSSTTN Push 3 [0,1,1,2,0,3] {0:4}
TSSN Multiply top two (0*3) [0,1,1,2,0] {0:4}
TSSS Add top two (2+0) [0,1,1,2] {0:4}
SNT Swap top two [0,1,2,1] {0:4}
SNS Duplicate top (1) [0,1,2,1,1] {0:4}
NTSTN If 0: Jump to Label PRINT [0,1,2,1] {0:4}
SNT Swap top two [0,1,1,2] {0:4}
NSNN Jump to Label INNER_LOOP [0,1,1,2] {0:4}
SSSTTN Push 3 [0,1,1,2,3] {0:4}
TSSN Multiply top two (2*3) [0,1,1,6] {0:4}
TSSS Add top two (1+6) [0,1,7] {0:4}
SNT Swap top two [0,7,1] {0:4}
SNS Duplicate top (1) [0,7,1,1] {0:4}
NTSTN If 0: Jump to Label PRINT [0,7,1] {0:4}
SNT Swap top two [0,1,7] {0:4}
NSNN Jump to Label INNER_LOOP [0,1,7] {0:4}
SSSTTN Push 3 [0,1,7,3] {0:4}
TSSN Multiply top two (7*3) [0,1,21] {0:4}
TSSS Add top two (1+21) [0,22] {0:4}
SNT Swap top two [22,0] {0:4}
SNS Duplicate top (0) [22,0,0] {0:4}
NTSTN If 0: Jump to Label PRINT [22,0] {0:4}
NSSTN Create Label PRINT [22,0] {0:4}
SNT Swap top two [0,22] {0:4}
TNST Print top to STDOUT [0] {0:4} 22
error
Experimente online (apenas com espaços brutos, guias e novas linhas).
Para com erro: Saída não definida.