Une tortue trouve un portail

30

La tortue veut se déplacer le long de la grille pour se rendre à sa nourriture. Il veut savoir combien de mouvements il lui faudra pour y arriver.

De plus, comme il est lent, il a installé des téléporteurs autour de son domaine qu'il utilisera s'il raccourcit son chemin. Ou évitez-les si cela allonge son chemin.

Rencontrez la tortue

🐢

La tortue vit sur une grille

XXXXXXXXXXXX🐢XXXXXXXXXXXX
La tortue peut se déplacer vers n'importe quel carré adjacent ...
XXXXXXXX🐢XXXXXXXX

Cependant, la tortue ne peut pas se déplacer vers un carré avec une montagne

X🌄XXXXXX🌄🐢XX🌄XX🌄XXX

X🌄🍓🐢🌄XX🌄XXXX
5
X🌄🍓🌄🌄XX
🔵🌄🍓🐢🌄🔴X🌄XXXX
2
🔵🌄🐢🌄🔴X🌄XXXX

Le défi

Étant donné une sortie de configuration de grille initiale, le nombre de mouvements qu'il faudra à la tortue pour atteindre sa fraise.

Règles

  • Vous pouvez supposer que la grille d'entrée a une solution

  • Chaque grille n'aura qu'un strawberry, deux portalset unturtle

  • La grille d'entrée peut être entrée dans n'importe quel format pratique

  • Vous devez traiter teleportersles articles à usage unique

  • Le tour que la tortue se déplace sur une teleportercase, il est déjà sur le correspondant teleporter. Il ne passe jamais sur un teleporteret y reste pour un mouvement

  • Le chemin le plus court n'a pas besoin d'utiliser le portail

  • La tortue ne peut pas passer dans les tuiles montagne

  • Vous pouvez utiliser un caractère ASCII ou entier pour représenter mountains, turtle, empty grid square,strawberry

  • Vous pouvez utiliser le même caractère ou deux caractères ou entiers ASCII différents pour représenter les teleporterpaires

  • Une grille peut avoir plusieurs chemins avec la même longueur de chemin la plus courte

  • C'est du

Clarifications des règles

  • Vous devez traiter teleportersles articles à usage unique.

🐢X🔵X🍓🌄🌄🌄🌄🌄🔴XXXX

Pourrait être résolu uniquement en entrant et en sortant deux fois des portails. Au moment de cette clarification, les deux solutions ont agi en supposant qu'elles étaient à usage unique ou qu'il n'y avait aucune raison d'essayer des carrés précédemment utilisés. Pour éviter de casser leurs solutions travaillées, cela semblait la meilleure façon de rendre compte de cette configuration. Par conséquent, cela serait considéré comme une grille non valide.

Cas de test formatés sous forme de listes

[ ['T', 'X', 'X', 'S', 'X'], ['X', 'X', 'X', 'X', 'X'], ['X', 'X', 'X', 'X', 'X'] ] --> 3
[ ['T', 'M', 'X', 'S', 'X'], ['X', 'M', 'X', 'X', 'X'], ['O', 'X', 'X', 'X', 'O'] ] --> 4
[ ['T', 'M', 'X', 'S', 'O'], ['O', 'M', 'X', 'X', 'X'], ['X', 'X', 'X', 'X', 'X'] ] --> 2
[ ['T', 'M', 'X', 'S', 'X'], ['O', 'M', 'X', 'X', 'X'], ['O', 'X', 'X', 'X', 'X'] ] --> 4
[ ['T', 'M', 'S', 'X', 'O'], ['X', 'M', 'M', 'M', 'M'], ['X', 'X', 'X', 'X', 'O'] ] --> 7
[ ['T', 'X', 'X', 'S', 'X'], ['O', 'M', 'M', 'M', 'X'], ['X', 'X', 'O', 'X', 'X'] ] --> 3

Cas de test formatés pour les humains

T X X S X
X X X X X
X X X X X --> 3

T M X S X
X M X X X
O X X X O --> 4

T M X S O
O M X X X
X X X X X --> 2

T M X S X
O M X X X
O X X X X --> 4

T M S X O
X M M M M
X X X X O --> 7

T X X S X
O M M M X
X X O X X --> 3

Crédits

Conception et structure via: Hungry mouse par Arnauld

Conseils proposés pour modifier les défis: Kamil-drakari , bœuf

Conseils généraux d'édition: okx nedla2004 mbomb007

akozi
la source
2
Je pense que ce serait une bonne idée d'ajouter un cas de test où l'utilisation du téléporteur prendrait plus de temps.
Okx
@Okx Créer et ajouter maintenant.
akozi
Modifié, merci.
akozi
1
@xnor Je pense que cela peut être un résumé de mes règles d'origine. Alors peut-être vaut-il mieux de porter un article à usage unique?
akozi
1
Connexes (je pense).
Charlie

Réponses:

13

JavaScript (ES7),  140 139  138 octets

Prend l'entrée comme une matrice d'entiers avec le mappage suivant:

  • 1
  • 0X
  • 1
  • 2
  • 3
m=>(R=g=(t,X,Y,i)=>m.map((r,y)=>r.map((v,x)=>r[(u=0,t?v-t:(x-X)**2+(y-Y)**2<3?v-3?~v?v:u--:R=R<i?R:i:1)||g(u,x,y,u-~i,r[x]=1),x]=v)))(2)|R

Essayez-le en ligne!

Comment?

gtt0(x,y)(X,Y)

iRmin(R,i)

Il est d'abord appelé avec pour trouver la position de départ de la tortue.t=2

