diff --git a/advent-of-code-2023/aoc-01/.gitignore b/advent-of-code-2023/.gitignore similarity index 84% rename from advent-of-code-2023/aoc-01/.gitignore rename to advent-of-code-2023/.gitignore index 4eb2cb8..79ef6cc 100644 --- a/advent-of-code-2023/aoc-01/.gitignore +++ b/advent-of-code-2023/.gitignore @@ -1,4 +1,3 @@ -.idea .gradle build/ !gradle/wrapper/gradle-wrapper.jar @@ -6,10 +5,7 @@ build/ !**/src/test/**/build/ ### IntelliJ IDEA ### -.idea/modules.xml -.idea/jarRepositories.xml -.idea/compiler.xml -.idea/libraries/ +/.idea *.iws *.iml *.ipr diff --git a/advent-of-code-2023/aoc-01/settings.gradle.kts b/advent-of-code-2023/aoc-01/settings.gradle.kts deleted file mode 100644 index a28a807..0000000 --- a/advent-of-code-2023/aoc-01/settings.gradle.kts +++ /dev/null @@ -1,12 +0,0 @@ -pluginManagement { - repositories { - mavenCentral() - gradlePluginPortal() - } -} - -plugins { - id("org.gradle.toolchains.foojay-resolver-convention") version "0.5.0" -} - -rootProject.name = "aoc-01" \ No newline at end of file diff --git a/advent-of-code-2023/aoc-01/src/main/kotlin/Main.kt b/advent-of-code-2023/aoc-01/src/main/kotlin/Main.kt deleted file mode 100644 index eae0973..0000000 --- a/advent-of-code-2023/aoc-01/src/main/kotlin/Main.kt +++ /dev/null @@ -1,56 +0,0 @@ -import java.io.File - -fun main(args: Array) { - if (args.isEmpty()) { - println("Missing input file path") - return - } - - val lines = File(args[0]).readLines() - - println(getCalibrationValues(lines, false)) - println(getCalibrationValues(lines, true)) -} - -fun getCalibrationValues(lines: List, findWords: Boolean): Int { - var sum = 0 - - lines.forEach { - var firstDigit = "" - var lastDigit = "" - - var s = it - 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 -} - -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.. '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" -APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/advent-of-code-2023/aoc-02/readme.md b/advent-of-code-2023/aoc-02/readme.md deleted file mode 100644 index 12e7786..0000000 --- a/advent-of-code-2023/aoc-02/readme.md +++ /dev/null @@ -1,77 +0,0 @@ -# Day 2: Cube Conundrum - -You're launched high into the atmosphere! -The apex of your trajectory just barely reaches the surface of a large island floating in the sky. -You gently land in a fluffy pile of leaves. It's quite cold, but you don't see much snow. -An Elf runs over to greet you. - -The Elf explains that you've arrived at Snow Island and apologizes for the lack of snow. -He'll be happy to explain the situation, but it's a bit of a walk, so you have some time. -They don't get many visitors up here; would you like to play a game in the meantime? - -As you walk, the Elf shows you a small bag and some cubes which are either red, green, or blue. -Each time you play this game, he will hide a secret number of cubes of each color in the bag, -and your goal is to figure out information about the number of cubes. - -To get information, once a bag has been loaded with cubes, the Elf will reach into the bag, -grab a handful of random cubes, show them to you, and then put them back in the bag. -He'll do this a few times per game. - -You play several games and record the information from each game (your puzzle input). -Each game is listed with its ID number (like the 11 in Game 11: ...) followed by a semicolon-separated list of subsets -of cubes that were revealed from the bag (like 3 red, 5 green, 4 blue). - -For example, the record of a few games might look like this: - -``` -Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green -Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue -Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red -Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red -Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green -``` - -In game 1, three sets of cubes are revealed from the bag (and then put back again). -The first set is 3 blue cubes and 4 red cubes; the second set is 1 red cube, 2 green cubes, and 6 blue cubes; -the third set is only 2 green cubes. - -The Elf would first like to know which games would have been possible if the bag contained only 12 red cubes, -13 green cubes, and 14 blue cubes? - -In the example above, games 1, 2, and 5 would have been possible if the bag had been loaded with that configuration. -However, game 3 would have been impossible because at one point the Elf showed you 20 red cubes at once; similarly, -game 4 would also have been impossible because the Elf showed you 15 blue cubes at once. -If you add up the IDs of the games that would have been possible, you get 8. - -Determine which games would have been possible if the bag had been loaded with only 12 red cubes, 13 green cubes, -and 14 blue cubes. What is the sum of the IDs of those games? - -## Part Two - -The Elf says they've stopped producing snow because they aren't getting any water! He isn't sure why the water stopped; -however, he can show you how to get to the water source to check it out for yourself. It's just up ahead! - -As you continue your walk, the Elf poses a second question: in each game you played, -what is the fewest number of cubes of each color that could have been in the bag to make the game possible? - -Again consider the example games from earlier: - -``` -Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green -Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue -Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red -Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red -Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green -``` - -- In game 1, the game could have been played with as few as 4 red, 2 green, and 6 blue cubes. If any color had even one fewer cube, the game would have been impossible. -- Game 2 could have been played with a minimum of 1 red, 3 green, and 4 blue cubes. -- Game 3 must have been played with at least 20 red, 13 green, and 6 blue cubes. -- Game 4 required at least 14 red, 3 green, and 15 blue cubes. -- Game 5 needed no fewer than 6 red, 3 green, and 2 blue cubes in the bag. - -The power of a set of cubes is equal to the numbers of red, green, and blue cubes multiplied together. -The power of the minimum set of cubes in game 1 is 48. In games 2-5 it was 12, 1560, 630, and 36, respectively. -Adding up these five powers produces the sum 2286. - -For each game, find the minimum set of cubes that must have been present. What is the sum of the power of these sets? \ No newline at end of file diff --git a/advent-of-code-2023/aoc-02/src/main/kotlin/Main.kt b/advent-of-code-2023/aoc-02/src/main/kotlin/Main.kt deleted file mode 100644 index 5f2d655..0000000 --- a/advent-of-code-2023/aoc-02/src/main/kotlin/Main.kt +++ /dev/null @@ -1,89 +0,0 @@ -import java.io.File -import kotlin.math.max - -class CubeCount(var red: Int, var green: Int, var blue: Int) { - fun lessOrEqualThan(other: CubeCount): Boolean { - return red <= other.red && green <= other.green && blue <= other.blue - } -} - -fun main(args: Array) { - if (args.size < 4) { - println("Usage: ") - return - } - - val cubeCount = CubeCount(args[1].toInt(), args[2].toInt(), args[3].toInt()) - val games = readGames(args[0]) - - println(getSumOfCorrectGameIDs(games, cubeCount)) - println(getPowerSum(games)) -} - -fun readGames(filepath: String): HashMap> { - val games = hashMapOf>() - - File(filepath).forEachLine { - // `it` example: "Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green" - val (game, sets) = it.split(": ") - val gameID = game.split(" ")[1].toInt() - games[gameID] = arrayListOf() - - // setStr example: "3 blue, 4 red" - for (setStr in sets.split("; ")) { - val gameSet = CubeCount(0,0,0) - // cubeStr example: "3 blue" - for (cubeStr in setStr.split(", ")) { - val (cubeCountStr, color) = cubeStr.split(" ") - when (color) { - "blue" -> gameSet.blue = cubeCountStr.toInt() - "red" -> gameSet.red = cubeCountStr.toInt() - "green" -> gameSet.green = cubeCountStr.toInt() - } - } - games[gameID]?.add(gameSet) - } - } - - return games -} - -fun getSumOfCorrectGameIDs(games: HashMap>, cubes: CubeCount): Int { - var sum = 0 - - for (game in games.entries) { - var valid = true - - for (count in game.value) { - if (!count.lessOrEqualThan(cubes)) { - valid = false - } - } - - if (valid) { - sum += game.key - } - } - - return sum -} - -fun getPowerSum(games: HashMap>): Int { - var sum = 0 - - for (game in games.values) { - var maxRed = 0 - var maxGreen = 0 - var maxBlue = 0 - - for (gameSet in game) { - maxRed = max(maxRed, gameSet.red) - maxGreen = max(maxGreen, gameSet.green) - maxBlue = max(maxBlue, gameSet.blue) - } - - sum += maxRed * maxGreen * maxBlue - } - - return sum -} \ No newline at end of file diff --git a/advent-of-code-2023/aoc-02/src/test/kotlin/MainKtTest.kt b/advent-of-code-2023/aoc-02/src/test/kotlin/MainKtTest.kt deleted file mode 100644 index 9b3b1ec..0000000 --- a/advent-of-code-2023/aoc-02/src/test/kotlin/MainKtTest.kt +++ /dev/null @@ -1,16 +0,0 @@ -import kotlin.test.Test -import kotlin.test.assertEquals - -class MainKtTest { - @Test - fun testGetSumOfCorrectGameIDs() { - val res = getSumOfCorrectGameIDs(readGames("test.txt"), CubeCount(12, 13, 14)) - assertEquals(8, res) - } - - @Test - fun testGetPowerSum() { - val res = getPowerSum(readGames("test.txt")) - assertEquals(2286, res) - } -} diff --git a/advent-of-code-2023/aoc-01/build.gradle.kts b/advent-of-code-2023/build.gradle.kts similarity index 91% rename from advent-of-code-2023/aoc-01/build.gradle.kts rename to advent-of-code-2023/build.gradle.kts index 105700c..4ee10ba 100644 --- a/advent-of-code-2023/aoc-01/build.gradle.kts +++ b/advent-of-code-2023/build.gradle.kts @@ -3,7 +3,7 @@ plugins { application } -group = "org.example" +group = "space.comfycamp" version = "1.0-SNAPSHOT" repositories { diff --git a/advent-of-code-2023/aoc-01/gradle.properties b/advent-of-code-2023/gradle.properties similarity index 100% rename from advent-of-code-2023/aoc-01/gradle.properties rename to advent-of-code-2023/gradle.properties diff --git a/advent-of-code-2023/aoc-01/gradle/wrapper/gradle-wrapper.jar b/advent-of-code-2023/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from advent-of-code-2023/aoc-01/gradle/wrapper/gradle-wrapper.jar rename to advent-of-code-2023/gradle/wrapper/gradle-wrapper.jar diff --git a/advent-of-code-2023/aoc-01/gradle/wrapper/gradle-wrapper.properties b/advent-of-code-2023/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from advent-of-code-2023/aoc-01/gradle/wrapper/gradle-wrapper.properties rename to advent-of-code-2023/gradle/wrapper/gradle-wrapper.properties diff --git a/advent-of-code-2023/aoc-01/gradlew b/advent-of-code-2023/gradlew similarity index 100% rename from advent-of-code-2023/aoc-01/gradlew rename to advent-of-code-2023/gradlew diff --git a/advent-of-code-2023/gradlew.bat b/advent-of-code-2023/gradlew.bat new file mode 100644 index 0000000..ac1b06f --- /dev/null +++ b/advent-of-code-2023/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/advent-of-code-2023/aoc-01/input.txt b/advent-of-code-2023/inputs/day-01/input.txt similarity index 100% rename from advent-of-code-2023/aoc-01/input.txt rename to advent-of-code-2023/inputs/day-01/input.txt diff --git a/advent-of-code-2023/aoc-01/test-1.txt b/advent-of-code-2023/inputs/day-01/test-01.txt similarity index 100% rename from advent-of-code-2023/aoc-01/test-1.txt rename to advent-of-code-2023/inputs/day-01/test-01.txt diff --git a/advent-of-code-2023/aoc-01/test-2.txt b/advent-of-code-2023/inputs/day-01/test-02.txt similarity index 100% rename from advent-of-code-2023/aoc-01/test-2.txt rename to advent-of-code-2023/inputs/day-01/test-02.txt diff --git a/advent-of-code-2023/aoc-02/input.txt b/advent-of-code-2023/inputs/day-02/input.txt similarity index 100% rename from advent-of-code-2023/aoc-02/input.txt rename to advent-of-code-2023/inputs/day-02/input.txt diff --git a/advent-of-code-2023/aoc-02/test.txt b/advent-of-code-2023/inputs/day-02/test.txt similarity index 100% rename from advent-of-code-2023/aoc-02/test.txt rename to advent-of-code-2023/inputs/day-02/test.txt diff --git a/advent-of-code-2023/readme.md b/advent-of-code-2023/readme.md deleted file mode 100644 index 7dd2816..0000000 --- a/advent-of-code-2023/readme.md +++ /dev/null @@ -1,4 +0,0 @@ -# Advent of code 2023 - -My goal is to learn the basics of Kotlin. -I have never worked with Kotlin or Java before. diff --git a/advent-of-code-2023/aoc-02/settings.gradle.kts b/advent-of-code-2023/settings.gradle.kts similarity index 82% rename from advent-of-code-2023/aoc-02/settings.gradle.kts rename to advent-of-code-2023/settings.gradle.kts index e69a7ca..593a840 100644 --- a/advent-of-code-2023/aoc-02/settings.gradle.kts +++ b/advent-of-code-2023/settings.gradle.kts @@ -9,4 +9,4 @@ plugins { id("org.gradle.toolchains.foojay-resolver-convention") version "0.5.0" } -rootProject.name = "aoc-02" \ No newline at end of file +rootProject.name = "advent-of-code-2023" \ No newline at end of file diff --git a/advent-of-code-2023/src/main/kotlin/Solution01.kt b/advent-of-code-2023/src/main/kotlin/Solution01.kt new file mode 100644 index 0000000..394c8b6 --- /dev/null +++ b/advent-of-code-2023/src/main/kotlin/Solution01.kt @@ -0,0 +1,46 @@ +object Solution01 { + @JvmStatic + fun getCalibrationValues(lines: List, 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..> { + val games = hashMapOf>() + + File(filepath).forEachLine { + // `it` example: "Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green" + val (game, sets) = it.split(": ") + val gameID = game.split(" ")[1].toInt() + games[gameID] = arrayListOf() + + // setStr example: "3 blue, 4 red" + for (setStr in sets.split("; ")) { + val gameSet = CubeCount(0,0,0) + // cubeStr example: "3 blue" + for (cubeStr in setStr.split(", ")) { + val (cubeCountStr, color) = cubeStr.split(" ") + when (color) { + "blue" -> gameSet.blue = cubeCountStr.toInt() + "red" -> gameSet.red = cubeCountStr.toInt() + "green" -> gameSet.green = cubeCountStr.toInt() + } + } + games[gameID]?.add(gameSet) + } + } + + return games + } + + // Part 1 + fun getSumOfCorrectGameIDs(games: HashMap>, cubes: CubeCount): Int { + var sum = 0 + + for (game in games.entries) { + var valid = true + + for (count in game.value) { + if (!count.lessOrEqualThan(cubes)) { + valid = false + } + } + + if (valid) { + sum += game.key + } + } + + return sum + } + + // Part 2 + fun getSumOfPowers(games: HashMap>): Int { + var sum = 0 + + for (game in games.values) { + var maxRed = 0 + var maxGreen = 0 + var maxBlue = 0 + + for (gameSet in game) { + maxRed = max(maxRed, gameSet.red) + maxGreen = max(maxGreen, gameSet.green) + maxBlue = max(maxBlue, gameSet.blue) + } + + sum += maxRed * maxGreen * maxBlue + } + + return sum + } +} \ No newline at end of file diff --git a/advent-of-code-2023/src/test/kotlin/Solution01Test.kt b/advent-of-code-2023/src/test/kotlin/Solution01Test.kt new file mode 100644 index 0000000..7df0ec9 --- /dev/null +++ b/advent-of-code-2023/src/test/kotlin/Solution01Test.kt @@ -0,0 +1,33 @@ +import java.io.File +import kotlin.test.Test +import kotlin.test.assertEquals + +class Solution01Test { + @Test + fun testGetCalibrationValues() { + val file = File("inputs/day-01/test-01.txt") + val res = Solution01.getCalibrationValues(file.readLines(), false) + assertEquals(142, res) + } + + @Test + fun testReplaceStringsAndGetCalibrationValues() { + val file = File("inputs/day-01/test-02.txt") + val res = Solution01.getCalibrationValues(file.readLines(), true) + assertEquals(281, res) + } + + @Test + fun solvePart1() { + val file = File("inputs/day-01/input.txt") + val res = Solution01.getCalibrationValues(file.readLines(), false) + println(res) + } + + @Test + fun solvePart2() { + val file = File("inputs/day-01/input.txt") + val res = Solution01.getCalibrationValues(file.readLines(), true) + println(res) + } +} \ No newline at end of file diff --git a/advent-of-code-2023/src/test/kotlin/Solution02Test.kt b/advent-of-code-2023/src/test/kotlin/Solution02Test.kt new file mode 100644 index 0000000..6a27c51 --- /dev/null +++ b/advent-of-code-2023/src/test/kotlin/Solution02Test.kt @@ -0,0 +1,32 @@ +import kotlin.test.Test +import kotlin.test.assertEquals + +class Solution02Test { + @Test + fun testGetSumOfCorrectGameIDs() { + val games = Solution02.readGames("inputs/day-02/test.txt") + val res = Solution02.getSumOfCorrectGameIDs(games, CubeCount(12, 13, 14)) + assertEquals(8, res) + } + + @Test + fun testGetPowerSum() { + val games = Solution02.readGames("inputs/day-02/test.txt") + val res = Solution02.getSumOfPowers(games) + assertEquals(2286, res) + } + + @Test + fun solvePart1() { + val games = Solution02.readGames("inputs/day-02/input.txt") + val res = Solution02.getSumOfCorrectGameIDs(games, CubeCount(12, 13, 14)) + println(res) + } + + @Test + fun solvePart2() { + val games = Solution02.readGames("inputs/day-02/input.txt") + val res = Solution02.getSumOfPowers(games) + println(res) + } +} \ No newline at end of file