Skip to content

Commit 8a82679

Browse files
committed
wip2
1 parent 95e7bb0 commit 8a82679

File tree

1 file changed

+87
-93
lines changed

1 file changed

+87
-93
lines changed

2024/Day21/Solution.cs

+87-93
Original file line numberDiff line numberDiff line change
@@ -2,135 +2,129 @@ namespace AdventOfCode.Y2024.Day21;
22

33
using System;
44
using System.Collections.Generic;
5-
using System.Collections.Immutable;
65
using System.Linq;
7-
using System.Text.RegularExpressions;
8-
using System.Text;
96
using System.Numerics;
10-
using System.Security.AccessControl;
117
using AngleSharp.Common;
12-
using AdventOfCode.Y2021.Day11;
13-
using System.Security.Cryptography;
8+
using Cache = System.Collections.Concurrent.ConcurrentDictionary<(char, System.Numerics.Complex, int, System.Numerics.Complex), (long, System.Numerics.Complex)>;
9+
1410

1511
[ProblemName("Keypad Conundrum")]
1612
class Solution : Solver {
1713

1814
public object PartOne(string input) {
19-
return input.Split("\n").Sum(Solve);
15+
return input.Split("\n").Sum(line => Solve2(line, 2));
2016
}
21-
2217
public object PartTwo(string input) {
23-
return 0;
18+
// 24: 156944425344350 low
19+
// 25: 400827838993176 high
20+
return input.Split("\n").Sum(line => Solve2(line, 24));
2421
}
2522

2623
static readonly Complex Left = -1;
2724
static readonly Complex Right = 1;
2825
static readonly Complex Up = Complex.ImaginaryOne;
2926
static readonly Complex Down = -Complex.ImaginaryOne;
3027

31-
int Solve(string line) {
28+
long Solve2(string line, int depth) {
3229
var keypad1 = ParseKeypad("789\n456\n123\n 0A");
3330
var keypad2 = ParseKeypad(" ^A\n<v>");
3431

35-
Console.WriteLine("========");
36-
// var q = "<v<A>>^AvA^A<vA<AA>>^AAvA<^A>AAvA^A<vA>^AA<A>A<v<A>A>^AAAvA<^A>A";
37-
// Console.WriteLine(q);
38-
// q = Decode(q, keypad2);
39-
// Console.WriteLine(q);
40-
// q = Decode(q, keypad2);
41-
// Console.WriteLine(q);
42-
// q = Decode(q, keypad1);
43-
// Console.WriteLine(q);
44-
45-
// Console.WriteLine();
46-
47-
var xs = Encode(line, keypad1, keypad1['A']).ToList();
48-
var ys = xs.SelectMany(x => Encode(x, keypad2, keypad2['A'])).ToList();
49-
foreach (var y in ys) {
50-
Console.WriteLine(Decode(Decode(y, keypad2), keypad1));
32+
Cache cache = new Cache();
33+
var res = long.MaxValue;
34+
foreach (var plan in Encode(line, keypad1, keypad1['A'])) {
35+
var (length, _) = EncodeString(plan, keypad2, depth, cache, keypad2['A']);
36+
res = Math.Min(res, length);
37+
}
38+
return res * int.Parse(line.Substring(0, line.Length - 1));
39+
}
40+
41+
(long, Complex) EncodeString(string st, Dictionary<char, Complex> keypad2, int depth, Cache cache, Complex top) {
42+
if (depth == 0) {
43+
return (st.Length, top);
44+
} else {
45+
var length = 0L;
46+
var pos = depth == 1 ? top : keypad2['A'];
47+
var originalTop = top;
48+
foreach (var step in st) {
49+
long cost;
50+
(cost, top) = EncodeKey(step, pos, keypad2, depth, cache, top);
51+
length += cost;
52+
pos = keypad2[step];
53+
}
54+
if (depth == 1) {
55+
top = st.Length == 1 ? originalTop : keypad2[st[^1]];
56+
}
57+
return (length, top);
58+
}
59+
}
60+
(long, Complex) EncodeKey(char ch, Complex pos, Dictionary<char, Complex> keypad2, int depth, Cache cache, Complex top) {
61+
var key = (ch, pos, depth, top);
62+
if (cache.ContainsKey(key)) {
63+
return cache[key];
64+
}
65+
66+
if (depth == 0) {
67+
throw new Exception();
5168
}
5269

53-
var cache = new Dictionary<(Complex, string), string> ();
5470

55-
var z = ys.Select(y => Mikkamakka(keypad2['A'], y, keypad2, cache)).MinBy(z => z.Length);
71+
var target = keypad2[ch];
5672

57-
Console.WriteLine(Decode(Decode(Decode(z, keypad2), keypad2), keypad1));
58-
return z.Length * int.Parse(line[0..^1]);
59-
}
73+
var dy = (int)(target.Imaginary - pos.Imaginary);
74+
var dx = (int)(target.Real - pos.Real);
6075

61-
76+
var resCost = long.MaxValue;
77+
var resTop = Complex.Infinity;
6278

63-
string Mikkamakka(Complex pos, string st, Dictionary<char, Complex> keypad, Dictionary<(Complex, string), string> cache) {
64-
if (st == "") {
65-
return "";
66-
}
67-
var key = (pos, st);
68-
if (!cache.ContainsKey(key)) {
69-
70-
var target = keypad[st[0]];
71-
72-
var dy = (int)(target.Imaginary - pos.Imaginary);
73-
var dx = (int)(target.Real - pos.Real);
74-
75-
var res1 = "";
76-
if (pos + dy * Up != keypad[' ']) {
77-
if (dy < 0) {
78-
res1 += new string('v', Math.Abs(dy));
79-
} else if (dy > 0) {
80-
res1 += new string('^', Math.Abs(dy));
81-
}
82-
if (dx < 0) {
83-
res1 += new string('<', Math.Abs(dx));
84-
} else if (dx > 0) {
85-
res1 += new string('>', Math.Abs(dx));
86-
}
87-
res1 += "A";
88-
res1 += Mikkamakka(target, st[1..], keypad, cache);
79+
var toEncode = "";
80+
if (pos + dy * Up != keypad2[' ']) {
81+
if (dy < 0) {
82+
toEncode += new string('v', Math.Abs(dy));
83+
} else if (dy > 0) {
84+
toEncode += new string('^', Math.Abs(dy));
8985
}
90-
var res2 = "";
91-
if (pos + dx * Right != keypad[' ']) {
92-
if (dx < 0) {
93-
res2 += new string('<', Math.Abs(dx));
94-
} else if (dx > 0) {
95-
res2 += new string('>', Math.Abs(dx));
96-
}
97-
98-
if (dy < 0) {
99-
res2 += new string('v', Math.Abs(dy));
100-
} else if (dy > 0) {
101-
res2 += new string('^', Math.Abs(dy));
102-
}
103-
104-
res2 += "A";
105-
res2 += Mikkamakka(target, st[1..], keypad, cache);
86+
if (dx < 0) {
87+
toEncode += new string('<', Math.Abs(dx));
88+
} else if (dx > 0) {
89+
toEncode += new string('>', Math.Abs(dx));
10690
}
91+
toEncode += "A";
92+
var (cost, topT) = EncodeString(toEncode, keypad2, depth - 1, cache, top);
10793

108-
cache[key] = res1 == "" ? res2 : res2 == "" ? res1 : res1.Length < res2.Length ? res1 : res2;
94+
if (cost < resCost) {
95+
resCost = cost;
96+
resTop = topT;
97+
}
10998
}
110-
return cache[key];
111-
}
11299

100+
if (pos + dx * Right != keypad2[' ']) {
101+
if (dx < 0) {
102+
toEncode += new string('<', Math.Abs(dx));
103+
} else if (dx > 0) {
104+
toEncode += new string('>', Math.Abs(dx));
105+
}
113106

114-
string Decode(string st, Dictionary<char, Complex> keymap) {
115-
var res = "";
116-
var pos = keymap['A'];
117-
foreach (var ch in st) {
118-
if (ch == '^') {
119-
pos += Up;
120-
} else if (ch == 'v') {
121-
pos += Down;
122-
} else if (ch == '<') {
123-
pos += Left;
124-
} else if (ch == '>') {
125-
pos += Right;
126-
} else if (ch == 'A') {
127-
res += keymap.Single(kvp => kvp.Value == pos).Key;
107+
if (dy < 0) {
108+
toEncode += new string('v', Math.Abs(dy));
109+
} else if (dy > 0) {
110+
toEncode += new string('^', Math.Abs(dy));
111+
}
112+
toEncode += "A";
113+
114+
var (cost, topT) = EncodeString(toEncode, keypad2, depth - 1, cache, top);
115+
116+
if (cost < resCost) {
117+
resCost = cost;
118+
resTop = topT;
128119
}
129120
}
130-
return res;
121+
122+
cache[key] = (resCost, resTop);
123+
return cache[key];
131124
}
132125

133-
126+
127+
134128
IEnumerable<string> Encode(string st, Dictionary<char, Complex> keymap, Complex pos) {
135129
if (st == "") {
136130
yield return "";

0 commit comments

Comments
 (0)