-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsolution.nim
83 lines (71 loc) · 1.71 KB
/
solution.nim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import std/[
algorithm,
bitops,
deques,
json,
math,
re,
sequtils,
sets,
strformat,
strutils,
tables,
sugar,
]
import checksums/md5
type
State = object
r, c: int
passcode, path: string
const dPos = [(-1, 0), (1, 0), (0, -1), (0, 1)]
iterator next(s: State): State =
let h = (&"{s.passcode}{s.path}").getMD5
for i, (dr, dc) in dPos:
if h[i] notin 'b' .. 'f': continue
let (nr, nc) = (s.r + dr, s.c + dc)
if nr notin 0 .. 3 or nc notin 0 .. 3: continue
var t = s
t.r = nr
t.c = nc
t.path &= "UDLR"[i]
yield t
proc bfs(s: State): State =
var q = @[s]
while q.len > 0:
var next: typeof q = @[]
for s in q:
if (s.r, s.c) == (3, 3): return s
for ns in s.next:
next.add ns
q = next
when defined(test):
block:
doAssert bfs(State(passcode: "ihgpwlah")).path == "DDRRRD"
doAssert bfs(State(passcode: "kglvqrro")).path == "DDUDRLRRUDRD"
doAssert bfs(State(passcode: "ulqzkmiv")).path == "DRURDRUDDLLDLUURRDULRLDUUDDDRR"
proc part1(input: string): string =
let s = State(passcode: input)
bfs(s).path
proc bfs2(s: State): int =
var q = @[s]
while q.len > 0:
var next: typeof q = @[]
for s in q:
if (s.r, s.c) == (3, 3):
result = result.max s.path.len
continue
for ns in s.next:
next.add ns
q = next
when defined(test):
block:
doAssert bfs2(State(passcode: "ihgpwlah")) == 370
doAssert bfs2(State(passcode: "kglvqrro")) == 492
doAssert bfs2(State(passcode: "ulqzkmiv")) == 830
proc part2(input: string): int =
let s = State(passcode: input)
bfs2(s)
when isMainModule and not defined(test):
let input = readAll(stdin).strip
echo part1(input)
echo part2(input)