Skip to content

Commit f25a831

Browse files
committed
Solution 2017-22 (Sporifica Virus)
1 parent bead815 commit f25a831

File tree

4 files changed

+117
-0
lines changed

4 files changed

+117
-0
lines changed

src/main/kotlin/de/ronny_h/aoc/extensions/grids/Coordinates.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ enum class Direction(val row: Int, val col: Int) {
5959
WEST -> SOUTH
6060
}
6161

62+
fun reverse() = when (this) {
63+
NORTH -> SOUTH
64+
EAST -> WEST
65+
SOUTH -> NORTH
66+
WEST -> EAST
67+
}
68+
6269
fun asChar() = when (this) {
6370
NORTH -> ''
6471
EAST -> ''
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package de.ronny_h.aoc.year2017.day22
2+
3+
import de.ronny_h.aoc.AdventOfCode
4+
import de.ronny_h.aoc.extensions.grids.Coordinates
5+
import de.ronny_h.aoc.extensions.grids.Direction.NORTH
6+
7+
fun main() = SporificaVirus().run(5538, 2511090)
8+
9+
class SporificaVirus : AdventOfCode<Int>(2017, 22) {
10+
override fun part1(input: List<String>): Int {
11+
val grid = SeeminglyInfiniteGrid(input)
12+
grid.burst1(10000)
13+
return grid.causedInfection
14+
}
15+
16+
override fun part2(input: List<String>): Int {
17+
val grid = SeeminglyInfiniteGrid(input)
18+
grid.burst2(10000000)
19+
return grid.causedInfection
20+
}
21+
}
22+
23+
class SeeminglyInfiniteGrid(input: List<String>) {
24+
private val clean = '.'
25+
private val infected = '#'
26+
private val weakened = 'W'
27+
private val flagged = 'F'
28+
29+
private val grid = mutableMapOf<Coordinates, Char>().withDefault { clean }
30+
31+
init {
32+
input.forEachIndexed { row, line ->
33+
line.forEachIndexed { col, node ->
34+
grid[Coordinates(row, col)] = node
35+
}
36+
}
37+
}
38+
39+
private var direction = NORTH
40+
private var position = Coordinates(input.size / 2, input[0].length / 2)
41+
var causedInfection = 0
42+
private set
43+
44+
fun burst1(times: Int) = repeat(times) {
45+
if (grid[position] == infected) {
46+
direction = direction.turnRight()
47+
grid[position] = clean
48+
} else {
49+
direction = direction.turnLeft()
50+
grid[position] = infected
51+
causedInfection++
52+
}
53+
position += direction
54+
}
55+
56+
fun burst2(times: Int) = repeat(times) {
57+
when (grid.getValue(position)) {
58+
clean -> {
59+
direction = direction.turnLeft()
60+
grid[position] = weakened
61+
}
62+
63+
weakened -> {
64+
// no turn
65+
grid[position] = infected
66+
causedInfection++
67+
}
68+
69+
infected -> {
70+
direction = direction.turnRight()
71+
grid[position] = flagged
72+
}
73+
74+
flagged -> {
75+
direction = direction.reverse()
76+
grid[position] = clean
77+
}
78+
}
79+
position += direction
80+
}
81+
}

src/test/kotlin/de/ronny_h/aoc/extensions/grids/CoordinatesTest.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,13 @@ class CoordinatesTest : StringSpec({
100100
Direction.WEST.turnLeft() shouldBe Direction.SOUTH
101101
}
102102

103+
"Direction reverse() does a u-turn" {
104+
Direction.NORTH.reverse() shouldBe Direction.SOUTH
105+
Direction.EAST.reverse() shouldBe Direction.WEST
106+
Direction.SOUTH.reverse() shouldBe Direction.NORTH
107+
Direction.WEST.reverse() shouldBe Direction.EAST
108+
}
109+
103110
"asChar gives a graphical representation" {
104111
Direction.NORTH.asChar() shouldBe ''
105112
Direction.EAST.asChar() shouldBe ''
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package de.ronny_h.aoc.year2017.day22
2+
3+
import de.ronny_h.aoc.extensions.asList
4+
import io.kotest.core.spec.style.StringSpec
5+
import io.kotest.matchers.shouldBe
6+
7+
class SporificaVirusTest : StringSpec({
8+
9+
val input = """
10+
..#
11+
#..
12+
...
13+
""".asList()
14+
15+
"part 1: The example causes 5587 infections in 10000 bursts" {
16+
SporificaVirus().part1(input) shouldBe 5587
17+
}
18+
19+
"part 2: The example causes 2511944 infections in 10000000 bursts" {
20+
SporificaVirus().part2(input) shouldBe 2511944
21+
}
22+
})

0 commit comments

Comments
 (0)