Куля мікрогравітації


33

Ви знаходитесь на передовій міжгалактичній космічній станції. Ваш друг, котрий є неповнолітнім у навчанні гравітації, щойно створив гру, яка передбачає використання мікрогравітації як способу переміщення м’яча.

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

  • У вас є дві кнопки спрямованості, зліва <і справа >.
  • Також у вас є 2 кнопки тяжкості вгору ^та вниз v(принаймні, з вашої системи відліку)
  • Ці кнопки зі стрілками використовуйте для переміщення кулі на екрані.

"Зараз є деякі правила, яких потрібно дотримуватися". вона каже

  1. Перед тим, як дістатися до чашки, необхідно пройти всі майданчики \ /
  2. Стрілки < > ^ vвикористовуються для вказівки руху м’яча
  3. Гравітація ^ v(вгору і вниз). Це переміщує м'яч до усієї наступної платформи в цьому напрямку. (Відстань не обчислюється вгору та вниз)
  4. Втратити м'яч - це погано! Не падайте через край і не перемикайте гравітацію занадто рано, щоб ваш куля ніколи не досягав платформи
  5. Рух рахується кроками < >
  6. М'яч може входити в чашку з будь-якого напрямку, дотримуючись правила 1
  7. Ви повинні вказати напрямок сили тяжіння, щоб куля не випливала
  8. Рух може бути випадковим до тих пір, доки дотримуються правила 1 та правила 4
  9. У випадках, які неможливо вирішити, вивести помилковий або недійсний

Простий приклад кульки, платформи та чашки:

v
o
---\ /

v>

 o
---\ /

v>>

  o
---\ /

v>>>

   o
---\ /

v>>>>


---\o/

Приклад повторного переходу через ту саму платформу.

v    

 o
 ----

\ /-------

v>   

  o
 ----

\ /-------

v>>

   o
 ----

\ /-------

v>>>

    o
 ----

\ /-------

v>>>>


 ----
     o
\ /-------

v>>>>>


 ----
      o
\ /-------

v>>>>>>


 ----
       o
\ /-------

v>>>>>>>


 ----
        o
\ /-------

v>>>>>>>>


 ----
         o
\ /-------

v>>>>>>>><<<<<<<< # move all the way to the left to get to the cup


 ----

\o/-------

Приклад перемикання сили тяжіння

v
   --/ \

o
----

v>
   --/ \

 o
----

v>>
   --/ \

  o
----

v>>>
   --/ \

   o
----

v>>>^
   --/ \
   o

----

v>>>^>
   --/ \
    o

----

v>>>^>>
   --/ \
     o

----

v>>>^>>>
   --/o\


----

Завдання

Ваше завдання - створити програму, яка буде приймати ASCII уявлення курсу як вхідне. І виведіть рядок зі стрілками, що <>^vпредставляють напрямок і гравітаційне тягнення, щоб перемістити кульку oпо всій platformsчашці.

Діють стандартні правила гольф-коду

Випробування

Введення (Ситуація, коли гравітація перемикається)

         ----   --/ \
---    --
o

  ------    -----

Вихідні дані

^>>v>>>>>^>>>>>v>>>>^>>>

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


Введення (ситуація, коли напрямок перемикається)

       ---
o   
----
    ---

     -----  

    --\ /

Вихідні дані

v>>>>>>^>>>v<<<<<v>>>

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


Введення (ситуація, коли потрібно двічі переходити на одній платформі)

 o
 ------

  ------

 ------ 

\ /------

Вихідні дані

v>>>>>><<<<<<>>>>>>><<<<<<

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


Погані випадки, програма повинна вивести Falsy для цих

Жоден спосіб, щоб м'яч дістався до наступної платформи

o
--- ---

Куля випливе в космос

---
o
   ---

Ситуація, коли м'яч потрапляє до чашки, але всі майданчики не проходять.

o
----
    ----
        \ /----

4
Правило 1 робить це досить складним ... хммм ...
JungHwan Min

Чи завжди головоломка буде вирішуваною? Також, я думаю, ви повинні включити тестовий випадок, який вимагає зворотного відстеження.
FryAmTheEggman

Так, головоломки завжди повинні бути вирішеними. Прогалини або стрибки, які втрачають м'яч або ситуації, які роблять лабіринт нерозв'язним, не будуть зроблені.
tisaconundrum

4
@JungHwanMin Правило 1 - саме тому це завдання, а не банально.
Erik the Outgolfer

2
Я ніколи так не відчував кролячої нори з питань кодового гольфу
dj0wns

Відповіді:


11

