Refactor day 2 of AoC 2023
This commit is contained in:
parent
fa27aa2405
commit
8a9f518b5b
12 changed files with 248 additions and 119 deletions
42
advent-of-code/2023/day_02/.gitignore
vendored
Normal file
42
advent-of-code/2023/day_02/.gitignore
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
.gradle
|
||||
gradle
|
||||
build/
|
||||
!**/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
|
81
advent-of-code/2023/day_02/README.md
Normal file
81
advent-of-code/2023/day_02/README.md
Normal file
|
@ -0,0 +1,81 @@
|
|||
# Advent of Code 2023 day 2 solution in Kotlin
|
||||
|
||||
## Cube Conundrum
|
||||
|
||||
[Task page](https://adventofcode.com/2023/day/2)
|
||||
|
||||
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?
|
18
advent-of-code/2023/day_02/build.gradle.kts
Normal file
18
advent-of-code/2023/day_02/build.gradle.kts
Normal file
|
@ -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()
|
||||
}
|
1
advent-of-code/2023/day_02/gradle.properties
Normal file
1
advent-of-code/2023/day_02/gradle.properties
Normal file
|
@ -0,0 +1 @@
|
|||
kotlin.code.style=official
|
2
advent-of-code/2023/day_02/settings.gradle.kts
Normal file
2
advent-of-code/2023/day_02/settings.gradle.kts
Normal file
|
@ -0,0 +1,2 @@
|
|||
rootProject.name = "day_02"
|
||||
|
61
advent-of-code/2023/day_02/src/main/kotlin/GameHost.kt
Normal file
61
advent-of-code/2023/day_02/src/main/kotlin/GameHost.kt
Normal file
|
@ -0,0 +1,61 @@
|
|||
package space.comfycamp
|
||||
|
||||
import kotlin.math.max
|
||||
|
||||
data class CubeSet(var red: Int, var green: Int, var blue: Int)
|
||||
|
||||
// Part 1
|
||||
fun getSumOfCorrectGameIDs(text: List<String>): Int {
|
||||
val games = readGames(text)
|
||||
|
||||
return games
|
||||
.withIndex()
|
||||
.filter{ el -> isGameValid(el.value) }
|
||||
.sumOf { el -> el.index + 1 }
|
||||
}
|
||||
|
||||
private fun isGameValid(cubeSets: List<CubeSet>): Boolean {
|
||||
for (cubeSet in cubeSets) {
|
||||
if (cubeSet.red > 12 || cubeSet.green > 13 || cubeSet.blue > 14) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// Part 2
|
||||
fun getSumOfPowers(text: List<String>): Int {
|
||||
val games = readGames(text)
|
||||
|
||||
return games
|
||||
.map { game ->
|
||||
game.reduce { acc, cubeSet ->
|
||||
CubeSet(
|
||||
max(acc.red, cubeSet.red),
|
||||
max(acc.green, cubeSet.green),
|
||||
max(acc.blue, cubeSet.blue)
|
||||
)
|
||||
}
|
||||
}
|
||||
.sumOf { cubeSet -> cubeSet.red * cubeSet.green * cubeSet.blue }
|
||||
}
|
||||
|
||||
private fun readGames(text: List<String>): List<List<CubeSet>> {
|
||||
return text
|
||||
.map{ line -> line.split(": ")[1] }
|
||||
.map{ sets -> sets.split("; ").map{ cubeSet -> parseCubeSet(cubeSet) } }
|
||||
}
|
||||
|
||||
private fun parseCubeSet(description: String): CubeSet {
|
||||
val cubeSet = CubeSet(0,0,0)
|
||||
for (cubeStr in description.split(", ")) {
|
||||
val (cubeCountStr, color) = cubeStr.split(" ")
|
||||
when (color) {
|
||||
"blue" -> cubeSet.blue = cubeCountStr.toInt()
|
||||
"red" -> cubeSet.red = cubeCountStr.toInt()
|
||||
"green" -> cubeSet.green = cubeCountStr.toInt()
|
||||
}
|
||||
}
|
||||
return cubeSet
|
||||
}
|
12
advent-of-code/2023/day_02/src/main/kotlin/Main.kt
Normal file
12
advent-of-code/2023/day_02/src/main/kotlin/Main.kt
Normal file
|
@ -0,0 +1,12 @@
|
|||
package space.comfycamp
|
||||
|
||||
fun main() {
|
||||
val resource = object{}.javaClass.getResource("/input.txt")!!
|
||||
val lines = resource.readText().trim().lines()
|
||||
|
||||
val res1 = getSumOfCorrectGameIDs(lines)
|
||||
println("Part 1: $res1")
|
||||
|
||||
val res2 = getSumOfPowers(lines)
|
||||
println("Part 2: $res2")
|
||||
}
|
|
@ -97,4 +97,4 @@ Game 96: 3 red, 10 green; 9 green, 11 red; 2 red, 6 green, 2 blue; 1 blue, 9 red
|
|||
Game 97: 3 green, 11 red, 1 blue; 3 green, 13 red, 4 blue; 1 green, 3 blue, 12 red; 4 green, 10 red; 4 blue, 10 green, 12 red
|
||||
Game 98: 6 blue, 12 red; 17 red, 1 green, 11 blue; 13 blue, 9 red; 9 red, 6 blue, 2 green
|
||||
Game 99: 15 green, 1 blue, 11 red; 12 green, 12 blue, 14 red; 12 green, 10 blue, 1 red
|
||||
Game 100: 1 green, 11 red, 4 blue; 4 green, 1 red; 9 red, 2 blue; 5 blue, 11 red, 9 green
|
||||
Game 100: 1 green, 11 red, 4 blue; 4 green, 1 red; 9 red, 2 blue; 5 blue, 11 red, 9 green
|
30
advent-of-code/2023/day_02/src/test/kotlin/GameHostTest.kt
Normal file
30
advent-of-code/2023/day_02/src/test/kotlin/GameHostTest.kt
Normal file
|
@ -0,0 +1,30 @@
|
|||
import space.comfycamp.getSumOfCorrectGameIDs
|
||||
import space.comfycamp.getSumOfPowers
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.Test
|
||||
|
||||
class GameHostTest {
|
||||
@Test
|
||||
fun testGetSumOfCorrectGameIDs() {
|
||||
val lines = listOf(
|
||||
"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"
|
||||
)
|
||||
assertEquals(8, getSumOfCorrectGameIDs(lines))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGetSumOfPowers() {
|
||||
val lines = listOf(
|
||||
"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"
|
||||
)
|
||||
assertEquals(2286, getSumOfPowers(lines))
|
||||
}
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
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
|
||||
}
|
||||
}
|
||||
|
||||
class Solution02 {
|
||||
// Part 1
|
||||
fun getSumOfCorrectGameIDs(text: List<String>, cubes: CubeCount): Int {
|
||||
val games = readGames(text)
|
||||
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(text: List<String>): Int {
|
||||
val games = readGames(text)
|
||||
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
|
||||
}
|
||||
|
||||
private fun readGames(text: List<String>): HashMap<Int, MutableList<CubeCount>> {
|
||||
val games = hashMapOf<Int, MutableList<CubeCount>>()
|
||||
|
||||
text.forEach {
|
||||
// `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
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
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
|
|
@ -1,32 +0,0 @@
|
|||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class Solution02Test {
|
||||
@Test
|
||||
fun testGetSumOfCorrectGameIDs() {
|
||||
val text = ResourceReader().readFile("day-02/test.txt")
|
||||
val res = Solution02().getSumOfCorrectGameIDs(text, CubeCount(12, 13, 14))
|
||||
assertEquals(8, res)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGetPowerSum() {
|
||||
val text = ResourceReader().readFile("day-02/test.txt")
|
||||
val res = Solution02().getSumOfPowers(text)
|
||||
assertEquals(2286, res)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun solvePart1() {
|
||||
val text = ResourceReader().readFile("day-02/input.txt")
|
||||
val res = Solution02().getSumOfCorrectGameIDs(text, CubeCount(12, 13, 14))
|
||||
println(res)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun solvePart2() {
|
||||
val text = ResourceReader().readFile("day-02/input.txt")
|
||||
val res = Solution02().getSumOfPowers(text)
|
||||
println(res)
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue