Skip to content

Commit 067bf84

Browse files
committed
Solution 2015-13 (Knights of the Dinner Table)
1 parent f3a6a70 commit 067bf84

File tree

2 files changed

+101
-0
lines changed

2 files changed

+101
-0
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package de.ronny_h.aoc.year2015.day13
2+
3+
import de.ronny_h.aoc.AdventOfCode
4+
import de.ronny_h.aoc.extensions.permutationsOf
5+
6+
fun main() = KnightsOfTheDinnerTable().run(664, 640)
7+
8+
class KnightsOfTheDinnerTable : AdventOfCode<Int>(2015, 13) {
9+
10+
override fun part1(input: List<String>): Int {
11+
return input.parse().maxHappiness()
12+
}
13+
14+
private fun List<HappinessPotential>.maxHappiness(): Int {
15+
val happinessLookup = associate { Pair(it.person, it.nextTo) to it.happiness }
16+
fun happinessChange(a: String, b: String) = happinessLookup[a to b]!! + happinessLookup[b to a]!!
17+
18+
val allGuests = map { it.person }.toSet().toList()
19+
return permutationsOf(allGuests).maxOf { guests ->
20+
var happiness = 0
21+
guests.windowed(2) { (person, nextTo) ->
22+
happiness += happinessChange(person, nextTo)
23+
}
24+
happiness += happinessChange(guests.first(), guests.last())
25+
happiness
26+
}
27+
}
28+
29+
override fun part2(input: List<String>): Int {
30+
val happinessPotentials = input.parse()
31+
val allGuests = happinessPotentials.map { it.person }.toSet().toList()
32+
33+
val myHappinessPotential = allGuests.flatMap {
34+
listOf(
35+
HappinessPotential("me", it, 0),
36+
HappinessPotential(it, "me", 0)
37+
)
38+
}
39+
return (happinessPotentials + myHappinessPotential).maxHappiness()
40+
}
41+
}
42+
43+
data class HappinessPotential(val person: String, val nextTo: String, val happiness: Int)
44+
45+
fun List<String>.parse() = this.map {
46+
val (person, remainder) = it.split(" would ")
47+
val sign = when {
48+
remainder.startsWith("gain") -> 1
49+
else -> -1
50+
}
51+
val (happiness, nextTo) = remainder.substring(5, remainder.lastIndex)
52+
.split(" happiness units by sitting next to ")
53+
HappinessPotential(person, nextTo, sign * happiness.toInt())
54+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package de.ronny_h.aoc.year2015.day13
2+
3+
import io.kotest.core.spec.style.StringSpec
4+
import io.kotest.data.forAll
5+
import io.kotest.data.row
6+
import io.kotest.matchers.shouldBe
7+
8+
class KnightsOfTheDinnerTableTest : StringSpec({
9+
10+
val input = listOf(
11+
"Alice would gain 54 happiness units by sitting next to Bob.",
12+
"Alice would lose 79 happiness units by sitting next to Carol.",
13+
"Alice would lose 2 happiness units by sitting next to David.",
14+
"Bob would gain 83 happiness units by sitting next to Alice.",
15+
"Bob would lose 7 happiness units by sitting next to Carol.",
16+
"Bob would lose 63 happiness units by sitting next to David.",
17+
"Carol would lose 62 happiness units by sitting next to Alice.",
18+
"Carol would gain 60 happiness units by sitting next to Bob.",
19+
"Carol would gain 55 happiness units by sitting next to David.",
20+
"David would gain 46 happiness units by sitting next to Alice.",
21+
"David would lose 7 happiness units by sitting next to Bob.",
22+
"David would gain 41 happiness units by sitting next to Carol.",
23+
)
24+
25+
"input can be parsed" {
26+
forAll(
27+
row(
28+
"Alice would gain 54 happiness units by sitting next to Bob.",
29+
HappinessPotential("Alice", "Bob", 54)
30+
),
31+
row(
32+
"Alice would lose 79 happiness units by sitting next to Carol.",
33+
HappinessPotential("Alice", "Carol", -79)
34+
),
35+
) { sentence, expected ->
36+
listOf(sentence).parse() shouldBe listOf(expected)
37+
}
38+
}
39+
40+
"part 1: the optimal total change in happiness" {
41+
KnightsOfTheDinnerTable().part1(input) shouldBe 330
42+
}
43+
44+
"part 2: the optimal total change in happiness, myself included" {
45+
KnightsOfTheDinnerTable().part2(input) shouldBe 286
46+
}
47+
})

0 commit comments

Comments
 (0)