84 lines
1.7 KiB
Nim
84 lines
1.7 KiB
Nim
import system/io
|
|
import strutils
|
|
import sequtils
|
|
import tables
|
|
import sugar
|
|
|
|
const
|
|
SYM_START = 'S'
|
|
SYM_END = 'E'
|
|
|
|
type
|
|
Coords = tuple
|
|
x, y: int
|
|
|
|
proc diff(a, b: int): int =
|
|
if a > b: a - b
|
|
else: b - a
|
|
|
|
proc height(i: char): int =
|
|
(
|
|
case i:
|
|
of SYM_START:
|
|
'a'
|
|
of SYM_END:
|
|
'z'
|
|
else:
|
|
i
|
|
).ord
|
|
|
|
var startPoint: Coords
|
|
var endPoint: Coords
|
|
var adjacents = initTable[Coords, seq[Coords]]()
|
|
|
|
let heightMap = collect(
|
|
for line in stdin.readAll.split:
|
|
if line != "": line
|
|
)
|
|
|
|
for x in 0 .. heightMap.len - 1:
|
|
for y in 0 .. heightMap[x].len - 1:
|
|
var adjs = newSeq[Coords](0)
|
|
|
|
let h = heightMap[x][y].height
|
|
|
|
case heightMap[x][y]:
|
|
of SYM_START:
|
|
startPoint = (x, y)
|
|
of SYM_END:
|
|
endPoint = (x, y)
|
|
else: discard
|
|
|
|
if y > 0 and h - heightMap[x][y - 1].height < 2:
|
|
adjs.add((x, y - 1))
|
|
if y < heightMap[x].len - 1 and h - heightMap[x][y + 1].height < 2:
|
|
adjs.add((x, y + 1))
|
|
if x > 0 and h - heightMap[x - 1][y].height < 2:
|
|
adjs.add((x - 1, y))
|
|
if x < heightMap.len - 1 and h - heightMap[x + 1][y].height < 2:
|
|
adjs.add((x + 1, y))
|
|
|
|
adjacents[(x, y)] = adjs
|
|
|
|
var unvisited = adjacents.keys.toSeq
|
|
var shortest = collect(initTable()):
|
|
for node in unvisited:
|
|
{node: high(int) - 1}
|
|
|
|
shortest[endPoint] = 0
|
|
|
|
while unvisited.len != 0:
|
|
var current_min: Coords = (-1, -1)
|
|
|
|
for node in unvisited:
|
|
if current_min.x == -1 or shortest[node] < shortest[current_min]:
|
|
current_min = node
|
|
|
|
for adj in adjacents[current_min]:
|
|
let t = shortest[current_min] + 1
|
|
if t < shortest[adj]:
|
|
shortest[adj] = t
|
|
|
|
unvisited.del(unvisited.find(current_min))
|
|
|
|
echo shortest[startPoint]
|