generated from mazharenko/aoc-agent-template-multipleyears
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay05.cs
124 lines (108 loc) · 2.31 KB
/
Day05.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
124
namespace aoc.Year2024;
internal partial class Day05
{
public record Page(List<int> Numbers)
{
public static Page Create(IEnumerable<int> numbers) => new(numbers.ToList());
public int? FindIndex(int number)
{
var index = Numbers.IndexOf(number);
return index == -1 ? null : index;
}
public int Middle() => Numbers[Numbers.Count / 2];
}
public record Rule(int Smaller, int Larger)
{
public static Rule Create(int smaller, int larger) => new(smaller, larger);
public bool Satisfied(Page page)
{
var smallerIndex = page.FindIndex(Smaller);
var largerIndex = page.FindIndex(Larger);
if (smallerIndex is null || largerIndex is null)
return true;
return smallerIndex < largerIndex;
}
}
public (Rule[] rules, Page[] pages) Parse(string input)
{
var rulesParser =
Numerics.IntegerInt32.ThenIgnore(Span.EqualTo("|"))
.Then(Numerics.IntegerInt32)
.Select(Rule.Create)
.Lines();
var pages =
Numerics.IntegerInt32.ManyDelimitedBy(Span.EqualTo(","))
.Select(Page.Create)
.Lines();
return rulesParser.Block().ThenBlock(pages).Parse(input);
}
internal partial class Part1
{
public Part1()
{
Expect(example, 143);
}
public int Solve((Rule[] rules, Page[] pages) input)
{
var correctPages
= input.pages.Where(page => input.rules.All(rule => rule.Satisfied(page)));
return correctPages.Select(x => x.Middle()).Sum();
}
}
internal partial class Part2
{
public Part2()
{
Expect(example, 123);
}
public int Solve((Rule[] rules, Page[] pages) input)
{
var incorrectPages
= input.pages.Where(page => ! input.rules.All(rule => rule.Satisfied(page)));
return incorrectPages.Select(page =>
Page.Create(page.Numbers.Order(new Comparer(input.rules))).Middle())
.Sum();
}
private class Comparer(Rule[] rules) : IComparer<int>
{
public int Compare(int x, int y)
{
if (rules.Contains(Rule.Create(x, y)))
return 1;
if (rules.Contains(Rule.Create(y, x)))
return -1;
return 0;
}
}
}
private readonly Example example = new(
"""
47|53
97|13
97|61
97|47
75|29
61|13
75|53
29|13
97|29
53|29
61|53
97|53
61|29
47|13
75|47
97|75
47|61
75|61
47|29
75|13
53|13
75,47,61,53,29
97,61,53,29,13
75,29,13
75,97,47,61,53
61,13,29
97,13,75,29,47
""");
}