Échappez au labyrinthe!

20

Vous êtes piégé dans ce labyrinthe 5x5 - chaque pièce est étiquetée de 1 à 25 et la sortie est dans la salle 1.

entrez la description de l'image ici

On vous donne en entrée la pièce dans laquelle vous vous trouvez. Votre tâche consiste à sortir la séquence de mouvements la plus courte (nord, est, sud, ouest) nécessaire pour atteindre la pièce 1.

Les mouvements peuvent être sortis dans le format de votre choix (liste, chaîne, tableau ...) tant que vous utilisez les caractères n,w,e,s.

Voici tous les cas de test:

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

La réponse la plus courte en octets gagne!

Arnaud
la source
3
Dans quelle mesure l'étiquetage / l'entrée de la pièce est-il flexible? Pouvons-nous 0-index au lieu de 1-index? Pouvons-nous prendre le numéro de la pièce comme un personnage (penser, comme dans la base 36)?
Chas Brown
2
@Therandomguy non, vous devez gérer ce labyrinthe spécifique.
Arnaud
6
Puisqu'il est possible, je pense que tous les cas possibles devraient être inclus dans les cas de test.
Jonathan Frech
1
@UnrelatedString Cette question prend 1 entrée et génère un chemin différent en fonction de son entrée. Je crois que cette exigence ne correspond pas à la balise kolmogorov-complexité .
tsh
2
Quelqu'un doit fournir une réponse dans Labyrinth .
Draco18s

Réponses:

20

Python 2 , 64 octets

def f(n):d=0x1211252b5375>>2*n-4&3;print"nwes"[d];f(n+d*3+d%2-5)

Essayez-le en ligne!

Une fonction qui imprime une direction par ligne, se terminant par une erreur.

La constante 0x1211252b5375code dans la base 4 la direction que dnous parcourons à partir de chaque numéro de pièce sous la forme d'un nombre compris entre 0 et 3. Le chiffre d'extraction >>2*n-4&3est également conçu pour donner une erreur de décalage négative lors de la n=1terminaison du code. Nous mettons à jour le numéro de la pièce nvia un décalage calculé à partir de la direction das d*3+d%2-5, qui mappe:

d   d*3+d%2-5
0  -> -5
1  -> -1
2  ->  1
3  ->  5 
xnor
la source
1
Je ne suis pas sûr que ce soit valide tel quel, les fonctions doivent être réutilisables et vous avez besoin d'une récupération d'erreur ( try/ except) pour pouvoir continuer l'exécution après avoir appelé cette fonction.
Erik the Outgolfer
10

Python 2 , 95 93 octets

f=lambda n:n>1and Q[n]+f(n+[-5,5,1,-1]['nsew'.find(Q[n])])or''
Q='  wwswsnwwseenwwenwnwnenwn'

Essayez-le en ligne!

Pourrait raser 3 2 octets si l'étiquetage de pièce indexé 0 est autorisé.

Chas Brown
la source
89 octets
Arnauld
6

05AB1E , 30 29 octets

-1 octet grâce à une coïncidence miraculeuse avec des nombres premiers

[Ð#•θzƶ‰`Ó•4вsè<DˆØ·5-+}'‹™¯è

Essayez-le en ligne!

[                      }    # 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)
Grimmy
la source
1
Cela génère 1une entrée1 , au lieu d'une chaîne vide (une solution simple serait d'ajouter un interligne õ?). A part ça, belle réponse!
Kevin Cruijssen
1
@KevinCruijssen merci d'avoir signalé cette erreur! J'ai trouvé un correctif sur un octet.
Grimmy
5

Rubis , 72 62 octets

f=->n{n<2?'':' en  sw'[x=4*18139004[n]+6*4267088[n]-5]+f[n+x]}

Essayez-le en ligne!

Comment?

L'astuce consiste à utiliser 2 constantes pour créer l'étape suivante pour chaque cellule, puis à résoudre récursivement le problème.

Les 2 constantes 18139004 et 4267088 sont des chaînes binaires donnant la direction du prochain mouvement, en extrayant un seul bit des deux pour chaque cellule, on peut obtenir:

"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

Plus facile que de se déplacer et de masquer un seul grand nombre binaire à mon humble avis.

