Spaceruj po labiryncie

15

A może nie jest to tak naprawdę labirynt, ale jednak.

Zasady:

  1. Wejście jest ciągiem dwóch linii, składające się z *, 1, xiX . Ten sznurek jest labiryntem do przejścia. Linie mają równą długość .

    Możesz wziąć dane wejściowe jako ciąg znaków za pomocą , (przecinek) lub dowolny wygodny separator między tymi dwoma wierszami. Lub możesz wziąć obie linie jako osobne argumenty dla swojej funkcji.

  2. Wynik to liczba kroków, które należy wykonać, aby wyjść z ciągu (ostatni krok to etap, który wyprowadza cię z łańcucha).

  3. Zaczynasz w lewym górnym rogu (wyższa linia), przed pierwszym symbolem.

  4. Dla każdego kroku przesuwasz się do przodu o jeden symbol (od n-tego do (n + 1) pozycji ). Następnie, w zależności od postaci, na którą stąpasz, wynik jest inny. Oto, co robi każdy znak:

    • *- nic. Po prostu stąpaj po nim normalnie.
    • x- po wejściu na niego zmień linię, ale pozostań w tej samej poziomej odległości od początku. Na przykład nadepnąłeś na trzecią pozycję wyższej linii i spotkałeś tu małe litery x. Następnie natychmiast przechodzisz do dolnej linii, ale znowu na trzeciej pozycji.
    • X- przełącz linię i przejdź do następnej pozycji. Przykład jest tam taki sam, ale przesuwasz się również z trzeciej do czwartej pozycji (w ten sposób znajdujesz się w drugiej linii na czwartej pozycji).
    • 1 - po prostu przejdź do przodu o jeszcze jedną pozycję.

Gdy każda postać wykona swoją pracę, zostaje zastąpiona spacją i przestaje „działać”.

Przykłady podano poniżej.

  1. Wejście :

    x
    *
    

    Jak powiedziano wcześniej, zaczynasz przed pierwszym symbolem pierwszego wiersza. Pierwszy krok przenosi cię na literę, xa ta litera powoduje przejście do drugiej linii. Litera xnie działa już jako x, ale została zastąpiona przez* . Będzie to bardziej odpowiednie w tych ostatnich przykładach. Jesteś teraz na gwiazdce w dolnej linii i nic ci to nie zrobiło.

    Drugi krok przesuwa cię do przodu i wychodzisz ze sznurka, więc labirynt jest ukończony i zajął 2 kroki.

    Wyjście 2 .

  2. Wejście :

    xX*
    x1*
    

    Pierwszy krok : idziesz dalej x, co przenosi cię na xdolną linię. Oto reguła, która mówi, że użyta postać jest zastąpiona gwiazdką. Następnie wracasz do pierwszej linii, ale już nie jestx ma, ponieważ została użyta i stała się gwiazdką. Poruszasz się więc bezpiecznie tą gwiazdką i krok jest zakończony (jesteś teraz na pierwszej pozycji pierwszego wiersza).

    Drugi krok : idziesz dalej X, to popycha cię do dolnej linii, a następnie popycha do przodu. Znajdujesz się teraz na trzeciej pozycji drugiej linii (gwiazdka), nigdy nie odwiedziłeś drugiej pozycji (która zawiera 1).

    Trzeci krok : idziesz naprzód, wychodząc ze sznurka.

    Wyjście : 3.

Przypadki testowe:

  1. Wejście:

    *1*
    xxx
    

    Wyjście: 3. (bo 1skacze na trzecią pozycję). Tam nigdy nie odwiedzasz drugiej linii, ale wymaga to części danych wejściowych.

  2. Wejście:

    *X*1*x
    x*1xx*
    

    Wyjście: 4.

  3. Wejście:

    1x1x
    ***X
    

    Wyjście: 3.

  4. Wejście:

    1*x1xxx1*x
    x*x1*11X1x
    

    Wyjście: 6.

  5. Wejście:

    xXXXxxx111*
    **xxx11*xxx
    

    Wyjście: 6.

Nicość
źródło
Pusty ciąg nie powinien być prawidłowym wejściem, ponieważ nie jest to ciąg
dwuwierszowy
@edc Haha, sam sobie zaprzeczam. W rzeczy samej.
nicael
"\n\n"jest ciągiem dwóch linii ...
feersum
@feersum, więc myślę, że wynik powinien być taki 1, jak zaczynasz przed pierwszą linią, a następnie przesuwasz się o jeden krok do przodu, a następnie kończysz labirynt ...
Amit Gold

Odpowiedzi:

5

Ślimaki, 34 bajty

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

Rozszerzony:

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

Dla ścieżki, która wykonuje N kroków, program znajduje jedno udane dopasowanie dla każdego przejścia 0 kroków, 1 kroków, ..., N - 1 kroków.

feersum
źródło
3

Haskell, 68 66 65 bajtów

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

Funkcja #przyjmuje obie linie jako osobne parametry. Przykład użycia: "1x1x" # "***X"-> 3.

Musimy tylko policzyć gwiazdy, na *które nadepniemy, plus 1 za odejście.

(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

Edycja: @feersum zapisał bajt. Dzięki!

nimi
źródło
Czy mógłbyś prawdopodobnie dostarczyć działające demo (na ideone.com byłoby to wygodne), nie jestem programistą Haskell, ale chciałbym się nim bawić.
nicael,
1
@nicael: patrz tutaj
nimi
Czy możesz użyć np. a>'a'Zamiast a=='x'?
feersum
Nie zdawałem sobie z tego sprawy, ale tak naprawdę pusty łańcuch jest nieprawidłowym wejściem (ponieważ sam stwierdziłem, że jest to ciąg dwuwierszowy), więc możesz usunąć sprawdzanie poprawności dla tego przypadku krawędzi :)
nicael
@feersum: tak, to działa. Dzięki!
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}

Mniej golfa

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

edc65
źródło
2

TSQL (sqlserver 2012+), 276 bajtów

Gra w golfa:

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

Nie golfowany:

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

Skrzypce

t-clausen.dk
źródło
1

JavaScript, 211 bajtów

Zastanawiam się nad stworzeniem wersji, która pokazuje każdy krok odtwarzany jeden po drugim, wyświetlana na stronie internetowej.

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

Użyłem więcej bajtów, niż miałem nadzieję przy zamianie xz *powodu niezmienności JS Strings. Doceniane są sugestie dotyczące ulepszenia, szczególnie w przypadku części zamiennej.

charredgrass
źródło