Sua tarefa - se você optar por aceitá-la - é criar um programa que analise e avalie uma sequência (da esquerda para a direita e de comprimento arbitrário) de tokens que dão instruções - esquerda ou direita. Aqui estão os quatro tokens possíveis e seus significados:
> go right one single step
< go left one single step
-> go right the total amount of single steps that you've gone right, plus one,
before you previously encountered this token and reset this counter to zero
<- go left the total amount of single steps that you've gone left, plus one,
before you previously encountered this token and reset this counter to zero
Porém, existe um problema - os tokens de instruções que seu programa deve poder analisar serão apresentados desta forma:
<<->-><<->->>->>->
... em outras palavras, eles são concatenados, e é tarefa do seu programa descobrir a precedência correta das direções e a quantidade de etapas a serem seguidas (olhando para o futuro). A ordem de precedência é a seguinte (da maior para a menor precedência):
->
<-
>
<
Se você encontrar <-
quando nenhuma etapa à esquerda foi feita anteriormente desde o início ou desde a última redefinição, dê um único passo à esquerda. A mesma regra se aplica a ->
, mas depois para ir para a direita.
Seu programa deve iniciar em 0 e seu resultado deve ser um número inteiro assinado representando a posição final final.
Você pode esperar que a entrada seja sempre válida (assim, nada como <--->>--<
, por exemplo).
Exemplo de entrada:
><->><-<-><-<>>->
Etapas neste exemplo:
step | token | amount | end position
------+-------+--------+--------------
1. | > | +1 | 1
2. | < | -1 | 0
3. | -> | +2 | 2
4. | > | +1 | 3
5. | <- | -2 | 1
6. | < | -1 | 0
7. | -> | +2 | 2
8. | <- | -2 | 0
9. | < | -1 | -1
10. | > | +1 | 0
11. | > | +1 | 1
12. | -> | +3 | 4
Para esclarecimento: a saída do programa deve ser apenas a posição final final como um número inteiro assinado. A tabela acima está lá apenas para ilustrar as etapas que meu exemplo deu. Não é necessário gerar uma tabela, linha de tabela ou mesmo apenas as posições finais das etapas. Somente a posição final final, como um número inteiro assinado, é necessária.
O código mais curto, depois de uma semana, vence.
<-
é se for imediatamente seguido por a<
ou a->
. Não há como, nessa linguagem, representar a sequência<-
então>
- o que seriago left the total amount of single steps that you've gone left, plus one, then go right one single step
. Isso está correto e por design?Respostas:
GolfScript, 46 caracteres
Este é um dos programas GolfScript mais lineares que já escrevi - não há um único loop, atribuição condicional ou variável nele. Tudo é feito usando manipulação de string:
Primeiro, substituo todas as ocorrências de
->
por)
. Como a entrada é garantida como válida, isso garante que qualquer ocorrência restante de-
deva fazer parte<-
.Em seguida, faço duas cópias da sequência. A partir da primeira cópia, removo os caracteres
<
e-
, deixando apenas>
e)
. Eu, então, duplicar o resultado, remover todo o)
s e cada>
após a última)
da segunda cópia, concatenar-los e contar os caracteres. Assim, com efeito, estou contando:)
,>
após o último)
e>
antes do último)
.Em seguida, eu fazer o mesmo para a outra cópia, só que desta contagem do tempo
<
e<-
, em vez de>
e)
, e removendo os-
s antes da contagem de caracteres final. Assim, conto:<-
,<
após o último<-
e<
antes do último<-
.Por fim, subtraio a segunda contagem da primeira e produzo o resultado.
fonte
Python 2.7 -
154147134128 bytesMudanças sérias foram feitas na maneira como este programa funciona. Removi a explicação antiga, que ainda pode ser encontrada no histórico de edições desta resposta.
Este é nojento.
Funciona da mesma maneira que outras respostas para essa pergunta, substituindo os caracteres na entrada por instruções válidas nesse idioma e executando-os. Há uma grande diferença, porém:
replace
é uma palavra longa. Dane-se isso.O @ProgrammerDan no bate-papo teve a idéia de usar uma tupla com a string
;').replace('
nele 4 vezes, para usar o pré-str.format()
método de formatação de texto. Quatro instâncias de%s
estão na sequência na segunda linha, cada uma tendo seu valor do elemento associado da tupla no final. Como são todos iguais, cada um%s
é substituído por;').replace('
. Ao executar as operações, você obtém esta sequência:Agora é um código python válido que pode ser executado com
exec
. Isso mesmo, querida: s aninhadosexec
me permitem usar operações de string no código que precisa executar operações de string no código . Alguém por favor me mate.O restante é bem direto: cada comando é substituído por um código que monitora três variáveis: A posição atual, o número de direitos desde o último
->
e o mesmo para esquerdas e<-
. A coisa toda é executada e a posição é impressa.Você notará que sim
raw_input(';')
, usando ';' como um prompt, em vez deraw_input()
que não tem nenhum prompt. Isso salva os caracteres de uma maneira não intuitiva: se eu fizesseraw_input()
, teria que preencher a tupla).replace('
e todas as instâncias%s
teriam '; \' 'antes dela, exceto a primeira . Ter um prompt cria mais redundância para que eu possa salvar mais caracteres em geral.fonte
list.index()
retorna-1
quando falha em encontrar o personagem" .. erm no. Isso gera umIndexError
. Você pode ter confundido issostr.find
. Na verdade, você pode substituir[list('><rl').index(c)]
por['><rl'.find(c)]
.Perl,
134131...9995 bytesRecebe a entrada como uma única linha no stdin, por exemplo:
ou:
Dividi as instruções nos operadores "direito" (">" e "->") e "esquerdo" ("<" e "<-"). As vantagens disso são que é mais fácil explorar o paralelismo entre operadores esquerdo e direito, e não precisamos fazer nada sofisticado para tokenizar a string. Cada "direção" é tratada como uma operação de substituição, onde ajustamos o total de corrida pelo número de etapas executadas nessa direção, ignorando a direção reversa que é tratada pela outra operação de substituição. Aqui está um ancestral menos influente desse código como uma espécie de documentação:
Em uma iteração anterior desse código, todas as substituições foram feitas em uma única passagem. Isso tinha a vantagem de manter um mapeamento direto entre $ p / $ pos e a posição que seria retornada em um determinado momento, mas consumia mais bytes de código.
Se você deseja usar () 5.10.0, pode / print / say / raspar outros 2 caracteres da contagem, mas esse não é realmente o meu estilo.
fonte
Perl,
88bytesA entrada é esperada via STDIN, por exemplo:
Atualizar
Não há necessidade de converter a sequência em um somatório, porque
s//
já está contando. :-)Primeira versão
A entrada é esperada via STDIN, exemplo:
Explicação:
A idéia é converter a sequência de direção em um somatório para que o resultado seja gerado de forma simples
print eval
.>
antes de qualquer dar->
dois passos, um de uma vez e outro no seguinte->
. Não importa, qual das vezes->
segue pelo menos um deles. O contador interno é redefinido após o próximo->
, portanto>
, não causa mais etapas, o máximo é duas etapas. Em seguida,->
adiciona um passo para si e os demais>
após o último->
.O mesmo vale para a direção inversa com contagem de passos negativa em vez de positiva.
Por exemplo:
><->><-<-><-<>>->
s/->/+1/
: Comece com a direção para frente, porque->
tem maior precedência.Por exemplo:
><+1><-<+1<-<>>+1
s/>(?=.*1)/+2/g
: O padrão de previsão assegura que apenas o>
antes de qualquer->
seja convertido.Por exemplo:
+2<+1+2<-<+1<-<+2+2+1
s/>/+1/g
: Agora o restante>
está coberto.Por exemplo:
+2<+1+2<-<+1<-<+2+2+1
s/<-/-1/g
: Analógico na direção inversa.Por exemplo:
+2<+1+2-1<+1-1<+2+2+1
s/<(?=.*-)/-2/g
: No padrão de antecipação, o total-1
do primeiro<-
não é necessário, porque não existem-
símbolos de direção restantes.Por exemplo:
+2-2+1+2-1-2+1-1<+2+2+1
s/</-1/g
: O restante<
após o último<-
é convertido.Por exemplo:
+2-2+1+2-1-2+1-1-1+2+2+1
print eval
: Calcule e produza o resultado.Por exemplo:
4
fonte
-p
: 74 bytes I mudou a suas/>//g
paray/>//
salvar um byte em cada caso, o que também permitiu a remoção dos parênteses na expressão.Ruby, 141 bytes
Ungolfed:
fonte
l=1;r=1
pode serl=r=1
e$><<o
pode serp o
. Eu acho que você poderia se barbear muito substituindo a declaração do caso por algo menos volumoso, talvez algo comoeval %w(o-=1;l+=1 o+=1;r+=1 o-=l;l=1 o+=r;r=1)['<>LR'.index c]
l=r=1;o=0;gets.gsub('->',??).scan(/<-|./){eval"o+=#{%w[-1;l+ -l;l 1;r+ r;r][$&[-1].ord%4]}=1"};p o
, você poderia ir até 94 usandoruby -p
D - 243
Golfe :
Sem golfe :
fonte
C,
148141140140:
141:
148:
Com espaço em branco:
Provavelmente muito mais espaço para jogar isso. Eu desisti de tentar manipular 4 variáveis em ternários que capturavam lvalues (continuava saindo por mais tempo e ficando mais tarde), mas não era um primeiro passo ruim. Passe de matriz bastante direto. Recebe a entrada como argumento da linha de comando e gera o valor de retorno.
Você precisará da
-std=c99
bandeira para compilá-la com o gcc.EDIT: Sim, é tarde - perdeu algumas coisas óbvias.
fonte
main
:main(char*x,char**v)
. Então você tem 138 em vez de 140.>><-
dá 0 em vez de 1 ou><->
dá 0 em vez de 2.char
e*
e substituir(*(x+1)==45)?(x++,o-=l+2,l=0):(o--,l++)
por(*++x==45)?(o-=l+2,l=0):(x--,o--,l++)
.JavaScript, 136
Desminificado:
Como funciona
Dada uma entrada de string da seguinte
s
forma:Ele usa um Regex para substituir cada comando por um conjunto de instruções que modificam
z
(a posição final),l
(movimentos da esquerda armazenados) er
movimentos da direita armazenados. Cada Regex é executado em ordem de precedência.Para a entrada acima, isso converte
s
em:Bonito, não é?
Finalmente nós
eval(s)
executar as instruções e alertasz
que contêm a posição final.fonte
Javascript (116,
122,130)116:
122:
130:
fonte
JavaScript [217 bytes]
Provavelmente pode ser encurtado um pouco mais ...
fonte
PHP,
284282Sem regex.
Ungolfed:
fonte
str_split($i)
(1
é o padrão para o segundo argumento). E$i
provavelmente deve estar$c
, correto?$i
): P Corrigida!Outra solução perl, 113 caracteres
Já existem duas respostas que superam isso, é apenas para rir. Ele usa uma abordagem baseada na observação de Ilmari sobre o valor dos tokens:
Explodiu um pouco:
fonte