-
Notifications
You must be signed in to change notification settings - Fork 0
/
Day13.kt
55 lines (48 loc) · 1.86 KB
/
Day13.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package com.github.ephemient.aoc2021
import kotlin.math.abs
/** [Day 13](https://adventofcode.com/2021/day/13): Transparent Origami */
class Day13(lines: List<String>) {
private val points: Set<IntPair>
private val folds: List<Fold>
init {
val iterator = lines.iterator()
points = buildSet {
for (line in iterator) {
if (line.isEmpty()) break
val (x, y) = line.split(',')
add(x.toInt() to y.toInt())
}
}
folds = buildList {
for (line in iterator) {
when {
line.startsWith("fold along x=") -> add(Fold.X(line.substring(13).toInt()))
line.startsWith("fold along y=") -> add(Fold.Y(line.substring(13).toInt()))
else -> throw IllegalStateException("bad input: $line")
}
}
}
}
fun part1(): Int = points.mapTo(mutableSetOf(), folds.first()::invoke).size
fun part2(): String {
val points = points.mapTo(mutableSetOf()) { folds.fold(it) { point, fold -> fold(point) } }
val x0 = points.minOf { it.first }
val y0 = points.minOf { it.second }
val x1 = points.maxOf { it.first }
val y1 = points.maxOf { it.second }
return (y0..y1).joinToString("\n") { y ->
(x0..x1).joinToString("") { x ->
if (x to y in points) "\u2593" else "\u2591"
}
}
}
private sealed interface Fold {
operator fun invoke(point: IntPair): IntPair
class X(private val x: Int) : Fold {
override fun invoke(point: IntPair): IntPair = point.copy(first = x - abs(point.first - x))
}
class Y(private val y: Int) : Fold {
override fun invoke(point: IntPair): IntPair = point.copy(second = y - abs(point.second - y))
}
}
}