Skip to content

Commit 620cca2

Browse files
committed
Solve 2024 day 4
1 parent b28656c commit 620cca2

File tree

3 files changed

+423
-0
lines changed

3 files changed

+423
-0
lines changed

2024.Tests/Day04Tests.cs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
using Basje.AdventOfCode.Y2024.D04;
2+
3+
namespace Basje.AdventOfCode.Y2024.Tests;
4+
5+
public static class Day04Tests
6+
{
7+
[Fact]
8+
public static void Part1()
9+
{
10+
var solution = new Day04();
11+
const string input = """
12+
MMMSXXMASM
13+
MSAMXMSMSA
14+
AMXSXMAAMM
15+
MSAMASMSMX
16+
XMASAMXAMM
17+
XXAMMXXAMA
18+
SMSMSASXSS
19+
SAXAMASAAA
20+
MAMMMXMMMM
21+
MXMXAXMASX
22+
""";
23+
24+
var answer = solution.SolvePart1(input);
25+
26+
answer.Should().Be(18);
27+
}
28+
29+
[Fact]
30+
public static void Part2()
31+
{
32+
var solution = new Day04();
33+
const string input = """
34+
MMMSXXMASM
35+
MSAMXMSMSA
36+
AMXSXMAAMM
37+
MSAMASMSMX
38+
XMASAMXAMM
39+
XXAMMXXAMA
40+
SMSMSASXSS
41+
SAXAMASAAA
42+
MAMMMXMMMM
43+
MXMXAXMASX
44+
""";
45+
46+
var answer = solution.SolvePart2(input);
47+
48+
answer.Should().Be(9);
49+
}
50+
}

