-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday7.cs
109 lines (93 loc) · 3.57 KB
/
day7.cs
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
class Day7 {
class Node {
public string name;
public Node parent;
public List<Node> children = new List<Node>();
public int size;
public bool isDir;
}
private static Node BuildFilesystem(string[] input) {
Node root = null;
Node currentNode = null;
foreach(var line in input) {
var tokens = line.Split(" ");
if (tokens.First().Equals("$")) { // is a command
var command = tokens.ElementAt(1);
var args = tokens.Skip(2);
switch (command) {
case "cd":
var dir = args.First();
if (dir == "/") {
root = new Node() {
isDir = true,
name = dir
};
currentNode = root;
} else if (dir == "..") {
currentNode = currentNode.parent;
} else {
currentNode = currentNode.children.FirstOrDefault(n => n.name == dir && n.isDir);
}
break;
case "ls": break;
default: Console.Error.WriteLine("unknown command"); break;
}
} else {
var token1 = tokens.ElementAt(0);
var token2 = tokens.ElementAt(1);
if (token1 == "dir") {
currentNode.children.Add(new Node() {
isDir = true,
name = token2,
parent = currentNode
});
} else {
Int32.TryParse(token1, out int filesize);
currentNode.children.Add(new Node() {
name = token2,
size = filesize,
parent = currentNode
});
var node = currentNode;
do {
node.size += filesize;
node = node.parent;
} while(node != null);
}
}
}
return root;
}
private static int GetDirectoriesSum(Node dir, int atMostSize) {
var acc = dir.size <= atMostSize ? dir.size : 0;
return acc + dir.children.Where(c => c.isDir).Select(d => GetDirectoriesSum(d, atMostSize)).Sum();
}
private static void part1(string[] input) {
Node root = BuildFilesystem(input);
Console.WriteLine($"Part 1: {GetDirectoriesSum(root, 100000)}");
}
private static void part2(string[] input) {
Node root = BuildFilesystem(input);
Queue<Node> toVisit = new Queue<Node>();
toVisit.Enqueue(root);
List<Node> elligebleNodes = new List<Node>();
var freespace = 70000000 - root.size;
var neededSize = 30000000;
while(toVisit.Count() > 0) {
var node = toVisit.Dequeue();
if(node.size + freespace >= neededSize) {
elligebleNodes.Add(node);
var elligebleChildren = node.children.Where(n => n.isDir);
foreach(var x in elligebleChildren){
toVisit.Enqueue(x);
}
}
}
Console.WriteLine($"Part 2: {elligebleNodes.OrderBy(n => n.size).First().size}");
}
public static void Run() {
string[] input = File.ReadAllLines(@"input/7");
part1(input);
part2(input);
}
}