Skip to content

Commit b68d37d

Browse files
authored
Day 04 2024 (#262)
1 parent e944cbc commit b68d37d

File tree

4 files changed

+98
-0
lines changed

4 files changed

+98
-0
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package me.peckb.aoc._2024.calendar.day04
2+
3+
import javax.inject.Inject
4+
import me.peckb.aoc.generators.InputGenerator.InputGeneratorFactory
5+
6+
class Day04 @Inject constructor(
7+
private val generatorFactory: InputGeneratorFactory,
8+
) {
9+
fun partOne(filename: String) = generatorFactory.forFile(filename).read { lines ->
10+
val (xLocations, area) = setup(lines, 'X')
11+
12+
xLocations.sumOf { (x, y) ->
13+
val N = area.findXMAS(y, -1, x, 0)
14+
val NE = area.findXMAS(y, -1, x, 1)
15+
val E = area.findXMAS(y, 0, x, 1)
16+
val SE = area.findXMAS(y, 1, x, 1)
17+
val S = area.findXMAS(y, 1, x, 0)
18+
val SW = area.findXMAS(y, 1, x, -1)
19+
val W = area.findXMAS(y, 0, x, -1)
20+
val NW = area.findXMAS(y, -1, x, -1)
21+
22+
listOf(N, NE, E, SE, S, SW, W, NW).count { it == "XMAS" }
23+
}
24+
}
25+
26+
fun partTwo(filename: String) = generatorFactory.forFile(filename).read { lines ->
27+
val (aLocations, area) = setup(lines, 'A')
28+
29+
aLocations.count { (x, y) ->
30+
val NE = area.getValue(y - 1, x + 1)
31+
val SE = area.getValue(y + 1, x + 1)
32+
val SW = area.getValue(y + 1, x - 1)
33+
val NW = area.getValue(y - 1, x - 1)
34+
35+
if (NW == NE && SE == SW) { (NW == 'M' && SW == 'S') || (NW == 'S' && SW == 'M') }
36+
else if (NW == SW && NE == SE) { (NW == 'M' && NE == 'S') || (NW == 'S' && NE == 'M') }
37+
else false
38+
}
39+
}
40+
41+
private fun setup(lines: Sequence<String>, target: Char): Pair<List<Location>, List<List<Char>>> {
42+
val locations = mutableListOf<Location>()
43+
val area = lines.toList().mapIndexed { yIndex, line ->
44+
line.mapIndexed { xIndex, letter ->
45+
letter.also { if (it == target) { locations.add(Location(xIndex, yIndex)) } }
46+
}
47+
}
48+
49+
return locations to area
50+
}
51+
}
52+
53+
data class Location(val x: Int, val y: Int)
54+
55+
private fun List<List<Char>>.findXMAS(y: Int, yDelta: Int, x: Int, xDelta: Int): String {
56+
return (0..3)
57+
.mapNotNull { delta -> this.getValue(y + (yDelta * delta), x + (xDelta * delta)) }
58+
.joinToString("")
59+
}
60+
61+
private fun List<List<Char>>.getValue(y: Int, x: Int): Char? {
62+
return if (y in indices && x in this[y].indices) { this[y][x] } else { null }
63+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
## [Day 4: Ceres Search](https://adventofcode.com/2024/day/4)

src/test/kotlin/me/peckb/aoc/_2024/TestDayComponent.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package me.peckb.aoc._2024
33
import dagger.Component
44
import me.peckb.aoc._2024.calendar.day02.Day02Test
55
import me.peckb.aoc._2024.calendar.day03.Day03Test
6+
import me.peckb.aoc._2024.calendar.day04.Day04Test
67
import javax.inject.Singleton
78
import me.peckb.aoc.DayComponent
89
import me.peckb.aoc.InputModule
@@ -14,4 +15,5 @@ internal interface TestDayComponent : DayComponent {
1415
fun inject(day01Test: Day01Test)
1516
fun inject(day02Test: Day02Test)
1617
fun inject(day03Test: Day03Test)
18+
fun inject(day04Test: Day04Test)
1719
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package me.peckb.aoc._2024.calendar.day04
2+
3+
import javax.inject.Inject
4+
5+
import me.peckb.aoc._2024.DaggerTestDayComponent
6+
import org.junit.jupiter.api.Assertions.assertEquals
7+
import org.junit.jupiter.api.BeforeEach
8+
import org.junit.jupiter.api.Test
9+
10+
internal class Day04Test {
11+
@Inject
12+
lateinit var day04: Day04
13+
14+
@BeforeEach
15+
fun setup() {
16+
DaggerTestDayComponent.create().inject(this)
17+
}
18+
19+
@Test
20+
fun testDay04PartOne() {
21+
assertEquals(2639, day04.partOne(DAY_04))
22+
}
23+
24+
@Test
25+
fun testDay04PartTwo() {
26+
assertEquals(2005, day04.partTwo(DAY_04))
27+
}
28+
29+
companion object {
30+
private const val DAY_04: String = "advent-of-code-input/2024/day04.input"
31+
}
32+
}

0 commit comments

Comments
 (0)