2024/D04/Day04.cs

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
namespace Basje.AdventOfCode.Y2024.D04;
2+
3+
public class Day04 : Solution<char[][]>
4+
{
5+
protected override char[][] ParseInput(string input)
6+
{
7+
return input
8+
.PerLine()
9+
.IgnoreEmptyLines()
10+
.Select(line => line.ToArray())
11+
.ToArray();
12+
}
13+
14+
protected override object SolvePart1(char[][] wordSearch)
15+
{
16+
var occurrences = 0;
17+
18+
for (var line = 0; line < wordSearch.Length; line++)
19+
{
20+
for (var column = 0; column < wordSearch[line].Length; column++)
21+
{
22+
if (wordSearch[line][column] == 'X')
23+
{
24+
occurrences += wordSearch.SearchFrom(line, column);
25+
}
26+
}
27+
}
28+
29+
return occurrences;
30+
}
31+
32+
protected override object SolvePart2(char[][] wordSearch)
33+
{
34+
var occurrences = 0;
35+
36+
for (var line = 0; line < wordSearch.Length; line++)
37+
{
38+
for (var column = 0; column < wordSearch[line].Length; column++)
39+
{
40+
if (wordSearch[line][column] == 'A')
41+
{
42+
occurrences += wordSearch.SearchXFrom(line, column);
43+
}
44+
}
45+
}
46+
47+
return occurrences;
48+
}
49+
50+
51+
}
52+
53+
internal static class Day04Extensions
54+
{
55+
internal static int SearchFrom(this char[][] wordSearch, int line, int column)
56+
{
57+
return wordSearch.SearchUp(line, column)
58+
+ wordSearch.SearchDown(line, column)
59+
+ wordSearch.SearchLeft(line, column)
60+
+ wordSearch.SearchRight(line, column)
61+
+ wordSearch.SearchNE(line, column)
62+
+ wordSearch.SearchNW(line, column)
63+
+ wordSearch.SearchSE(line, column)
64+
+ wordSearch.SearchSW(line, column);
65+
}
66+
67+
internal static int SearchUp(this char[][] wordSearch, int line, int column)
68+
{
69+
if (column - 3 < 0) return 0;
70+
71+
if (wordSearch[line][column - 1] == 'M'
72+
&& wordSearch[line][column - 2] == 'A'
73+
&& wordSearch[line][column - 3] == 'S')
74+
{
75+
return 1;
76+
}
77+
78+
return 0;
79+
}
80+
81+
internal static int SearchDown(this char[][] wordSearch, int line, int column)
82+
{
83+
if (column + 3 >= wordSearch[line].Length) return 0;
84+
85+
if (wordSearch[line][column + 1] == 'M'
86+
&& wordSearch[line][column + 2] == 'A'
87+
&& wordSearch[line][column + 3] == 'S')
88+
{
89+
return 1;
90+
}
91+
92+
return 0;
93+
}
94+
95+
internal static int SearchLeft(this char[][] wordSearch, int line, int column)
96+
{
97+
if (line - 3 < 0) return 0;
98+
99+
if (wordSearch[line - 1][column] == 'M'
100+
&& wordSearch[line - 2][column] == 'A'
101+
&& wordSearch[line - 3][column] == 'S')
102+
{
103+
return 1;
104+
}
105+
106+
return 0;
107+
}
108+
109+
internal static int SearchRight(this char[][] wordSearch, int line, int column)
110+
{
111+
if (line + 3 >= wordSearch.Length) return 0;
112+
113+
if (wordSearch[line + 1][column] == 'M'
114+
&& wordSearch[line + 2][column] == 'A'
115+
&& wordSearch[line + 3][column] == 'S')
116+
{
117+
return 1;
118+
}
119+
120+
return 0;
121+
}
122+
123+
internal static int SearchNE(this char[][] wordSearch, int line, int column)
124+
{
125+
if (line - 3 < 0 || column + 3 >= wordSearch[line].Length) return 0;
126+
127+
if (wordSearch[line - 1][column + 1] == 'M'
128+
&& wordSearch[line - 2][column + 2] == 'A'
129+
&& wordSearch[line - 3][column + 3] == 'S')
130+
{
131+
return 1;
132+
}
133+
134+
return 0;
135+
}
136+
137+
internal static int SearchSE(this char[][] wordSearch, int line, int column)
138+
{
139+
if (line + 3 >= wordSearch.Length || column + 3 >= wordSearch[line].Length) return 0;
140+
141+
if (wordSearch[line + 1][column + 1] == 'M'
142+
&& wordSearch[line + 2][column + 2] == 'A'
143+
&& wordSearch[line + 3][column + 3] == 'S')
144+
{
145+
return 1;
146+
}
147+
148+
return 0;
149+
}
150+
151+
internal static int SearchSW(this char[][] wordSearch, int line, int column)
152+
{
153+
if (line + 3 >= wordSearch.Length || column - 3 < 0) return 0;
154+
155+
if (wordSearch[line + 1][column - 1] == 'M'
156+
&& wordSearch[line + 2][column - 2] == 'A'
157+
&& wordSearch[line + 3][column - 3] == 'S')
158+
{
159+
return 1;
160+
}
161+
162+
return 0;
163+
}
164+
165+
internal static int SearchNW(this char[][] wordSearch, int line, int column)
166+
{
167+
if (line - 3 < 0 || column - 3 < 0) return 0;
168+
169+
if (wordSearch[line - 1][column - 1] == 'M'
170+
&& wordSearch[line - 2][column - 2] == 'A'
171+
&& wordSearch[line - 3][column - 3] == 'S')
172+
{
173+
return 1;
174+
}
175+
176+
return 0;
177+
}
178+
179+
internal static int SearchXFrom(this char[][] wordSearch, int line, int column)
180+
{
181+
if (line - 1 < 0
182+
|| column - 1 < 0
183+
|| line + 1 >= wordSearch.Length
184+
|| column + 1 >= wordSearch[line].Length)
185+
return 0;
186+
187+
return wordSearch.SearchXNE(line, column)
188+
+ wordSearch.SearchXNW(line, column)
189+
+ wordSearch.SearchXSE(line, column)
190+
+ wordSearch.SearchXSW(line, column)
191+
== 2 ? 1 : 0;
192+
}
193+
194+
internal static int SearchXNE(this char[][] wordSearch, int line, int column)
195+
{
196+
if (wordSearch[line + 1][column - 1] == 'M' && wordSearch[line - 1][column + 1] == 'S')
197+
{
198+
return 1;
199+
}
200+
201+
return 0;
202+
}
203+
204+
internal static int SearchXSE(this char[][] wordSearch, int line, int column)
205+
{
206+
if (wordSearch[line - 1][column - 1] == 'M' && wordSearch[line + 1][column + 1] == 'S')
207+
{
208+
return 1;
209+
}
210+
211+
return 0;
212+
}
213+
214+
internal static int SearchXSW(this char[][] wordSearch, int line, int column)
215+
{
216+
if (wordSearch[line - 1][column + 1] == 'M' && wordSearch[line + 1][column - 1] == 'S')
217+
{
218+
return 1;
219+
}
220+
221+
return 0;
222+
}
223+
224+
internal static int SearchXNW(this char[][] wordSearch, int line, int column)
225+
{
226+
if (wordSearch[line + 1][column + 1] == 'M' && wordSearch[line - 1][column - 1] == 'S')
227+
{
228+
return 1;
229+
}
230+
231+
return 0;
232+
}
233+
}

0 commit comments

Comments
 (0)