From fa27aa24055ceb22f1c94e03e08320dcccca743d Mon Sep 17 00:00:00 2001 From: Ivan Reshetnikov Date: Thu, 19 Dec 2024 13:25:09 +0500 Subject: [PATCH] Refactor day 1 of AoC 2023 - The solution is in a separate project. - Separation of logic and file reading. - Removed all the garbage from Gradle. --- advent-of-code/2023/day_01/.gitignore | 43 +++++++++++++ advent-of-code/2023/day_01/README.md | 63 +++++++++++++++++++ advent-of-code/2023/day_01/build.gradle.kts | 18 ++++++ advent-of-code/2023/day_01/gradle.properties | 1 + .../2023/day_01/settings.gradle.kts | 2 + .../2023/day_01/src/main/kotlin/Calibrator.kt | 52 +++++++++++++++ .../2023/day_01/src/main/kotlin/Main.kt | 12 ++++ .../src/main/resources}/input.txt | 2 +- .../day_01/src/test/kotlin/CalibratorTest.kt | 30 +++++++++ .../2023/kotlin/src/main/kotlin/Solution01.kt | 45 ------------- .../src/main/resources/day-01/test-01.txt | 4 -- .../src/main/resources/day-01/test-02.txt | 7 --- .../kotlin/src/test/kotlin/Solution01Test.kt | 32 ---------- 13 files changed, 222 insertions(+), 89 deletions(-) create mode 100644 advent-of-code/2023/day_01/.gitignore create mode 100644 advent-of-code/2023/day_01/README.md create mode 100644 advent-of-code/2023/day_01/build.gradle.kts create mode 100644 advent-of-code/2023/day_01/gradle.properties create mode 100644 advent-of-code/2023/day_01/settings.gradle.kts create mode 100644 advent-of-code/2023/day_01/src/main/kotlin/Calibrator.kt create mode 100644 advent-of-code/2023/day_01/src/main/kotlin/Main.kt rename advent-of-code/2023/{kotlin/src/main/resources/day-01 => day_01/src/main/resources}/input.txt (99%) create mode 100644 advent-of-code/2023/day_01/src/test/kotlin/CalibratorTest.kt delete mode 100644 advent-of-code/2023/kotlin/src/main/kotlin/Solution01.kt delete mode 100644 advent-of-code/2023/kotlin/src/main/resources/day-01/test-01.txt delete mode 100644 advent-of-code/2023/kotlin/src/main/resources/day-01/test-02.txt delete mode 100644 advent-of-code/2023/kotlin/src/test/kotlin/Solution01Test.kt diff --git a/advent-of-code/2023/day_01/.gitignore b/advent-of-code/2023/day_01/.gitignore new file mode 100644 index 0000000..e71d1ef --- /dev/null +++ b/advent-of-code/2023/day_01/.gitignore @@ -0,0 +1,43 @@ +.gradle +gradle +build/ +gradlew* +!**/src/main/**/build/ +!**/src/test/**/build/ + +### IntelliJ IDEA ### +/.idea +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Kotlin ### +.kotlin + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store diff --git a/advent-of-code/2023/day_01/README.md b/advent-of-code/2023/day_01/README.md new file mode 100644 index 0000000..ea41060 --- /dev/null +++ b/advent-of-code/2023/day_01/README.md @@ -0,0 +1,63 @@ +# Advent of Code 2023 day 1 solution in Kotlin + +## Day 1: Trebuchet?! + +[Task page](https://adventofcode.com/2023/day/1) + +Something is wrong with global snow production, and you've been selected to take a look. +The Elves have even given you a map; on it, they've used stars to mark the top fifty locations that are likely +to be having problems. + +You've been doing this long enough to know that to restore snow operations, +you need to check all fifty stars by December 25th. + +Collect stars by solving puzzles. Two puzzles will be made available on each day in the Advent calendar; +the second puzzle is unlocked when you complete the first. Each puzzle grants one star. Good luck! + +You try to ask why they can't just use a weather machine ("not powerful enough") and where they're even sending +you ("the sky") and why your map looks mostly blank ("you sure ask a lot of questions") and hang on did you just say +the sky ("of course, where do you think snow comes from") when you realize that the Elves are already loading you +into a trebuchet ("please hold still, we need to strap you in"). + +As they're making the final adjustments, they discover that their calibration document (your puzzle input) has been +amended by a very young Elf who was apparently just excited to show off her art skills. Consequently, +the Elves are having trouble reading the values on the document. + +The newly-improved calibration document consists of lines of text; each line originally contained a specific +calibration value that the Elves now need to recover. On each line, the calibration value can be found by combining +the first digit and the last digit (in that order) to form a single two-digit number. + +For example: + +``` +1abc2 +pqr3stu8vwx +a1b2c3d4e5f +treb7uchet +``` + +In this example, the calibration values of these four lines are 12, 38, 15, and 77. Adding these together produces 142. + +Consider your entire calibration document. What is the sum of all of the calibration values? + + +## Part Two + +Your calculation isn't quite right. It looks like some of the digits are actually spelled out with letters: +one, two, three, four, five, six, seven, eight, and nine also count as valid "digits". + +Equipped with this new information, you now need to find the real first and last digit on each line. For example: + +``` +two1nine +eightwothree +abcone2threexyz +xtwone3four +4nineeightseven2 +zoneight234 +7pqrstsixteen +``` + +In this example, the calibration values are 29, 83, 13, 24, 42, 14, and 76. Adding these together produces 281. + +What is the sum of all of the calibration values? diff --git a/advent-of-code/2023/day_01/build.gradle.kts b/advent-of-code/2023/day_01/build.gradle.kts new file mode 100644 index 0000000..6397ac9 --- /dev/null +++ b/advent-of-code/2023/day_01/build.gradle.kts @@ -0,0 +1,18 @@ +plugins { + kotlin("jvm") version "2.0.21" +} + +group = "space.comfycamp" +version = "1.0" + +repositories { + mavenCentral() +} + +dependencies { + testImplementation(kotlin("test")) +} + +tasks.test { + useJUnitPlatform() +} diff --git a/advent-of-code/2023/day_01/gradle.properties b/advent-of-code/2023/day_01/gradle.properties new file mode 100644 index 0000000..7fc6f1f --- /dev/null +++ b/advent-of-code/2023/day_01/gradle.properties @@ -0,0 +1 @@ +kotlin.code.style=official diff --git a/advent-of-code/2023/day_01/settings.gradle.kts b/advent-of-code/2023/day_01/settings.gradle.kts new file mode 100644 index 0000000..bce7d78 --- /dev/null +++ b/advent-of-code/2023/day_01/settings.gradle.kts @@ -0,0 +1,2 @@ +rootProject.name = "day_01" + diff --git a/advent-of-code/2023/day_01/src/main/kotlin/Calibrator.kt b/advent-of-code/2023/day_01/src/main/kotlin/Calibrator.kt new file mode 100644 index 0000000..12dc9b2 --- /dev/null +++ b/advent-of-code/2023/day_01/src/main/kotlin/Calibrator.kt @@ -0,0 +1,52 @@ +package space.comfycamp + +import kotlin.text.iterator + +val words = listOf("one", "two", "three", "four", "five", "six", "seven", "eight", "nine") + +fun getCalibrationValues(lines: List, replaceWords: Boolean): Int { + val processedLines = lines + .takeIf{ replaceWords } + ?.map{ s -> replaceWords(s) } + ?: lines + + return processedLines + .map { s -> extractFirstAndLastDigits(s) } + .sumOf { pair -> pair.first * 10 + pair.second } +} + +private fun extractFirstAndLastDigits(s: String): Pair { + var firstDigit = '0' + var lastDigit = '0' + + for (char in s) { + if (!char.isDigit()) { + continue + } + + lastDigit = char + if (firstDigit == '0') { + firstDigit = char + } + } + + return Pair(firstDigit.digitToInt(), lastDigit.digitToInt()) +} + +private fun replaceWords(line: String): String { + var s = line + var i = 0 + while (i < s.length) { + val subStr = s.slice(i.., findWords: Boolean): Int { - var sum = 0 - - lines.forEach { - var firstDigit = "" - var lastDigit = "" - - var s = it - // Required for the second part - if (findWords) { - s = replaceStrWithDigits(s) - } - - for (char in s) { - if (char.isDigit()) { - lastDigit = char.toString() - if (firstDigit == "") { - firstDigit = char.toString() - } - } - } - - sum += (firstDigit + lastDigit).toInt() - } - - return sum - } - - private fun replaceStrWithDigits(line: String): String { - var s = line - val words = arrayOf("one", "two", "three", "four", "five", "six", "seven", "eight", "nine") - var i = 0 - while (i < s.length) { - for (w in words.indices) { - if (s.slice(i..