-
Notifications
You must be signed in to change notification settings - Fork 0
/
Day7.cs
73 lines (59 loc) · 2.4 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
using System;
using System.Collections.Generic;
using System.IO;
class Day7 {
public static int Solution1() {
Dictionary<string, (string, int)[]> rules = GetRules();
Dictionary<string, List<string>> reverseRules = new Dictionary<string, List<string>>();
foreach (KeyValuePair<string, (string, int)[]> rule in rules) {
foreach ((string content, _) in rule.Value) {
if (reverseRules.TryGetValue(content, out List<string> containers)) {
containers.Add(rule.Key);
} else {
reverseRules[content] = new List<string> { rule.Key };
}
}
}
HashSet<string> potentialContainers = new HashSet<string>();
Stack<string> checkStack = new Stack<string>();
checkStack.Push("shiny gold");
while (checkStack.Count > 0) {
string bag = checkStack.Pop();
foreach (string container in reverseRules.TryGetValue(bag, out List<string> containers) ? containers : (IEnumerable<string>)new string[0]) {
if (potentialContainers.Add(container)) {
checkStack.Push(container);
}
}
}
return potentialContainers.Count;
}
public static int Solution2() {
Dictionary<string, (string, int)[]> rules = GetRules();
int answer = 0;
Dictionary<string, int> toCheck = new Dictionary<string, int> { { "shiny gold", 1 } };
while (toCheck.Count > 0) {
Dictionary<string, int>.Enumerator enumerator = toCheck.GetEnumerator();
enumerator.MoveNext();
string container = enumerator.Current.Key;
int containerCount = enumerator.Current.Value;
toCheck.Remove(container);
foreach ((string bag, int count) in rules[container]) {
int additionalCount = count * containerCount;
toCheck[bag] = additionalCount + (toCheck.TryGetValue(bag, out int currentCount) ? currentCount : 0);
answer += additionalCount;
}
}
return answer;
}
static Dictionary<string, (string, int)[]> GetRules() {
Dictionary<string, (string, int)[]> rules = new Dictionary<string, (string, int)[]>();
foreach (string line in File.ReadLines("input7.txt")) {
string[] rule = line.Split(new[] { " bags contain " }, StringSplitOptions.None);
rules[rule[0]] = rule[1] == "no other bags." ? new (string, int)[0] : Array.ConvertAll(rule[1].Split(new[] { ", " }, StringSplitOptions.None), bag => {
string[] pieces = bag.Split(' ');
return ($"{pieces[1]} {pieces[2]}", int.Parse(pieces[0]));
});
}
return rules;
}
}