Lorsque nous obtenons la direction, nous extrayons la lettre correspondante de la chaîne "en sw":

  1   5
  |   |
" en  sw"
   |   |
  -5  -1

Et procéder récursivement sur la cellule [n + x]

GB
la source
3

Perl 5 ( -n), 94 octets

-5 octets grâce à Grimy

@A=map/./g,__wwswsnwwseenwwenwnwnenwn;%H=(n,-5,s=>5,e,1,w,-1);$_+=$H{$,=$A[$_]},say$,until$_<2

TIO

Nahuel Fouilleul
la source
-8
Grimmy
-2
Grimmy
-5
Grimmy
1
Voulez-vous dire que je devrais l'afficher comme une réponse distincte?
Grimmy
1
oui car il semble que vous ayez fait le plus gros du travail, c'était intéressant de voir comment on peut toujours économiser de l'espace
Nahuel Fouilleul
2

JavaScript, 80 73 71 octets

Adapté de la solution Python de Chas alors faites- +1lui plaisir aussi.

f=n=>--n?(d=" wwswsnwwseenwwenwnwnenwn"[n])+f(n+~~{n:-4,s:6,e:2}[d]):``

Essayez-le en ligne!

1 octet économisé grâce à Arnauld .

Hirsute
la source
Merci, @Arnauld :) Je venais de le remarquer moi aussi.
Shaggy
2

Fusain , 43 40 octets

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

Essayez-le en ligne! Le lien est vers la version détaillée du code. Basé sur les réponses de @ ChasBrown et @ xnor. Explication:

Nθ

Entrez dans la pièce.

W⊖θ«

Définissez la variable de boucle ià un de moins que le numéro de la pièce et répétez pendant qu'elle est différente de zéro.

«≔I§”)“⊞x⟧∧⎚⁵2”ιι

Extrayez la direction de la chaîne compressée 0113130113220112010102010. (Le premier 0n'est qu'un chiffre de remplissage.)

§nwesι

Imprimez la direction.

≧⁺⁻⁺﹪ι²×³ι⁵θ

Utilisez la formule @ xnor pour calculer le nouveau numéro de chambre.

Neil
la source
2

Gelée , 30 29 octets

“þ&ƊĿñ÷°e’b6Ḥ_5Ż⁸+ị¥ƬI‘ị“®ȯẹ»

Essayez-le en ligne!

Un lien monadique prenant la cellule de départ et renvoyant une chaîne avec les directions.

J'adore le fait que le dictionnaire de Jelly a un mot comme «Kennesaw» (une ville au nord-ouest d'Atlanta, en Géorgie), utilisé ici parce que l'indexation avec [5, 1, -5, -1] + 1donne nesw!

Explication

“þ...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"
Nick Kennedy
la source
2

PHP , 110 octets

Une solution qui n'est pas un port de grande réponse de Chas Brown ou grande réponse xnor . Je sais que c'est plus long mais je voulais avoir une solution différente!

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

Essayez-le en ligne!

J'ai créé une chaîne de mappage qui a 2 caractères pour chaque cellule du tableau. Le premier caractère de chaque cellule est un déplacement (n / e / s / w) ou 0et le code ASCII mod 30 du deuxième caractère renverra un autre numéro de cellule que nous devrions suivre son déplacement en mode récursif jusqu'à ce que nous arrivions à quitter la cellule ( cell < 2).

Par exemple pour une entrée de 8:

  • 2 caractères pour la cellule 8sont:w%
  • Cela signifie imprimer wet continuer les mouvements pour la cellule de%
  • Le code ASCII %est de 37 dont le mod 30 sera 7, donc la prochaine cellule à suivre est 7.
  • 2 caractères pour la cellule 7sont: n (le dernier caractère est un espace, code ASCII = 32)
  • Cela signifie imprimer net continuer avec des mouvements pour la cellule de 32 mod 30 qui est 2.
  • 2 caractères pour la cellule 2sont: w<(dernier code ASCII de caractère = 60)
  • Cela signifie imprimer wet continuer avec des mouvements pour une cellule de 60 mod 30 qui est 0.
  • Si le nombre de cellules est inférieur à 2, la boucle s'arrête!
  • Résultat final imprimé: wnw

PHP , 75 octets

