Skip to content

Commit 6cc9ad5

Browse files
committed
Factor out an abstract class providing a scaffolding for all AoC days
1 parent 4adee7e commit 6cc9ad5

File tree

5 files changed

+74
-16
lines changed

5 files changed

+74
-16
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@
44
build
55
src/input/**/*.txt
66
!src/input/2024/ForTests.txt
7+
!src/input/2024/Day99.txt
78
local.properties
89
/.kotlintest/

src/input/2024/Day99.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
This file is just for testing
2+
line two
3+
line three
4+
5+
line five
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package de.ronny_h.aoc
2+
3+
import kotlin.io.path.Path
4+
import kotlin.io.path.readText
5+
import kotlin.time.TimedValue
6+
import kotlin.time.measureTimedValue
7+
8+
abstract class AdventOfCode<T>(val year: Int, val day: Int) {
9+
abstract fun part1(input: List<String>): T
10+
abstract fun part2(input: List<String>): T
11+
12+
private val input = readInput()
13+
14+
fun run(expectedPart1: T, expectedPart2: T) {
15+
println("Day $day $year, part 1")
16+
printAndCheck(::part1, expectedPart1)
17+
println("Day $day $year, part 2")
18+
printAndCheck(::part2, expectedPart2)
19+
}
20+
21+
private fun readInput() = Path("src/input/$year/Day${paddedDay()}.txt").readText().trim().lines()
22+
23+
private fun paddedDay(): String = day.toString().padStart(2, '0')
24+
25+
private fun printAndCheck(block: (List<String>) -> T, expected: T) {
26+
printAndCheck(measureTimedValue { block(input) }, expected)
27+
}
28+
29+
private fun printAndCheck(result: TimedValue<T>, expected: T) {
30+
println("result: ${result.value}, expected: $expected, took: ${result.duration}")
31+
check(result.value == expected)
32+
}
33+
}

src/main/kotlin/de/ronny_h/aoc/year24/day01/HistorianHysteria.kt

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,12 @@
11
package de.ronny_h.aoc.year24.day01
22

3-
import de.ronny_h.aoc.extensions.printAndCheck
4-
import de.ronny_h.aoc.extensions.readInput
3+
import de.ronny_h.aoc.AdventOfCode
54
import kotlin.math.abs
65

7-
fun main() {
8-
val day = "Day01"
9-
val input = readInput(day)
10-
val historianHysteria = HistorianHysteria()
6+
fun main() = HistorianHysteria().run(3714264, 18805872)
117

12-
println("$day part 1")
13-
printAndCheck(input, historianHysteria::part1, 3714264)
14-
15-
println("$day part 2")
16-
printAndCheck(input, historianHysteria::part2, 18805872)
17-
}
18-
19-
class HistorianHysteria {
20-
fun part1(input: List<String>): Int {
8+
class HistorianHysteria() : AdventOfCode<Int>(2024, 1) {
9+
override fun part1(input: List<String>): Int {
2110
val teamOne = input
2211
.filter { it.isNotBlank() }
2312
.map { it.split(" ").first().toInt() }
@@ -30,7 +19,7 @@ class HistorianHysteria {
3019
return distances.sum()
3120
}
3221

33-
fun part2(input: List<String>): Int {
22+
override fun part2(input: List<String>): Int {
3423
val (teamOne, teamTwo) = input
3524
.filter { it.isNotBlank() }
3625
.map {
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package de.ronny_h.aoc
2+
3+
import io.kotest.core.spec.style.StringSpec
4+
import io.kotest.assertions.throwables.shouldThrow
5+
import io.kotest.matchers.shouldBe
6+
7+
class AdventOfCodeTest : StringSpec({
8+
val adventOfCode = object : AdventOfCode<Int>(2024, 99) {
9+
override fun part1(input: List<String>) = input.size
10+
override fun part2(input: List<String>) = input.size
11+
}
12+
13+
"The day's file can be read and has the right number of lines" {
14+
adventOfCode.run(5, 5)
15+
}
16+
17+
"Failure of part one is detected" {
18+
val exception = shouldThrow<IllegalStateException> {
19+
adventOfCode.run(4, 5)
20+
}
21+
exception.message shouldBe "Check failed."
22+
}
23+
24+
"Failure of part two is detected" {
25+
val exception = shouldThrow<IllegalStateException> {
26+
adventOfCode.run(5, 4)
27+
}
28+
exception.message shouldBe "Check failed."
29+
}
30+
})

0 commit comments

Comments
 (0)