Pyth, 431 байт

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

Jmmck\:cd\%c.Z"xÚU±Ã@DÅ W,J áDPáÒ­V`ýüw{g$ÍÀÞÇr§o.÷å8èÝÇr{øºy{~1åõ:noßÃú/.yçíäÂ'ëL¢êF¸èÆ\ka´QÒnÒ@tãÒÁµÆ¾õö»bÍH¥¦$¨%5Eyîÿ}ó§ûrh³oÄåËÄqõ XÔHû"\_KYDrGHFN@JGIn=bm:d.*NHHRb)RHDiNTR.turNG.tT;M:jH)hh@JG0DXGHN=Ti+3qG\^HI!},GTK aK,GT aY+eKNI&!g5T}\EjT)N.q;D(GHNT)INIqHhT=ZrGhtTInZhtTXHZ+eTN))).?I&nHhTgGhtTXHhtT+eTH; aK,di2i1r0.z aY+eKk#=N.(Y0(6\vkN)(7\^kN)(8\v\<N)(9\v\>N)(10\^\<N)(11\^\>N

Спробуйте тут (остання тестова шафа потрібна занадто довго, її потрібно перевірити за допомогою локальної установки Pyth).

Шестнадцятковий дамп коду (використання xxd -r <filename>для декодування):

