Пройдіться лабіринтом


15

А може, це насправді не лабіринт, але все ж.

Правила:

  1. Введення є рядком два рядки, що складається з *, 1, xі X. Ця струна - це лабіринт, який потрібно пройти. Лінії мають рівну довжину .

    Ви можете взяти введення як рядок із ,(кома) або будь-який зручний роздільник між цими двома рядками. Або ви можете взяти обидва рядки як окремі аргументи своєї функції.

  2. Вихід - це кількість кроків, які потрібно зробити для виходу з рядка (останній крок - це крок, який виводить вас із рядка).

  3. Ви починаєте у верхньому лівому куті (верхній рядок) перед першим символом.

  4. Для кожного кроку ви рухаєтесь вперед одним символом (від n-ої до (n + 1) позиції ). Тоді, залежно від характеру, на який ви наступаєте, результат відрізняється. Ось що робить кожен char:

    • *- нічого. Ви просто наступаєте на нього нормально.
    • 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.


Порожній рядок не повинен бути дійсним введенням, оскільки це не дворядковий рядок
edc65

@edc Haha, я суперечу собі. Так, справді.
nicael

"\n\n"це рядок з двох рядків ...
feersum

@feersum, то я думаю, що вихід повинен бути 1, коли ви починаєте перед першим рядком, потім рухаєтесь на крок вперед, а потім закінчуєте лабіринт ...
Аміт Золото

Відповіді:


5

Равлики, 34 байти

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

Розширено:

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

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


3

Haskell, 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, але хотів би пограти з ним.
nicael


Ви можете використовувати, наприклад, a>'a'замість a=='x'?
feersum

Я цього не зрозумів, але насправді порожній рядок є недійсним введенням (оскільки я заявив, що вхід є дворядковою рядком), тому ви можете видалити перевірку для цього крайового випадку :)
nicael

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


2

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

Гольф:

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

Безголівки:

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

Скрипка


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. Пропозиції щодо вдосконалення оцінюються, особливо із заміною.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.