Palla per microgravità


33

Sei su una stazione spaziale intergalattica avanzata. Un tuo amico che sta minacciando nello Studio della gravità ha appena creato un gioco che prevede l'uso della microgravità come modo per muovere una palla.

Ti porge un piccolo controller con quattro frecce direzionali su di esso e una struttura simile a un labirinto con una palla seduta a sinistra. Comincia a spiegare come funziona il gioco.

  • Hai 2 pulsanti direzionali, sinistro <e destro >.
  • Hai anche 2 pulsanti di gravità, su ^e giù v(almeno dal tuo quadro di riferimento)
  • Utilizzerai questi pulsanti freccia per spostare la palla sullo schermo.

"Ora ci sono alcune regole che devono essere seguite." lei dice

  1. Tutte le piattaforme devono essere attraversate prima di arrivare alla coppa \ /
  2. Le frecce < > ^ vverranno utilizzate per specificare il movimento della palla
  3. La gravità è ^ v(su e giù). Questo sposta la palla fino alla piattaforma successiva in quella direzione. (La distanza non viene calcolata su e giù)
  4. Perdere la palla è male! Non cadere oltre il bordo e non cambiare gravità troppo presto in modo tale che la tua palla non raggiunga mai una piattaforma
  5. Il movimento viene conteggiato in passi di < >
  6. La palla può entrare nella coppa da qualsiasi direzione purché venga seguita la Regola 1
  7. Devi specificare la direzione di gravità in modo che la tua palla non fluttui via
  8. Il movimento può essere casuale fintanto che la regola 1 e la regola 4 sono seguite
  9. Per i casi che non possono essere risolti, output False o Invalid

Semplice esempio di palla, piattaforma e tazza:

v
o
---\ /

v>

 o
---\ /

v>>

  o
---\ /

v>>>

   o
---\ /

v>>>>


---\o/

Esempio di attraversamento di nuovo sulla stessa piattaforma.

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/-------

Esempio di commutazione della gravità

v
   --/ \

o
----

v>
   --/ \

 o
----

v>>
   --/ \

  o
----

v>>>
   --/ \

   o
----

v>>>^
   --/ \
   o

----

v>>>^>
   --/ \
    o

----

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

----

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


----

Compito

Il tuo compito è creare un programma che prenderà come input una rappresentazione ASCII di un corso. E emette una serie di frecce che <>^vrappresentano la direzione e la forza gravitazionale per spostare una palla osu platformsuna tazza.

Si applicano le regole standard per il golf

Casi test

Input (una situazione in cui la gravità viene commutata)

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

  ------    -----

Produzione

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

inserisci qui la descrizione dell'immagine


Input (una situazione in cui la direzione viene commutata)

       ---
o   
----
    ---

     -----  

    --\ /

Produzione

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

inserisci qui la descrizione dell'immagine


Input (una situazione in cui è necessario attraversare due volte la stessa piattaforma)

 o
 ------

  ------

 ------ 

\ /------

Produzione

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

inserisci qui la descrizione dell'immagine


Casi sbagliati, il programma dovrebbe generare Falsy per questi

Non c'è modo che la palla arrivi alla piattaforma successiva

o
--- ---

La palla fluttuerebbe nello spazio

---
o
   ---

Una situazione in cui la palla arriva alla coppa, ma tutte le piattaforme non vengono attraversate.

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

4
La Regola 1 rende questo piuttosto impegnativo ... hmmm ...
JungHwan Min

Il puzzle sarà sempre risolvibile? Inoltre, penso che dovresti includere un test case che richiede backtracking.
FryAmTheEggman,

Sì, i puzzle dovrebbero essere sempre risolvibili. Non saranno fatti vuoti o salti che perdono la palla o situazioni che rendono il labirinto irrisolvibile.
tisaconundrum,

4
@JungHwanMin La regola 1 è esattamente il motivo per cui questa è una sfida e non banale.
Erik the Outgolfer,

2
Non mi sono mai sentito così lontano in una tana di coniglio su una domanda di
codegolf

Risposte:


11

Pyth, 431 byte

Questo è il mio primo programma Pyth (in realtà questo è il mio primo programma in qualsiasi linguaggio di golf di codice), il che significa che probabilmente può essere ancora migliorato.

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

Provalo qui (l'ultimo testcase richiede troppo tempo, deve essere testato con un'installazione Pyth locale).

Dump esadecimale del codice (usare xxd -r <filename>per decodificare):

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

Spiegazione

