Stackylogic é uma linguagem de programação baseada em lógica que inventei 0
's 1
' e 's para entrada e saída de um único 0
ou 1
após a conclusão.
Um programa Stackylogic consiste em linhas que podem conter apenas os três caracteres 01?
, bem como exatamente um <
no final de uma das linhas. As linhas podem não estar vazio e a linha com o <
deve ter pelo menos um 0
, 1
ou ?
antes dela.
Aqui está um exemplo de programa que (como explicarei) calcula a NAND de dois bits:
1
?<
11
?
0
Cada linha em um programa Stackylogic é considerada uma pilha , com a parte inferior à esquerda e a parte superior à direita. Implicitamente, há uma pilha vazia (linha vazia) antes da primeira linha de um programa e depois da última linha.
O <
, que chamaremos de cursor , marca a pilha para iniciar quando um programa Stackylogic é executado. A execução de um programa Stackylogic ocorre da seguinte maneira:
Retire o caractere superior da pilha para a qual o cursor está apontando.
- Se o personagem for
?
, solicite a0
ou a um usuário1
e aja como se fosse o personagem. - Se o caractere for
0
, mova o cursor uma pilha para cima (para a linha acima da linha atual). - Se o caractere for
1
, mova o cursor uma pilha para baixo (para a linha abaixo da linha atual).
- Se o personagem for
Se a pilha para a qual o cursor se move estiver vazia, imprima o último valor que foi retirado de uma pilha (sempre a
0
ou1
) e encerre o programa.Caso contrário, se a pilha para a qual o cursor se move não estiver vazia, volte para a etapa 1 e repita o processo.
Observe que os programas Stackylogic sempre terminam porque eles acabam esgotando suas pilhas.
Exemplo NAND
No programa NAND, o cursor inicia em ?
:
1
?<
11
?
0
Assumiremos que o usuário digita uma 1
vez que ?
é acionado, o que significa que o cursor se moverá para baixo, fazendo com que o programa fique assim:
1
11<
?
0
Agora, uma planície 1
está no topo da pilha do cursor. É devidamente acionado e o cursor se move novamente:
1
1
?<
0
Agora assuma as entradas do usuário 0
para o ?
, o que significa que o cursor se moverá para cima:
1
1<
0
Novamente, a 1
está na pilha de cursores, então o cursor aparece e se move para baixo:
1
<
0
Finalmente, a pilha do cursor está vazia; portanto, o último valor exibido, o 1
, é gerado e o programa termina.
Isso é preciso para uma porta NAND porque 1 NAND 0
é 1
. Obviamente, isso funciona para as outras três entradas de dois bits, se você quiser verificar.
Exemplo OR
Este programa Stackylogic simula uma porta OR :
?
?<
É fácil ver que uma entrada inicial de 1
empurrará o cursor para a pilha vazia implícita abaixo da última linha, encerrando o programa e emitindo a 1
que acabou de ser inserida.
Por 00
outro lado, para uma entrada de , o cursor seguirá para a pilha vazia implícita na parte superior, encerrando o programa e emitindo a última 0
a ser inserida.
Desafio
Escreva um programa ou função que pegue um programa Stackylogic como uma string e execute-o, imprimindo ou retornando o 0
ou resultante 1
.
Após a ?
's, você pode solicitar que o usuário para uma 0
ou 1
entrada, ou ler o valor de uma string pré-estabelecido de 0
' s e 1
's que você também tomar como entrada. (Essa pode ser outra entrada de string para seu programa / função ou você pode simplesmente assumir que a primeira ou a última linha da string de programa será o fluxo de entrada).
Você pode assumir que o programa e a entrada estão sempre bem formados. Opcionalmente, você pode assumir que os programas de entrada vêm com uma única nova linha à direita (embora lembre-se de que sempre há uma pilha vazia implícita no final).
O código mais curto em bytes vence.
Mais programas de amostra
ZERO
0<
ONE
1<
BUFFER
?<
NOT
1
?<
0
AND
?<
?
NAND
1
?<
11
?
0
OR
?
?<
NOR
1
?
00
?<
0
XOR(v1)
?
0
1?<
?
0
XOR(v2)
?
?<
11
?
0
XNOR(v1)
1
?
0?<
1
?
XNOR(v2)
1
?
00
?<
?
MEDIAN(v1)
1
???<
0
MEDIAN(v2)
?
1?<
??
fonte
?\1?<\??
. Como alternativa, aqui está uma implementação simétrica de 5 linhas:?\?0\?<\?1\?
1\???<\0
.111\???????<\000
.Respostas:
Retina ,
79787368666563625544 bytesA contagem de bytes assume a codificação ISO 8859-1.
A entrada é via STDIN e espera-se que seja a entrada do usuário separada por dois feeds de linha do código-fonte.
Experimente online! (As duas primeiras linhas ativam um conjunto de testes, em que cada linha é um caso de teste separado, em
/
vez de feeds de linha.)Não tenho muita certeza do que aconteceu aqui.
Parece uma solução realmente desajeitada eesse não é realmente o tipo de problema para o qual a Retina foi criada, mas ainda supera todas as respostas atuais por algum motivo.Explicação
A versão final disso acabou sendo bastante simples.
O primeiro estágio é simplesmente um loop (devido à
+
opção) que faz a interpretação real do idioma. O estágio é uma substituição de regex única, mas na verdade são três substituições diferentes compactadas em um estágio, aproveitando o fato de que grupos de captura de ramificações não utilizadas são simplesmente considerados vazios durante a substituição.Processamento
?
:Isso simplesmente pega o primeiro caractere da entrada, depois combina caracteres arbitrários até encontrar
?<
, e coloca esse primeiro caractere na frente de<
(excluindo o?
).Processamento
0
:Isso corresponde à linha que precede a
0<
e a coloca após a<
remoção0
. (Efetivamente, isso apenas exclui0
e move a<
linha para cima.)Processamento
1
:Praticamente a mesma coisa, exceto que movemos
<
uma linha para baixo ao excluir a1
. Um detalhe importante a ser observado é o uso de, em+
vez de*
, ou seja, exigir que a próxima linha não fique vazia.A parte interessante é descobrir por que isso funciona e por que não precisamos acompanhar o último valor que exibimos para determinar a saída final. Para fazer isso, precisamos considerar como o loop acima pode terminar. Como todas as correspondências possíveis alteram a sequência (já que pelo menos um caractere é descartado), precisamos considerar apenas os casos em que a correspondência falha completamente.
Se o caractere na frente
<
é?
a única maneira de a partida falhar é que não há caractere sem avanço de linha em nenhum lugar à sua frente, mas isso não pode acontecer porque estamos garantidos de que sempre há entrada suficiente.Se o caractere na frente de
<
for0
, o regex sempre corresponderá, pois sempre há outra linha acima da atual (que pode ser a linha vazia que separa a entrada do código-fonte).Se o caractere na frente de
<
for1
, a regex falhará se estivermos na última linha (pois a¶
correspondência falhará) ou se a próxima linha estiver vazia (pois a.+
correspondência falhará). Observe que os dois casos correspondem ao encerramento do programa após a exibição de a1
.Finalmente, há também a possibilidade que
<
não é precedida por nenhum?01
. Acontece que só podemos chegar a essa situação pulando um0
e movendo-o para uma linha vazia, de modo que<
agora seja precedido por um avanço de linha.Assim, quando o programa termina em um
1
, o<
continuará sendo depois disso1
. Mas se o programa terminar em um0
, ele será movido para uma linha vazia. Podemos facilmente transformar essas informações na saída desejada com um estágio de correspondência simples:Isso simplesmente conta as correspondências de
1<
na string. Pelo raciocínio acima, isso ocorrerá1
se o programa tiver terminado em a1
e0
se tiver terminado em a0
.fonte
Convexo ,
10295 bytesBem, uma linguagem baseada em lista de pilhas codificada em uma linguagem baseada em pilha acabou sendo bastante difícil.
Marque minhas palavras: chegarei a 100 bytes ou menos!EDIT: Sucesso!Experimente online!
A entrada do programa é via args da linha de comando. Entrada
0
s e1
s normalmente (na TIO, este meio de nova linha-separado na caixa de "entrada").Explicação:
Todo o código pode ser dividido em três partes:
Este bit simplesmente pega o programa de entrada e o converte em uma matriz de linhas e também adiciona
" "
linhas ao início da matriz. Uma vez que as matrizes do Convex são finalizadas, ter apenas uma pilha vazia no início serve.Esta parte determina com qual linha (ou pilha) iniciar a execução. Ele pesquisa em cada linha e coloca o número de pilha correto na
M
variável.Esta é a parte divertida! Ele faz um loop contínuo até atingir uma linha com apenas um espaço (
" "
) (simbolizando uma pilha vazia). Se a linha não estiver vazia, faça o seguinte:?
, insira e inclua esse caractere na linha.0
, mova o ponteiro de linha para cima um.1
, mova o ponteiro de linha para baixo um.(espaço), imprima o item exibido mais recentemente e finalize o programa.
fonte
Código de máquina x86 de 32 bits, 70 bytes
Em hexadecimal:
Input é uma sequência de várias linhas terminada em NULL (separada por avanço de linha) transmitida via ESI. A entrada do usuário é assumida como a primeira linha. Retorna '0' / '1' em AL.
Desmontagem:
fonte
JavaScript (ES6),
136138Assumindo uma nova linha final no programa
Menos golfe
Teste
fonte
05AB1E ,
58565553515046 bytesEconomizou 2 bytes graças a Emigna ! Código:
Usa a codificação CP-1252 . Experimente online! .
fonte
Python 3,
147146145 145144 bytes1 byte graças a @Lynn.
fonte
Python 3, 318
F sendo o programa, z sendo inserido. Sim, meus nomes de variáveis são loucos.
fonte
ES6, 190 bytes
Use como
f(program, input)
fonte
[...o]
vez deo.split``
e use emfor
vez dewhile
, pois isso permite mover duas expressões parafor
salvar dois bytes. Algumas dicas específicas: eu acho que o seuNumber
elenco é desnecessário, pois o*2
elenco será para você, e eu apenas leriai
usandoj=0
ei[j++]
que acho que economiza 11 bytes.f=
funções anônimas.Java,
256255231219215213 bytesDemonstração sobre Ideone.
Pega o programa e a entrada como argumentos e retorna o resultado como um número inteiro.
fonte
for
loop, mas o que seu primeiro comentário significa?int f(String[]I)...
e você pode evitar oString[]p=I.split("\n");
int f(String[]P)
->(String[]I){...
PHP (<7.0),
195192 bytesLeva o programa como primeiro argumento e cada valor como um argumento adicional.
Observe que eu testei isso com espaços asn divididos ("", ..) em vez de novas linhas, mas deve funcionar de qualquer maneira.
Dá um aviso obsoleto se executado em php> 5.3.
Também dá um aviso se você sair do topo do programa. No entanto, ele ainda funciona e sai corretamente, então tudo bem.
fonte
C,
264249244242C não se sai tão bem com a manipulação de strings, mas isso é bastante curto.
Ele funciona pesquisando a seqüência de caracteres em busca do cursor (
<
), recuando 1 lugar, lendo o comando, substituindo-o por umtab
caractere e avançando ou recuando uma linha. A entrada está na forma de uma matriz de caracteres C, comochar array[]="1\n?<\n11\n?\n0";result = f(array);
, embora os retornos de carro também sejam permitidos.Embora a sequência de entrada seja modificada, o comprimento não é alterado.
Programa de teste
Execute este programa com cada caso de teste como um parâmetro separado, usando uma única barra invertida no lugar de novas linhas. Os casos de teste serão separados por uma linha em branco.
fonte