Ande pelo labirinto

15

Ou talvez não seja realmente um labirinto, mas ainda assim.

Regras:

  1. Entrada é uma seqüência de duas linhas, consistindo de *, 1, xe X. Essa corda é um labirinto para percorrer. As linhas têm o mesmo comprimento .

    Você pode considerar a entrada como uma string com ,(vírgula) ou qualquer separador conveniente entre essas duas linhas. Ou você pode usar as duas linhas como argumentos separados para sua função.

  2. Resultado é o número de etapas que você deve executar para sair da sequência (o último passo é a etapa que o move para fora da sequência).

  3. Você começa no canto superior esquerdo (a linha superior), antes do primeiro símbolo.

  4. Para cada etapa, você avança com um símbolo (da enésima a (n + 1) ª posição ). Então, dependendo do personagem em que você pisa, o resultado é diferente. Aqui está o que cada caractere faz:

    • *- nada. Você apenas pisa nele normalmente.
    • x- depois de pisar, alterne a linha, mas permaneça na mesma distância horizontal desde o início. Por exemplo, você pisou na terceira posição da linha superior e encontrou uma letra minúsculax aqui. Então você se move imediatamente para a linha inferior, mas novamente na terceira posição.
    • X- mude a linha e vá para a próxima posição. O exemplo é o mesmo lá, mas você também se move da terceira para a quarta posição (portanto, você está na segunda linha na quarta posição).
    • 1 - apenas avance em mais uma posição.

Uma vez que cada personagem faz seu trabalho, ele é substituído por um espaço e não funciona mais.

Seguem exemplos.

  1. Entrada :

    x
    *
    

    Como dito anteriormente, você começa antes do primeiro símbolo da primeira linha. O primeiro passo leva você à letra xe essa letra muda para a segunda linha. A letra xnão funciona mais como x, mas substituída por* . Isso será mais relevante nos últimos exemplos. Agora você está em um asterisco na linha inferior e isso não fez nada para você.

    O segundo passo é avançar e você sair da corda, para que o labirinto seja concluído e foram necessários 2 passos.

    Saída 2 .

  2. Entrada :

    xX*
    x1*
    

    1º passo : você xsegue em frente , o que o move na xlinha inferior. Aí vem a regra que diz que o caractere usado é substituído pelo asterisco. Então você volta para a primeira linha, mas ela não está mais xlá, pois foi usada e se tornou um asterisco. Então você se move com segurança nesse asterisco e a etapa é concluída (agora você está na primeira posição da primeira linha).

    2º passo : você segue em frente X, empurra você para a linha inferior e empurra você para a frente. Agora você reside na terceira posição da segunda linha (asterisco), nunca tendo visitado a segunda posição (que contém 1).

    3º passo : você avança, saindo da corda.

    Saída : 3.

Casos de teste:

  1. Entrada:

    *1*
    xxx
    

    Saída: 3. (porque 1faz você pular na terceira posição). Lá você nunca visita a segunda linha, mas é necessária parte da entrada.

  2. Entrada:

    *X*1*x
    x*1xx*
    

    Saída: 4.

  3. Entrada:

    1x1x
    ***X
    

    Saída: 3.

  4. Entrada:

    1*x1xxx1*x
    x*x1*11X1x
    

    Saída: 6.

  5. Entrada:

    xXXXxxx111*
    **xxx11*xxx
    

    Saída: 6.

nicael
fonte
Uma cadeia vazia não deve ser uma entrada válida, pois não é um dois linha da corda
edc65
@edc Haha, estou me contradizendo. Sim, de fato.
Nicael 12/07
"\n\n" é uma string de duas linhas ...
feersum
@feersum então eu acho que a saída deve ser 1, como você começar antes da 1ª linha, então você avançar um passo, e depois de terminar o labirinto ...
Amit ouro

Respostas:

5

Caracóis, 34 bytes

A^
\1r|\xud|\Xaa7},(\*|\xud=\x)r},

Expandido:

{
    {
        \1 r |
        \x ud |
        \X aa7
    },
    (\* | \x ud =\x)
    r
},

Para um caminho que executa N etapas, o programa encontra uma correspondência bem-sucedida para cada passagem de 0 etapas, 1 etapas, ..., etapas N-1.

feersum
fonte
3

Haskell, 68 66 65 bytes

(a:b)#l@(c:d)|a<'+'=1+b#d|a>'w'=l#('*':b)|a>'W'=d#b|1<2=b#d
_#_=1

Função # usa as duas linhas como parâmetros separados. Exemplo de uso: "1x1x" # "***X"-> 3.

Nós apenas temos que contar as estrelas * que pisamos mais 1 para partir.

