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];
Experimente online!
Já era hora de eu usar Rutger novamente. Infelizmente, pode não ser o melhor idioma para a tarefa, pois não possui forma deeval
, me forçando a usar quatro declarações if
Como funciona
Como o Rutger funciona
Um breve prefácio sobre como a linguagem funciona: tudo é uma atribuição ou uma função, e toda função requer exatamente um argumento. Para operações que requerem mais de um argumento (por exemplo, multiplicação), a primeira chamada retorna uma função parcial que, quando chamada novamente com o segundo argumento, retorna o resultado esperado. Por exemplo:
left = Times[5];
Print[left[6]];
imprimirá 30: Experimente online!. Embora geralmente seja mais longo do que a alternativa usual, às vezes é possível salvar bytes, se uma função for chamada repetidamente com um argumento constante e um argumento alterado, por exemplo, ao imprimir tabelas de tempos.
Essa regra de um argumento se aplica a tudo que não é uma constante ou uma variável, incluindo loops e condicionais. No entanto, loops e condicionais ( For
, Each
, While
, DoWhile
, If
e IfElse
) são factível , o que significa que, a fim de realmente executá-los, a Do
função deve ser chamada (ver a última linha na resposta). Novamente, isso pode economizar bytes ao executar repetidamente o mesmo loop ou permitir que você execute código arbitrário entre a definição e a execução de loops.
Finalmente, existem três maneiras de se referir a variáveis, todas usadas neste programa. O primeiro é a referência direta , onde o nome da variável é prefixado com um $
símbolo. Isso acessa o valor da variável diretamente e a retorna. O segundo é a referência funcional , que não possui um caractere de prefixo. Isso permite que o código faça a distinção entre funções (potencialmente parciais) atribuídas a variáveis e variáveis reais que contêm um valor específico. Finalmente, a referência indireta , prefixada com um @
símbolo, cria uma variável (se ela ainda não existe) e retorna o objeto variável dentro de um determinado escopo. Isso permite que você crie uma variável de loop (por exemplo, i
in for i in range(...)
).
Como a solução real funciona
Aqui está o código não destruído:
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];
Experimente online!
Como você pode ver, ele começa atribuindo as três variáveis n
, e
e a
, que representam a entrada, o elemento de mudança na seqüência, eo número de modificação para cada novo elemento respectivamente. Em seguida, criamos um loop while:
w=While[{m=Modulo[$e];Not[m[1]];}];
As chaves ( {
e }
) definem um bloco de código, em que a instrução final no bloco é a condição para o loop while. Nesse caso, começamos definindo uma função de módulo parcial, que receberá um segundo argumento m
e retornará e % m
. Em seguida, chamamos essa função parcial com1 1 como seu segundo argumento, retornando 0 0para números inteiros e um número inteiro diferente de zero para flutuadores. Em seguida, calculamos o não lógico disso, mapeando0 → 1 e n → 0 , n ≠ 0.
Em seguida, chegamos à monstruosidade absoluta que consiste no corpo do loop 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];}];
A parte principal desse loop é um loop for, que itera 4vezes cada iteração do loop while, tem uma variável de iteração x
e consiste em:
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]];
A primeira instrução imprime cada iteração da sequência antes de modificá-la. Em seguida, criamos uma função parcial para verificar a igualdade com a variável loopx
e encontramos quatro instruções if. Cada instrução verifica se x
é igual a 1, 2, 3 ou 4, respectivamente, e depois atribui k
a cada função *
, +
, -
e /
, em seguida, faz-lo em uma função parcial com e
como argumento. Por fim, atribuímos e
a k
execução a
como segundo argumento e incremento a
.