15
\$\begingroup\$

Or maybe it's not really a labyrinth, but still.

Rules:

  1. Input is a two-line string, consisting of *, 1, x and X. That string is a labyrinth to walk through. The lines have the equal length.

    You could take the input as a string with , (comma) or any convenient separator between these two lines. Or you could take both lines as separate arguments to your function.

  2. Output is the number of steps you have to take to exit the string (last step is the step which moves you out of the string).

  3. You start in the top left corner (the higher line), before the first symbol.

  4. For each step, you move forward by one symbol (from nth to (n+1)th position). Then, depending on the character you step on, the outcome is different. Here's what each char does:

    • * - nothing. You just step on it normally.
    • x - once you stepped on it, switch the line, but remain on the same horizontal distance from the beginning. For example, you stepped on the third position of the higher line, and met a lowercase x here. Then you immediately move to the lower line, but again at the third position.
    • X - switch the line and go to the next position. The example is the same there, but you also move from the third to the forth position (thus you're on the second line at the forth position).
    • 1 - just move forward by yet another position.

Once each character does its job, it's replaced with a space and no longer "works".

Examples follow.

  1. Input:

    x
    *
    

    As said before, you start before the first symbol of the first line. The first step moves you on letter x and this letter switches you to the second line. The letter x no longer functions as x, but replaced with *. This will be more relevant in the latter examples. You're now on an asterisk on the lower line, and it did nothing to you.

    The second step is moving you forward and you exit the string, so the labyrinth is completed, and it took 2 steps.

    Output 2.

  2. Input:

    xX*
    x1*
    

    1st step: you move on x, which moves you on the x of the lower line. Here comes the rule which says that the used character is replaced with asterisk. Then you move back on the first line, but it's no longer x there, since it has been used and became an asterisk. So you move safely on this asterisk and the step is completed (you are now on the first position of the first line).

    2nd step: you move on X, it pushes you to the lower line and then pushes you forward. You now reside on the third position of the second line (asterisk), having never visited the second position (which contains 1).

    3rd step: you move forward, exiting the string.

    Output: 3.

Test cases:

  1. Input:

    *1*
    xxx
    

    Output: 3. (because 1 makes you jump on the third position). There you never visit the second line, but it's required part of the input.

  2. Input:

    *X*1*x
    x*1xx*
    

    Output: 4.

  3. Input:

    1x1x
    ***X
    

    Output: 3.

  4. Input:

    1*x1xxx1*x
    x*x1*11X1x
    

    Output: 6.

  5. Input:

    xXXXxxx111*
    **xxx11*xxx
    

    Output: 6.

\$\endgroup\$
  • \$\begingroup\$ An empty string should not be a valid input, as it's not a two line string \$\endgroup\$ – edc65 Jul 12 '16 at 10:15
  • \$\begingroup\$ @edc Haha, I'm contradicting myself. Yes, indeed. \$\endgroup\$ – nicael Jul 12 '16 at 10:22
  • \$\begingroup\$ "\n\n" is a two line string... \$\endgroup\$ – feersum Jul 12 '16 at 12:53
  • \$\begingroup\$ @feersum then I think output should be 1, as you start before the 1st line, then you move forward one step, and then you finish the labyrinth... \$\endgroup\$ – Amit Gold Jul 18 '16 at 10:58
5
\$\begingroup\$

Snails, 34 bytes

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

Expanded:

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

For a path that takes N steps, the program finds one successful match for each traversal of 0 steps, 1 steps, ..., N - 1 steps.

\$\endgroup\$
3
\$\begingroup\$

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

Function # takes both lines as separate parameters. Usage example: "1x1x" # "***X" -> 3.

We just have to count the stars * we step on plus 1 for leaving.

(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 saved a byte. Thanks!

\$\endgroup\$
  • \$\begingroup\$ Could you probably provide a working demo (on ideone.com it would be convenient), I'm not a Haskell programmer but would like to play with it. \$\endgroup\$ – nicael Jul 11 '16 at 20:41
  • 1
    \$\begingroup\$ @nicael: see here \$\endgroup\$ – nimi Jul 11 '16 at 20:46
  • \$\begingroup\$ Could you use e.g. a>'a' instead of a=='x' ? \$\endgroup\$ – feersum Jul 12 '16 at 6:41
  • \$\begingroup\$ I haven't realized that, but actually empty string is invalid input (since I've stated myself that the input is a two-line string), so you could remove the validation for this edge case :) \$\endgroup\$ – nicael Jul 12 '16 at 10:26
  • \$\begingroup\$ @feersum: yes, that works. Thanks! \$\endgroup\$ – nimi Jul 12 '16 at 14:44
2
\$\begingroup\$

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}

Less golfed

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

\$\endgroup\$
2
\$\begingroup\$

TSQL(sqlserver 2012+), 276 bytes

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

Fiddle

\$\endgroup\$
1
\$\begingroup\$

JavaScript, 211 bytes

I'm thinking about making a version that shows each step played after each other, displayed on a webpage.

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

Used more bytes than I'd hoped to when replacing x with * because of JS immutable Strings. Suggestions to improve are appreciated, especially with the replacement part.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.