Втечі з лабіринту!


20

Ви потрапили в цей лабіринт 5х5 - кожна кімната позначена від 1 до 25, а вихід - у кімнаті 1.

введіть тут опис зображення

Вам надається як вхід приміщення, в якому ви зараз перебуваєте. Ваше завдання - вивести найкоротшу послідовність рухів (північ, схід, південь, захід), необхідних для досягнення кімнати 1.

Рухи можна виводити в будь-якому бажаному форматі (список, рядок, масив ...), поки ви використовуєте символи n,w,e,s.

Ось усі тестові випадки:

1 => empty string/list
2 => w
3 => ww
4 => swwnw
5 => wswwnw
6 => seenwnw
7 => nw
8 => wnw
9 => wwnw
10 => swwnwnw
11 => eenwnw
12 => enwnw
13 => nwnw
14 => wnwnw
15 => wwnwnw
16 => enenwnw
17 => nenwnw
18 => wnenwnw
19 => nwnwnw
20 => wnwnwnw
21 => nenenwnw
22 => enwnenwnw
23 => nwnenwnw
24 => wnwnenwnw
25 => nwnwnwnw

Найкоротша відповідь у байтах виграє!


3
Наскільки гнучким є маркування приміщення / введення? Чи можемо ми 0-індекс замість 1-індексу? Чи можемо ми прийняти номер кімнати як персонаж (думаючи, як у базі 36)?
Час Браун

2
@Therandomguy ні, вам потрібно обробити цей специфічний лабіринт.
Арно

6
Оскільки це можливо, я вважаю, що всі можливі випадки повинні бути включені до тестових випадків.
Джонатан Фрех

1
@UnrelatedString Це питання займає 1 вхід та виводить інший шлях на основі його введення. Я вважаю, що ця вимога не відповідає тегу складності колмогорова .
tsh

2
Комусь потрібно надати відповідь у Лабіринті .
Draco18s

Відповіді:


20

Python 2 , 64 байти

def f(n):d=0x1211252b5375>>2*n-4&3;print"nwes"[d];f(n+d*3+d%2-5)

Спробуйте в Інтернеті!

Функція, яка друкує один напрямок на рядок, закінчуючи помилкою.

Постійна 0x1211252b5375кодує в базі 4 напрямок, яким dми рухаємося від номера кожного номера, як число 0 до 3. Цифра вилучення >>2*n-4&3також розроблена для надання негативної помилки зсуву при n=1завершенні коду. Ми оновлюємо номер кімнати nза допомогою зміщення, яке обчислюється у напрямку dяк d*3+d%2-5, яке відображає:

d   d*3+d%2-5
0  -> -5
1  -> -1
2  ->  1
3  ->  5 

1
Я не впевнений, чи дійсно це як є, функції повинні бути повторно використані, і вам потрібно відключити помилку ( try/ except), щоб мати можливість продовжувати виконання після виклику цієї функції.
Ерік Аутгольфер


6

05AB1E , 30 29 байт

-1 байт завдяки чудодійному збігу з простими числами

