Deixe-me falar sobre um sistema numérico simples. (que eu inventei apenas para esse desafio)
Este sistema contém as funções ()
, []
, {}
e <>
.
1 ()
Quando ()
não há argumentos, ele avalia como 0
.
Quando ()
é dado um ou mais argumentos, ele avalia a soma dos argumentos.
2) []
Quando []
não há argumentos, ele avalia como -1
.
Quando []
é fornecido um ou mais argumentos, ele avalia o primeiro argumento menos a soma dos outros argumentos.
3) {}
Quando {}
não há argumentos, ele avalia como 1
.
Quando {}
recebe um ou mais argumentos, ele avalia o produto desses argumentos.
4) <>
Quando <>
não há argumentos, ele avalia como 1
.
Quando <>
recebe um ou mais argumentos, ele avalia o primeiro número inteiro dividido pelo produto dos outros argumentos.
Sua tarefa
Dada uma sequência que contém um número válido (isso significa que os colchetes são balanceados, sem divisão por 0s etc.) nesse sistema simples de números, imprima seu valor.
Casos de teste
() -> 0
(()()) -> 0
([][]) -> -2
({}<>) -> 2
({}[]) -> 0
[] -> -1
[[][]] -> 0
[()<>] -> -1
{()} -> 0
{([]<>)} -> 0
Lembre-se, isso é código-golfe , então o código com o menor número de bytes vence.
fonte
5/3
,5/-3
,-5/3
e-5/-3
?Respostas:
Dyalog APL , 94 bytes
o←{(⊂(1⊃⍵),⍺⍺⊃⍵),2↓⍵}⋄u←{(⊃⍵,⍺⍺1)⍺⍺⍵⍵/1↓⍵}⋄⍎⍕'+/o' '-u+o' '×/o' '÷u×o' '(⊂⍬),'[')]}>'⍳⌽⍞],'⊂⍬'
usa
⎕IO←0
substitui
)]}>
por uma chamada de função que pega uma pilha, aplica uma operação em seu quadro superior, exclui-o e anexa o resultado ao seu próximo quadro (o operador monádicoo
é usado para isso; o operador diádicou
lida com os casos mais complicados de-
e÷
)substitui
([{<
pelo código que adiciona um quadro à pilha ((⊂⍬),
)executa a expressão resultante (invertida, para corresponder à ordem de execução da APL) com uma pilha inicial de um quadro vazio (
⊂⍬
)fonte
Haskell,
357306277251228224188185180 bytesUm analisador baseado em token com uma pilha explícita.
(%)
pega uma pilha de tokens e um caractere e pressiona (código de operação, número padrão) ou (0, número) para({[<
, ou exibe os números mais altos e um código de operação e pressiona a resposta)}]>
. Os códigos de operação são codificados por um corte de enumeração ascii.Parabéns a @ChristianSievers por sua ótima resposta, da qual pedi emprestadas algumas idéias.
One-liner!
Agora com menos manipulação de erros! Uso:
Obrigado @ChristianSievers por salvar 14 + 3 bytes!
Obrigado @Zgarb por salvar alguns + 4 bytes!
fonte
(0,[0,0,1,-1,1]!!o):s
na quinta linha?!
, para que você possa fazer(s:_)!_=d s
o segundo caso. Além disso, acho que você poderia ligarx<-p$d<$>init a,y<-d$last a
no último caso de%
.%
você pode soltar parênteses ao redor_:b
eg c
.Python 2,
292265248235223206204 bytesSubstitui todos os colchetes por um lambda que faz o que o colchete faz e avalia o código Python resultante. Requer sua entrada entre aspas, como
'[<><>([]{})]'
.Este programa armazena o tipo de colchete como o primeiro caractere em cada seqüência de caracteres no
for
, e tudo depois da palavra-chavelambda
como o restante. Ele então usa o primeiro caractere para substituir; o resto é combinado em um lambda(lambda*x:sum(x))()
.Experimente no Ideone!
fonte
PEG.js (ES6) , 132 bytes
Deve ser corrigido agora.
Explicação
Mais legível:
O PEG.js é uma versão estendida do Javascript criada especificamente para análise. É MUITO rigoroso, e é por isso que eu tive que usar
var
. Além disso, parece haver um bug com colchetes dentro de strings, que incharam significativamente o código.Para começar, definimos uma regra
x
que corresponde a qualquer colchetea
que pode ou não conter várias expressões que correspondem à regrax
.Para cada partida para regra
x
, pressionamos um 0 na matriz da partida internab
seb
o comprimento for 1.Se
b
o comprimento for maior que 0, então encontramos o índice dea
in([<
e obtemos um caractere+-/
usando esse índice. Se o resultado for indefinido (o que significava quea
era{
), transformamos o resultado em*
. Finalmente, aderimos a um espaço e nos juntamosb
ao resultado.Se
b
comprimento = 0, então encontramos o índice dea
in([<
e obtemos um caractere10
usando esse índice. Se o resultado é indefinido (significando quea
era{
ou<
), transformamos o resultado em 2. Finalmente, simplesmente diminuímos.No final, podemos apenas avaliar a expressão e somar o resultado.
fonte
Perl, 113 + 2 = 115 bytes
Corra com
-lp
(penalidade de 2 bytes).Mais legível (nota: esta "versão mais legível" não será executada, porque eu coloquei comentários em locais que não são permitidos sintaticamente):
A idéia básica é que estamos convertendo uma entrada como
[()<>]
no programa Perlb(a(0),d(0),0),
via processamento de texto; Perl está bem com a vírgula à direita. No início, definimos as funçõesa
,b
,c
,d
para ter o mesmo efeito que o()
,[]
,{}
,<>
construções de linguagem que está implementando; cada um desconsidera seu último argumento (o 0 no final), que é incluído para garantir que todas as entradas sejam analisadas corretamente e funcionem usando a implementação comumente vista na programação funcional em que a cabeça e a cauda são processadas separadamente. Porqueb(e,f,g,0)
significae-f-g
, isto é, trata especialmente seu primeiro argumento, enquantoa
trata seus argumentos simetricamente (a(e,f,g,0)
meiose+f+g
), implementamosa
recursivamente eb
via chamadaa
.c
ed
tem um relacionamento semelhante. Todas essas quatro funções são muito semelhantes, portanto, nós as geramos em tempo de execução, em vez de implementá-las separadamente; armazenamos um modelo que se aplica a todas as quatro funções em uma string e, em seguida, geramos as funções substituindo caracteres no modelo.Como o Perl
/
faz a divisão de ponto flutuante, o implementado{}
também. Suponho que isso não seja um problema por si só ou-Minteger
(selecione uma variante de idioma em que todas as operações aritméticas sejam operações inteiras) seja gratuito, porque, caso contrário, eu teria que gastar bytes extras escrevendo uma divisão inteira em Perl, que não parece ser o principal problema do problema. (Eu acho que você precisaria gastar quatro bytes mudando(shift)
paraint+(shift)
; eu não testei isso.)fonte
Octave,
215206198 bytesexperimente online
fonte
PHP,
315300285258250244 bytessubstitui subexpressões por sublinhado + valor; o loop quebra quando a iteração não substitui.
19 anos desde que conheci C, 17 anos trabalhando com PHP;
esta é a primeira vez que
strtok
faz sentido ... ajudando a economizar 24 bytes!demolir
fonte
ES6 (Javascript),
250,171,154,149, 147 bytesUma versão Javascript pura.
A "metaprogramação" (como a maioria das outras respostas aqui) converte o texto do programa de entrada em um programa Javascript correspondente, aplicando várias substituições diretas de texto (ou seja, mantendo a estrutura do programa como está).
Provavelmente pode ser jogado mais.
ATUALIZAÇÃO (v2.1)
ATUALIZAÇÃO (v2)
Acabei de perceber que vírgulas pendentes nas matrizes ES são totalmente válidas, portanto todo o código de normalização de vírgula pode ser removido. Também seguiu um excelente conselho de @Titus, sobre a otimização da pesquisa do alfabeto.
ATUALIZAÇÃO (v1)
Removido o alias duplicado de "substituição".
ATUALIZAÇÃO (v1)
Use um alfabeto melhor: () => 1+ [] => 0 {} => 2 * <> => 2 / (cada caractere pode ser reutilizado diretamente como valor ou operador)
Substituir reduzir () por substituir () (mapeamento do alfabeto)
Processamento constante de braçadeiras de embutimento, abertura e fechamento constantes em uma única etapa
Golfe (v2.1)
Golfe (v1)
Golfe (v0)
Explicado (v0)
Teste
Saída de teste
fonte
s.reduce((r,c)=>r+="abcdefgh"["()[]{}<>".indexOf(c)],'')
(-5)? Nesse caso, você pode se lembrarindexOf
de uma variável e pegar o operador de uma terceira string literal.Haskell,
184 179 172 161 161 160 159 151 148145 bytesDescida recursiva, enfiando a entrada porque Haskell. Como de costume, a última linha não é uma definição, mas afirma a função que resolve o problema. Portanto, para testar, coloque as linhas, exceto a última em um arquivo, carregue-a e faça algo assim:
Agradecemos a @Zgarb pela inspiração e muitas dicas detalhadas, e a @Angs pela inspiração de sua solução e outras dicas.
Não foi especificado como a divisão deve se comportar com números inteiros negativos. De qualquer forma, o uso repetido
div
parece errado, pois não é o mesmo que usardiv
uma vez com o produto dos valores restantes. Agora usandoquot
, eu obtenho os mesmos resultados para<{}([][])[]>
e<{}{([][])[]}>
.Para um código agradável, quase legível, veja a primeira versão. As versões intermediárias contêm todos os tipos de código agradável e intimidador e ajudam a entender esta versão.
fonte
(!)=(,)
e usando em!
vez de tuplas explícitas.m x
ed x
como1#x
e0#x
, você pode mesclar os casosm[x]
ed[x]
em um, que eu acho que poupa alguns bytes também.!
truque não compensa. Sua segunda sugestão é má, lá está o meu código quase legível ... Inteligente!s%(c:i)=(s?c,i)
es?')'=sum s
etc será muito mais curto, pois você pode se livrar dosi
s repetidos . ..Não, espere, isso provavelmente não vai funcionar por causa dos%(_:i)
caso.elem
ediv
, isso deve economizar mais alguns bytes.JavaScript (ES6), não
eval
, 156 bytesExplicação: O regexp localiza o primeiro colchete de fechamento não processado e corresponde ao colchete de abertura (presumivelmente) correspondente e a quaisquer argumentos intermediários. Os argumentos são divididos e reduzidos de acordo com a operação (infelizmente '(' e '[' não são o par ideal para
+
e-
)) ou, se não houver argumentos, o valor apropriado é calculado (novamente a correspondência de caracteres com valores é abaixo do ideal) do meu ponto de vista) .O resultado é então substituído por um espaço à esquerda para separá-lo de outros resultados. A função se chama recursivamente até que não haja mais alterações a serem feitas, nesse caso, ele retorna o valor resultante. Exemplo:fonte