-
Notifications
You must be signed in to change notification settings - Fork 0
/
day10_part02.fs
86 lines (69 loc) · 2.42 KB
/
day10_part02.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
77
78
79
80
81
82
83
84
85
86
module day10_part02
open AdventOfCode_2024.Modules
type Node = {
Name: int;
Row: int;
Col: int;
Neighbours : Node list;
}
let isInBoundaries (row: int) (col: int) (maxRows: int) (maxCols: int) =
row >= 0 && row < maxRows && col >= 0 && col < maxCols
let buildGraph (map: int[,]) =
let maxRows = Array2D.length1 map
let maxCols = Array2D.length2 map
let nodes =
[ for row in 0 .. maxRows - 1 do
for col in 0 .. maxCols - 1 do
let value = map[row, col]
if value > -1 then
yield (row, col), { Name = value; Row = row; Col = col; Neighbours = [] } ]
|> Map.ofList
let getNeighbors row col =
[ (row - 1, col)
(row + 1, col)
(row, col - 1)
(row, col + 1)]
|> List.choose (fun (rowIdx, colIdx) ->
if isInBoundaries rowIdx colIdx maxRows maxCols then
Map.tryFind (rowIdx, colIdx) nodes
else
None)
nodes
|> Map.map (fun (row, col) node ->
{ node with Neighbours = getNeighbors row col })
|> Map.toList
|> List.map snd
let parseContent (lines: string array) =
let maxRows = lines.Length
let maxCols = lines[0].Length
let map = Array2D.create maxRows maxCols -1
for row in 0..maxRows - 1 do
for col in 0..maxCols - 1 do
map[row, col] <- (int)(lines[row][col]) - int '0'
map
let findHeads (nodes: Node list) =
nodes |> List.filter(fun node -> node.Name = 0)
let isComplete (startNode: Node) (connections: Node list) =
let nodeMap =
connections
|> List.map (fun node -> (node.Row, node.Col), node)
|> Map.ofList
let rec foundValidTrails (currentNode: Node) =
if currentNode.Name = 9 then
[currentNode]
else
match nodeMap.TryFind((currentNode.Row, currentNode.Col)) with
| Some c ->
c.Neighbours
|> List.filter (fun neighbor -> neighbor.Name - currentNode.Name = 1)
|> List.collect (fun neighbor -> foundValidTrails neighbor)
| None -> []
foundValidTrails startNode
let execute() =
let path = "day10/day10_input.txt"
let content = LocalHelper.GetLinesFromFile path
let connections =
parseContent content |> buildGraph
findHeads connections
|> List.collect (fun h -> isComplete h connections)
|> List.length