Skip to content

Commit fc689f5

Browse files
committed
2022/Day 14
1 parent 3159f90 commit fc689f5

File tree

5 files changed

+243
-1
lines changed

5 files changed

+243
-1
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@
5858
🎄 ---- Day 13: Distress Signal ---
5959
🌟 Part 1: 5292 (43.82ms)
6060
🌟 Part 2: 23868 (8.9us)
61+
62+
🎄 ---- Day 14: Regolith Reservoir ---
63+
🌟 Part 1: 843 (255.6ms)
64+
🌟 Part 2: 27625 (8us)
6165
```
6266

6367
## Visualizations

src/main/kotlin/me/grison/aoc/Extensions.kt

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -403,4 +403,22 @@ fun Int.padLeft(length: Int, value: Char): String {
403403

404404
fun Char.int() = this.toString().toInt()
405405

406-
fun <T,U,V> t(t: T, u: U, v: V) = Triple(t, u, v)
406+
fun <T,U,V> t(t: T, u: U, v: V) = Triple(t, u, v)
407+
408+
fun Position.sign() = p(first.sign(), second.sign())
409+
410+
fun Position.x() = first
411+
fun Position.y() = second
412+
413+
fun List<Int>.min() = minByOrNull { it }!!
414+
fun Iterable<Position>.minX() = map {it.first}.min()
415+
fun Iterable<Position>.minY() = map {it.second}.min()
416+
417+
fun List<Int>.max() = maxByOrNull { it }!!
418+
fun Iterable<Position>.maxX() = map {it.first}.max()
419+
fun Iterable<Position>.maxY() = map {it.second}.max()
420+
421+
fun <T> List<T>.peek(index: Int, sideEffect: (T) -> Unit) : List<T> {
422+
sideEffect.invoke(this[index])
423+
return this;
424+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package me.grison.aoc.y2022
2+
3+
import arrow.syntax.function.memoize
4+
import me.grison.aoc.*
5+
6+
class Day14 : Day(14, 2022) {
7+
override fun title() = "Regolith Reservoir"
8+
9+
override fun partOne() = solve().first
10+
11+
override fun partTwo() = solve().second
12+
13+
private val solve = {
14+
val filled = parse()
15+
16+
val floor = filled.maxY() + 2
17+
fun canMove(sand: Position) =
18+
sand.y() != floor && sand !in filled
19+
20+
var (part1, part2, tick) = listOf(-1, 0, 0)
21+
while (true) {
22+
var sand = p(500, 0)
23+
while (true) {
24+
if (sand.y() + 1 >= floor && part1 < 0)
25+
part1 = tick
26+
27+
sand += when {
28+
canMove(sand + p(0, 1)) -> p(0, 1)
29+
canMove(sand + p(-1, 1)) -> p(-1, 1)
30+
canMove(sand + p(1, 1)) -> p(1, 1)
31+
else -> break
32+
}
33+
}
34+
35+
if (sand == p(500, 0)) {
36+
part2 = tick + 1
37+
break
38+
}
39+
filled.add(sand)
40+
tick += 1
41+
}
42+
43+
p(part1, part2)
44+
}.memoize()
45+
46+
private fun parse() = mutableSetOf<Position>().let { filled ->
47+
inputList.forEach { line ->
48+
var last = p(-1, -1)
49+
line.normalSplit(" -> ")
50+
.map { it.allInts().pair() }
51+
.forEach { pos ->
52+
if (last == p(-1, -1)) {
53+
filled.add(pos)
54+
} else {
55+
val diff = pos - last
56+
filled.addAll((0..diff.abs().max()).map { p(it, it) * diff.sign() + last })
57+
}
58+
last = pos
59+
}
60+
}
61+
filled
62+
}
63+
}

0 commit comments

Comments
 (0)