Bóng siêu trọng lực


33

Bạn đang ở trên một trạm vũ trụ liên thiên hà tiên tiến. Một người bạn của bạn, người đang khai thác trong Nghiên cứu về lực hấp dẫn, đã tạo ra một trò chơi liên quan đến việc sử dụng vi trọng lực như một cách để di chuyển quả bóng xung quanh.

Cô ấy đưa cho bạn một bộ điều khiển nhỏ với bốn mũi tên định hướng trên đó và một cấu trúc giống như mê cung với một quả bóng ngồi bên trái. Cô bắt đầu giải thích cách trò chơi hoạt động.

  • Bạn có 2 nút định hướng, trái <và phải >.
  • Bạn cũng có 2 nút trọng lực, lên ^và xuống v(ít nhất là từ khung tham chiếu của bạn)
  • Bạn sẽ sử dụng các nút mũi tên này để di chuyển quả bóng xung quanh màn hình của bạn.

"Bây giờ có một số quy tắc cần phải được tuân theo." cô ấy nói

  1. Tất cả các nền tảng phải được duyệt qua trước khi đến cốc \ /
  2. Mũi tên < > ^ vsẽ được sử dụng để xác định chuyển động của quả bóng
  3. Trọng lực là ^ v(lên & xuống). Điều này di chuyển quả bóng tất cả các cách để nền tảng tiếp theo theo hướng đó. (Khoảng cách không được tính cho lên và xuống)
  4. Mất bóng là xấu! Đừng ngã qua rìa và đừng chuyển trọng lực quá sớm để bóng của bạn không bao giờ chạm tới một nền tảng
  5. Chuyển động được tính theo các bước của < >
  6. Quả bóng có thể đi vào cốc từ bất kỳ hướng nào miễn là tuân theo Quy tắc 1
  7. Bạn phải xác định hướng trọng lực để quả bóng của bạn không trôi đi
  8. Chuyển động có thể là ngẫu nhiên miễn là theo Quy tắc 1 và Quy tắc 4
  9. Đối với các trường hợp không thể giải quyết đầu ra Sai hoặc không hợp lệ

Ví dụ đơn giản về một quả bóng, nền tảng và cốc:

v
o
---\ /

v>

 o
---\ /

v>>

  o
---\ /

v>>>

   o
---\ /

v>>>>


---\o/

Ví dụ về di chuyển trên cùng một nền tảng một lần nữa.

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í dụ về chuyển trọng lực

v
   --/ \

o
----

v>
   --/ \

 o
----

v>>
   --/ \

  o
----

v>>>
   --/ \

   o
----

v>>>^
   --/ \
   o

----

v>>>^>
   --/ \
    o

----

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

----

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


----

Bài tập

Nhiệm vụ của bạn là tạo ra một chương trình sẽ lấy đại diện ASCII của một khóa học làm đầu vào. Và xuất ra một chuỗi các mũi tên <>^vđại diện cho hướng và lực hấp dẫn để di chuyển một quả bóng otrên tất cả platformsvào một cái cốc.

Luật golf tiêu chuẩn được áp dụng

Các trường hợp thử nghiệm

Đầu vào (Một tình huống trong đó trọng lực đang được chuyển đổi)

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

  ------    -----

Đầu ra

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

nhập mô tả hình ảnh ở đây


Đầu vào (Một tình huống trong đó hướng được chuyển)

       ---
o   
----
    ---

     -----  

    --\ /

Đầu ra

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

nhập mô tả hình ảnh ở đây


Đầu vào (Một tình huống mà bạn cần phải di chuyển trên cùng một nền tảng hai lần)

 o
 ------

  ------

 ------ 

\ /------

Đầu ra

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

nhập mô tả hình ảnh ở đây


Các trường hợp xấu, Chương trình nên xuất Falsy cho các trường hợp này

Không có cách nào để bóng đến được nền tảng tiếp theo

o
--- ---

Bóng sẽ trôi vào không gian

---
o
   ---

Một tình huống mà bóng đến được cốc, nhưng tất cả các nền tảng không bị cản trở.

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

4
Quy tắc 1 làm cho điều này khá khó khăn ... hmmm ...
JungHwan Min

Câu đố sẽ luôn luôn có thể giải được? Ngoài ra, tôi nghĩ bạn nên bao gồm một trường hợp thử nghiệm yêu cầu quay lại.
FryAmTheEggman

Có, câu đố nên luôn luôn có thể giải được. Những khoảng trống hoặc cú nhảy mất bóng hoặc những tình huống khiến mê cung không thể giải quyết sẽ không được thực hiện.
tisaconundrum

4
@JungHwanMin Quy tắc 1 chính xác là lý do tại sao đây là một thách thức và không tầm thường.
Erik the Outgolfer

2
Tôi chưa bao giờ cảm thấy xuống hố thỏ trong câu hỏi về codegolf
dj0wns

Câu trả lời:


11

Pyth, 431 byte

Đây là chương trình Pyth đầu tiên của tôi (thực ra đây là chương trình đầu tiên của tôi trong bất kỳ ngôn ngữ mã golf nào), có nghĩa là nó có thể vẫn còn được cải thiện.

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

Hãy thử ở đây (bản thử nghiệm cuối cùng cần quá lâu, nó phải được kiểm tra với bản cài đặt Pyth cục bộ).

Kết xuất hex của mã (sử dụng xxd -r <filename>để giải mã):

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

Giải trình

