Escreva um programa que tenha uma sequência de comprimento ímpar contendo apenas os caracteres .
e :
. Com o auxílio de uma pilha inicialmente vazia , gere um número a partir desta sequência da seguinte maneira:
Para cada caractere c na string (da esquerda para a direita) ...
- Se c for
.
e a pilha tiver menos de 2 elementos, pressione 1 na pilha. - Se c for
.
e a pilha tiver 2 ou mais elementos, retire os dois principais valores da pilha e empurre sua soma para a pilha. - Se c for
:
e a pilha tiver menos de 2 elementos, pressione 2 na pilha. - Se c for
:
e a pilha tiver 2 ou mais elementos, retire os dois principais valores da pilha e empurre o produto para a pilha.
O número resultante é o valor no topo da pilha. Seu programa deve imprimir esse número em stdout (com uma nova linha à direita opcional).
(Uma pequena análise mostra que resta apenas um número, a menos que a string tenha um comprimento uniforme, e é por isso que estamos ignorando-os. Na verdade, a pilha nunca possui mais de 2 elementos.)
Por exemplo, o número para ::...:.:.
é 9:
2 1 2 2 /______ stack just after the character below is handled
2 2 4 4 5 5 7 7 9 \
: : . . . : . : . <-- string, one character at a time
Como verificação de integridade, eis os números para todas as cadeias de comprimento 1, 3 e 5:
. 1
: 2
... 2
..: 1
.:. 3
.:: 2
:.. 3
:.: 2
::. 4
::: 4
..... 3
....: 2
...:. 4
...:: 4
..:.. 2
..:.: 1
..::. 3
..::: 2
.:... 4
.:..: 3
.:.:. 5
.:.:: 6
.::.. 3
.::.: 2
.:::. 4
.:::: 4
:.... 4
:...: 3
:..:. 5
:..:: 6
:.:.. 3
:.:.: 2
:.::. 4
:.::: 4
::... 5
::..: 4
::.:. 6
::.:: 8
:::.. 5
:::.: 4
::::. 6
::::: 8
O programa mais curto em bytes vence. O desempatador é um post anterior.
- Você pode assumir que a entrada é sempre válida, ou seja, uma string contendo apenas
.
e:
cujo comprimento é ímpar. - Em vez de escrever um programa, você pode escrever uma função que recebe uma sequência válida e imprime ou retorna o número gerado.
Respostas:
CJam,
27 24 2322 bytesBem direto. Eu uso a pilha de CJam como a pilha mencionada na pergunta;)
Algoritmo
Primeiro vamos olhar o código ASCII para
.
e:
.Como no CJam, o índice envolve, vamos ver se podemos usar esses valores diretamente para obter a operação desejada.
Portanto, não posso simplesmente usar os códigos ASCII em uma sequência de operações de 4 comprimentos. Vamos tentar alguns outros valores
que em uma corda de 4 comprimentos se resume a
Eu posso usar esta operação mod 10, mas isso custará 2 bytes. Vamos tentar outra coisa
Bom !, agora subtraímos 1 para a condição de tamanho da pilha para obter os índices
0, 1, 2 and 3
e usar uma5
matriz de comprimento ("1+2* "
) como uma caixa de opção. O último espaço é apenas um preenchedor para o comprimento 5. Este é apenas 1 byte extra em comparação com a operação de modificação.Experimente online aqui
1 byte salvo graças a cosechy
fonte
> <> (Peixe) , 33 bytes
Bastante simples, com pequenos truques / otimizações.
Explicação:
i
= ponto de código do próximo caractere de entrada,-1
se o final da entrada for atingido;a
= 10;b
= 11;)
=>
i
codepoint do primeiro caractere de entrada,b%1-
top_of_stack mod 11 - 1
máscaras48 ('.') , 56 (':')
para1 , 2
i:1+?\~n;
se o fim da entrada alcançado imprimir o último resultado e terminarb%1-
mascarar a entrada para1 , 2
0@
empurre0
sob o número doisi5a*)
leia a próxima entrada e oculte-a para0 , 1
comparar com50
1
(':'
) multiplique os dois principais elementos, criando a pilha [0 produto][0 sum]
ou[0+product=product]
40.
pule (loop) de volta à posição(4,0)
, nosso ponto4
,i:1+?\~n;
fonte
Haskell,
7365 bytesUma solução simples, usando o fato de que a pilha nunca possui mais de 2 elementos.
fonte
C, 104 bytes
Bem, isso é muito longo.
fonte
Pitão,
2524 bytesTive uma idéia estudando a solução de @ isaacg. Mas estou usando uma pilha.
Demonstração on-line ou suíte de testes
Explicação
A primeira coisa que faço é converter a string de entrada em 0s e 1s. A
"."
é convertido em a0
, a":"
em a1
.Então reduzo esta lista de números:
fonte
JavaScript (ES6), 65
Nós usamos apenas 2 células da nossa pilha.
Comece colocando um valor em s [0].
Então, em cada posição ímpar (contando de 0) na string de entrada, coloque um valor em s [1].
Em cada posição par, execute um cálculo (adicione ou multiplique) e armazene o resultado em s [0].
Então esqueça a pilha e use apenas 2 variáveis, a e b.
Um teste rápido
Saída
fonte
f=s=>[(c=s[i]>'.',i&1?b=1+c:+i?c?a*=b:a+=b:a=1+c)for(i in s)]|a
Pitão, 27 bytes
Uma pilha? Quem precisa de uma pilha.
Demonstração.
fonte
Retina ,
1057573 bytesMeu primeiro programa de Retina! (Agradecemos a Martin Büttner por salvar 2 bytes, sem mencionar a invenção do idioma em primeiro lugar.)
Cada linha deve ir em um arquivo separado; ou, você pode colocá-los todos em um arquivo e usar o
-s
sinalizador. A<empty>
notação representa um arquivo / linha vazio.Inspirado pela resposta de mbomb007 , mas adoto uma abordagem um pouco diferente. Uma grande diferença é que eu construo a pilha na frente da string pontilhada (com o topo da pilha voltado para a direita). Isso facilita a conversão de símbolos para os números correspondentes no local. Eu também uso, em
a
vez de1
, trocá-lo apenas no final, para evitar a análise de ambiguidade em sequências como$1a
. Se uma resposta comoaaaaaa
for aceitável como um número unário, as duas últimas linhas / arquivos poderão ser eliminadas para economizar 4 bytes.Explicação:
Corresponde se houver 0 ou 1 item na pilha (
(a+;)?
) seguido por um ponto (\.
); Nesse caso, substitui o período pora;
(ou seja, pressiona 1).Corresponde se houver 0 ou 1 item na pilha seguido por dois pontos. Nesse caso, ele substitui o cólon por
aa;
(ou seja, pressiona 2).Corresponde se houver dois itens na pilha seguidos por um ponto. Exclui o período e o ponto e vírgula entre os itens, adicionando-os.
Corresponde se houver dois itens na pilha, cujo topo é um 2, seguido por dois pontos. Exclui os dois pontos e o 2 e repete o outro número duas vezes, multiplicando-o por 2.
A regex corresponde se houver dois itens na pilha, cuja parte superior é 1, seguida por dois pontos. Exclui os dois pontos e o 1, deixando o outro número inalterado (ou seja, multiplicado por 1).
)`
indica o fim de um loop. Se alguma alteração foi feita na cadeia, o controle retornará para a parte superior do programa e executará as substituições novamente. Se a string parou de mudar, substituímos todos os pontos e dois pontos e tudo o que resta é a limpeza ...Exclui o ponto e vírgula restante.
Transforma todos os a em 1. Novamente, se números unários puderem usar qualquer símbolo, esta etapa será desnecessária.
fonte
Ferrugem, 170 caracteres
Mais uma prova de que Rust é absolutamente terrível no golfe. Código completo não-destruído:
Aqui está um truque interessante que usei neste. Você pode raspar um caractere em uma instrução if / else fazendo com que ele retorne um valor que é imediatamente descartado, o que significa que você precisa apenas de um ponto e vírgula em vez de dois.
Por exemplo,
pode ser transformado em
que salva um personagem cortando um ponto e vírgula.
fonte
Haskell,
888179 BytesParece que alguém me levou até o ponto em uma solução Haskell, não apenas isso, a solução deles é mais curta que a minha. Isso é ruim, mas não vejo razão para não postar o que eu criei.
fonte
APL (50)
Estou em grande desvantagem aqui, porque o APL não é uma linguagem baseada em pilha. Finalmente, acabei abusando da redução para encurtar o programa.
A função interna pega um 'comando' à esquerda e uma pilha à direita e a aplica, retornando a pilha. A função externa reduz a string, começando com uma pilha vazia.
Explicação:
(⌽⍵),⊂⍬
: a lista inicial para reduzir o excesso.⊂⍬
é uma lista vazia em caixa, que representa a pilha,(⌽⍵)
é o inverso da entrada. (A redução é aplicada da direita para a esquerda na lista, para que a sequência seja processada da direita para a esquerda. A reversão da entrada antecipadamente faz com que os caracteres sejam aplicados na ordem correta.){
...}
: a função interna. Ele pega a pilha à direita, um caractere à esquerda e retorna a pilha modificada.F←'.:'⍳⍺
: o índice do caractere na string.:
, este será 1 ou 2, dependendo do valor.2>⍴⍵:F,⍵
: Se 2 for maior que o tamanho atual da pilha, basta acrescentar o valor atual à pilha.⋄
: de outra forma,2↓⍵
: remova os dois principais itens da pilha(
...)/2↑⍵
: reduza uma determinada função sobre eles e adicione-a à pilha.⍎F⌷'+×'
: a função é+
(adição) ou×
(multiplicação), selecionada porF
.⊃
: finalmente, retorne o item mais alto da pilhafonte
Ruby - 96 caracteres
A parte interessante aqui é
eval
.Além disso, estou assumindo que, após o primeiro caractere, a pilha sempre será 2, matemática, 2, matemática, .... Isso me permite usar menos código pegando dois caracteres ao mesmo tempo - nunca preciso descobrir descobrir se um caractere é matemática ou número. É posicional.
Ungolfed:
fonte
TI-BASIC,
7873706966 bytesO TI-BASIC é bom em one-liners, porque os parênteses de fechamento são opcionais; por outro lado, é uma linguagem ruim em que o armazenamento de vários valores é necessário porque o armazenamento em uma variável ocupa de dois a quatro bytes de espaço. Portanto, o objetivo é escrever o máximo possível em cada linha. O TI-BASIC também é péssimo (para uma linguagem tokenizada) na manipulação de cadeias de qualquer tipo; até ler uma substring é demorado.
Os truques incluem:
int(e^([boolean]
em vez de1+(boolean
; salva um bytefonte
".:.":prgmDOTTY
, economizando 4 bytes.1+(":"=sub(Ans,1,1
Vai,
129115112 bytes(um pouco) não destruído:
Experimente online aqui: http://play.golang.org/p/B3GZonaG-y
fonte
Python 3, 74
Primeiro transforma a lista de entrada em uma sequência de 1 e 2, assumindo o primeiro valor como valor inicial
x
. Em seguida, retira dois elementos de cada vez da frentes
, pegando o primeiro número e adicionando ou multiplicando o número atual com base no fato de o segundo ser 1 ou 2.fonte
bem, essa é uma operação tão fácil, sofisticada pela operação (intencionalmente)
é apenas ...
Código: C (80 bytes)
entrada
length = 2n + 1 vetor V do tipo char '.' ou ':'
Saída
um inteiro k
Função
Simulação:
tente aqui
fonte
*(V-1)
) é zero?Retina,
181135129 bytesCada linha deve estar em um arquivo separado.
<empty>
representa um arquivo vazio. A saída está em Unário.Quando${0}1
é usado, as chaves separar$0
do1
, caso contrário, seria$01
, o grupo 1 correspondente. Eu tentei usar$001
, mas isso parece não funcionar no sabor do .NET regex.Editar: encontrado
$&
o mesmo que$0
.No pseudo-código, este seria essencialmente um loop do-while, como visto abaixo. Eu pressiono o primeiro número e, em seguida, faço o loop: pressione o segundo número, remova a operação (instrução), faça contas, remova a operação Continue dando laços. Observe que, quando uma operação é acionada, isso também remove o espaço após todas as instruções serem concluídas.
Comentado:
fonte
(:)(.*)
->$1$2
, que eu tenho certeza que podem ser(:.*)
->$1
(já que você mantém os dois grupos na mesma ordem e não faz mais nada com eles )Python 3, 122 bytes
Ungolfed:
Em python, você faz referência ao índice de uma lista como esta:
Você pode colocar um valor booleano nisso,
True
é1
eFalse
é0
.Experimente online aqui
fonte
Perl, 77 bytes
expandido:
o
@o
matriz mapeia os dígitos para os operadores. Em seguida, substituímos pares de dígitos pelo operador apropriado, reordenado para infix. O regexp começa com,\B
para não correspondermos ao primeiro caractere. O resultado des///g
nos diz quantas parênteses abertas precisamos no início. Então, quando montamos a expressão do infixo completo, podemos avaliá-la. (Removaeval
se você gostaria de ver a expressão).Aqui está o equipamento de teste que eu usei para verificar os resultados:
Entrada é a lista de expressões pontilhadas e seus valores (fornecidos na pergunta) e a saída é pares de {real, esperado}.
fonte