Cammina nel labirinto


15

O forse non è davvero un labirinto, ma comunque.

Regole:

  1. Ingresso è una stringa di due linee, composto da *, 1, xe X. Quella corda è un labirinto da percorrere. Le linee hanno la stessa lunghezza .

    È possibile prendere l'input come stringa con ,(virgola) o qualsiasi comodo separatore tra queste due righe. Oppure potresti prendere entrambe le righe come argomenti separati per la tua funzione.

  2. L'output è il numero di passaggi che è necessario eseguire per uscire dalla stringa (l'ultimo passaggio è il passaggio che consente di uscire dalla stringa).

  3. Inizi nell'angolo in alto a sinistra (la linea più alta), prima del primo simbolo.

  4. Per ogni passaggio, ci si sposta in avanti di un simbolo (dall'ennesima (n + 1) alla posizione ). Quindi, a seconda del personaggio su cui calpesti, il risultato è diverso. Ecco cosa fa ogni personaggio:

    • *- Niente. Lo calpesti normalmente.
    • x- dopo averlo calpestato, cambia la linea, ma rimani sulla stessa distanza orizzontale dall'inizio. Ad esempio, sei salito sulla terza posizione della linea superiore e xqui hai incontrato una lettera minuscola . Quindi si passa immediatamente alla riga inferiore, ma di nuovo alla terza posizione.
    • X- cambia linea e vai alla posizione successiva. L'esempio è lo stesso lì, ma ti sposti anche dalla terza alla quarta posizione (quindi sei sulla seconda linea nella quarta posizione).
    • 1 - vai avanti di un'altra posizione.

Una volta che ogni personaggio fa il suo lavoro, viene sostituito con uno spazio e non "funziona" più.

Seguono esempi.

  1. Input :

    x
    *
    

    Come detto prima, inizi prima del primo simbolo della prima riga. Il primo passo ti sposta sulla lettera xe questa lettera passa alla seconda riga. La lettera xnon funziona più come x, ma sostituita con *. Ciò sarà più pertinente negli ultimi esempi. Ora sei su un asterisco nella riga inferiore e non ti ha fatto nulla.

    Il secondo passo ti sta portando avanti e tu esci dalla stringa, quindi il labirinto è completo e ha fatto 2 passi.

    Uscita 2 .

  2. Input :

    xX*
    x1*
    

    1 ° passo : vai avanti x, che ti sposta sulla xriga inferiore. Ecco la regola che dice che il carattere usato è sostituito da un asterisco. Quindi si torna indietro sulla prima riga, ma non è più xpresente, poiché è stato utilizzato ed è diventato un asterisco. Quindi ti muovi in ​​sicurezza su questo asterisco e il passaggio è completato (ora sei nella prima posizione della prima riga).

    2 ° passo : vai avanti X, ti spinge alla linea inferiore e poi ti spinge in avanti. Ora risiedi sulla terza posizione della seconda riga (asterisco), non avendo mai visitato la seconda posizione (che contiene 1).

    3 ° passo : vai avanti, uscendo dalla stringa.

    Uscita : 3.

Casi test:

  1. Ingresso:

    *1*
    xxx
    

    Uscita: 3. (perché 1ti fa saltare in terza posizione). Lì non visiti mai la seconda riga, ma è necessaria una parte dell'input.

  2. Ingresso:

    *X*1*x
    x*1xx*
    

    Uscita: 4.

  3. Ingresso:

    1x1x
    ***X
    

    Uscita: 3.

  4. Ingresso:

    1*x1xxx1*x
    x*x1*11X1x
    

    Uscita: 6.

  5. Ingresso:

    xXXXxxx111*
    **xxx11*xxx
    

    Uscita: 6.


Una stringa vuota non dovrebbe essere un input valido, in quanto non è una stringa a due righe
edc65

@edc Haha, mi sto contraddicendo. Si Certamente.
nicael,

"\n\n"è una stringa di due righe ...
feersum

@feersum allora penso che dovrebbe essere l'output 1, mentre inizi prima della 1a riga, poi vai avanti di un passo e poi finisci il labirinto ...
Amit Gold,

Risposte:


5

Lumache, 34 byte

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

Allargato:

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

Per un percorso che esegue N passaggi, il programma trova una corrispondenza corretta per ogni attraversamento di 0 passaggi, 1 passaggi, ..., N - 1 passaggi.


3

Haskell, 68 66 65 byte

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

La funzione #accetta entrambe le linee come parametri separati. Esempio di utilizzo: "1x1x" # "***X"-> 3.

Dobbiamo solo contare le stelle su *cui calpestiamo più 1 per andarcene.

(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

Modifica: @feersum ha salvato un byte. Grazie!


Potresti probabilmente fornire una demo funzionante (su ideone.com sarebbe conveniente), non sono un programmatore di Haskell ma mi piacerebbe giocarci.
nicael,

1
@nicael: vedi qui
nimi

Potresti usare ad esempio a>'a'invece di a=='x'?
febbraio

Non me ne sono reso conto, ma in realtà la stringa vuota è un input non valido (poiché mi sono dichiarato che l'input è una stringa a due righe), quindi potresti rimuovere la convalida per questo caso limite :)
nicael

@feersum: sì, funziona. Grazie!
nimi,

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}

Meno golf

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
}

Test

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 byte

golfed:

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 byte

Sto pensando di creare una versione che mostri ogni passaggio riprodotto uno dopo l'altro, visualizzato su una pagina 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}

Utilizzato più byte di quanto sperassi quando lo sostituivo xcon *JS immutabile Strings. I suggerimenti per migliorare sono apprezzati, specialmente con la parte di ricambio.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.