generated from mazharenko/aoc-agent-template-multipleyears
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay21.cs
121 lines (104 loc) · 2.92 KB
/
Day21.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
using mazharenko.AoCAgent.Generator;
using MoreLinq;
namespace aoc.Year2024;
[BypassNoExamples]
internal partial class Day21
{
private static long CountMinSequence(char[] keys, int level, int levels, Dictionary<(string, int), long> counts)
{
if (level == levels) return keys.Length;
var pad = level is 0 ? (IPad)new NumPad() : new ArrowPad();
if (counts.TryGetValue((new string(keys), level), out var count))
return count;
var res = keys.Prepend('A').Pairwise(pad.Routes)
.Select(routes =>
routes.Select(route =>
CountMinSequence(route.Append('A').ToArray(), level + 1, levels, counts)).Min()
).Sum();
counts[(new string(keys), level)] = res;
return res;
}
internal partial class Part1
{
public long Solve(char[][] input)
{
return input.Select(l =>
CountMinSequence(l, 0, 3, new Dictionary<(string, int), long>())
* int.Parse(new string(l.Where(char.IsDigit).ToArray()))
).Sum();
}
}
internal partial class Part2
{
public long Solve(char[][] input)
{
return input.Select(l =>
CountMinSequence(l, 0, 26, new Dictionary<(string, int), long>())
* long.Parse(new string(l.Where(char.IsDigit).ToArray()))
).Sum();
}
}
public char[][] Parse(string input)
{
return Character.LetterOrDigit.Many()
.Lines().Parse(input);
}
private interface IPad
{
IEnumerable<char[]> Routes(char from, char to);
}
private class ArrowPad : IPad
{
public IEnumerable<char[]> Routes(char from, char to)
{
var dcol = Col(to) - Col(from);
var drow = Row(to) - Row(from);
if (Col(from) is not 0 || Row(to) is not 1)
yield return Enumerable.Repeat(drow > 0 ? '^' : 'v', Math.Abs(drow))
.Concat(Enumerable.Repeat(dcol > 0 ? '>' : '<', Math.Abs(dcol)))
.ToArray();
if (Row(from) is not 1 || Col(to) is not 0)
yield return Enumerable.Repeat(dcol > 0 ? '>' : '<', Math.Abs(dcol))
.Concat(Enumerable.Repeat(drow > 0 ? '^' : 'v', Math.Abs(drow)))
.ToArray();
yield break;
int Col(char c) =>
c switch
{
'<' => 0,
'^' or 'v' => 1,
_ => 2
};
int Row(char c) =>
c switch
{
'^' or 'A' => 1,
_ => 0
};
}
}
private class NumPad : IPad
{
public IEnumerable<char[]> Routes(char from, char to)
{
var dcol = Col(to) - Col(from);
var drow = Row(to) - Row(from);
if (Col(to) is not 0 || Row(from) is not 0)
yield return Enumerable.Repeat(dcol > 0 ? '>' : '<', Math.Abs(dcol))
.Concat(Enumerable.Repeat(drow > 0 ? '^' : 'v', Math.Abs(drow)))
.ToArray();
if (Col(from) is not 0 || Row(to) is not 0)
yield return Enumerable.Repeat(drow > 0 ? '^' : 'v', Math.Abs(drow))
.Concat(Enumerable.Repeat(dcol > 0 ? '>' : '<', Math.Abs(dcol)))
.ToArray();
yield break;
int Col(char c) => c switch
{
'0' => 1,
'A' => 2,
_ => (Convert.ToInt32(c.ToString()) - 1) % 3
};
int Row(char c) => c is 'A' or '0' ? 0 : (Convert.ToInt32(c.ToString()) - 1) / 3 + 1;
}
}
}