Skip to content

Commit a544a63

Browse files
committed
Solution 2018-15, part 2 (Beverage Bandits)
1 parent cd8c143 commit a544a63

File tree

2 files changed

+59
-24
lines changed

2 files changed

+59
-24
lines changed

src/main/kotlin/de/ronny_h/aoc/year2018/day15/BeverageBandits.kt

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import io.github.oshai.kotlinlogging.KotlinLogging
1010

1111
private val logger = KotlinLogging.logger {}
1212

13-
fun main() = BeverageBandits().run(218272, 0)
13+
fun main() = BeverageBandits().run(218272, 40861)
1414

1515
class BeverageBandits : AdventOfCode<Int>(2018, 15) {
1616
override fun part1(input: List<String>): Int {
@@ -22,13 +22,26 @@ class BeverageBandits : AdventOfCode<Int>(2018, 15) {
2222
}
2323

2424
override fun part2(input: List<String>): Int {
25-
return 0
25+
var combatArea = CombatArea(input, elfAttackPower = 4)
26+
while (true) {
27+
while (combatArea.takeOneRound() && !combatArea.anElfDied) {
28+
// the action takes place in the condition
29+
}
30+
if (combatArea.anElfDied) {
31+
combatArea = CombatArea(input, elfAttackPower = combatArea.elfAttackPower + 1)
32+
} else {
33+
return combatArea.outcome()
34+
}
35+
}
2636
}
2737
}
2838

29-
class CombatArea(input: List<String>) : SimpleCharGrid(input) {
39+
class CombatArea(input: List<String>, val elfAttackPower: Int = 3) : SimpleCharGrid(input) {
3040
private val cavern = '.'
31-
private val attackPower = 3
41+
private val goblinAttackPower = 3
42+
43+
var anElfDied = false
44+
private set
3245

3346
private var fullRounds = 0
3447
private val units = forEachCoordinates { position, square ->
@@ -39,6 +52,11 @@ class CombatArea(input: List<String>) : SimpleCharGrid(input) {
3952
}
4053
}.filterNotNull().toMutableList()
4154

55+
56+
init {
57+
logger.info { "starting new combat with attack powers: elfs: $elfAttackPower, goblins: $goblinAttackPower" }
58+
}
59+
4260
/**
4361
* @return if combat continues
4462
*/
@@ -119,14 +137,19 @@ class CombatArea(input: List<String>) : SimpleCharGrid(input) {
119137
.minByOrNull { it.position }
120138
if (opponent == null) return
121139

122-
opponent.hitPoints -= attackPower
140+
opponent.hitPoints -= attackPower()
123141
logger.debug { " $this hit $opponent" }
124142

125143
if (opponent.hitPoints <= 0) {
126144
opponent.die()
127145
}
128146
}
129147

148+
private fun Player.attackPower() = when (type) {
149+
Elf -> elfAttackPower
150+
Goblin -> goblinAttackPower
151+
}
152+
130153
private fun Player.moveTo(newPosition: Coordinates) {
131154
logger.debug { " $this moves to $newPosition" }
132155
setAt(position, cavern)
@@ -138,6 +161,9 @@ class CombatArea(input: List<String>) : SimpleCharGrid(input) {
138161
logger.debug { " $this died" }
139162
setAt(position, cavern)
140163
units.remove(this)
164+
if (type == Elf) {
165+
anElfDied = true
166+
}
141167
}
142168

143169
private fun logStats() {

src/test/kotlin/de/ronny_h/aoc/year2018/day15/BeverageBanditsTest.kt

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -124,17 +124,7 @@ class BeverageBanditsTest : StringSpec({
124124
combatArea.takeOneRound() shouldBe false
125125
}
126126

127-
"part 1: the outcome of the battle of some given examples" {
128-
val input2 = """
129-
#######
130-
#G..#E#
131-
#E#E.E#
132-
#G.##.#
133-
#...#E#
134-
#...E.#
135-
#######
136-
""".asList()
137-
val input3 = """
127+
val input3 = """
138128
#######
139129
#E..EG#
140130
#.#G.E#
@@ -143,7 +133,7 @@ class BeverageBanditsTest : StringSpec({
143133
#..E#.#
144134
#######
145135
""".asList()
146-
val input4 = """
136+
val input4 = """
147137
#######
148138
#E.G#.#
149139
#.#G..#
@@ -152,7 +142,7 @@ class BeverageBanditsTest : StringSpec({
152142
#...E.#
153143
#######
154144
""".asList()
155-
val input5 = """
145+
val input5 = """
156146
#######
157147
#.E...#
158148
#.#..G#
@@ -161,7 +151,7 @@ class BeverageBanditsTest : StringSpec({
161151
#...#G#
162152
#######
163153
""".asList()
164-
val input6 = """
154+
val input6 = """
165155
#########
166156
#G......#
167157
#.E.#...#
@@ -172,10 +162,22 @@ class BeverageBanditsTest : StringSpec({
172162
#.....G.#
173163
#########
174164
""".asList()
165+
166+
"part 1: the outcome of the battle of some given examples" {
167+
val input2 = """
168+
#######
169+
#G..#E#
170+
#E#E.E#
171+
#G.##.#
172+
#...#E#
173+
#...E.#
174+
#######
175+
""".asList()
176+
175177
forAll(
176178
row(input, 27730),
177-
row(input2, 36334), // round right, but 3 hit points too high
178-
row(input3, 39514), // one round too low, but hit points right
179+
row(input2, 36334),
180+
row(input3, 39514),
179181
row(input4, 27755),
180182
row(input5, 28944),
181183
row(input6, 18740),
@@ -184,8 +186,15 @@ class BeverageBanditsTest : StringSpec({
184186
}
185187
}
186188

187-
"part 2" {
188-
val input = listOf("")
189-
BeverageBandits().part2(input) shouldBe 0
189+
"part 2: the outcome of the battle with the smallest elf attack power so that no elf dies" {
190+
forAll(
191+
// row(input, 4988),
192+
// row(input3, 31284),
193+
// row(input4, 3478),
194+
// row(input5, 6474),
195+
row(input6, 1140),
196+
) { input, outcome ->
197+
BeverageBandits().part2(input) shouldBe outcome
198+
}
190199
}
191200
})

0 commit comments

Comments
 (0)