-
Notifications
You must be signed in to change notification settings - Fork 0
/
Day7.cs
123 lines (98 loc) · 3.45 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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
using System;
using System.Collections.Generic;
using System.Linq;
namespace AdventOfCode
{
public class Day7 : ISolver
{
private IList<Bag> Bags { get; set; }
public Day7(string inputFile)
{
Bags = Reader.ReadStrings(inputFile)
.Select(line => new Bag(line))
.ToList();
}
public void Part1()
{
var inputBag = "shinygold";
var parentBags = FindParentBags(inputBag)
.Select(bag => bag.Identifier)
.Distinct();
Console.WriteLine(string.Join(", ", parentBags));
Console.WriteLine(parentBags.Count());
}
public void Part2()
{
var inputBag = "shinygold";
var numChildBags = FindChildBagQuantities(inputBag);
Console.WriteLine(numChildBags - 1);
// childBags.ForEach(cb => Console.Write($"{cb.Quantity} {cb.Identifier}, "));
}
private IEnumerable<Bag> FindParentBags(string identifier)
{
var parentBags = Bags
.Where(bag => bag.CanHold.Any(b => b.Identifier == identifier))
.ToList();
if (parentBags.Count == 0)
{
return Enumerable.Empty<Bag>();
}
return parentBags.Concat(parentBags.SelectMany(parentBag => FindParentBags(parentBag.Identifier)));
}
private int FindChildBagQuantities(string identifier)
{
var childBags = Bags
.FirstOrDefault(b => b.Identifier == identifier)
.CanHold;
if (childBags.Count == 0)
{
Console.WriteLine($"{identifier} has no bags");
return 1;
}
Console.WriteLine($"{identifier} has child bags:");
childBags.ForEach(cb => Console.WriteLine($" {cb.Quantity} {cb.Identifier}"));
return 1 + childBags
.Select(cb => cb.Quantity * FindChildBagQuantities(cb.Identifier))
.Sum();
}
}
internal class Bag
{
public string Identifier { get; set; }
public List<ChildBagAndQuantity> CanHold { get; set; }
public Bag() { }
public Bag(string rule)
{
var splitRule = rule.Split("contain");
var bagId = splitRule[0].TrimEnd().Split(" ").SkipLast(1);
Identifier = string.Join("", bagId);
CanHold = splitRule[1]
.TrimStart()
.Split(", ")
.Select(content =>
{
if (content == "no other bags.")
{
return null;
}
var splitContents = content.Split(" ").SkipLast(1);
var quantity = Int32.Parse(splitContents.First());
var identifier = string.Join("", splitContents.Skip(1));
return new ChildBagAndQuantity(identifier, quantity);
})
.Where(content => content != null)
.ToList();
}
}
internal class ChildBagAndQuantity
{
public string Identifier { get; set; }
public int Quantity { get; set; }
public ChildBagAndQuantity() { }
public ChildBagAndQuantity(string identifier, int quantity)
{
Identifier = identifier;
Quantity = quantity;
}
}
}