-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday17_part01.fs
76 lines (60 loc) · 1.98 KB
/
day17_part01.fs
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
module day17_part01
open AdventOfCode_2016.Modules
open System
open System.Collections.Generic
open System.Text
type DoorStateKind =
| Open
| Closed
type Pos = {
Row: int
Col: int
}
let md5 = System.Security.Cryptography.MD5.Create()
let hash (s:string) =
Encoding.Default.GetBytes(s)
|> md5.ComputeHash
|> (fun h -> BitConverter.ToString(h).ToLower().Replace("-",""))
let doorState (door: char) =
match door with
| d when d = 'b' || d = 'c' || d = 'd' || d = 'e'|| d = 'f' ->
Open
| _ -> Closed
let doorStates (doors : string) =
let states =
doors.ToCharArray()
|> Array.take(4)
|> Array.map doorState
[
((states[0], "U"), (-1, 0));
((states[1], "D"), (1, 0));
((states[2], "L"), (0, -1));
((states[3], "R"), (0, 1))
]
let findShortestPath (init: string) ((start, goal): (Pos*Pos)) =
let (maxRows, maxCols) = (4, 4)
let isInBoundaries pos =
pos.Row >= 0 && pos.Col >= 0 && pos.Row < maxRows && pos.Col < maxCols
let queue = Queue<Pos*string>()
queue.Enqueue(start, "")
let rec walk (currentpath: string) =
if queue.Count = 0 then None
else
let (current, path) = queue.Dequeue()
if current = goal then
Some(path)
else
let doorhash = hash (currentpath+path)
let validStates = doorStates doorhash |> List.filter(fun ((s,_) , _) -> s.IsOpen)
for ((_, d), (dr, dc)) in validStates do
let nextpos = { Row = current.Row + dr; Col = current.Col + dc}
if isInBoundaries nextpos then
queue.Enqueue((nextpos, path+d))
walk currentpath
walk init
let execute =
let path = "day17/day17_input.txt"
let content = LocalHelper.GetContentFromFile path
match findShortestPath content ({ Row = 0; Col = 0 }, { Row = 3; Col = 3 }) with
| None -> ""
| Some(p) -> p