[Ð#•θzƶ‰`Ó•4вsè<DˆØ·5-+}'‹™¯è

Спробуйте в Інтернеті!

[                      }    # infinite loop:
 Ð                          #  triplicate the room number (initially, the input)
  #                         #  break if room number == 1
   •θzƶ‰`Ó•4в               #  compressed list 202232302231102210202010
             sè             #  use the room number to index into that list
               <            #  decrement
                Dˆ          #  add a copy to the global array
                  Ø         #  nth prime (-1 => 0, 0 => 2, 1 => 3, 2 => 5)
                   ·        #  double
                    5-      #  subtract 5
                      +     #  add that to the room number
'‹™                         # dictionary string "western"
   ¯                        # push the global array
    è                       # index (wraps around, so -1 => n, 0 => w, 1 => e, 2 => s)

1
Це виводи 1для введення1 замість порожнього рядка (легко виправити було б додати ведучий õ?). Крім того, приємна відповідь!
Кевін Круїссен

1
@KevinCruijssen дякую за вказівку на цю помилку! Я знайшов однобайтове виправлення.
Гриммі

5

Рубі , 72 62 байти

f=->n{n<2?'':' en  sw'[x=4*18139004[n]+6*4267088[n]-5]+f[n+x]}

Спробуйте в Інтернеті!

Як?

Хитрість тут полягає у використанні 2 констант, щоб побудувати наступний крок для кожної комірки, а потім рекурсивно вирішити проблему.

2 константи 18139004 і 4267088 - це двійкові рядки, що дають напрямок наступного руху, витягуючи по одному біту з обох для кожної комірки, ми можемо отримати:

"n" = 4*0+6*0-5 = -5
"w" = 4*1+6*0-5 = -1
"e" = 4*0+6*1-5 = +1
"s" = 4*1+6*1-5 = +5

Простіше, ніж пересуватися і маскувати єдине велике двійкове число IMHO.

Коли ми отримаємо напрямок, ми витягуємо відповідну букву з рядка "en sw":

  1   5
  |   |
" en  sw"
   |   |
  -5  -1

І продовжуйте рекурсивно на клітинку [n + x]



3

Perl 5 ( -n), 94 байти

-5 байт завдяки Гримі

@A=map/./g,__wwswsnwwseenwwenwnwnenwn;%H=(n,-5,s=>5,e,1,w,-1);$_+=$H{$,=$A[$_]},say$,until$_<2

ТІО





1
Ви маєте на увазі, що я повинен розміщувати це як окрему відповідь?
Grimmy

1
так, адже, здається, ви зробили більшу частину роботи, було цікаво побачити, як ми завжди можемо заощадити місце
Nahuel Fouilleul



2

Вугілля деревне , 43 40 байт

NθW⊖θ«≔I§”)“⊞x⟧∧⎚⁵2”ιι§nwesι≧⁺⁻⁺﹪ι²×³ι⁵θ

Спробуйте в Інтернеті! Посилання на багатослівну версію коду. На основі відповідей @ ChasBrown та @ xnor. Пояснення:

Nθ

Введіть номер.

W⊖θ«

Встановіть змінну циклу iна одну меншу, ніж номер кімнати, і повторіть, поки вона не дорівнює нулю.

«≔I§”)“⊞x⟧∧⎚⁵2”ιι

Витягніть напрямок із стисненого рядка 0113130113220112010102010. (Провідна 0- це лише цифра заповнення.)

§nwesι

Надрукуйте напрямок.

≧⁺⁻⁺﹪ι²×³ι⁵θ

Використовуйте формулу @ xnor для обчислення нового номера кімнати.


2

Желе , 30 29 байт

“þ&ƊĿñ÷°e’b6Ḥ_5Ż⁸+ị¥ƬI‘ị“®ȯẹ»

Спробуйте в Інтернеті!

Монадійне посилання, що приймає початкову клітинку і повертає рядок з напрямками.

Мені подобається те, що в словнику Джеллі є таке слово, як «Кеннесоу» (місто на північний захід від Атланти, штат Джорджія), яке тут використовується, тому що індексується в ньому символами, що [5, 1, -5, -1] + 1дають nesw!

Пояснення

“þ...e’                    | Base-250 integer 1962789844189344852  
       b6                  | Convert to base 6 (2, 2, 5, 2, 5, 0, 2, 2, 5, 3, 3, 0, 2, 2, 3, 0, 2, 0, 2, 0, 3, 0, 2, 0)
         Ḥ                 | Double
          _5               | Subtract 5
            Ż              | Prepend 0
             ⁸  ¥Ƭ         | Using this as the right argument and the original link argument as the left argument, loop the following as a dyad until there is no change, collecting up results
              +            | - Add the left argument to:
               ị           |   - The left argument indexed into the right argument
                  I        | Differences between consecutive numbers
                   ‘       | Increment by 1
                    ị“®ȯẹ» | Index into "Kennesaw"

2

PHP , 110 байт

Рішення, яке не є великою відповіддю Часа Брауна чи великою відповіддю xnor . Я знаю, що це довше, але я хотів мати інше рішення!

for($n=$argn;$n>1;$n=ord($s[$n*2+1])%30)echo($s='0000w<w sEw"s)n w%w&s-e*e+n&w+w,e/n*w/n,w1n.e5n0w5n2')[$n*2];

Спробуйте в Інтернеті!

Я створив рядок відображення, який містить 2 символи для кожної комірки на дошці. Перший символ для кожної комірки - це переміщення (n / e / s / w), або 0AS 30 коду ASCII другого символу поверне інше число комірки, яке ми повинні слідувати його переміщенню в рекурсивному режимі, поки не дістанемося до виходу з комірки ( cell < 2).

Наприклад для введення 8:

  • 2 символи для комірки 8:w%
  • Це означає, що надрукуйте wі продовжуйте рухатися за коміркою%
  • Код ASCII %становить 37, мод 30 буде 7, тож наступна комірка, яку слід слідувати, - це 7.
  • 2 символи для комірки 7: n (останній символ - пробіл, код ASCII = 32)
  • Це означає, що надрукувати nта продовжити з ходами для комірки 32 mod 30, що є 2.
  • 2 символи для комірки 2: w<(останній символ ASCII код = 60)
  • Це означає, що надрукуйте wта продовжуйте рухатися за коміркою 60 мод 30, яка є 0.
  • Якщо номер комірки менше 2, цикл припиняється!
  • Остаточний друкований результат: wnw

PHP , 75 байт

Цю версію написав Гримі , вона на 35 байт коротше моєї оригінальної відповіді, оскільки він / вона розумніший! Коментар Гримі: "4 * 25 <256, тому вам потрібно лише 1 байт на клітинку, а не 2"

for($n=$argn;$n=ord("0\0~f;6o4R:s%ql&rup*@^tIDbx"[$n%25]);)echo news[$n%4];

Спробуйте в Інтернеті!


PHP , 71 байт

Цей порт відповіді Арнальда, який є портом відповіді xnor , але як цикл замість рекурсивної функції, оскільки він виявляється коротшим у PHP.

for($n=$argn;--$n;$n+=$d*3+$d%2-4)echo nwes[$d=79459389361621/4**$n&3];

Спробуйте в Інтернеті!


2
4 * 25 <256, тож вам потрібно лише 1 байт на клітинку, а не 2: Спробуйте в Інтернеті!
Grimmy

1
@Grimy, дивовижно, я думаю, що ви повинні розмістити його як окрему відповідь, це досить різне.
Ніч2

1
Я не збираюсь цього робити, тож ви вибираєте, включити його у свою відповідь чи залишити це лише як коментар.
Grimmy

1
@Grimy, додав свою версію зі своїм іменем. Спасибі все одно.
Ніч2,

2

C (стук) , 81 байт

v;f(p){p-1&&putchar(v="00wwswsnwwseenwwenwnwnenwn"[p])+f(p+=v%5?6-v%8:v%2?5:-5);}

Спробуйте в Інтернеті!

Завдяки пропозиції @ Tommylee2k -8! + рекурсивний дзвінок

C (стук) , 90 байт

v;f(p){for(char*l="00wwswsnwwseenwwenwnwnenwn";p-1;p+=v%5?6-v%8:v%2?5:-5)putchar(v=l[p]);}

Спробуйте в Інтернеті!

Подібно до всіх не стиснених розчинів.


1
можна скоротити:v;f(p){for(;p-1;p+=v%5?6-v%8:v%2?5:-5)putchar(v="00wwswsnwwseenwwenwnwnenwn"[p]);}
Tommylee2k

1

05AB1E , 45 43 байт

õ?[Ð#.•DUo¢ê`Ω÷‰₂¡)R€ûK•¦sè©?Ž₁9₂в6-'€Ã®kè+