Cette version est écrite par Grimy , elle est 35 octets plus courte que ma réponse d'origine car il / elle est plus intelligent! Commentaire de Grimy: "4 * 25 <256, vous n'avez donc besoin que d'un octet par cellule, pas de 2"

for($n=$argn;$n=ord("0\0~f;6o4R:s%ql&rup*@^tIDbx"[$n%25]);)echo news[$n%4];

Essayez-le en ligne!


PHP , 71 octets

Ce port de la réponse d' Arnauld qui est le port de la réponse de xnor , mais comme une boucle au lieu d'une fonction récursive, car il s'avère plus court en PHP.

for($n=$argn;--$n;$n+=$d*3+$d%2-4)echo nwes[$d=79459389361621/4**$n&3];

Essayez-le en ligne!

Nuit2
la source
2
4 * 25 <256, vous n'avez donc besoin que d'un octet par cellule et non de 2: essayez-le en ligne!
Grimmy
1
@Grimy, incroyable, je pense que vous devez le poster comme une réponse séparée, c'est assez différent.
Night2
1
Je ne vais pas le faire, vous choisissez donc de l'intégrer dans votre réponse ou de le laisser comme un commentaire.
Grimmy
1
@Grimy, a ajouté votre version avec votre nom. Merci quand même.
Night2
2

C (clang) , 81 octets

v;f(p){p-1&&putchar(v="00wwswsnwwseenwwenwnwnenwn"[p])+f(p+=v%5?6-v%8:v%2?5:-5);}

Essayez-le en ligne!

Merci à @ Tommylee2k suggestion -8! + appel récursif

C (clang) , 90 octets

v;f(p){for(char*l="00wwswsnwwseenwwenwnwnenwn";p-1;p+=v%5?6-v%8:v%2?5:-5)putchar(v=l[p]);}

Essayez-le en ligne!

Similaire à toutes les solutions non compressées.

AZTECCO
la source
1
peut être raccourci: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 octets

õ?[Ð#.•DUo¢ê`Ω÷‰₂¡)R€ûK•¦sè©?Ž₁9₂в6-'€Ã®kè+

Port de la réponse Python 2 de @ChasBrown .

Essayez-le en ligne ou vérifiez tous les cas de test .

Explication:

õ?               # 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

Voir cette astuce de mes 05AB1E (quatre sections) de comprendre pourquoi .•DUo¢ê`Ω÷‰₂¡)R€ûK•est "a wwswsnwwseenwwenwnwnenwn"; Ž₁9est 22449; Ž₁9₂вest [1,7,5,11]; et '€Ãest "news".

Kevin Cruijssen
la source
1
Cette chaîne de dictionnaire pratique a dû être une bonne nouvelle!
Neil
@Neil Certainement. :) Bien qu'apparemment la chaîne du dictionnaire westernsoit meilleure. ; p
Kevin Cruijssen
1

Bash , 120 octets

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; }

Essayez-le en ligne!

J'ai joué pendant un certain temps en essayant de compresser la chaîne en bits, mais le décodage nécessiterait plus de caractères que le nombre enregistré.

Comment ça fonctionne:

S=__wwswsnwwseenwwenwnwnenwn

La chaîne $ S contient un seul caractère (n, w, s, e) pour chaque pièce indiquant la direction à prendre pour déplacer une pièce vers la sortie, en sautant les pièces 0 et 1.

N=n-5w-1s05e01

La chaîne $ N a le delta à ajouter / soustraire du numéro de pièce actuel pour chaque changement de direction (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; }

Commencez avec $ i égal au numéro de chambre indiqué sur la ligne de commande ($ 1). Attribuez le caractère à l'index $ i dans la chaîne $ S à $ d. Récupérez la valeur delta de $ N pour la direction à prendre vers la pièce suivante, en l'affectant à $ j.

Imprimez la prochaine direction pour saisir $ d.

Ajoutez / soustrayez le delta de $ j à / de $ i.

Boucle jusqu'à ce que nous quittions la chambre # 2 (alors que $ i> 1).

frapper
la source
1

Kotlin , 112 octets

val d="  113130113220112010102010"
fun p(r:Int):String=if(r>1)"nwes"[d[r]-'0']+p("046:"[d[r]-'0']-'5'+r)
else ""

Essayez-le en ligne!

JohnWells
la source