Skip to content

Commit 7d2a840

Browse files
committed
feat: solve day 4
1 parent 5e9a987 commit 7d2a840

File tree

5 files changed

+307
-12
lines changed

5 files changed

+307
-12
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
- [Day 1 - Historian Hysteria](https://github.com/Flashky/advent-of-code-2024/tree/master/src/main/java/com/adventofcode/flashk/day01)
77
- [Day 2 - Red-Nosed Reports](https://github.com/Flashky/advent-of-code-2024/tree/master/src/main/java/com/adventofcode/flashk/day02)
88
- [Day 3 - Mull It Over](https://github.com/Flashky/advent-of-code-2024/tree/master/src/main/java/com/adventofcode/flashk/day03)
9-
- [Day 4](https://github.com/Flashky/advent-of-code-2024/tree/master/src/main/java/com/adventofcode/flashk/day04)
9+
- [Day 4 - Ceres Search](https://github.com/Flashky/advent-of-code-2024/tree/master/src/main/java/com/adventofcode/flashk/day04)
1010
- [Day 5](https://github.com/Flashky/advent-of-code-2024/tree/master/src/main/java/com/adventofcode/flashk/day05)
1111
- [Day 6](https://github.com/Flashky/advent-of-code-2024/tree/master/src/main/java/com/adventofcode/flashk/day06)
1212
- [Day 7](https://github.com/Flashky/advent-of-code-2024/tree/master/src/main/java/com/adventofcode/flashk/day07)
Lines changed: 284 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,284 @@
1+
package com.adventofcode.flashk.day04;
2+
3+
import com.adventofcode.flashk.common.Vector2;
4+
import org.apache.commons.lang3.StringUtils;
5+
6+
import java.util.ArrayList;
7+
import java.util.List;
8+
9+
public class CeresSearch {
10+
11+
private final char[][] input;
12+
private final int rows;
13+
private final int cols;
14+
private final List<Vector2> xPositions = new ArrayList<>();
15+
private final List<Vector2> aPositions = new ArrayList<>();
16+
17+
public CeresSearch(char[][] input){
18+
this.input = input;
19+
this.rows = input.length;
20+
this.cols = input[0].length;
21+
22+
for(int row = 0; row < rows; row++) {
23+
for(int col = 0; col < cols; col++) {
24+
if(input[row][col] == 'X') {
25+
xPositions.add(new Vector2(col,row));
26+
} else if(input[row][col] == 'A') {
27+
aPositions.add(new Vector2(col,row));
28+
}
29+
}
30+
}
31+
}
32+
33+
public long solveA() {
34+
long wordCount = 0;
35+
36+
wordCount += countHorizontal();
37+
wordCount += countVertical();
38+
wordCount += countDiagonal();
39+
40+
return wordCount;
41+
}
42+
43+
public long solveB() {
44+
long wordCount = 0;
45+
46+
for(Vector2 aPosition : aPositions) {
47+
if(countXShapeDiagonal1(aPosition.getY(), aPosition.getX()) && countXShapeDiagonal2(aPosition.getY(), aPosition.getX())) {
48+
wordCount++;
49+
}
50+
51+
}
52+
53+
return wordCount;
54+
}
55+
56+
57+
private boolean countXShapeDiagonal1(int row, int col){
58+
59+
int upLeftRow = row-1;
60+
int upLeftCol = col-1;
61+
62+
if(isOutOfRange(upLeftRow, upLeftCol)) {
63+
return false;
64+
}
65+
66+
int downRightRow = row+1;
67+
int downRightCol = col+1;
68+
69+
if(isOutOfRange(downRightRow, downRightCol)) {
70+
return false;
71+
}
72+
73+
if(input[upLeftRow][upLeftCol] == 'M' && input[downRightRow][downRightCol] == 'S'){
74+
return true;
75+
}
76+
77+
if(input[upLeftRow][upLeftCol] == 'S' && input[downRightRow][downRightCol] == 'M'){
78+
return true;
79+
}
80+
81+
return false;
82+
}
83+
84+
private boolean countXShapeDiagonal2(int row, int col){
85+
86+
int upRightRow = row-1;
87+
int upRightCol = col+1;
88+
89+
if(isOutOfRange(upRightRow, upRightCol)) {
90+
return false;
91+
}
92+
93+
int downLeftRow = row+1;
94+
int downLeftCol = col-1;
95+
96+
if(isOutOfRange(downLeftRow, downLeftCol)) {
97+
return false;
98+
}
99+
100+
if(input[upRightRow][upRightCol] == 'M' && input[downLeftRow][downLeftCol] == 'S'){
101+
return true;
102+
}
103+
104+
if(input[upRightRow][upRightCol] == 'S' && input[downLeftRow][downLeftCol] == 'M'){
105+
return true;
106+
}
107+
108+
return false;
109+
}
110+
111+
private int countHorizontal() {
112+
int totalCount = 0;
113+
for(int row = 0; row < rows; row++) {
114+
String line = new String(input[row]);
115+
totalCount += StringUtils.countMatches(line, "XMAS") + StringUtils.countMatches(line, "SAMX");
116+
}
117+
return totalCount;
118+
}
119+
120+
private int countVertical() {
121+
122+
char[][] transposedInput = transpose();
123+
int totalCount = 0;
124+
for(int row = 0; row < rows; row++) {
125+
String line = new String(transposedInput[row]);
126+
totalCount += StringUtils.countMatches(line, "XMAS") + StringUtils.countMatches(line, "SAMX");
127+
}
128+
return totalCount;
129+
}
130+
131+
private long countDiagonal() {
132+
int totalCount = 0;
133+
for(Vector2 xPosition : xPositions) {
134+
// Recorrer hacia cada una de las 4 esquinas buscando "MAS"
135+
totalCount += upLeftDiagonal(xPosition.getY(), xPosition.getX());
136+
totalCount += upRightDiagonal(xPosition.getY(), xPosition.getX());
137+
totalCount += downLeftDiagonal(xPosition.getY(), xPosition.getX());
138+
totalCount += downRightDiagonal(xPosition.getY(), xPosition.getX());
139+
}
140+
141+
return totalCount;
142+
}
143+
144+
145+
private int upLeftDiagonal(int row, int col) {
146+
147+
int nextPosRow = row-1;
148+
int nextPosCol = col-1;
149+
150+
if(isOutOfRange(nextPosRow, nextPosCol)) {
151+
return 0;
152+
}
153+
154+
if(input[nextPosRow][nextPosCol] != 'M') {
155+
return 0;
156+
}
157+
158+
if(isOutOfRange(--nextPosRow, --nextPosCol)) {
159+
return 0;
160+
}
161+
162+
if(input[nextPosRow][nextPosCol] != 'A') {
163+
return 0;
164+
}
165+
166+
if(isOutOfRange(--nextPosRow, --nextPosCol)) {
167+
return 0;
168+
}
169+
170+
if(input[nextPosRow][nextPosCol] != 'S') {
171+
return 0;
172+
}
173+
174+
return 1;
175+
}
176+
177+
private int upRightDiagonal(int row, int col) {
178+
179+
int nextPosRow = row-1;
180+
int nextPosCol = col+1;
181+
182+
if(isOutOfRange(nextPosRow, nextPosCol)) {
183+
return 0;
184+
}
185+
186+
if(input[nextPosRow][nextPosCol] != 'M') {
187+
return 0;
188+
}
189+
190+
if(isOutOfRange(--nextPosRow, ++nextPosCol)) {
191+
return 0;
192+
}
193+
194+
if(input[nextPosRow][nextPosCol] != 'A') {
195+
return 0;
196+
}
197+
198+
if(isOutOfRange(--nextPosRow, ++nextPosCol)) {
199+
return 0;
200+
}
201+
202+
if(input[nextPosRow][nextPosCol] != 'S') {
203+
return 0;
204+
}
205+
206+
return 1;
207+
}
208+
209+
private int downLeftDiagonal(int row, int col) {
210+
int nextPosRow = row+1;
211+
int nextPosCol = col-1;
212+
213+
if(isOutOfRange(nextPosRow, nextPosCol)) {
214+
return 0;
215+
}
216+
217+
if(input[nextPosRow][nextPosCol] != 'M') {
218+
return 0;
219+
}
220+
221+
if(isOutOfRange(++nextPosRow, --nextPosCol)) {
222+
return 0;
223+
}
224+
225+
if(input[nextPosRow][nextPosCol] != 'A') {
226+
return 0;
227+
}
228+
229+
if(isOutOfRange(++nextPosRow, --nextPosCol)) {
230+
return 0;
231+
}
232+
233+
if(input[nextPosRow][nextPosCol] != 'S') {
234+
return 0;
235+
}
236+
237+
return 1;
238+
}
239+
240+
private int downRightDiagonal(int row, int col) {
241+
int nextPosRow = row+1;
242+
int nextPosCol = col+1;
243+
244+
if(isOutOfRange(nextPosRow, nextPosCol)) {
245+
return 0;
246+
}
247+
248+
if(input[nextPosRow][nextPosCol] != 'M') {
249+
return 0;
250+
}
251+
252+
if(isOutOfRange(++nextPosRow, ++nextPosCol)) {
253+
return 0;
254+
}
255+
256+
if(input[nextPosRow][nextPosCol] != 'A') {
257+
return 0;
258+
}
259+
260+
if(isOutOfRange(++nextPosRow, ++nextPosCol)) {
261+
return 0;
262+
}
263+
264+
if(input[nextPosRow][nextPosCol] != 'S') {
265+
return 0;
266+
}
267+
268+
return 1;
269+
}
270+
271+
private boolean isOutOfRange(int row, int col) {
272+
return row < 0 || row >= rows || col < 0 || col >= cols;
273+
}
274+
275+
private char[][] transpose() {
276+
char[][] transposedInput = new char[cols][rows];
277+
for(int row = 0; row < rows; row++) {
278+
for(int col = 0; col < cols; col++) {
279+
transposedInput[col][row] = input[row][col];
280+
}
281+
}
282+
return transposedInput;
283+
}
284+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
# Day 4:
1+
# Day 4: Ceres Search
22

33
[https://adventofcode.com/2024/day/4](https://adventofcode.com/2024/day/4)

src/test/java/com/adventofcode/flashk/day04/Day04Test.java

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@
1919
import com.adventofcode.flashk.common.test.utils.Timer;
2020
import com.adventofcode.flashk.common.test.utils.Input;
2121

22+
import static org.junit.jupiter.api.Assertions.assertEquals;
23+
2224
@DisplayName(TestDisplayName.DAY_04)
2325
@TestMethodOrder(OrderAnnotation.class)
24-
@Disabled // TODO Remove comment when implemented
2526
public class Day04Test extends PuzzleTest {
2627

2728
private final static String INPUT_FOLDER = TestFolder.DAY_04;
@@ -42,8 +43,10 @@ public void testSolvePart1Sample() {
4243
System.out.print("1 | sample | ");
4344

4445
// Read input file
45-
List<String> inputs = Input.readStringLines(INPUT_FOLDER, TestFilename.INPUT_FILE_SAMPLE);
46-
46+
char[][] inputs = Input.read2DCharArray(INPUT_FOLDER, TestFilename.INPUT_FILE_SAMPLE);
47+
CeresSearch ceresSearch = new CeresSearch(inputs);
48+
49+
assertEquals(18, ceresSearch.solveA());
4750
}
4851

4952
@Test
@@ -56,8 +59,11 @@ public void testSolvePart1Input() {
5659
System.out.print("1 | input | ");
5760

5861
// Read input file
59-
List<String> inputs = Input.readStringLines(INPUT_FOLDER, TestFilename.INPUT_FILE);
60-
62+
char[][] inputs = Input.read2DCharArray(INPUT_FOLDER, TestFilename.INPUT_FILE);
63+
CeresSearch ceresSearch = new CeresSearch(inputs);
64+
65+
assertEquals(2344, ceresSearch.solveA());
66+
6167
}
6268

6369
@Test
@@ -70,8 +76,10 @@ public void testSolvePart2Sample() {
7076
System.out.print("2 | sample | ");
7177

7278
// Read input file
73-
List<String> inputs = Input.readStringLines(INPUT_FOLDER, TestFilename.INPUT_FILE_SAMPLE);
74-
79+
char[][] inputs = Input.read2DCharArray(INPUT_FOLDER, TestFilename.INPUT_FILE_SAMPLE);
80+
CeresSearch ceresSearch = new CeresSearch(inputs);
81+
82+
assertEquals(9, ceresSearch.solveB());
7583
}
7684

7785
@Test
@@ -84,8 +92,11 @@ public void testSolvePart2Input() {
8492
System.out.print("2 | input | ");
8593

8694
// Read input file
87-
List<String> inputs = Input.readStringLines(INPUT_FOLDER, TestFilename.INPUT_FILE);
88-
95+
char[][] inputs = Input.read2DCharArray(INPUT_FOLDER, TestFilename.INPUT_FILE);
96+
CeresSearch ceresSearch = new CeresSearch(inputs);
97+
98+
assertEquals(1815, ceresSearch.solveB());
99+
89100
}
90101

91102
}

src/test/resources/inputs

0 commit comments

Comments
 (0)