Порт відповіді @ChasBrown 's Python 2 .

Спробуйте в Інтернеті або перевірте всі тестові випадки .

Пояснення:

õ?               # Output an empty string
                 # (to overwrite the implicit output if the input is 1)
[                # Start an infinite loop:
 Ð               #  Triplicate the top of the stack
                 #  (which is the (implicit) input in the first iteration)
  #              #  If it's exactly 1: stop the infinite loop
  .•DUo¢ê`Ω÷‰₂¡)R€ûK
                 #  Push compressed string "a  wwswsnwwseenwwenwnwnenwn"
   ¦             #  Remove the first character
    sè           #  Swap to get the number, and use it to index into the string
      ©          #  Store it in variable `®` (without popping)
       ?         #  Print it without trailing newline
  Ž₁9            #  Push compressed integer 22449
     ₂в          #  Convert to base-26 as list: [1,7,5,11]
       6-        #  Subtract 6 from each: [-5,1,-1,5]
         '€Ã    '#  Push dictionary string "news"
            ®k   #  Get the index in this string of character `®`
              è  #  And use that to index into the integer-list
               + #  And add it to the originally triplicated integer

Дивіться цей мінський наконечник 05AB1E (усі чотири розділи), щоб зрозуміти, чому .•DUo¢ê`Ω÷‰₂¡)R€ûK•це "a wwswsnwwseenwwenwnwnenwn"; Ž₁9є 22449; Ž₁9₂вє [1,7,5,11]; і '€Ãє "news".


1
Цей зручний рядок словника, мабуть, був гарною новиною!
Ніл

@Neil Однозначно. :) Хоча, мабуть, словниковий рядокwestern краще. ; p
Кевін Круїссен

1

Баш , 120 байт

S=__wwswsnwwseenwwenwnwnenwn
N=n-5w-1s05e01
for((i=$1;$i>1;i+=$j)){ d=${S:$i:1};j=${N:`expr index $N $d`:2};printf $d; }

Спробуйте в Інтернеті!

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

Як це працює:

S=__wwswsnwwseenwwenwnwnenwn

Рядок $ S містить по одному символу (n, w, s, e) для кожної кімнати, показуючи, в якому напрямку рухатися, щоб перемістити одну кімнату до виходу, пропускаючи кімнати 0 і 1.

N=n-5w-1s05e01

Рядок $ N має дельту для додавання / віднімання від поточного номера кімнати для кожної зміни напрямку (n: -5, w: -1, s: +5, e: +1)

for((i=$1;$i>1;i+=$j)){ d=${S:$i:1};j=${N:`expr index $N $d`:2};printf $d; }

Почніть з $ i, що дорівнює номеру кімнати, вказаному в командному рядку ($ 1). Призначте символ в індексі $ i в рядку $ S до $ d. Отримайте значення дельти від $ N для напрямку до наступної кімнати, призначивши його $ $.

Друкуйте наступний напрямок, щоб скористатися $ d.

Додавання / віднімання дельти в $ j до / від $ i.

Цикл, поки ми не залишимо номер 2 (поки $ i> 1).



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