Il s'appelle avec si un portail est atteint, de sorte que la tortue est téléportée vers l'autre portail. Nous n'incrémentons pas lors d'une telle itération.t=1i

Chaque tuile visitée est temporairement placée sur une montagne pour empêcher la tortue de se déplacer deux fois sur la même tuile dans le même chemin. Si nous sommes pris au piège dans une impasse, la récursion arrête simplement sans mise à jour .R

Commenté

m => (                        // m[] = input matrix
  R =                         // initialize R to a non-numeric value
  g = (t, X, Y, i) =>         // g = recursive search function taking t = expected tile,
                              //     (X, Y) = current coordinates, i = path length
    m.map((r, y) =>           // for each row r[] at position y in m[]:
      r.map((v, x) =>         //   for each tile v at position x in r[]:
        r[                    //     this statement will eventually restore r[x] to v
          ( u = 0,            //     u = next tile to look for, or 0 if none
            t ?               //     if we're looking for a specific tile:
              v - t           //       test whether we've found it
            :                 //     else:
              (x - X) ** 2 +  //       compute the squared Euclidean distance between
              (y - Y) ** 2    //       (x, y) and (X, Y)
              < 3 ?           //       if it's less than 3 (i.e. reachable from (X, Y)):
                v - 3 ?       //         if v is not equal to 3:
                  ~v ?        //           if v is not equal to -1:
                    v         //             test if v = 0
                  :           //           else (v = -1):
                    u--       //             set u = -1 to find the other portal
                :             //         else (v = 3):
                  R = R < i ? //           we've found the strawberry: set R = min(R, i)
                      R : i   //
              :               //       else (this tile can't be reached):
                1             //         yield 1
          ) ||                //     if the above result is falsy:
          g(                  //       do a recursive call:
            u,                //         t = u
            x, y,             //         move to (x, y)
            u - ~i,           //         unless u is set to -1, increment i
            r[x] = 1          //         set this tile to a mountain
          ),                  //       end of recursive call
          x                   //     restore r[x] ...
        ] = v                 //     ... to v
    ))                        // end of both map() loops
)(2) | R                      // initial call to g with t = 2; return R
Arnauld
la source
1
"Chaque tuile visitée est temporairement placée sur une montagne pour empêcher la tortue de se déplacer deux fois sur la même tuile" Quelle belle astuce. Excellente réponse, et comme toujours, j'apprécie les réponses avec des explications :)
akozi
5

Python 2 , 441 431 341 octets

from itertools import*
G=input()
W=len(G[0])
H=len(G)
A=[0]*5
E=enumerate
for y,r in E(G):
 for x,C in E(r):A[C]=[x,y]
for L in count():
 for M in product(*[zip('UDLR'*2,'LRDU    ')]*L):
  x,y=A[0]
  for m in M:
    x+='R'in m;x-='L'in m;y+='D'in m;y-='U'in m
    if(x,y)==A[3]:x,y=A[2]
    if 1-(W>x>-1<y<H)or G[y][x]>3:break
  if[x,y]==A[1]:exit(L)

Essayez-le en ligne!

Saisie sous forme de listes, mais en utilisant des nombres au lieu de caractères (grâce à Quintec) et une valeur distincte pour la destination du téléporteur. Ces grandes indentations doivent être des tabulations si Stack Exchange les supprime. Tous les conseils ou idées sont particulièrement les bienvenus, car je pense que cela pourrait devenir beaucoup plus court.

Le tableau des caractères utilisés dans le défi des numéros utilisés pour mon programme est ci-dessous, mais vous pouvez également utiliser ce programme .

Challenge | My program
T         | 0
S         | 1
E         | 2
O         | 3
M         | 4
X         | -1

-10 octets grâce à Quintec en changeant l'entrée d'utiliser des caractères en chiffres.

- Beaucoup d'octets grâce à Jonathan Frech, ElPedro et Jonathan Allan.

nedla2004
la source
2
Vous pouvez probablement raser quelques caractères en prenant une liste où chaque objet est représenté par un nombre au lieu d'un caractère de chaîne.
Quintec
@Quintec Ajouté, merci. Je voudrais faire la même chose pour les directions, mais ensuite les diagonales devraient être faites séparément. Il peut néanmoins être possible de les déplacer vers des nombres.
nedla2004
1
@ElPedro Ahha Je peux raser 4 comme ça
Jonathan Allan
1
... et encore 10 pour 356
Jonathan Allan
2
@JonathanAllan et ElPedro et Jonathan French. De bons conseils de vous tous, et je les ai ajoutés avec quelques choses que j'ai trouvées. (Après beaucoup de retard)
nedla2004
2

Python 2 , 391 397 403 422 octets

M=input()
from networkx import*
a=b=c=d=0
N,h,w,S=[-1,0,1],len(M),len(M[0]),[]
for i in range(h):
 for j in range(w):
  I,m=(i,j),M[i][j]
  if m>7:c,d=a,b;a,b=I
  if m<0:Z=I
  if m==5:F=I
  S+=[I+I]
S+=[(a,b,c,d),(c,d,a,b)]
print len(shortest_path(from_edgelist([((A+p,B+q),(C,D))for A,B,C,D in S for p,q in[(p,q)for p in N for q in N]if-1<A+p<h and-1<B+q<w and M[C][D]*M[A+p][B+q]]),Z,F))-1

Essayez-le en ligne!

Le problème est traduit dans un graphique et la solution est de trouver le chemin le plus court de la tortue à la fraise.

Challenge | This code
T         | -1
S         |  5
O         |  8
M         |  0
X         |  1
mdahmoune
la source