Ý tưởng chính cho chương trình này là sử dụng các biểu thức chính quy để sửa đổi đầu vào. Để tiết kiệm không gian, tất cả các biểu thức chính quy này được chứa trong một chuỗi nén. Bước đầu tiên trong chương trình là giải nén chuỗi và tách chuỗi int int biểu thức chính quy đơn và các chuỗi thay thế tương ứng.

            .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

Nội dung của biến Jlà:

[[['\\\\ /', '=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

Hàm ráp dụng thay thế regex từ danh sách được lưu trữ trong Jchỉ mục Gcho tất cả các chuỗi trong danh sách H. Nó trả về ngay khi bất kỳ chuỗi nào được thay đổi.

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

Chức năng itương tự như chức năng rvới 2 sự khác biệt. Nó áp dụng các thay thế trên một danh sách chuyển đổi (dọc thay vì ngang). Nó cũng thực hiện các thay thế liên tục miễn là bất cứ điều gì được thay đổi.

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

Hàm gkiểm tra nếu regex từ danh sách được lưu trữ trong Jchỉ mục Gcó thể được tìm thấy trong bất kỳ chuỗi nào trong danh sách 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

Phần còn lại của mã chứa logic chương trình thực tế. Nó thực hiện tìm kiếm đầu tiên cho các chuyển động có thể cho đến khi tìm thấy giải pháp. Vị trí trong cây tìm kiếm được xác định duy nhất bởi hướng của trọng lực và một bản sao sửa đổi của đầu vào chương trình. Để tránh việc xử lý cùng một vị trí lặp đi lặp lại, các vị trí đã xử lý được lưu trữ trong danh sách toàn cầu K. Các vị trí vẫn phải xử lý được lưu trữ cùng với phần tương ứng của giải pháp trong danh sách Y.

Việc sửa đổi đầu vào và khởi tạo KYđược thực hiện theo đoạn mã sau:

           .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

Việc sửa đổi đầu vào làm một cái gì đó như sau. Đầu vào:

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

  ------    -----

được chuyển thành:

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

Các giá trị có ý nghĩa như sau:

  • - Nền tảng vẫn phải được truy cập
  • = Nền tảng không cần phải truy cập nữa
  • M Cốc có thể được nhập với trọng lực được đặt thành "xuống"
  • W Cốc có thể được nhập với trọng lực được đặt thành "lên"
  • V An toàn để di chuyển đến nơi này với trọng lực được đặt thành "xuống"
  • A An toàn để di chuyển đến nơi này với trọng lực được đặt thành "lên"
  • X An toàn để di chuyển đến nơi này bất kể cài đặt trọng lực
  • 6 Bóng trên một nơi sẽ được đánh dấu là V
  • 9 Bóng trên một nơi sẽ được đánh dấu là A
  • 0 Bóng trên một nơi sẽ được đánh dấu là X

Logic là sử dụng các biểu thức thông thường để thực hiện các động tác. Trong ví dụ trên, nếu trọng lực sẽ được đặt thành "lên", chúng ta có thể thay thế "9A" bằng "A9" bằng một regex để di chuyển quả bóng sang phải. Điều này có nghĩa là bằng cách cố gắng áp dụng regex, chúng ta có thể tìm thấy tất cả các chuyển động có thể.


Chức năng XThực hiện dọc phong trào bóng dựa trên các thiết lập trọng lực hiện tại, lưu trữ kết quả trong danh sách toàn cầu KY, và kiểm tra nếu một giải pháp đã được tìm thấ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

Chức năng (thực hiện kiểm tra các nút 4 hướng / trọng lực. Các nút trọng lực chỉ có thể được nhấn nếu trọng lực hiện tại sẽ thay đổi và nếu quả bóng ở nơi an toàn để thay đổi trọng lực. Các nút định hướng chỉ có thể được nhấn nếu an toàn để di chuyển đến vị trí tương ứng.

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])

Cuối cùng là vòng lặp chính. Phần tử đầu tiên Yđược loại bỏ nhiều lần và kiểm tra tất cả các di chuyển có thể được thực hiện.

#                                                        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)

Tôi có đúng khi nghĩ rằng bạn cho rằng mọi đầu vào đều có thể giải quyết được không? Bởi vì câu hỏi vẫn nói rằng đầu vào không thể giải quyết được nên được phát hiện, tuy nhiên, các ý kiến ​​cho thấy rằng mọi đầu vào sẽ có thể giải quyết được. Tôi không chắc đó là trường hợp nào, mặc dù tôi nghĩ rằng mã của bạn không phát hiện ra khả năng không thể giải quyết.
Jonathan Frech

@JonathanFrech Nếu đầu vào không thể giải quyết được thì sẽ không có đầu ra. Khi tất cả các khả năng đã được kiểm tra, Ydanh sách sẽ trống, pop sẽ xuất hiện lỗi và #vòng lặp sẽ kết thúc.
Sleafar

1
Khi bạn loại bỏ cốc khỏi đầu vào (`/ \`), câu đố sẽ không thể giải được (vì bạn không thể chạm tới cốc) nhưng chương trình của bạn vẫn tạo ra đầu ra.
Jonathan Frech

Tôi không có nghĩa là những gì chương trình của bạn làm, tôi nghĩ rằng đầu vào câu đố không thể giải quyết này tạo ra một đầu ra.
Jonathan Frech

@JonathanFrech Bạn nói đúng. Tôi chỉ đang cố gắng sửa nó, nhưng tôi gặp vấn đề về mã hóa với chuỗi nén.
Sleafar
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.