Het is inderdaad als een graafprobleem te modelleren en dan met Dijkstra's algoritme op te lossen.
Er zijn twee verschillende representaties mogelijk. In de eerste, die ik oorspronkelijk had gekozen, correspondeert een vertex met een tupel (rij, kolom, richting, aantal) waarbij
richting de laatstgenomen richting is en
aantal het aantal stappen dat je in die richting hebt gezet. Voor elke state heb je dan twee soorten edges: je kunt ofwel in dezelfde richting doorgaan als het aantal dat toestaat, waarbij aantal verhoogd wordt (bijvoorbeeld: (0, 0, oost, 1) -> (0, 1, oost, 2)), of je kunt in een andere richting doorgaan waarbij aantal reset naar 1 (bijvoorbeeld: (0, 1, oost, 2) -> (1, 1, zuid, 1)).
Op die manier heb je ongeveer H×W×4×3 vertices (voor deel 1) of H×W×4×10 vertices (voor deel 2) en max. 3 edges per vertex (want je kunt hooguit vooruit, linksaf, of rechtsaf).
Python code (~4 seconde)
Een efficiëntere variant die ik pas later bedacht had is om de vertices te representeren als (rij, kolom, vorige richting), waarbij je elke keer van richting verandert. Voor iedere vertex heb je dan aparte edges voor 1, 2, of 3 stappen vooruit (bijvoorbeeld: (10, 10, oost) → (10, 11, zuid), (10, 12, zuid), (10, 13, zuid), (10, 9, noord), (10, 8, noord), (10, 7, noord)). Bij deel 2 mag je dan ipv 1 t/m 3 stappen, 4 t/m 10 stappen vooruit.
(Ik zie dat @
FCA deze variant gebruikt heeft).
Dat is een efficiëntere graaf omdat het aantal vertices kleiner is (H×W×4), en hoewel het aantal edges per vertex gemiddeld hoger is (max. 4 voor deel 1, max. 14 voor deel 2) is het totaal aantal edges kleiner.
Het helpt hierbij dat in het laatste voorbeeld van deel 2 expliciet wordt gezegd dat je het doel niet in minder dan 4 stappen mag bereiken. Zonder die restrictie zou deze oplossing wat extra werk op het einde nodig hebben.
Python code (~1,4 seconde)
(In beide versies heeft de startpositie nog wat speciale aandacht nodig, omdat er geen vorige richting is.)