00000000: 4a6d 6d63 6b5c 3a63 645c 2563 2e5a 2278  Jmmck\:cd\%c.Z"x
00000010: da55 8eb1 8ac3 400c 447f c58d 2057 2c99  .U....@.D... W,.
00000020: 4aa0 e144 50e1 d2ad 5660 87fd 84fc 7f77  J..DP...V`.....w
00000030: 7b67 1f24 cdc0 8319 de1c c772 a76f 2ef7  {g.$.......r.o..
00000040: e538 e8dd c772 7bf8 9eba 797b 7e31 e5f5  .8...r{...y{~1..
00000050: 8e3a 6e8f 6fdf c3fa 2f2e 0c79 e717 ede4  .:n.o.../..y....
00000060: c21f 27eb 8395 189a 4c15 140b a28d ea82  ..'.....L.......
00000070: 46b8 e8c6 5c05 1b6b 1d61 b490 0251 d28c  F...\..k.a...Q..
00000080: 6ed2 4087 74e3 1ad2 c1b5 c6be f5f6 1cbb  n.@.t...........
00000090: 6286 cd48 a5a6 24a8 2535 4579 eeff 7df3  b..H..$.%5Ey..}.
000000a0: 8a8a 1613 a7fb 7204 68b3 6fc4 e51b 160c  ......r.h.o.....
000000b0: 1304 cbc4 8a71 f57f 2058 d448 fb22 5c5f  .....q.. X.H."\_
000000c0: 4b59 4472 4748 464e 404a 4749 6e3d 626d  KYDrGHFN@JGIn=bm
000000d0: 3a64 2e2a 4e48 4852 6229 5248 4469 4e54  :d.*NHHRb)RHDiNT
000000e0: 522e 7475 724e 472e 7454 3b4d 3a6a 4829  R.turNG.tT;M:jH)
000000f0: 6868 404a 4730 4458 4748 4e3d 5469 2b33  hh@JG0DXGHN=Ti+3
00000100: 7147 5c5e 4849 217d 2c47 544b 2061 4b2c  qG\^HI!},GTK aK,
00000110: 4754 2061 592b 654b 4e49 2621 6735 547d  GT aY+eKNI&!g5T}
00000120: 5c45 6a54 294e 2e71 3b44 2847 484e 5429  \EjT)N.q;D(GHNT)
00000130: 494e 4971 4868 543d 5a72 4768 7454 496e  INIqHhT=ZrGhtTIn
00000140: 5a68 7454 5848 5a2b 6554 4e29 2929 2e3f  ZhtTXHZ+eTN))).?
00000150: 4926 6e48 6854 6747 6874 5458 4868 7454  I&nHhTgGhtTXHhtT
00000160: 2b65 5448 3b20 614b 2c64 6932 6931 7230  +eTH; aK,di2i1r0
00000170: 2e7a 2061 592b 654b 6b23 3d4e 2e28 5930  .z aY+eKk#=N.(Y0
00000180: 2836 5c76 6b4e 2928 375c 5e6b 4e29 2838  (6\vkN)(7\^kN)(8
00000190: 5c76 5c3c 4e29 2839 5c76 5c3e 4e29 2831  \v\<N)(9\v\>N)(1
000001a0: 305c 5e5c 3c4e 2928 3131 5c5e 5c3e 4e    0\^\<N)(11\^\>N

Пояснення

Основна ідея цієї програми полягала у використанні регулярних виразів для зміни вхідних даних. Для економії місця всі ці регулярні вирази містяться в стисненому рядку. Перший крок програми - розпакувати рядок і розділити його на єдиний регулярний вираз та відповідні рядки заміни.

            .Z"..."     Decompress the string
           c       \_   Split the result into pieces (separator is "_")
  m    cd\%             Split all pieces (separator is "%")
 m ck\:                 Split all sub-pieces (separator is ":")
J                       Assign the result to variable J

Вміст змінної Jє:

[[['\\\\ /', '=M='], ['/ \\\\', '=W=']],
 [[' (?=[V6M=-])', 'V'], ['o(?=[V6M=-])', '6']],
 [['(?<=[A9W=-]) ', 'A'], ['(?<=[A9W=-])o', '9'], ['(?<=[X0W=-])V', 'X'], ['(?<=[X0W=-])6', '0']],
 [['6V', 'V6'], ['0X', 'X0'], ['6-', '6='], ['0-', '0='], ['6M', 'VE'], ['0M', 'XE']],
 [['A9', '9A'], ['X0', '0X'], ['-9', '=9'], ['-0', '=0'], ['W9', 'EA'], ['W0', 'EX']],
 [['[MW-]']],
 [['[60]']],
 [['[90]']],
 [['V6', '6V'], ['V0', '6X'], ['X6', '0V'], ['X0', '0X']],
 [['6V', 'V6'], ['0V', 'X6'], ['6X', 'V0'], ['0X', 'X0']],
 [['A9', '9A'], ['A0', '9X'], ['X9', '0A'], ['X0', '0X']],
 [['9A', 'A9'], ['0A', 'X9'], ['9X', 'A0'], ['0X', 'X0']]]

KY   Set the variable K to an empty list

Функція rзастосовує заміни регулярних виразів зі списку, що зберігається в Jіндексі, Gдо всіх рядків списку H. Він повертається, як тільки будь-який з рядків був змінений.

DrGH                         Define the function r(G,H)
    FN@JG              )     Loop for all entries in J[G]
             m:d.*NH         Regex substitution, replace N[0] with N[1] in all strings in list H
           =b                Store the result in variable b
         In         HRb      If b != H return b
                        RH   Return H

Функція iсхожа на функцію rз 2 відмінностями. Він застосовує підстановки в перекладеному списку (вертикальний, а не горизонтальний). Він також виконує заміни повторно, доки що-небудь буде змінено.

DiNT          ;   Define the function i(N,T)
           .tT    Transpose the list T
       urNG       Apply r(N,...) repeatedly as long as something changes
    R.t           Transpose the result back and return it

Функція gперевіряє, чи може регулярний вираз зі списку, що зберігається в Jіндексі G, знайдений у будь-якому рядку списку H.

M             Define the function g(G,H)
     hh@JG    Get the single regex stored in J[G]
  jH)         Join all strings in H
 :        0   Check if the regex is found anywhere in the joined string

Решта коду містить фактичну логіку програми. Він здійснює пошук попереду на широту можливих рухів, поки не знайдеться рішення. Позиція в дереві пошуку однозначно визначається напрямом гравітації та модифікованою копією введення програми. Щоб уникнути обробки однієї і тієї ж позиції знову і знову, оброблені позиції зберігаються у глобальному списку K. Позиції, які ще належить обробити, зберігаються разом із відповідною частиною рішення у списку Y.

Модифікація введення та ініціалізації Kта Yвиконується за допомогою наступного коду:

           .z          Get all input as a line list
     i2i1r0            Apply the regular expressions stored in J[0] horizontally, and the the ones from J[1] and J[2] vertically
   ,d                  Create a list with " " (represents "no gravity set") and the modifed input
 aK                    Append the result to the list K
                 eK    Retrieve the appended list again
                +  k   Append "" to the list (represents the empty starting solution)
              aY       Append the result to the list Y

Модифікація входу робить щось на зразок наступного. Вхід:

         ----   --/ \
---    --
o

  ------    -----

перетворюється на:

VVVVVVVVV----VVV--=W=
---VVVV--AAAXVVVXAAAA
9AXVVVVXAAAAXVVVXAAAA
AAXVVVVXAAAAXVVVXAAAA
AA------AAAA-----AAAA

Значення мають таке значення:

  • - Платформа, яку потрібно все-таки відвідати
  • = Платформа, яку більше не потрібно відвідувати
  • M Чашку, яку можна вводити з силою тяжіння, встановити на "вниз"
  • W Чашку, яку можна вводити з силою тяжіння, встановити на "вгору"
  • V Безпечно переходити до цього місця із гравітацією, встановленою на "вниз"
  • A Безпечно переміщатися до цього місця з гравітацією, встановленою на "вгору"
  • X Безпечно пересуватися до цього місця незалежно від налаштування сили тяжіння
  • 6 Куля на місці, яке було б позначено як V
  • 9 Куля на місці, яке було б позначено як A
  • 0 Куля на місці, яке було б позначено як X

Логіка використовує регулярні вирази для виконання рухів. У наведеному вище прикладі, якщо для сили тяжіння було б встановлено значення "вгору", ми можемо замінити "9A" на "A9" на регулярний вираз, щоб перемістити м'яч праворуч. Це означає, що намагаючись застосувати регулярний вираз, ми можемо знайти всі можливі рухи.


Функція Xвиконує вертикальні руху кульки на основі поточного значення сили тяжіння, зберігають результат в глобальних списках Kі Y, і перевіряє , якщо рішення було знайдено.

DXGHN                                             ;   Define the function X(G,H,N)
        +3qG\^                                        Select the correct set of regular expressions based on the current gravity setting G (3 for "v" and 4 for "^")
     =Ti      H                                       Apply i(...,H) and store the result in T 
               I!},GTK                                If [G,T] not in K
                       aK,GT                          Store [G,T] in K 
                             aY+eKN                   Store [G,T,N] in Y 
                                   I&!g5T}\EjT)       If J[5] not found in T and T contains "E" (all platforms visited and ball in cup)
                                               N.q    Print N and exit

Функція (реалізує перевірку на 4 кнопки спрямованості / гравітації. Кнопки гравітації можна натискати лише в тому випадку, якщо змінилася б сила струму і якщо м'яч знаходиться в безпечному місці для зміни сили тяжіння. Кнопки спрямованості можна натискати, лише якщо безпечно пересуватися до відповідного місця.

D(GHNT)                                                    ;   Define the function ( (G,H,N,T)
       IN                           )                          If N is not empty (contains either "<" or ">" representing directional buttons)
         IqHhT                     )                           If H (gravity setting for which this test is performed) is equal T[0] (the current gravity)
              =ZrGhtT                                          Apply r(G,T[1]) and store the result in Z (G is the appropriate regex index for the combination of gravity and directional button, T[1] is the current modified input) 
                     InZhtT       )                            If Z != T[1] (the regex operation changed something, meaning we found a valid move)
                           XHZ+eTN                             Call X(H,Z,[T[2],N]) 
                                     .?                        Else (gravity button pressed)
                                       I                       If ...
                                         nHhT                  H (new gravity setting) is not equal T[0] (current gravity setting) 
                                        &                      ... and ...
                                             gGhtT             J[G] found in T[1] (ball is in an appropriate place to switch gravity) 
                                                  XHhtT+eTH    Call X(H,T[1],[T[2],H])

Нарешті основна петля. Перший елемент Yвидаляється неодноразово, і перевіряються всі можливі рухи.

#                                                        Loop until error (Y empty)
 =N.(Y0                                                  Pop first element of Y and store it in the variable N
       (6\vkN)                                           Call ( (6,"v","",N)
              (7\^kN)                                    Call ( (7,"^","",N)
                     (8\v\<N)                            Call ( (8,"v","<",N)
                             (9\v\>N)                    Call ( (9,"v",">",N)
                                     (10\^\<N)           Call ( (10,"^","<",N)
                                              (11\^\>N   Call ( (11,"^",">",N)

Я маю рацію, думаючи, що ви вважаєте, що кожен вхід вирішується? Оскільки питання все ще говорить про те, що слід виявити нерозв’язні вхідні дані, однак коментарі дозволяють припустити, що кожен вхід буде вирішеним. Я не впевнений, що це так, хоча я думаю, що ваш код не виявляє нерозв'язності.
Джонатан Фрех

@JonathanFrech Якщо вхід нерозв’язний, вихід не буде. Коли всі можливості були перевірені, Yсписок буде порожнім, поп викине помилку і #цикл закінчиться.
Sleafar

1
Коли ви виймаєте чашку з входу (`/ \`), головоломка стає нерозв'язною (оскільки ви не можете дістатись до чашки), але програма все ще генерує результат.
Джонатан Фрех

Я не мав на увазі те, що робить ваша програма, я зазначив, що цей нерозв’язний вклад головоломки генерує результат.
Джонатан Фрех

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