(a:b)#l@(c:d)             -- bind: a -> first char of first line
                                   b -> rest of first line
                                   l -> whole second line
                                   c -> first char of second line (never used)
                                   d -> rest of second line
   |a < '+' = 1+b#d       -- stepped on a *, so add 1 and go on
   |a > 'w' = l#('*':b)   -- x switches lines and replaces the x with *
   |a > 'W' = d#b         -- X switch lines and go on
   |1<2     = b#d         -- the rest (-> 1) simply walks forward
_#_=1                     -- base case: the empty string counts 1 for leaving

Edit: @feersum salvou um byte. Obrigado!

nimi
fonte
Você provavelmente poderia fornecer uma demonstração funcional (no ideone.com seria conveniente), eu não sou um programador Haskell, mas gostaria de brincar com ela.
Nicael 11/07
1
@nicael: see here
nimi
Você poderia usar, por exemplo, em a>'a'vez de a=='x'?
feersum 12/07
Eu não ter percebido isso, mas seqüência realmente vazia é uma entrada inválida (desde que eu já disse a mim mesmo que a entrada é uma seqüência de duas linhas), para que você possa remover a validação para este caso extremo :)
nicael
@feersum: sim, isso funciona. Obrigado!
N
2

JavaScript (ES6), 119

l=>{z=-~l.search`
`,l=[...l+' '];for(n=p=0;(c=l[p%=2*z])>' ';p+=c>'X'?z:c>'1'?z+1:c>'0'?1:(++n,1))l[p]='*';return-~n}

Menos golfe

l=>{
  z=1+l.search`\n`;
  l=[...l+' '];
  for( n = p = 0; 
       (c=l[p%=2*z])>' '; 
       p += c>'X' ? z : c>'1' ? z+1 : c>'0'? 1 : (++n,1) )
    l[p] = '*';
  return 1+n
}

Teste

f=l=>{z=-~l.search`
`,l=[...l+' '];for(n=p=0;(c=l[p%=2*z])>' ';p+=c>'X'?z:c>'1'?z+1:c>'0'?1:(++n,1))l[p]='*';return-~n}

[['x\n*',2]
,['xX*\nx1*',3]
,['*1*\nxxx',3]
,['*X*1*x\nx*1xx*',4]
,['1x1x\n***X',3]
,['1*x1xxx1*x\nx*x1*11X1x',6]
,['xXXXxxx111*\n**xxx11*xxx',6]
].forEach(t=>{
  var i=t[0],k=t[1],r=f(i) 
  console.log('Test result '+r+(r==k?' OK ':' KO (expected '+k+')')+'\n'+i)
})  
 

edc65
fonte
2

TSQL (sqlserver 2012+), 276 bytes

Golfe:

DECLARE @i VARCHAR(99)=
'xXXXxxx111*'+CHAR(13)+CHAR(10)+
'**xxx11*xxx'

,@t BIT=0,@c INT=1,@ INT=1WHILE @<LEN(@i)/2SELECT @t-=IIF(a like'[1*]'or'xx'=a+b,0,1),@c+=IIF(a='*'or'xx'=a+b,1,0),@+=IIF(a='x'and'x'>b,0,1)FROM(SELECT SUBSTRING(d,@t*c+@,1)a,SUBSTRING(d,(1-@t)*c+@,1)b FROM(SELECT LEN(@i)/2+1c,REPLACE(@i,'X','q'COLLATE thai_bin)d)x)x PRINT @c

Ungolfed:

DECLARE @i VARCHAR(99)=
'xXXXxxx111*'+CHAR(13)+CHAR(10)+
'**xxx11*xxx'

,@t BIT=0,@c INT=1,@ INT=1
WHILE @<LEN(@i)/2
  SELECT
    @t-=IIF(a like'[1*]'or'xx'=a+b,0,1),
    @c+=IIF(a='*'or'xx'=a+b,1,0),
    @ +=IIF(a='x'and'x'>b,0,1)
  FROM
    (
      SELECT
        SUBSTRING(d,@t*c+@,1)a,
        SUBSTRING(d,(1-@t)*c+@,1)b
      FROM 
        (SELECT LEN(@i)/2+1c,REPLACE(@i,'X','q'COLLATE thai_bin)d)x
    )x

PRINT @c

Violino

t-clausen.dk
fonte
1

JavaScript, 211 bytes

Estou pensando em criar uma versão que mostre cada etapa executada uma após a outra, exibida em uma página da web.

(x,y)=>{t=0;l=0;n=1;while(t<x.length){c=(l?x:y);if(c[t]=='x'){l=!l;if(l){x=x.slice(0,t-2)+'*'+x.slice(t-1);}else{y=y.slice(0,t-2)+'*'+y.slice(t-1);}}if(c[t]=='X'){l=!l;t++;}if(c[t]=='1'){return n}

Usou mais bytes do que eu esperava ao substituir xpor *causa de JS imutável Strings. Sugestões para melhorar são apreciadas, especialmente com a peça de reposição.

charredgrass
fonte