Побег из лабиринта!


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помощью смещения, которое вычисляется из направления das d*3+d%2-5, которое отображает:

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

1
Я не уверен, если это действительно как есть, функции должны быть многоразовыми, и вам нужно перехватывать ошибки ( try/ except), чтобы иметь возможность продолжить выполнение после вызова этой функции.
Эрик Outgolfer


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 спасибо за указание на эту ошибку! Я нашел однобайтовое исправление.
Grimmy

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

Проще чем смещаться и маскировать одно большое двоичное число ИМХО.

Когда мы получаем направление, мы извлекаем соответствующую букву из строки «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

TIO





1
Вы имеете в виду, что я должен опубликовать это как отдельный ответ?
Grimmy

1
да, потому что, кажется, вы проделали большую часть работы, было интересно посмотреть, как мы всегда можем сэкономить место
Науэль Фуйе



2

Древесный уголь , 43 40 байт

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

Попробуйте онлайн! Ссылка на подробную версию кода. На основе ответов @ ChasBrown's и @ 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), или 0код 30 ASCII-кода второго персонажа будет возвращать другой номер ячейки, за которым мы должны следить за его движением в рекурсивном режиме, пока не доберемся до выхода из ячейки (cell < 2 ).

Например, для ввода 8:

  • 2 символа для ячейки 8:w%
  • Это означает, что печать wи продолжить ходы для ячейки%
  • Код ASCII %равен 37, мод 30 будет 7, поэтому следующая ячейка будет 7.
  • 2 символа для ячейки 7: n (последний символ - пробел, код ASCII = 32)
  • Это означает печатать nи продолжать ходы для ячейки 32 мод 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
@ Грими, удивительно, я думаю, что вы должны опубликовать его как отдельный ответ, он достаточно отличается.
Night2

1
Я не собираюсь этого делать, поэтому вы выбираете, включать ли это в свой ответ или оставить просто как комментарий.
Grimmy

1
@ Грими, добавил твою версию с твоим именем. В любом случае спасибо.
Night2

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 для направления в следующую комнату, присвоив его $ j.

Выведите следующее направление, чтобы взять $ d.

Добавьте / вычтите дельту из $ j в / из $ i.

Цикл пока мы не покинем комнату № 2 (пока $ i> 1).



Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.