Neste desafio, você escreverá um intérprete para um idioma simples que eu inventei. O idioma é baseado em um único acumulador A, com exatamente um byte de comprimento. No início de um programa, A = 0. Estas são as instruções de idiomas:
!
: Inversão
Esta instrução simplesmente inverte todos os bits do acumulador. Todo zero se torna um e cada um se torna um zero. Simples!
>
: Deslocar para a direita
Esta instrução muda todos os bits em um lugar para a direita. O bit mais à esquerda se torna zero e o bit mais à direita é descartado.
<
: Shift para a esquerda
Esta instrução muda cada bit em um lugar para a esquerda. O bit mais à direita se torna zero e o bit mais à esquerda é descartado.
@
: Trocar Nybbles
Esta instrução troca os quatro bits superiores de A pelos quatro bits inferiores. Por exemplo, se A é 01101010
e você executa @
, A será 10100110
:
____________________
| |
0110 1010 1010 0110
|_______|
Essas são todas as instruções! Simples, certo?
Regras
- Seu programa deve aceitar entrada uma vez no início. Esta será uma linha de código. Este não é um intérprete interativo! Você só pode aceitar entrada uma vez e não precisa voltar ao início depois que a linha for executada.
- Seu programa deve avaliar a entrada mencionada. Todo personagem que não é mencionado acima é ignorado.
- Seu programa deve imprimir o valor final do acumulador, em decimal.
- Aplicam-se regras usuais para linguagens de programação válidas.
- As brechas padrão não são permitidas.
- Isso é código-golfe , a menor contagem de bytes ganha.
Aqui estão alguns pequenos programas para testar seus envios. Antes da seta estar o código, depois do resultado esperado:
!
->255
!>>
->63
!<@
->239
!nop!&6*!
->255
Apreciar!
fonte
! -> 255
que vamos usar 8 bits por byte aqui? A pergunta não é explícita.Respostas:
Pitão,
3635 bytesEquipamento de teste
A representação interna do acumulador é um número inteiro. Esse número inteiro é modificado por 256 em cada iteração, conforme desejado. As operações executadas são
-G-1
,G/2
,G*2
eG
convertido para a base 16, invertida e volta convertido para a base 10, ondeG
é o acumulador.Perdi a linha sobre ignorar todo o resto. Isso foi remediado. Obrigado, @Dennis.
fonte
-G-1
é mais curto que~G
em Pyth? Duvido um pouco disso.t_G
, na verdade , onde_
está a negação et
está-1
. Em Pyth,~
significa algo totalmente diferente.~
(bitwise NOT)C, 96
Supondo entrada ASCII (ou compatível):
Mais arrumado:
Basicamente, é apenas uma coleção de expressões ternárias aninhadas. Estou incrementando o valor obtido
getchar()
para que um EOF (-1) resulte em um valor zero e o programa saia.(link ideone)
fonte
!<>
deve resultar em127
e não255
). Defina seua
comochar
ou use a linhaa&=255
(e use%u
) para obter o efeito correto. Além disso, você pode reduzir sua negaçãoa^255
para~a
.a>>4&15
também é mais curto que o seu(a&240)/16
.%u
vez de%hhu
a/16|a*16
vez dea/16|(a&15)*16
. Os poucos bits no topo são removidos pelo&255
.a*257/16
é um byte menor quea/16|a*16
.Python 3, 133 bytes
Usa um dicionário para compensar a falta de sintaxe de caso de opção no Python. Veja mais aqui .
O acumulador é uma string que é convertida em um número base 10 no final.
Exemplo de E / S:
fonte
for i in sys.stdin:
:)Javascript (ES6),
809190 bytesPraticamente o mais curto possível. Define uma função anônima que recebe o programa como entrada.
!
, levax XOR 255
, como JSs~
considerariax
um número de 32 bits.<
, multiplicax
por 2 e pega o resultado mod 256.>
, realmente muda os bits dex
1 bit para a direita.@
, pisosx/16
e adiciona-o ax%16*16
.Agradecemos a @vihan por sugerir o uso de
reduce
para salvar um byte.fonte
<
para salvar cerca de 4 bytes. Usando reduzir pode também poupar alguns bytes<
no lugar de==
? Nesse caso, isso não funcionaria, pois os caracteres não-op executariam incorretamente uma operação. Eu usei isso na minha solução anterior de 80 bytes.CJam, 37 bytes
Experimente online no intérprete CJam .
Como funciona
fonte
Caracteres Java (8),
514483411366359239224229198194187186184182181180177 caracteresUau, isso foi muito jogado! Obrigado a todos que me deram sugestões! Eu aprecio muito!
Golpeou 31 (!) Bytes otimizando a troca de mordidelas com operações bit a bit, em oposição a
Integer.???
métodos longos .Jogou 72 caracteres (!!!!) com a remoção da sequência desnecessária criada para trocar petiscos. Muito melhor do que antes !?
Jogou 45 (!!) caracteres removendo o uso
java.util.Scanner
e lendoSystem.in
diretamente. Observe que agora que a expressão lambda se foi, o Java 8 não é mais necessário! Apenas o Java 1 faria!Jogou 7 chars ao criar classe
(default)
(public
palavra-chave removida ), graças a @bmarksJogou 120 chars (!!!!!!!) chars girando todas aquelas
Integer
operações demoradas de classe no bit para255 - a
. Agora isso é muito mais curto!Jogou 15 chars (!) Convertendo turnos em multiplicação e divisão, removendo os chaves da instrução while e tornando
a
local dentro domain
método.Ungolfed 9 = (caracteres por causa de um problema com o deslocamento à esquerda que não descarta o byte mais à esquerda. Portanto, agora o faço
mod (256)
. O deslocamento à direita tornará o número resultante um pouco mais curto do que antes, portanto, não há necessidade de usarmod
o deslocamento à direita. Minha coisa de troca de petiscos trocará os últimos 4 bits e o segundo último petisco, eand (&)
truncará todos os outros bits.O meu programa de inversão não causa problemas se o número original for menor que 256.Jogou
3135 chars graças ao @Geobits, convertendoswitch
declaração para várias declarações ternárias e também convertendo chars para ints, diminuindo os literais.Jogou 7 chars ao remover desnecessários
&240
na troca de petiscos ((a&240)>>4
paraa>>4
e convertendo(a&15)<<4
ema<<4&240
. A última alteração apenas jogou um caractere no entanto.Golfed um caractere removendo desnecessário
=
ema /= 2
, porquea = a /= 2
é equivalente aa = a / 2
.Golfed 2 chars, virando
println
- se paraprint
.Golfou 2 caracteres removendo acidentalmente
a=
ema=255-a
(a=a=255-a
é equivalente aa=255-a
)Golfed 1 char, transformando
a<<4&240
ema%16<<4
.Jogou 1 char adicionando colchetes à parte externa da declaração ternária e fazendo
%256
. Dessa forma,%16
é desnecessário na parte do turno à esquerda da troca de petiscos. Os colchetes adicionam 2 caracteres e os%16
salvos 3 caracteres.Golfed 3 caracteres, alterando
class
ainterface
e removendopublic
usando o recurso de método de interface estática de Java 8. Obrigado a @TheNumberOne (sem comentários, mas encontre sua resposta em "Dicas para jogar golfe em Java"fonte
Integer
os métodos de classe.switch
golfe enquanto. Oscase
/break
são muito longos. Você deve ser capaz de salvar um monte, tornando a coisa toda um ternário; algo comoa=i=='!'?255-a:i==62?a/2:i=='<'?a*2%256:i=='@'?(a&240)>>4|(a&15)<<4:a;
Ferrugem,
121115 bytesExemplo de execução:
Ungolfed:
Surpreendentemente curto para Rust. Nada mais interessante além do fato de eu ter aprendido mais regras de precedência hoje - quem sabia que
(a>>b)|c
é a mesma coisaa>>b|c
?Raspou um byte alterando
n>>=1
paran/=2
; no entanto, o mesmo não pode ser feito com a multiplicação, porque o estouro aritmético é um pânico (ou seja, falha) no Rust.fonte
>>
é uma espécie de divisão semelhante e|
é uma adição semelhante.HP 41C / CV / CX (? Bytes, 42 etapas)
Puramente para risadinhas, aqui está a calculadora HP 41C / CV / CX. (Requer o módulo Extended Functions ou 41CX para a função ATOX.) Infelizmente, a calculadora não informa o tamanho do programa em bytes.
Coloque seu programa no registro Alpha, o que é um pouco complicado, pois não há como entrar! ou @ diretamente do teclado (use XTOA com os códigos ASCII 33 e 64 respectivamente para anexá-los).
As etapas 08 e 10 permitem ignorar códigos de operação inválidos; remova-os para salvar 2 etapas, mas o programa falhará com entrada inválida.
fonte
Python 2, 79 bytes
Percebi que fiz algo muito semelhante a isso em Python anteriormente. Esta é apenas uma porta da minha resposta Ruby , mas, aliás, é a resposta mais curta do Python a partir de agora: D
A diferença da versão Ruby é que esta não ignora instruções inválidas enquanto itera sobre a entrada. Em vez disso, aproveito o fato de que o Python tende a retornar em
-1
vez denil
quando não há correspondência - O valor atual dea
é anexado à parte de trás da matriz de resultados, para que todas as instruções inválidas sejam mapeadas para o mesmo valor inalterado.fonte
Python 3,
1249493 bytes"!" é o mesmo que subtrair de 255.
"<" é o mesmo que multiplicar por 2. Mas o registro de 8 bits significa mod 256.
">" é o mesmo que divisão inteira por 2.
"@" significa mudar os últimos 4 bits (
a%16
) por 4 bits (*16
) e adicionando os quatro primeiros bits (a/16
).EDIT (leia a cópia sem vergonha)
Vi a outra resposta em python (por decaimento Beta). Ele usa uma maneira realmente eficaz de simular casos de troca usando o dicionário. Usando isso, podemos escrever
Obrigado, Beta Decay.
fonte
256
certo? Então por que não fazer isso no final:a={"!":255-a,"<":a*2,">":a//2,"@":(a%16)<<4+a>>4}.get(i,a)%256
. Isso economiza imediatamente um byte (porque você fará ema*2
vez dea<<1
) ... mas a resposta de @ daniero também mostra que, se você fizer dessa maneira,(a%16)<<4
poderá ser reduzido para apenasa<<4
, porque qualquer bit 16 ou maior será eliminado quando você multiplicar por 16 e reduzi-lo mod 256. Bom! Além disso, agora você pode substituir255-a
por-1-a
... ou melhor, apenas~a
. No total, essas sugestões devem economizar 9 bytes.Haskell, 89 bytes
Exemplo de uso:
f "!>>"
->63
fonte
Ferrugem, 111 bytes
Mais um comentário sobre a resposta da @ Doorknob, mas não tenho nenhum representante para comentar, pois acabei de criar uma conta.
Pode-se raspar 10 bytes de sua solução Rust com o seguinte:
fonte
Python 3, 127 bytes
Edit: shorting, obrigado @Jakube
Edit2: corrigir, obrigado @Anachor
fonte
!<
dá510
ao mesmo tempo que deve ser254
Ceilão,
297290Formatado:
#f
e#f0
são números hexadecimais para os nibbles,.byte
converte um número inteiro em um byte. Tenho sorte que o.string
atributo Byte já use a representação não assinada de um byte. O Ceilão também apresenta uma instrução switch sem falhas, e uma string é uma lista de caracteres que podem ser iterados.Também tentei reduzir esses nomes de métodos de turno longo usando uma importação de alias, mas isso na verdade se torna 7 bytes mais:
Formatado:
Isso pode ser útil se precisarmos desses métodos com mais frequência.
fonte
Rubi,
8173 bytesMuito mais simples - sem avaliação! Para cada caractere válido na entrada, ele avalia cada instrução e encontra a instrução apropriada através do índice de
$&
(o caractere atual na entrada).fonte
STATA, 197 bytes
Ungolfed
Não funciona com o intérprete online e requer o intérprete padrão não livre. Isso seria um pouco mais fácil com as operações bit a bit reais, mas não acho que sejam muito úteis para a maioria dos usos comuns do STATA.
fonte
JavaScript, 104
Operadores ternários aninhados mapeiam para instruções.
BITWISE AND é usado para restringir nosso tipo de número a um único byte.
fonte
Julia,
117948673 bytesEsta é uma função anônima que aceita uma string e retorna um número inteiro. Para chamá-lo, atribua-o a uma variável.
Ungolfed:
Economizou 8 bytes graças ao Sp3000 e 13 graças ao Dennis!
fonte
JavaScript (ES6), 76
81Como uma função sem nome, retornando o valor do acumulador
Esta é uma descrição das respostas super inteligentes de @daniero (que têm muito poucos votos positivos)
Bônus: você pode passar um valor inicial do acumulador. Se não for passado, o valor inicial é 0, conforme específico.
Teste a execução do snippet abaixo em qualquer navegador EcmaScript 6 (testei no Firefox)
fonte
Cristal, 139 bytes
fonte
C # 193
fonte
using System;
ou algo assim para acessarConsole.ReadLine
eConsole.Write
sem oSystem.
prefixo?byte
cada operação, mas eu posso estar errado.Lua, 344 char
Inspirado pelo uso de um acumulador de string pelo @Beta Decay, visto que lua não tem tipo de byte. Provavelmente poderia jogar mais usando menos funções.
fonte
R, 194 bytes
destroçado
fonte
<-
pode ser substituído por=
aqui, reduzindo assim o código em 7 bytes. Além disso, você pode ser capaz de substituir a série deif
declarações por uma chamada paraswitch
(como emA=switch(r,"!"=(A+1)%%2, ...)
)b=readline();A=rep(0,8);s=strsplit(b,"")[[1]];for(r in s)A=switch(r,"!"=(A+1)%%2,">"=c(0,A)[1:length(A)],"<"=c(A,0)[-1],"@"=c(A[5:8],A[1:4]),A);print(sum(A*(2^(7:0))))
é 167 bytes.RPL, 170,5 bytes
A entrada deve ser inserida como uma sequência no nível 1.
fonte
K, 57 bytes
É um começo:
testado usando Kona:
Talvez eu consiga fazer melhor no k5, mas é uma série complexa de trocas - por exemplo, converter binário em decimal é tão fácil quanto
2/
, mas o comportamento de?
torna mais difícil lidar com um caso padrão para pesquisa de instruções.fonte
PHP, 189 bytes
Não é que ele supere muitas respostas, é apenas para praticar
fonte
HPPPL ,
302294 bytesUngolfed:
Essa resposta garante que o HP Prime use números inteiros de 8 bits não assinados, mesmo que o modo esteja definido como, por exemplo, 64 bits pelo usuário. Se a calculadora estiver configurada manualmente para usar números inteiros decimais de 8 bits, o
pragma
comando poderá ser omitido. Se a saída não precisar seguir rigorosamente o formato,a*1
o final pode ser simplesmentea
. Multiplicar o resultado por 1 apenas garante que a saída não siga a saída interna para valores inteiros. Oprint
comando na linha 4 também pode ser omitido se o terminal não precisar ser limpo antes de imprimir o resultado. Se passar o programa como um argumento de seqüência de caracteres for permitido, oINPUT
comando também poderá ser omitido.Esta é a versão mais curta com entrada e saída adequada, sem o argumento pragma (se a calculadora estiver definida como Uint8 por padrão:
243 bytes:
fonte
Perl 6,
9689 bytesSolução antiga:
fonte
C #, 119 bytes
Outras versões que tentei, mas preciso de mais bytes:
fonte
Python 2.7.3, 104 bytes
Ter código em cadeias a serem avaliadas parece bastante sujo, mas funciona: D
Aqui está a saída (e entrada realmente ..)
E sim, ele está realmente rodando em um RaspberryPi :)
fonte