Skip to content

Commit 749275d

Browse files
committed
Day 01 2025
1 parent cd6436c commit 749275d

File tree

4 files changed

+144
-0
lines changed

4 files changed

+144
-0
lines changed
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package me.peckb.aoc._2025.calendar.day01
2+
3+
import me.peckb.aoc._2025.calendar.day01.Day01.Direction.LEFT
4+
import me.peckb.aoc._2025.calendar.day01.Day01.Direction.RIGHT
5+
import javax.inject.Inject
6+
import me.peckb.aoc.generators.InputGenerator.InputGeneratorFactory
7+
import kotlin.sequences.forEach
8+
9+
class Day01 @Inject constructor(private val generatorFactory: InputGeneratorFactory) {
10+
companion object {
11+
const val DIAL_NUMBERS = 100
12+
const val START_LOCATION = 50
13+
}
14+
15+
fun partOne(filename: String) = generatorFactory.forFile(filename).readAs(::rotation) { rotations ->
16+
var dialLocation = START_LOCATION
17+
var countAtZeroAfterMovement = 0
18+
19+
rotations.forEach { rotation ->
20+
when (rotation.direction) {
21+
LEFT -> dialLocation -= rotation.count
22+
RIGHT -> dialLocation += rotation.count
23+
}
24+
25+
while (dialLocation !in 0 until DIAL_NUMBERS) {
26+
if (dialLocation < 0) {
27+
dialLocation += DIAL_NUMBERS
28+
} else { // if (dialLocation >= DIAL_NUMBERS)
29+
dialLocation -= DIAL_NUMBERS
30+
}
31+
}
32+
33+
if (dialLocation == 0) { countAtZeroAfterMovement++ }
34+
}
35+
36+
countAtZeroAfterMovement
37+
}
38+
39+
fun partTwo(filename: String) = generatorFactory.forFile(filename).readAs(::rotation) { rotations ->
40+
var dialLocation = START_LOCATION
41+
var countAtZeroAfterMovement = 0
42+
43+
rotations.forEach { rotation ->
44+
val fullLoops = rotation.count / DIAL_NUMBERS
45+
val remainingTurns = rotation.count % DIAL_NUMBERS
46+
47+
// always increment a full loop
48+
countAtZeroAfterMovement += fullLoops
49+
50+
val dialLocationBeforeChanging = dialLocation
51+
if (remainingTurns != 0) {
52+
when (rotation.direction) {
53+
RIGHT -> {
54+
dialLocation += remainingTurns
55+
// if we pass over 99, increment again
56+
if (dialLocation >= DIAL_NUMBERS) {
57+
dialLocation -= DIAL_NUMBERS
58+
countAtZeroAfterMovement++
59+
}
60+
}
61+
LEFT -> {
62+
dialLocation -= remainingTurns
63+
// if we go under 0 ... maybe increment
64+
if (dialLocation <= 0) {
65+
// going under zero but starting at zero shouldn't double count
66+
if (dialLocationBeforeChanging != 0) { countAtZeroAfterMovement++ }
67+
// but either way we're under zero and need to fix our dial
68+
if (dialLocation < 0) { dialLocation += DIAL_NUMBERS }
69+
}
70+
}
71+
}
72+
}
73+
}
74+
75+
countAtZeroAfterMovement
76+
}
77+
78+
private fun rotation(line: String) : Rotation {
79+
val direction = when(val dc = line[0]) {
80+
'L' -> LEFT
81+
'R' -> RIGHT
82+
else -> throw IllegalStateException("Unknown direction $dc")
83+
}
84+
val count = line.drop(1).toInt()
85+
86+
return Rotation(direction, count)
87+
}
88+
89+
enum class Direction(val d: String) {
90+
LEFT("L"), RIGHT("R");
91+
92+
override fun toString(): String = d
93+
}
94+
95+
data class Rotation(val direction: Direction, val count: Int) {
96+
override fun toString(): String = "$direction$count"
97+
}
98+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
## [Day 1: Secret Entrance](https://adventofcode.com/2025/day/1)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package me.peckb.aoc._2025
2+
3+
import dagger.Component
4+
import javax.inject.Singleton
5+
import me.peckb.aoc.DayComponent
6+
import me.peckb.aoc.InputModule
7+
import me.peckb.aoc._2025.calendar.day01.Day01Test
8+
9+
@Singleton
10+
@Component(modules = [InputModule::class])
11+
internal interface TestDayComponent : DayComponent {
12+
fun inject(day01Test: Day01Test)
13+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package me.peckb.aoc._2025.calendar.day01
2+
3+
import javax.inject.Inject
4+
5+
import me.peckb.aoc._2025.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 Day01Test {
11+
@Inject
12+
lateinit var day01: Day01
13+
14+
@BeforeEach
15+
fun setup() {
16+
DaggerTestDayComponent.create().inject(this)
17+
}
18+
19+
@Test
20+
fun testDay01PartOne() {
21+
assertEquals(962, day01.partOne(DAY_01))
22+
}
23+
24+
@Test
25+
fun testDay01PartTwo() {
26+
assertEquals(5782, day01.partTwo(DAY_01))
27+
}
28+
29+
companion object {
30+
private const val DAY_01: String = "advent-of-code-input/2025/day01.input"
31+
}
32+
}

0 commit comments

Comments
 (0)