Le problème du pion perdu

14

Le problème du pion perdu

Après la fin du jeu d'échecs, un pion survivant a été laissé derrière les lignes ennemies. aidons-le à trouver le chemin le plus court pour rentrer chez lui.

Le problème d'origine décrit un plateau d'échecs nXn et une fonction f: {1,..,n-1}X{1,..,n}X{-1,0,1} => R+des poids. le but est de trouver le meilleur chemin entre un carré de la ligne de fond et un autre carré de la ligne supérieure, où les mouvements possibles sont: gauche-haut, haut, droite-haut, et vous ne pouvez pas quitter le plateau.

Le problème est relativement facile à résoudre dans O (n ^ 2) en utilisant la programmation dynamique, mais c'est du codegolf, et nous ne nous soucions pas de choses inutiles comme la complexité du temps d'exécution ...

Le problème

entrée: un tableau à 3 dimensions (ou une autre collection de votre choix, reçue via stdin, ou comme argument de fonction), correspondant à un échiquier régulier, exactement de la taille: 7X8X3 (#linePasses X #rowSize X #movesPerPass) contenant entiers non négatifs. les mouvements coûtent à partir d' une position (i,j)iest l'index de ligne, et jest l'index de colonne, sont:

  • a[i][j][0]pour les frais de voyage jusqu'à gauche à la case départ (i+1,j-1)ou graphique: \.
  • a[i][j][1]pour les frais de voyage jusqu'à carré (i+1,j)ou graphique: |.
  • a[i][j][2]pour les frais de voyage en haut à droite à la case départ (i+1,j+1)ou graphique: /.

vous pouvez supposer qu'il ne contiendra pas de chemin supérieur à MAX_INT.

sortie: une sortie ascii 8X8 montrant le meilleur chemin (le plus court, c'est-à-dire la somme minimale des poids) (s'il y a plus d'un résultat optimal, vous pouvez montrer un chemin arbitraire de votre choix). le chemin est tracé de bas en haut, où dans chaque ligne, le caractère correspondant à la position du pion dans le chemin, est celui qu'il s'apprête à faire. Par exemple, si le pion est sur le point de se déplacer vers le haut à gauche de la colonne 3 (vers la colonne 2), vous devez dessiner:

#?######
##\#####

?devrait être remplacé par le prochain mouvement. la position finale doit être tracée comme X.

Exemples

contribution:

[
  [[1,1,1],[1,1,1],[0,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]],
  [[1,1,1],[1,0,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]],
  [[1,1,1],[1,1,0],[1,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]],
  [[1,1,1],[1,1,1],[1,1,0],[1,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]],
  [[1,1,1],[1,1,1],[1,1,1],[1,0,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]],
  [[1,1,1],[1,1,1],[1,1,1],[1,0,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]],
  [[1,1,1],[1,1,1],[1,1,1],[0,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]]
]

production:

##X#####
###\####
###|####
###|####
##/#####
#/######
#|######
##\#####

contribution:

[
  [[41,27,38],[12,83,32],[50,53,35],[46,32,26],[55,89,82],[75,30,87],[2,11,64],[8,55,22]],
  [[56,21,0],[83,25,38],[43,75,63],[56,60,77],[68,55,89],[99,48,67],[94,30,9],[62,62,58]],
  [[23,18,40],[24,47,61],[96,45,72],[71,6,48],[75,63,98],[93,56,51],[23,31,30],[49,34,99]],
  [[20,47,42],[62,79,72],[32,28,44],[68,61,55],[62,39,57],[4,17,49],[97,85,6],[91,18,12]],
  [[51,50,11],[32,39,56],[12,82,23],[33,88,87],[60,55,22],[29,78,14],[70,11,42],[63,94,67]],
  [[75,64,60],[27,79,86],[70,72,56],[55,45,32],[95,67,12],[87,93,98],[81,36,53],[38,22,93]],
  [[31,80,50],[77,71,22],[59,46,86],[64,71,53],[41,19,95],[62,71,22],[92,80,41],[26,74,29]]
]

production:

######X#
#####/##
####/###
#####\##
#####|##
######\#
######|#
#######\

c'est le , donc le code le plus court l'emporte.

jouer franc jeu. pas d'échappatoires ...

ÉDITER:

Iv'e a écrit une solution simple sans golf en scala que vous pouvez regarder. Il y a aussi un site que vous pouvez jouer avec du code scala en ligne: scalakata (copiez et collez simplement l'essentiel sur scalakata et appuyez sur le bouton de lecture)

gilad hoch
la source

Réponses:

5

Q: 199 octets

f:{m::x;n::{@/[+/-1 0 1_\:/:(x;m[y;;|!3]);0 2;(0W,),{x,0W}]};i:*<*|r:{&/n[x;y]}\[8#0;!7];  s:{-1+{*<x}'+n[y;z]}\[();(,8#0),-1_r;!7];j:i,{x+y x}\[i;|s];-1(@[8#"#";;:;]'[j;"X","/|\\"1+s'[|!7;-1_j]]);}

REMARQUES

  • Interprète Q (kx.com) gratuit pour une utilisation non commerciale (versions pour Windows, Linux, Mac)
  • Cette solution utilise le noyau interne de Q (nommé en interne k4), nous avons donc besoin d'un fichier de script avec l'extension k ou d'un interpréteur interactif en mode k (\ commande à la première invite). En revanche, la version «verbeuse» (lisible) de la langue nécessite un script avec l'extension q et est le mode par défaut de l'interpréteur interactif.

TESTER

f ((1 1 1; 1 1 1; 0 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1)
   (1 1 1; 1 0 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1)
   (1 1 1; 1 1 0; 1 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1)
   (1 1 1; 1 1 1; 1 1 0; 1 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1)
   (1 1 1; 1 1 1; 1 1 1; 1 0 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1)
   (1 1 1; 1 1 1; 1 1 1; 1 0 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1)
   (1 1 1; 1 1 1; 1 1 1; 0 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1))

##X#####
###\####
###|####
###|####
##/#####
#/######
#|######
##\#####

f ((41 27 38; 12 83 32; 50 53 35; 46 32 26; 55 89 82; 75 30 87;  2 11 64;  8 55 22)
   (56 21  0; 83 25 38; 43 75 63; 56 60 77; 68 55 89; 99 48 67; 94 30  9; 62 62 58)
   (23 18 40; 24 47 61; 96 45 72; 71  6 48; 75 63 98; 93 56 51; 23 31 30; 49 34 99)
   (20 47 42; 62 79 72; 32 28 44; 68 61 55; 62 39 57;  4 17 49; 97 85  6; 91 18 12)
   (51 50 11; 32 39 56; 12 82 23; 33 88 87; 60 55 22; 29 78 14; 70 11 42; 63 94 67)
   (75 64 60; 27 79 86; 70 72 56; 55 45 32; 95 67 12; 87 93 98; 81 36 53; 38 22 93)
   (31 80 50; 77 71 22; 59 46 86; 64 71 53; 41 19 95; 62 71 22; 92 80 41; 26 74 29))

######X#
#####/##
####/###
#####\##
######\#
######|#
######|#
#######\

EXPLICATION

À des fins d'illustration, nous supposons un deuxième test (matrice ((41 27 38; 12 83 32; ....)

Nous transformons la matrice d'origine (m au niveau du code): au lieu de matrice d'origine avec un triplet pour chaque coordonnée, nous définissons la matrice pour les déplacements gauche, haut et droit. La matrice de gauche contient des valeurs 7x7 (nous supprimons la première colonne), la matrice supérieure 7x8 et la matrice de droite 7x7 (nous supprimons la dernière colonne).

left                           up                         right
12 50 46 55 75 2  8       27 83 53 32 89 30 11 55     38 32 35 26 82 87 64
83 43 56 68 99 94 62      21 25 75 60 55 48 30 62     0  38 63 77 89 67 9 
24 96 71 75 93 23 49      18 47 45 6  63 56 31 34     40 61 72 48 98 51 30
62 32 68 62 4  97 91      47 79 28 61 39 17 85 18     42 72 44 55 57 49 6 
32 12 33 60 29 70 63      50 39 82 88 55 78 11 94     11 56 23 87 22 14 42
27 70 55 95 87 81 38      64 79 72 45 67 93 36 22     60 86 56 32 12 98 53
77 59 64 41 62 92 26      80 71 46 71 19 71 80 74     50 22 86 53 95 22 41

Pour calculer la position finale, nous devons évaluer la trajectoire du coût minimum. Nous supposons le coût initial 0 0 0 0 0 0 0 0 (coût pour arriver à chaque colonne de la première ligne), et itère avec chaque ligne suivante. À chaque colonne i, nous calculons trois valeurs:

  • coût de la valeur i + 1 précédente plus gauche [i + 1]. Nous supprimons la première composante du coût (colonnes de décalage et d'alinéation à ajouter) et la somme de composante à composante

  • coût de la valeur i précédente plus [i]. Nous additionnons composant à composant

  • coût de la valeur i-1 précédente plus le droit [i-1]. Nous supprimons la dernière composante du coût (colonnes de décalage et d'alinéation à ajouter) et somme la composante à composante

Pour calculer le minimum, nous complétons le coût gauche avant l'infini et le coût droit après l'infini: avec 3 vecteurs de huit composants, calculez le composant minimum à composant. La valeur résultante est le coût de base pour une nouvelle itération

Pour la première itération on obtient des valeurs (0W est infini en Q)

0W 12 50 46 55 75 2  8
27 83 53 32 89 30 11 55
38 32 35 26 82 87 64 0W

et calcule le minimum de chaque colonne

27 12 35 26 55 30 2 8

Après toutes les itérations, nous avons le coût minimum pour arriver à chaque carré (en supposant que la ligne 0 en haut, 7 en bas). Nous ne sommes intéressés que par la dernière colonne, mais je dessine tous les résultats intermédiaires à des fins illustratives

0   0   0   0   0   0   0   0
27  12  35  26  55  30  2   8
27  37  78  82  110 78  11  70
45  61  123 88  173 129 34  104
87  123 151 143 212 133 40  122
98  155 163 176 234 147 51  185
158 182 219 208 246 234 87  207
208 204 265 261 265 256 128 233

Maintenant, nous avons trouvé la valeur minimale à la dernière ligne (128, à la colonne 6). C'est la fin du chemin (caractère X en sortie).

Nous répétons le calcul des coûts à nouveau, mais maintenant nous annotons la direction à partir de laquelle nous obtenons chaque minimum (laquelle des 3 valeurs utilisées pour calculer le minimum est la valeur sélectionnée).

\|/|\///
\\\\\/|/
\\\|//|/
\\|\//|/
\\|//|\/
\\//|\|/
\|/|/|\/

Nous inversons les lignes, mettons «X» à la pos 6 et ne conservons que le chemin qui se termine à la colonne 6 (les autres sont remplacés par #)

######X#
#####/##
####/###
#####\##
######\#
######|#
######|#
#######\
J. Sendra
la source
Iv'e n'a jamais entendu parler de Q, mais merci pour une réponse aussi détaillée :)
gilad hoch