Continuação deste desafio porque o autor se foi e a pergunta está encerrada.
O que você precisa fazer é criar um analisador booleano.
Expressões booleanas, caso você ainda não as tenha ouvido, têm duas entradas e uma saída.
Existem quatro "portas" na aritmética booleana, a saber:
- OR (representado por
|
) (operador binário, entre argumentos) - AND (representado por
&
) (operador binário, entre argumentos) - XOR (representado por
^
) (operador binário, entre argumentos) - NOT (representado por
!
) (operador unário, argumento à direita)
Esses portões operam em suas entradas que são verdadeiras (representadas por 1
) ou falsas (representadas por 0
). Podemos listar as entradas possíveis ( A
e B
, neste caso) e as saídas ( O
) usando uma tabela verdade da seguinte maneira:
XOR
A|B|O
-----
0|0|0
0|1|1
1|0|1
1|1|0
OR
A|B|O
-----
0|0|0
0|1|1
1|0|1
1|1|1
AND
A|B|O
-----
0|0|0
0|1|0
1|0|0
1|1|1
NOT
A|O
---
0|1
1|0
Um exemplo de entrada seria 1^((1|0&0)^!(1&!0&1))
, que seria avaliado para:
1^((1|0&0)^!(1&!0&1))
=1^(( 1 &0)^!(1&!0&1))
=1^( 0 ^!(1&!0&1))
=1^( 0 ^!(1& 1&1))
=1^( 0 ^!( 1 &1))
=1^( 0 ^! 1 )
=1^( 0 ^ 0 )
=1^0
=1
A saída seria 1
.
Detalhes
- Como visto no exemplo, não há ordem de prevalência. Todos são avaliados da esquerda para a direita, exceto quando entre parênteses, que devem ser avaliados primeiro.
- A entrada conterá apenas
()!^&|01
. - Você pode escolher qualquer caractere de 8 bytes para substituir os 8 caracteres acima, mas eles devem ter um mapeamento de 1 para 1 e devem ser indicados.
- Especificamente, a função
eval
não pode ser usada em nenhuma sequência derivada da entrada . Especificamente, a funçãoinput
(ou o equivalente no idioma) e qualquer função que a chama não podem ser usadaseval
. Você também não pode concatenar oinput
em sua string dentro doeval
.
Pontuação
Isso é código-golfe . A solução mais curta em bytes vence.
code-golf
parsing
logic-gates
Freira Furada
fonte
fonte
Respostas:
JavaScript (ES6) 116 bytes
editar thx @ user81655 por 3 bytes salvos e um erro encontrado
Provavelmente não é a melhor abordagem, mas nenhum operador avaliador e booleano, apenas tabelas verdadeiras.
Personagem usado:
Teste
fonte
x>7
?r=f(x.replace(/./g,c=>"01!&|^()".indexOf(c)))
0|!0
funciona, mas agora eu faço, tenho meu voto positivo.Retina, 49 bytes
Não tenho idéia de como saiu tão curto.
Mapeamento de caracteres:
1
,0
E!
são deixadas inalteradas.Isso funciona através da substituição de todas as expressões truthy (única
1
entre parênteses,!0
,1&1
,1^0
,0|1
, etc.) com1
, e todos os outros (single0
entre parênteses,!1
,1&0
,1^1
,0|0
, etc.) com0
.Experimente online!
Experimente online com o mapeamento automático de caracteres!
fonte
utilitários grep + shell, 131 bytes
Os seguintes caracteres são renomeados:
Comecei a tentar escrever uma solução grep, mas descobri que ela não funcionava bem com os operadores de infixo associativos à esquerda. Eu precisava ter um padrão como (cadeia de operadores) = (cadeia de operadores) (operação binária) (operando único), mas isso contém uma possível recursão infinita, portanto o grep se recusa a executá-lo. Mas notei que podia analisar operadores associativos certos. Isso fez do
!
operador uma dor, mas ainda era possível. Então, criei um regex para calcular expressões booleanas anteriores e enviei a entrada através derev
. O próprio regex, que corresponde a expressões verdadeiras, é de 116 bytes.TODO: escolha caracteres diferentes para a entrada, para que eu possa distinguir todos os grupos de operadores usados com classes de caracteres internas.
fonte
(?9)
significa isso ?\9
que significaria corresponder ao que o 9º grupo de captura correspondia). Por exemplo,(\d)\1
corresponde ao mesmo dígito duas vezes, enquanto(\d)(\?1)
corresponde a dois dígitos.Python, 210 bytes
Descida recursiva muito ruim, espero que seja batida em um piscar de olhos.
fonte
Mathematica,
139129 bytesUma solução simples de substituição de string tem uma pontuação muito melhor do que eu esperava.
fonte
JavaScript ES6, 223 bytes
Usa um algoritmo de desvio de jarda.
Usa
+
para OR,!
para negação,^
para XOR e&
para e.0
e1
são usados para seus respectivos valores. Claro, eu poderia jogar alguns números dos operadores, mas não estou ganhando o prêmio JavaScript, mesmo que o faça, então pensei em torná-lo pelo menos um pouco legível e correto.fonte
C, 247
Golfe:
Ungolfed, with
main()
(assume a expressão como 1º argumento). A versão golfed não possui depuração printfs e usa códigos ascii de dois dígitos em vez de char literals (40 == '('
). Eu poderia ter salvo alguns caracteres mapeando()|^&!
para234567
- isso teria facilitado muitas manipulações e testes depois de subtraídos48
de cada um.fonte
for(j=i=1;i+=s[++j]==')'?-1:s[j]=='('?1:0,i;);
.Java, 459 bytes
AND
é&
OR
él
(L minúsculo)XOR
éx
(ou qualquer outro personagem que tenha um bom desempenho comString
os métodos, comoString.replaceAll(...)
)NOT
é!
(
éa
)
éb
aqui está uma versão mais legível:
experimente online
fonte
Java, 218
Usa a correspondência de padrões, mas evita substituições fora de ordem da minha tentativa anterior de Java com falha (olhos nítidos, @Kenny Lau !).
Golfe:
Sem jogar, lê a entrada dos argumentos e aplica o mapeamento
oaxn
para|&^!
e<>
para()
:O Java's
m.group(i)
diz qual grupo corresponde; o 1º grupo é para substituições verdadeiras e o 2º para falsas. Isso é iterado em ordem estrita da esquerda para a direita até que nenhuma substituição seja executada.fonte