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.


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.


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!


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)
})  
 


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


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.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.