L'idea principale per questo programma era di usare espressioni regolari per modificare l'input. Per risparmiare spazio, tutte queste espressioni regolari sono contenute in una stringa compressa. Il primo passo nel programma è decomprimere la stringa e dividerla in singola espressione regolare e le stringhe di sostituzione corrispondenti.

            .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

I contenuti della variabile Jsono quindi:

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

La funzione rapplica le sostituzioni regex dall'elenco memorizzato Jnell'indice Ga tutte le stringhe dell'elenco H. Ritorna non appena una delle stringhe è stata cambiata.

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

La funzione iè simile alla funzione rcon 2 differenze. Applica le sostituzioni su un elenco trasposto (verticale anziché orizzontale). Esegue inoltre le sostituzioni ripetutamente finché tutto è cambiato.

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

La funzione gcontrolla se la regex dall'elenco memorizzata Jnell'indice Gpuò essere trovata in qualsiasi stringa nell'elenco 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

Il resto del codice contiene l'attuale logica del programma. Esegue una prima ricerca dei possibili movimenti fino a trovare una soluzione. La posizione nella struttura di ricerca è definita in modo univoco dalla direzione della gravità e da una copia modificata dell'input del programma. Per evitare l'elaborazione della stessa posizione più e più volte, le posizioni elaborate vengono memorizzate nell'elenco globale K. Le posizioni che devono ancora essere elaborate vengono memorizzate insieme alla parte corrispondente della soluzione nell'elenco Y.

La modifica dell'input e l'inizializzazione di Ke Yviene eseguita dal seguente codice:

           .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

La modifica dell'input fa qualcosa di simile al seguente. L'input:

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

  ------    -----

si trasforma in:

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

I valori hanno il seguente significato:

  • - Piattaforma che deve essere ancora visitata
  • = Piattaforma che non ha più bisogno di essere visitata
  • M Tazza che può essere inserita con la gravità impostata su "giù"
  • W Tazza che può essere inserita con la gravità impostata su "su"
  • V Sicuro di spostarsi in questo posto con la gravità impostata su "giù"
  • A Sicuro di spostarsi in questo posto con la gravità impostata su "su"
  • X Trasferirsi in sicurezza in questo luogo indipendentemente dall'impostazione della gravità
  • 6 Palla su un posto che sarebbe contrassegnato come V
  • 9 Palla su un posto che sarebbe contrassegnato come A
  • 0 Palla su un posto che sarebbe contrassegnato come X

La logica sta usando espressioni regolari per eseguire i movimenti. Nell'esempio sopra, se la gravità fosse impostata su "up", possiamo sostituire "9A" con "A9" con una regex per spostare la palla verso destra. Ciò significa che provando ad applicare la regex possiamo trovare tutti i possibili movimenti.


La funzione XEsegue i movimenti palla in verticale in base all'impostazione gravità corrente, memorizza il risultato in liste globali Ke Y, e controlla se è stata trovata una soluzione.

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

La funzione (implementa i controlli per i 4 pulsanti direzionali / a gravità. I pulsanti di gravità possono essere premuti solo se la gravità attuale cambierebbe e se la palla si trova in un posto sicuro per cambiare la gravità. I pulsanti direzionali possono essere premuti solo se è sicuro spostarsi nella posizione corrispondente.

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

Finalmente il ciclo principale. Il primo elemento di Yviene rimosso ripetutamente e vengono eseguiti i controlli per tutte le mosse possibili.

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

Ho ragione nel pensare che supponi che ogni input sia risolvibile? Poiché la domanda dice ancora che dovrebbero essere rilevati input irrisolvibili, i commenti, tuttavia, suggeriscono che ogni input sarà risolvibile. Non sono sicuro che sia il caso, anche se penso che il tuo codice non rilevi insolvibilità.
Jonathan Frech,

@JonathanFrech Se l'input è irrisolvibile non ci sarà output. Quando tutte le possibilità sono state verificate, l' Yelenco sarà vuoto, il pop genererà un errore e il #ciclo terminerà.
Sleafar,

1
Quando rimuovi la tazza dall'input (`/ \`), il puzzle diventa irrisolvibile (poiché non puoi raggiungere la tazza) eppure il tuo programma genera ancora un output.
Jonathan Frech,

Non intendevo quello che fa il tuo programma, menziono che questo input puzzle irrisolvibile genera un output.
Jonathan Frech,

@JonathanFrech Hai ragione. Sto solo cercando di risolverlo, ma ho problemi di codifica con la stringa compressa.
Sleafar,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.