Contexte
J'ai construit un parcours d'obstacles simple en plaçant des boîtes dans une pièce rectangulaire. Maintenant, je veux compter le nombre de façons essentiellement différentes de le résoudre. J'ai besoin que vous m'écriviez un programme pour ça.
Contribution
Votre entrée est un tableau rectangulaire non vide de caractères .#
. Les points .
sont des espaces vides et les #
obstacles sont.
Un chemin à travers la course d'obstacles commence dans le coin supérieur gauche et se termine dans le coin inférieur droit, et ne va que vers la droite ou vers le bas. De plus, un chemin valide ne peut pas traverser un obstacle. Voici quelques exemples dessinés avec des +
caractères:
Valid path Invalid path Invalid path Invalid path
++........ ++........ +++++..... ..+.......
.++++++#.. .+.....#.. ....+++#++ ..++...#..
......+#.. .+.++++#.. .......#.+ ...+++.#..
....#.++++ .+++#.++++ ....#....+ ....#+....
Deux chemins sont essentiellement similaires 1 si l'un peut être transformé en l'autre en se déplaçant un +
à la fois. Les chemins intermédiaires doivent également être valides, vous ne pouvez donc pas plier un chemin au-dessus d'un obstacle. Par exemple, les deux premiers chemins ici sont essentiellement similaires, mais le troisième est essentiellement différent d'eux, car il ne peut pas être déplacé sur les deux obstacles:
++........ +......... +++++++++.
.+++++.#.. ++.....#.. .......#+.
.....+.#.. .++++++#.. .......#++
....#+++++ ....#.++++ ....#....+
Production
Votre résultat est le nombre de chemins essentiellement différents à travers le parcours du combattant. En d'autres termes, si tous les chemins valides sont divisés en classes de chemins essentiellement similaires, la sortie est le nombre de classes. Notez que ce nombre peut être 0 s'il n'y a pas de chemins valides.
Règles et notation
Vous pouvez écrire un programme complet ou une fonction. Le nombre d'octets le plus bas l'emporte et les failles standard sont interdites. Il n'y a pas de limites de temps, sauf que vous devez évaluer votre programme sur chaque cas de test avant de le soumettre.
Cas de test
....
....
.... => 1
...#
....
...# => 0
#..#
..#.
.... => 0
......
......
..##..
......
...... => 2
......
...#..
......
..#...
#..... => 3
......
..#...
......
....#.
#..... => 4
.......
##.....
....###
...#...
..##.#.
#....#.
..#.... => 0
......#.
..##....
...#....
.......#
....#...
.##...#.
....#...
##...... => 7
.........
.#.#.#.#.
.........
#.#...#.#
.........
.#.#.#.#.
......... => 17
..........
.#........
..........
.....#....
#.........
........#.
......#...
.......... => 10
.........
.#.......
.........
...#.....
.........
.....#...
.........
.......#.
......... => 16
1 Le terme technique correct est "homotopique" .
+
à la fois »? Est-ce à dire que des chemins essentiellement similaires doivent avoir la même longueur?+
», j'entends essentiellement qu'un coin du chemin est inversé dans un coin de la direction opposée.Réponses:
Escargots ,
5349 octetsPour une fois, je n'ai pas eu à utiliser
t
, la redoutable instruction de téléportation. En conséquence, les cas de test se terminent instantanément au lieu de prendre des éons.Non golfé:
Les options
A^
signifient commencer dans le coin supérieur gauche et compter tous les chemins correspondants. L'idée principale est de vérifier une condition de canonicité pour les chemins. Honnêtement, je ne m'attendais pas à ce que cela fonctionne, mais il a cloué les cas de test, alors ... Ce qu'il essaie de vérifier, c'est que, dans le chemin actuel, l'itinéraire le plus gourmand a été sélectionné, c'est-à-dire aller le plus de fois possible , descendre autant de fois que possible, etc. sans franchir d'obstacles. Cela se fait en vérifiant, après avoir bougé 1 fois ou plus à droite puis 1 ou plusieurs fois vers le bas, que le carré suivant (qui doit être à droite) n'a pas pu être atteint en allant encore une fois à droite dans le segment droit précédent. La condition analogue est également vérifiée après un déplacement vers la droite puis vers le bas.la source
Python 2,
170131112 octetsUne fonction,
f
prenant le parcours du combattant comme une liste de lignes et renvoyant le nombre de chemins essentiellement différents.Explication
Le concept de base est le suivant: nous choisissons un certain obstacle, o , de telle sorte qu'il n'y ait pas d'autres obstacles dans la boîte délimitant o et le coin supérieur gauche.
Nous considérons ensuite les deux sous-cours à l'est et au sud de o . Nous ne considérons l'un de ces sous-cours que si o peut effectivement être traversé dans une direction qui y mène, c'est-à-dire traversé du nord pour se rendre à l'est, et traversé de l'ouest pour se rendre au sud. Nous résolvons le problème pour chacun des sous-cours sélectionnés et retournons la somme des résultats. Ces nombres correspondent au nombre de chemins essentiellement différents lors du croisement de o de gauche et de droite, respectivement, donc les deux ensembles de chemins résultants sont essentiellement différents. Puisqu'il n'y a aucun obstacle entre le point de départ et o, il existe un chemin entre le point de départ et tout point d'entrée dans chacune de ces régions, et tous ces chemins qui mènent au même point sont essentiellement similaires, d'où la somme ci-dessus est le nombre complet de chemins essentiellement différents dans l'ensemble du parcours.
Les choses sont légèrement compliquées par le fait que le parcours du combattant à lui seul ne transmet pas toutes les informations nécessaires. Par exemple, considérez le cours B dans le diagramme ci-dessus. Pris isolément, nous ne pouvons pas déterminer si chacun des obstacles peut être franchi par le nord. Si B était la route d'entrée, alors, puisque tous les chemins commencent dans le coin supérieur gauche, aucun obstacle n'aurait pu être traversé du nord, mais, puisque nous pouvons atteindre B de chaque côté de l'obstacle gauche en traversant o depuis l'est , nous devons traiter cet obstacle comme s'il pouvait être franchi par le nord lors de la résolution du parcours; il n'en va pas de même pour le bon obstacle, cependant, qui ne peut pas être traversé dans cette direction.
Nous convertissons ces informations supplémentaires en spécifiant, avec la course d'obstacles, le nombre de caractères le long de la première ligne, en partant de la gauche, sur lequel le chemin peut commencer. Dans le diagramme ci-dessus, cela est décrit comme la ligne continue à côté de chaque cours. Bien que, techniquement, nous devons également spécifier le nombre correspondant de caractères le long de la première colonne à partir de laquelle le chemin peut commencer, comme dans le cas du sous-cours A , en pratique, nous avons toujours sélectionné l'obstacle le plus élevé, de sorte que ces informations ne sont pas requises .
La sélection réelle de o est la suivante: nous prétendons que chaque ligne, autre que la dernière, est suivie d'un obstacle (c.-à-d., A une
#
annexe), et sélectionnons le premier obstacle dans le parcours résultant, dans l'ordre de lecture. Pour les lignes (autres que la dernière) qui n'avaient pas d'obstacle à l'origine, cela signifie effectivement que nous les ignorons (tout en notant que le chemin ci-dessous peut commencer à n'importe quel caractère le long de la ligne supérieure). Finalement, nous nous retrouvons avec un parcours qui a une seule rangée sans obstacles, pour lequel il n'y a qu'un seul chemin possible.la source
CJam,
858482818079 octetsEssayez-le en ligne. Ou exécutez l'ensemble de la suite de tests.
L'efficacité de cette solution est probablement assez horrible mais elle résout chaque cas de test en quelques secondes.
Explication
Je vais devoir ajouter une ventilation complète du code plus tard, mais l'idée algorithmique est la suivante:
W
etH
, respectivement.W-1
copies de0
et desH-1
copies deW-1
(où0
représente une étape horizontale etW-1
une étape verticale). Nous parcourons tous ces chemins en prenant à plusieurs reprises le premier élément de la grille, puis en sautant lesstep
cellules dans l'ordre de lecture (oùstep
est0
ouW-1
). Nous rejetons tous les chemins qui contiennent a#
.x
a bougé, nous vérifions si les chemins diffèrent exactement à deux endroits. Si tel est le cas, ces deux endroits auront un déplacement vertical et horizontal inversé. Cela provoque le décalage du segment entier entre ces mouvements en diagonale d'une cellule. Mais si ces deux chemins sont valides, le déplacement d'une partie du chemin d'une cellule en diagonale ne peut pas traverser un obstacle, ils sont donc similaires. Nous devons encore trouver la fermeture transitive, alors nous continuons à le faire jusqu'à ce que nous ne trouvions plus de chemins similaires avant de passer au groupe suivant.la source