Skip to content

Commit f872e94

Browse files
committed
day 23
1 parent 15c874b commit f872e94

File tree

2 files changed

+115
-48
lines changed

2 files changed

+115
-48
lines changed

.vscode/launch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"preLaunchTask": "build",
1313
// If you have changed target frameworks, make sure to update the program path.
1414
"program": "${workspaceFolder}/bin/Debug/net6.0/adventofcode.dll",
15-
"args": ["today"],
15+
"args": ["2021/23"],
1616
"cwd": "${workspaceFolder}",
1717
// For more information about the 'console' field, see https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md#console-terminal-window
1818
"console": "internalConsole",

2021/Day23/Solution.cs

Lines changed: 114 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,24 @@ namespace AdventOfCode.Y2021.Day23;
88
[ProblemName("Amphipod")]
99
class Solution : Solver {
1010

11-
public object PartOne(string input) => Solve(input).Min();
12-
public object PartTwo(string input) => Solve(Upscale(input)).Min();
11+
public object PartOne(string input) => Solve(input);
12+
public object PartTwo(string input) => Solve(Upscale(input));
1313

14-
string Upscale(string input){
14+
string Upscale(string input) {
1515
var lines = input.Split("\n").ToList();
1616
lines.Insert(3, " #D#C#B#A#");
1717
lines.Insert(4, " #D#B#A#C#");
1818
return string.Join("\n", lines);
1919
}
2020

21-
IEnumerable<int> Solve(string input) {
21+
int Solve(string input) {
2222
var maze = GetMaze(input);
2323

2424
var q = new PriorityQueue<Maze, int>();
25-
var seen = new Dictionary<string, Maze>();
26-
q.Enqueue(maze, maze.cost);
27-
seen.Add(maze.Tsto(), maze);
25+
var cost = new Dictionary<Maze, int>();
26+
27+
q.Enqueue(maze, 0);
28+
cost.Add(maze, 0);
2829

2930
bool finished(Maze maze) {
3031
bool colMatch(int icol, char c) {
@@ -39,28 +40,36 @@ bool colMatch(int icol, char c) {
3940
}
4041

4142
while (q.Count > 0) {
42-
maze = q.Dequeue();
43-
44-
foreach (var mazeT in Neighbours(maze)) {
45-
if (finished(mazeT)) {
46-
yield return mazeT.cost;
47-
} else if (!seen.ContainsKey(mazeT.Tsto()) || seen[mazeT.Tsto()].cost > mazeT.cost) {
48-
seen[mazeT.Tsto()] = mazeT;
49-
q.Enqueue(mazeT with { prev = maze }, mazeT.cost);
43+
while (cost[q.UnorderedItems.First().Element] != q.UnorderedItems.First().Priority) {
44+
q.Dequeue();
45+
}
46+
47+
maze = q.Dequeue();;
48+
49+
if (finished(maze)) {
50+
return cost[maze];
51+
}
52+
53+
foreach (var n in Neighbours(maze)) {
54+
if (n.cost + cost[maze] < cost.GetValueOrDefault(n.maze, int.MaxValue)) {
55+
cost[n.maze] = n.cost + cost[maze];
56+
q.Enqueue(n.maze, cost[n.maze]);
5057
}
5158
}
5259
}
60+
61+
throw new Exception();
5362
}
5463

5564
Maze GetMaze(string input) {
5665
var map = input.Split("\n");
57-
return new Maze((
58-
from y in Enumerable.Range(0, map.Length)
59-
from x in Enumerable.Range(0, map[0].Length)
60-
select new KeyValuePair<Point, char>(new Point(y, x), y < map.Length && x < map[y].Length ? map[y][x] : ' ')
61-
).ToImmutableDictionary(),
62-
0
63-
);
66+
var maze = new Maze(0, 0, 0, 0, map.Length > 6);
67+
foreach (var y in Enumerable.Range(0, map.Length)) {
68+
foreach (var x in Enumerable.Range(0, map[0].Length)) {
69+
maze = maze.SetItem(new Point(y, x), y < map.Length && x < map[y].Length ? map[y][x] : '#');
70+
}
71+
}
72+
return maze;
6473
}
6574

6675
int stepCost(char actor) {
@@ -97,7 +106,7 @@ bool finishedColumn(Maze maze, int icol) {
97106
return true;
98107
}
99108

100-
IEnumerable<Maze> Neighbours(Maze maze) {
109+
IEnumerable<(Maze maze, int cost)> Neighbours(Maze maze) {
101110

102111
bool columnIsClean(int icol, char ch) {
103112
var pt = new Point(2, icol);
@@ -125,7 +134,7 @@ Point step(Point pt) {
125134
}
126135

127136
// le-e lehet menni?
128-
Maze Lemegy(Maze maze) {
137+
(Maze maze, int cost) Lemegy(Maze maze) {
129138
for (var icol = 1; icol < 12; icol++) {
130139
var ch = maze.ItemAt(new Point(1, icol));
131140

@@ -144,17 +153,16 @@ Maze Lemegy(Maze maze) {
144153
steps++;
145154
}
146155

147-
return Lemegy(maze with {
148-
map = maze.map.SetItem(new Point(1, icol), '.').SetItem(pt, ch),
149-
cost = maze.cost + steps * stepCost(ch)
150-
});
156+
var l = Lemegy(maze.SetItem(new Point(1, icol), '.').SetItem(pt, ch));
157+
return (l.maze, l.cost + steps * stepCost(ch));
151158
}
152159
}
153-
return maze;
160+
return (maze, 0);
154161
}
155162

156-
if (Lemegy(maze).Tsto() != maze.Tsto()) {
157-
yield return Lemegy(maze);
163+
var lemegy = Lemegy(maze);
164+
if (lemegy.cost != 0) {
165+
yield return lemegy;
158166
yield break;
159167
}
160168
var allowedHColumns = new int[] { 1, 2, 4, 6, 8, 10, 11 };
@@ -184,10 +192,10 @@ Maze Lemegy(Maze maze) {
184192
while (maze.ItemAt(ptDst) == '.') {
185193

186194
if (allowedHColumns.Contains(ptDst.icol)) {
187-
yield return maze with {
188-
map = maze.map.SetItem(ptSrc, '.').SetItem(ptDst, ch),
189-
cost = maze.cost + (stepsV + stepsH) * stepCost(ch)
190-
};
195+
yield return (
196+
maze.SetItem(ptSrc, '.').SetItem(ptDst, ch),
197+
(stepsV + stepsH) * stepCost(ch)
198+
);
191199
}
192200

193201
if (dj == -1) {
@@ -209,19 +217,78 @@ record Point(int irow, int icol) {
209217
public Point Left => new Point(irow, icol - 1);
210218
public Point Right => new Point(irow, icol + 1);
211219
}
212-
record Maze(ImmutableDictionary<Point, char> map, int cost, Maze prev = null) {
213-
214-
public char ItemAt(Point pt) => map.GetValueOrDefault(pt, '#');
220+
record Maze(int a, int b, int c, int d, bool big) {
221+
222+
int BitFromPoint(Point pt) =>
223+
(big, pt.irow, pt.icol) switch {
224+
(_, 1, 1) => 1 << 0,
225+
(_, 1, 2) => 1 << 1,
226+
(_, 1, 3) => 1 << 2,
227+
(_, 1, 4) => 1 << 3,
228+
(_, 1, 5) => 1 << 4,
229+
(_, 1, 6) => 1 << 5,
230+
(_, 1, 7) => 1 << 6,
231+
(_, 1, 8) => 1 << 7,
232+
(_, 1, 9) => 1 << 8,
233+
(_, 1, 10) => 1 << 9,
234+
(_, 1, 11) => 1 << 10,
235+
236+
(_, 2, 3) => 1 << 11,
237+
(_, 2, 5) => 1 << 12,
238+
(_, 2, 7) => 1 << 13,
239+
(_, 2, 9) => 1 << 14,
240+
241+
(_, 3, 3) => 1 << 15,
242+
(_, 3, 5) => 1 << 16,
243+
(_, 3, 7) => 1 << 17,
244+
(_, 3, 9) => 1 << 18,
245+
246+
(true, 4, 3) => 1 << 19,
247+
(true, 4, 5) => 1 << 20,
248+
(true, 4, 7) => 1 << 21,
249+
(true, 4, 9) => 1 << 22,
250+
251+
(true, 5, 3) => 1 << 23,
252+
(true, 5, 5) => 1 << 24,
253+
(true, 5, 7) => 1 << 25,
254+
(true, 5, 9) => 1 << 26,
255+
256+
_ => 1 << 31,
257+
};
258+
259+
public char ItemAt(Point pt) {
260+
var bit = BitFromPoint(pt);
261+
return
262+
bit == 1 << 31 ? '#' :
263+
(a & bit) != 0 ? 'A' :
264+
(b & bit) != 0 ? 'B' :
265+
(c & bit) != 0 ? 'C' :
266+
(d & bit) != 0 ? 'D' :
267+
(d & bit) != 0 ? 'D' :
268+
'.';
269+
}
215270

216-
public string Tsto() {
217-
var st = "";
218-
for (var irow = 0; irow < 7; irow++) {
219-
for (var icol = 0; icol < 13; icol++) {
220-
st += map.GetValueOrDefault(new Point(irow, icol), ' ');
221-
}
222-
st += "\n";
271+
public Maze SetItem(Point pt, char ch) {
272+
var bit = BitFromPoint(pt);
273+
if (bit == 1 << 31) {
274+
if (ch != '#' && ch != ' ')
275+
throw new Exception();
276+
return this;
223277
}
224-
st += "---\n";
225-
return st;
278+
279+
return ch switch {
280+
'.' =>
281+
this with {
282+
a = a & ~bit,
283+
b = b & ~bit,
284+
c = c & ~bit,
285+
d = d & ~bit
286+
},
287+
'A' => this with { a = a | bit },
288+
'B' => this with { b = b | bit },
289+
'C' => this with { c = c | bit },
290+
'D' => this with { d = d | bit },
291+
_ => throw new Exception()
292+
};
226293
}
227294
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy