Пройти лабиринт

15

Или, возможно, это не настоящий лабиринт, но все же.

Правила:

  1. Ввод является строкой две строки, состоящей из *, 1, xи X. Эта нить - лабиринт, через который нужно пройти. Строки имеют одинаковую длину .

    Вы можете взять ввод в виде строки с ,(запятой) или любым удобным разделителем между этими двумя строками. Или вы можете взять обе строки в качестве отдельных аргументов вашей функции.

  2. Выход - это количество шагов, которые вы должны предпринять, чтобы выйти из строки (последний шаг - это шаг, который выводит вас из строки).

  3. Вы начинаете в верхнем левом углу (верхняя линия), перед первым символом.

  4. Для каждого шага вы двигаетесь вперед на один символ (от n-й до (n + 1) -й позиции ). Затем, в зависимости от характера, на которого вы наступаете, результат будет другим. Вот что делает каждый символ:

    • *- ничего. Вы просто наступаете на это нормально.
    • x- как только вы наступите на него, переключите линию, но оставайтесь на том же горизонтальном расстоянии от начала. Например, вы вышли на третью позицию более высокой строки и встретили здесь нижний регистр x. Затем вы сразу переходите на нижнюю линию, но снова на третью позицию.
    • X- переключить линию и перейти к следующей позиции. Пример там тот же, но вы также переходите с третьей на четвертую позицию (таким образом, вы находитесь на второй строке в четвертой позиции).
    • 1 - просто двигаться вперед еще на одну позицию.

Как только каждый персонаж выполняет свою работу, он заменяется пробелом и больше не «работает».

Примеры следуют.

  1. Вход :

    x
    *
    

    Как сказано выше, вы начинаете перед первым символом первой строки. Первый шаг перемещает вас на букву, xи эта буква переключает вас на вторую строку. Буква xбольше не функционирует x, но заменена на* . Это будет более актуально в последних примерах. Вы сейчас на звёздочке в нижней строке, и она ничего не сделала для вас.

    Второй шаг продвигает вас вперед и вы выходите из струны, так что лабиринт завершен, и он занял 2 шага.

    Выход 2 .

  2. Вход :

    xX*
    x1*
    

    1-й шаг : вы двигаетесь дальше x, что перемещает вас по xнижней линии. Здесь следует правило, согласно которому используемый символ заменяется звездочкой. Затем вы возвращаетесь на первую строку, но ее больше xнет, поскольку она была использована и стала звездочкой. Таким образом, вы безопасно перемещаетесь по этой звездочке, и шаг завершен (теперь вы находитесь на первой позиции первой строки).

    2-й шаг : вы двигаетесь дальше X, он подталкивает вас к нижней линии, а затем подталкивает вас вперед. Теперь вы находитесь на третьей позиции второй строки (звездочка), никогда не посещая вторую позицию (которая содержит 1).

    3-й шаг : вы двигаетесь вперед, выходя из строки.

    Выход : 3.

Тестовые случаи:

  1. Входные данные:

    *1*
    xxx
    

    Выход: 3. (потому что 1заставляет вас прыгать на третьей позиции). Там вы никогда не посещаете вторую строку, но это обязательная часть ввода.

  2. Входные данные:

    *X*1*x
    x*1xx*
    

    Выход: 4.

  3. Входные данные:

    1x1x
    ***X
    

    Выход: 3.

  4. Входные данные:

    1*x1xxx1*x
    x*x1*11X1x
    

    Выход: 6.

  5. Входные данные:

    xXXXxxx111*
    **xxx11*xxx
    

    Выход: 6.

nicael
источник
Пустая строка не должна быть допустимым вводом, так как это не строка из двух строк
edc65
@edc Ха-ха, я противоречу себе. Да, в самом деле.
Никаль
"\n\n"это строка из двух строк ...
feersum
@feersum тогда я думаю, что вывод должен быть 1, когда вы начинаете до 1-й строки, затем вы продвигаетесь вперед на один шаг, а затем вы заканчиваете лабиринт ...
Amit Gold

Ответы:

5

Улитки, 34 байта

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

Expanded:

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

Для пути, который занимает N шагов, программа находит одно успешное совпадение для каждого обхода: 0 шагов, 1 шаг, ..., N - 1 шаг.

feersum
источник
3

Хаскелл, 68 66 65 байт

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

функция # принимает обе строки как отдельные параметры. Пример использования: "1x1x" # "***X"->3 .

Мы просто должны считать звезды * мы наступаем, плюс 1 за уход.

(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

Изменить: @feersum сохранил байт. Благодарность!

Ними
источник
Не могли бы вы предоставить рабочую демонстрацию (на ideone.com это было бы удобно), я не программист на Haskell, но хотел бы поиграть с ней.
Никель
1
@nicael: см. здесь
Ними,
Не могли бы вы использовать, например, a>'a'вместо a=='x'?
feersum
Я не понял этого, но на самом деле пустая строка является недопустимым вводом (поскольку я сам заявил, что ввод является строкой из двух строк), так что вы можете удалить проверку для этого крайнего случая :)
крайнего
@feersum: да, это работает. Благодарность!
Ними,
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}

Меньше гольфа

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
}

Тестовое задание

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
источник
2

TSQL (sqlserver 2012+), 276 байт

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

скрипка

t-clausen.dk
источник
1

JavaScript, 211 байт

Я думаю о создании версии, которая показывает каждый шаг, воспроизводимый после друг друга, отображаемый на веб-странице.

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

Используются больше байт , чем я надеялся при замене xс *из - за JS непреложного Strings. Предложения по улучшению приветствуются, особенно с запасной частью.

charredgrass
источник