Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# aoc2022
# Advent of Code

https://adventofcode.com/2022
This repository contains various Advent of Code solutions. Kotlin support is now available for the 2024 edition.

Useful links:

* [Advent of Code 2022](https://adventofcode.com/2022)
* [Advent of Code 2024](https://adventofcode.com/2024)
11 changes: 8 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@
</goals>
<configuration>
<sourceDirs>
<source>src/main/java</source>
<source>target/generated-sources/annotations</source>
<source>src/main/java</source>
<source>src/main/kotlin</source>
<source>target/generated-sources/annotations</source>
</sourceDirs>
</configuration>
</execution>
Expand All @@ -37,7 +38,11 @@
</execution>
</executions>
<configuration>
<jvmTarget>1.8</jvmTarget>
<jvmTarget>21</jvmTarget>
<testSourceDirs>
<testSourceDir>src/test/kotlin</testSourceDir>
<testSourceDir>src/test/java</testSourceDir>
</testSourceDirs>
</configuration>
</plugin>
<plugin>
Expand Down
55 changes: 55 additions & 0 deletions src/main/kotlin/fr/lmo/aoc2024/AoCHelper.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package fr.lmo.aoc2024

import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths

/**
* Utility helper inspired by previous years to ease solving Advent of Code 2024 puzzles.
*/
abstract class AoCHelper {
abstract fun run()

private fun directoryName(): String = this::class.java.simpleName.lowercase()

private fun fileName(name: String): String {
var fileName = name
if (System.getProperty("test", "false").toBoolean()) {
fileName += "-test"
}
return "$fileName.txt"
}

private fun path(name: String): Path =
Paths.get("src", "main", "resources", "2024", directoryName(), fileName(name))

Comment on lines +22 to +25
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider using classpath resources for better JAR compatibility.

The current path construction uses filesystem paths which may not work when the application is packaged in a JAR file. Consider using classpath resources instead.

-private fun path(name: String): Path =
-    Paths.get("src", "main", "resources", "2024", directoryName(), fileName(name))
+private fun path(name: String): Path {
+    val resourcePath = "/2024/${directoryName()}/${fileName(name)}"
+    return this::class.java.getResource(resourcePath)?.toURI()?.let { Paths.get(it) }
+        ?: throw IllegalStateException("Resource not found: $resourcePath")
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
private fun path(name: String): Path =
Paths.get("src", "main", "resources", "2024", directoryName(), fileName(name))
private fun path(name: String): Path {
val resourcePath = "/2024/${directoryName()}/${fileName(name)}"
return this::class.java
.getResource(resourcePath)
?.toURI()
?.let { Paths.get(it) }
?: throw IllegalStateException("Resource not found: $resourcePath")
}
🤖 Prompt for AI Agents
In src/main/kotlin/fr/lmo/aoc2024/AoCHelper.kt around lines 22 to 25, the method
constructs file system paths directly, which can fail when running from a JAR.
Refactor the path function to load resources using the class loader's
getResource or getResourceAsStream methods to access files from the classpath,
ensuring compatibility when packaged as a JAR.

fun getTestInputPath(): Path = path("input-test")

fun getInputPath(): Path = path("input")
Comment on lines +26 to +28
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Critical bug: getTestInputPath() will return incorrect filename when test property is set.

The getTestInputPath() method calls path("input-test"), but the fileName() method will append "-test" again if the system property "test" is true, resulting in "input-test-test.txt" instead of "input-test.txt".

-fun getTestInputPath(): Path = path("input-test")
+fun getTestInputPath(): Path = 
+    Paths.get("src", "main", "resources", "2024", directoryName(), "input-test.txt")

Or create a separate method that bypasses the system property logic:

+private fun pathWithoutTestSuffix(name: String): Path =
+    Paths.get("src", "main", "resources", "2024", directoryName(), "$name.txt")
+
-fun getTestInputPath(): Path = path("input-test")
+fun getTestInputPath(): Path = pathWithoutTestSuffix("input-test")

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/main/kotlin/fr/lmo/aoc2024/AoCHelper.kt around lines 26 to 28, the
getTestInputPath() method calls path("input-test"), but since path() appends
"-test" when the "test" system property is true, this results in
"input-test-test.txt" instead of "input-test.txt". To fix this, create a
separate method that returns the path for "input-test" without applying the
"-test" suffix logic, bypassing the system property check, or adjust
getTestInputPath() to directly return the correct filename without double
appending "-test".


fun readFile(path: Path): String = Files.readString(path)

fun lines(path: Path): List<String> = Files.readAllLines(path)

fun <T> list(path: Path, mapper: (String) -> T): List<T> =
Files.lines(path).use { it.map(mapper).toList() }

companion object {
@JvmStatic
fun main(args: Array<String>) {
if (args.isEmpty()) {
println("Arg should contain classname")
return
}
val className = args[0]
try {
val clazz = Class.forName("${AoCHelper::class.java.packageName}.$className")
.asSubclass(AoCHelper::class.java)
val instance = clazz.getDeclaredConstructor().newInstance()
instance.run()
} catch (e: Exception) {
e.printStackTrace()
}
}
}
}
12 changes: 12 additions & 0 deletions src/main/kotlin/fr/lmo/aoc2024/D01.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package fr.lmo.aoc2024

class D01 : AoCHelper() {
override fun run() {
println("Test: " + readFile(getTestInputPath()))
// println("Real: " + readFile(getInputPath()))
}
}

fun main(args: Array<String>) {
AoCHelper.main(args)
}
1 change: 1 addition & 0 deletions src/main/resources/2024/d01/input-test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
TODO
1 change: 1 addition & 0 deletions src/main/resources/2024/d01/input.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
TODO