-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday12_part02.fs
65 lines (53 loc) · 1.86 KB
/
day12_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
module day12_part02
open System.Collections.Generic
open AdventOfCode_2017.Modules
type Node = {
Value: int
}
type Edge = {
Connection: Node*Node
}
type Graph<'T> = Dictionary<'T, List<'T>>
let parseContent(lines: string array) =
let thegraph = Dictionary<Node, Node list>()
let edges =
lines
|> Array.collect(fun l ->
let fromnode = l.Split(" <-> ")[0] |> int
let tonodes = (l.Split(" <-> ")[1]).Split(", ") |> Array.map int
tonodes
|> Array.map(fun tnode ->
{ Connection = ({ Value = fromnode }, { Value = tnode }) }
)
)
|> Array.collect(fun e -> [| e; { Connection = (snd e.Connection, fst e.Connection) }|])
edges
|> Array.groupBy(fun e -> fst e.Connection)
|> Array.iter(fun (n, edges) ->
let toconnets = edges |> Array.map(fun e -> snd e.Connection) |> List.ofArray |> List.distinct
thegraph.Add(n, toconnets)
)
thegraph
let isConnected (graph: Dictionary<Node, Node list>) (from: Node) =
let rec collectNodes (start: Node) (visited: Set<Node>) =
match graph.TryGetValue start with
| false, _ -> visited
| true, children ->
let toProcess = children |> List.filter (fun c -> not (visited.Contains c))
let updatedVisited = visited.Add start
toProcess
|> List.fold (fun acc child -> collectNodes child acc) updatedVisited
collectNodes from Set.empty
let findGroups(graph: Dictionary<Node, Node list>) =
let groups =
graph.Keys
|> Seq.map(fun k -> isConnected graph k)
|> Seq.distinct
|> List.ofSeq
groups
let execute() =
let path = "day12/day12_input.txt"
let content = LocalHelper.GetLinesFromFile path
let graph = parseContent content
let groups = findGroups graph
groups.Length