Skip to content

Commit 3d4b21d

Browse files
committed
09
1 parent 3addad1 commit 3d4b21d

4 files changed

Lines changed: 137 additions & 143 deletions

File tree

2025/Day09/Solution.cs

Lines changed: 64 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,12 @@ namespace AdventOfCode.Y2025.Day09;
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.Drawing;
11-
using System.Reflection.Metadata.Ecma335;
12-
using System.IO;
137

148
record Segment(Complex a, Complex b);
9+
record Rectangle(Complex top, Complex left, Complex bottom, Complex right);
1510

16-
17-
// rossz: 1525957356 <5328; 67412> <94891; 50375>
18-
// 1310082477
19-
// 1525812304
20-
// 1525991432 <94891; 50375> <5328; 67412> too low
21-
// 1525991432
22-
// 1525991432
23-
// 1310082477
2411
[ProblemName("Movie Theater")]
2512
class Solution : Solver {
2613

@@ -29,100 +16,74 @@ public object PartOne(string input) {
2916
return (
3017
from p1 in points
3118
from p2 in points
32-
select Math.Abs((p1.Real - p2.Real + 1) * (p1.Imaginary - p2.Imaginary + 1))
19+
select Area(p1, p2)
3320
).Max();
3421
}
3522

36-
3723
public object PartTwo(string input) {
38-
39-
// 94891; 50375
40-
// 94891; 48378
24+
// The input looks like a circle with a slot in the middle of it:
25+
//
26+
// xxx
27+
// xxxxxxxxx
28+
// xxxxxxxxxAx
29+
// xx
30+
// xxxxxxxxxBx
31+
// xxxxxxxxx
32+
// xxx
33+
//
34+
// To speed things up we find the corners A and B first. Based on
35+
// visual observation one of them must be a corner of the final rectangle.
36+
//
37+
// Then go over the 'red' points in the upper and lower halves of
38+
// the picture and find the greatest rectangle.
4139

4240
var points = Parse(input);
41+
var segments = Segments(points);
4342
var shape = Draw(points);
4443

4544
var res = 0L;
46-
// var p1 = 9 + 5 * Complex.ImaginaryOne;
47-
// var p2 = 2 + 3 * Complex.ImaginaryOne;
48-
49-
var reactanglesByArea = (
50-
// from p1 in points
51-
// from p1 in new []{94891 + 48378 * Complex.ImaginaryOne, 94891 + 50375 * Complex.ImaginaryOne}
52-
// from p1 in new []{94891 + 50375 * Complex.ImaginaryOne}
53-
from p1 in new []{94891 + 48378 * Complex.ImaginaryOne}
54-
from p2 in points
55-
orderby Area(p1, p2) descending
56-
select (p1, p2)
57-
).ToArray();
5845

59-
// <94891; 48378> <3933; 33976>
46+
var slot = Segments(points)
47+
.OrderByDescending(s => Area(s.Item1, s.Item2))
48+
.ThenBy(s=>s.Item1.Imaginary)
49+
.Select(s => s.Item1.Real > s.Item2.Real ? s.Item1 : s.Item2)
50+
.Take(2)
51+
.ToArray();
6052

61-
var centerY = (points.Select(x=>x.Imaginary).Max() + points.Select(x=>x.Imaginary).Min())/2;
53+
var upper = from p in points where p.Imaginary >= slot[0].Imaginary select (p1: slot[0], p2: p);
54+
var lower = from p in points where p.Imaginary <= slot[1].Imaginary select (p1: slot[1], p2: p);
6255

63-
var i =0;
64-
foreach (var (p1, p2) in reactanglesByArea) {
65-
i++;
66-
if (i%1000 == 0) {
67-
Console.WriteLine(i);
68-
}
69-
if (Math.Sign(p1.Imaginary-centerY) != Math.Sign(p2.Imaginary - centerY)) {
70-
continue;
71-
}
56+
var reactanglesByArea = (
57+
from ps in upper.Concat(lower)
58+
let p1 = ps.p1
59+
let p2 = ps.p2
60+
let top = Math.Min(p1.Imaginary, p2.Imaginary) * Complex.ImaginaryOne
61+
let bottom = Math.Max(p1.Imaginary, p2.Imaginary) * Complex.ImaginaryOne
62+
let left = Math.Min(p1.Real, p2.Real)
63+
let right = Math.Max(p1.Real, p2.Real)
64+
orderby Area(top+left, bottom + right) descending
65+
select new Rectangle(top, left, bottom, right)
66+
).ToArray();
7267

73-
// <9; 5> <2; 3>
74-
var top = Math.Min(p1.Imaginary, p2.Imaginary);
75-
var left = Math.Min(p1.Real, p2.Real);
76-
var bottom = Math.Max(p1.Imaginary, p2.Imaginary);
77-
var right = Math.Max(p1.Real, p2.Real);
78-
79-
var corners = new Complex[]{
80-
left + Complex.ImaginaryOne * top,
81-
right + Complex.ImaginaryOne * top,
82-
right + Complex.ImaginaryOne * bottom,
83-
left + Complex.ImaginaryOne * bottom,
84-
};
85-
86-
// var shape2 = Draw(corners);
87-
88-
// foreach (var p in shape2) {
89-
// Console.WriteLine(p + " " + Inside(p, shape));
90-
// }
91-
92-
93-
if (corners.All(c => Inside(c, shape))) {
94-
95-
var qqq = points.Where(p => InRect(p, top, left, bottom, right)).ToArray();
96-
if (qqq.Any()) {
97-
continue;
98-
}
99-
var area = Area(p1, p2);
100-
Console.WriteLine("found " + p1 + " " + p2 + " " + area);
101-
File.WriteAllText("2025/Day09/coords.txt",
102-
$"""
103-
{p1.Real},{p1.Imaginary}
104-
{p2.Real},{p2.Imaginary}
105-
"""
106-
);
107-
res = Area(p1, p2);
68+
foreach (var r in reactanglesByArea) {
69+
if (Inside(r.top + r.left, shape) &&
70+
Inside(r.top + r.right, shape) &&
71+
Inside(r.bottom + r.right, shape) &&
72+
Inside(r.bottom + r.left, shape) &&
73+
points.All(p => !InRect(p, r))
74+
) {
75+
res = Area(r.top + r.left, r.bottom + r.right);
10876
break;
10977
}
110-
// else {
111-
// res = Area(p1, p2);
112-
// Console.WriteLine(p1 + " " + p2 + " " + res + " x");
113-
// }
11478
}
11579

11680
return res;
117-
// return (
118-
// from p1 in pointsInShape
119-
// from p2 in pointsInShape
120-
// where points.All(p => !InsideRectangle(p1, p2, p))
121-
// select Math.Abs((p1.Real - p2.Real + 1) * (p1.Imaginary - p2.Imaginary + 1))
122-
// ).Max();
12381
}
12482

12583

84+
IEnumerable<(Complex, Complex)> Segments(Complex[] points) {
85+
return points.Zip(points.Prepend(points.Last()));
86+
}
12687
Complex[] Parse(string input) => (
12788
from line in input.Split("\n")
12889
let parts = line.Split(",").Select(int.Parse).ToArray()
@@ -135,11 +96,13 @@ long Area(Complex p1, Complex p2) {
13596
}
13697
HashSet<Complex> Draw(Complex[] points) {
13798
var res = new HashSet<Complex>();
138-
var lines = points.Zip(points.Prepend(points.Last())).ToArray();
139-
foreach (var line in lines) {
140-
var a = line.First;
141-
var b = line.Second;
142-
var d = Math.Sign(b.Real - a.Real) + Complex.ImaginaryOne * Math.Sign(b.Imaginary - a.Imaginary);
99+
var segments = Segments(points);
100+
foreach (var line in segments) {
101+
var a = line.Item1;
102+
var b = line.Item2;
103+
var d =
104+
Math.Sign(b.Real - a.Real) +
105+
Complex.ImaginaryOne * Math.Sign(b.Imaginary - a.Imaginary);
143106
for (var p = a; p != b; p += d) {
144107
res.Add(p);
145108
}
@@ -148,24 +111,27 @@ HashSet<Complex> Draw(Complex[] points) {
148111
return res;
149112
}
150113

151-
bool InRect(Complex position, double top, double left, double bottom, double right) {
114+
bool InRect(Complex position, Rectangle r) {
152115
return
153-
left < position.Real && position.Real < right &&
154-
top < position.Imaginary && position.Imaginary < bottom
116+
r.left.Real < position.Real && position.Real < r.right.Real &&
117+
r.top.Imaginary < position.Imaginary && position.Imaginary < r.bottom.Imaginary
155118
;
156119
}
120+
157121
// Check if position is inside the loop using ray casting algorithm
158122
bool Inside(Complex position, HashSet<Complex> shape) {
123+
// Imagine a small elf starting from the top half of a cell and moving
124+
// to the left jumping over the borders it encounters. It needs to jump
125+
// over only 'vertically' oriented pipes leading upwards, since it runs
126+
// in the top of the row. Each jump flips the "inside" variable.
159127
if (shape.Contains(position)) {
160128
return true;
161129
}
162130

163131
var inside = false;
164132
position -= 1;
165133
while (position.Real > 0) {
166-
if (
167-
shape.Contains(position) && shape.Contains(position + Complex.ImaginaryOne)
168-
) {
134+
if (shape.Contains(position) && shape.Contains(position + Complex.ImaginaryOne)) {
169135
inside = !inside;
170136
}
171137

2025/Day09/input.refout

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
4748769124
1+
4748769124
2+
1525991432

2025/SplashScreen.cs

Lines changed: 55 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ public void Show() {
88

99
var color = Console.ForegroundColor;
1010
Write(0xcc00, false, " ▄█▄ ▄▄█ ▄ ▄ ▄▄▄ ▄▄ ▄█▄ ▄▄▄ ▄█ ▄▄ ▄▄▄ ▄▄█ ▄▄▄\n █▄█ █ █ █ █ █▄█ █ █ █ █ █ █▄ ");
11-
Write(0xcc00, false, " █ █ █ █ █ █▄█\n █ █ █▄█ ▀▄▀ █▄▄ █ █ █▄ █▄█ █ █▄ █▄█ █▄█ █▄▄ λy.2025\n \n ");
12-
Write(0xcc00, false, " ");
13-
Write(0xffffff, false, "' ____ ' . '' ");
14-
Write(0xffff66, true, "* ");
15-
Write(0xffffff, false, ".''. .' . ... ");
11+
Write(0xcc00, false, " █ █ █ █ █ █▄█\n █ █ █▄█ ▀▄▀ █▄▄ █ █ █▄ █▄█ █ █▄ █▄█ █▄█ █▄▄ /* 2025 */\n \n ");
12+
Write(0xcc00, false, " ");
13+
Write(0xffffff, false, "' ' ' ____ . .. ");
14+
Write(0xffff66, true, "* ");
15+
Write(0xffffff, false, "' .. ' ");
1616
Write(0xff9900, false, "<");
17-
Write(0xffffff, false, "o ' . \n ________/");
17+
Write(0xffffff, false, "o ' \n ________/");
1818
Write(0x999999, false, "O___");
1919
Write(0xffffff, false, "\\__________");
2020
Write(0xff0000, false, "|");
@@ -23,8 +23,8 @@ public void Show() {
2323
Write(0xffff66, false, "**\n ");
2424
Write(0x999999, false, "_______");
2525
Write(0xaabbcc, false, "||");
26-
Write(0x999999, false, "_________ ");
27-
Write(0x32211a, false, "'.' ' . \n ' ");
26+
Write(0x999999, false, "_________ ");
27+
Write(0x32211a, false, "' .'' ' ' . \n ");
2828
Write(0x999999, false, "| ");
2929
Write(0x9b715b, false, "_");
3030
Write(0xbb66ff, false, "@");
@@ -60,8 +60,8 @@ public void Show() {
6060
Write(0x666666, false, ". ");
6161
Write(0xff0000, false, ".");
6262
Write(0x666666, false, ". ");
63-
Write(0x999999, false, "| \n ");
64-
Write(0x32211a, false, "' . ' . ");
63+
Write(0x999999, false, "| \n ");
64+
Write(0x32211a, false, ".' ' . ' . ");
6565
Write(0x999999, false, "\\_");
6666
Write(0xaabbcc, false, "]");
6767
Write(0x999999, false, "__");
@@ -77,8 +77,8 @@ public void Show() {
7777
Write(0xaabbcc, false, "//");
7878
Write(0x999999, false, "_| ");
7979
Write(0xcccccc, false, " 3 ");
80-
Write(0xffff66, false, "**\n ");
81-
Write(0x32211a, false, ".' . . ' ' '''.. ");
80+
Write(0xffff66, false, "**\n ");
81+
Write(0x32211a, false, ". . '' ' .' . . '.. . ");
8282
Write(0x999999, false, "____________");
8383
Write(0xaabbcc, false, "//");
8484
Write(0x999999, false, "___ \n __________________________ ");
@@ -135,14 +135,14 @@ public void Show() {
135135
Write(0x999999, false, "_");
136136
Write(0x9b715b, false, "T");
137137
Write(0x999999, false, "_");
138-
Write(0xaa7744, false, "...' ");
139-
Write(0x32211a, false, ". .'.' ' . ");
138+
Write(0xaa7744, false, "...' ");
139+
Write(0x32211a, false, "'. ' '.'..' ' ");
140140
Write(0xcccccc, false, " 5 ");
141141
Write(0xffff66, false, "**\n ");
142142
Write(0x9900, false, "|| ");
143-
Write(0x999999, false, "____________ ");
144-
Write(0x32211a, false, "' ");
145-
Write(0x999999, false, "_______________________ \n _");
143+
Write(0x999999, false, "____________ _______________________ ");
144+
Write(0x32211a, false, "' \n ");
145+
Write(0x999999, false, "_");
146146
Write(0x9900, false, "||");
147147
Write(0x999999, false, "__/");
148148
Write(0xff0000, false, "'...' ");
@@ -167,9 +167,7 @@ public void Show() {
167167
Write(0x9b715b, false, "/ \\");
168168
Write(0xff00, false, "'..' ");
169169
Write(0xff0000, false, "'..' ");
170-
Write(0x999999, false, "|");
171-
Write(0x666666, false, "____ \n ");
172-
Write(0x999999, false, "|");
170+
Write(0x999999, false, "|____ \n |");
173171
Write(0xff0000, false, "&");
174172
Write(0xffff66, false, "%");
175173
Write(0xaaaa, false, ";");
@@ -188,8 +186,9 @@ public void Show() {
188186
Write(0x9b715b, false, "|");
189187
Write(0x66ff, false, "\\ ");
190188
Write(0xaabbcc, false, "\\\\\\\\\\\\ ");
191-
Write(0x999999, false, "|");
192-
Write(0x666666, false, " | | ");
189+
Write(0x999999, false, "| ");
190+
Write(0xaabbcc, false, "| ");
191+
Write(0x999999, false, "| ");
193192
Write(0xcccccc, false, " 7 ");
194193
Write(0xffff66, false, "**\n '...");
195194
Write(0x999999, false, "|");
@@ -206,14 +205,42 @@ public void Show() {
206205
Write(0xaabbcc, false, "|");
207206
Write(0x9900, false, "_");
208207
Write(0x9b715b, false, "[");
209-
Write(0x666666, false, "_O_| \n | ");
208+
Write(0x999999, false, "_");
209+
Write(0xaabbcc, false, "O");
210+
Write(0x999999, false, "_| \n ");
211+
Write(0x666666, false, " __________________________ ");
212+
Write(0x32211a, false, "'. . ");
213+
Write(0xaabbcc, false, "| ");
210214
Write(0xcccccc, false, " 8 ");
211215
Write(0xffff66, false, "**\n ");
212-
Write(0x333333, false, " _________________O__ \n | ");
213-
Write(0x333333, false, "[ ] | | ");
214-
Write(0x666666, false, " 9\n ");
215-
Write(0x333333, false, " ]_____-/_-/_-/___|_| \n ");
216-
Write(0x333333, false, " ");
216+
Write(0x666666, false, "/ ______ __ | ");
217+
Write(0x999999, false, "_________________");
218+
Write(0xaabbcc, false, "O");
219+
Write(0x999999, false, "__ \n ");
220+
Write(0x666666, false, "[ |(__) [ ] \\ |__");
221+
Write(0x999999, false, "| ");
222+
Write(0x66ff, false, "[ ] ");
223+
Write(0xff00, false, "'");
224+
Write(0xff0000, false, "'");
225+
Write(0xff00, false, "'");
226+
Write(0xff0000, false, "'");
227+
Write(0xff00, false, "'");
228+
Write(0xff0000, false, "' ");
229+
Write(0xaabbcc, false, "| ");
230+
Write(0x999999, false, "| ");
231+
Write(0xcccccc, false, " 9 ");
232+
Write(0xffff66, false, "**\n ");
233+
Write(0x333333, false, "o=====|_____o=========o_|_[__");
234+
Write(0x9b715b, false, "]");
235+
Write(0x999999, false, "_____");
236+
Write(0x9b715b, false, "-/");
237+
Write(0x999999, false, "_");
238+
Write(0x9b715b, false, "-/");
239+
Write(0x999999, false, "_");
240+
Write(0x9b715b, false, "-/");
241+
Write(0x999999, false, "___");
242+
Write(0xaabbcc, false, "|");
243+
Write(0x999999, false, "_| \n ");
217244
Write(0x666666, false, "10\n \n ");
218245
Write(0x666666, false, " 11\n ");
219246
Write(0x666666, false, " \n 12\n \n");

0 commit comments

Comments
 (0)