-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay07.fs
86 lines (67 loc) · 2.34 KB
/
Day07.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 Day07
// problem page
// http://adventofcode.com/2017/day/7
open System.Text.RegularExpressions
open System.Collections.Generic
open System.IO
let problemFileName = @"Data\07.txt"
let processFile (filePath : string) =
seq {
use fileReader = new StreamReader(filePath)
while not fileReader.EndOfStream do
let line = fileReader.ReadLine()
yield line
};;
let lines = problemFileName |> processFile
type Program = { Name : string; Weight : int }
type Tree =
| Branch of Program * Tree list
| Leaf of Program
let toProgram (x : string[]) = {Name = x.[0]; Weight = (int)x.[1] }
let programs = new Dictionary<string, Program * string[]>()
lines
|> Seq.map
(fun x ->
Regex.Split (x, @"\W")
|> Array.filter (fun x -> x <> ""))
|> Seq.iter
(fun (a : string[]) ->
programs.Add(a.[0], (toProgram a, a.[2..])))
let rec getTree name =
let found, value = programs.TryGetValue name
if Array.isEmpty (snd value)
then Leaf(fst value)
else
let leafs = (snd value) |> Array.map (getTree) |> Array.toList
Branch(fst value, leafs)
let allNodeNames = programs.Values |> Seq.map (snd) |> Seq.fold (fun s x -> Array.concat [|s; x|]) [||]
let bottom = programs.Keys |> Seq.find (fun x -> not (Array.contains x allNodeNames))
//2nd part
let tree = getTree "cqmvs"
let rec getWeight node =
match node with
| Branch (program, list) -> List.fold (fun s x -> s + getWeight x) program.Weight list
| Leaf(program) -> program.Weight
let findBadNode treeList =
let badNode =
treeList
|> List.distinctBy (getWeight)
|> List.tryFind (fun _ -> true)
let badWeight = getWeight badNode.Value
let reference = (List.fold (fun s x -> s + getWeight x) 0 treeList - badWeight) / (List.length treeList - 1)
if (reference <> badWeight) then
Some(badNode.Value, reference - badWeight)
else
None
let rec findBadNodeRec tree diff =
match tree with
| Branch (program, list) ->
let result = findBadNode list
if result.IsSome then
let badNode, newDiff = result.Value
printfn "%d" newDiff
findBadNodeRec badNode newDiff
else
program.Weight + diff
| Leaf (program) -> program.Weight + diff
let properWeight = findBadNodeRec tree 0;;