Advent of Code 2023 day 16
12/16/2024, 5:00 AMMarcin Wisniowski
12/16/2024, 5:33 AMbj0
12/16/2024, 6:13 AMbj0
12/16/2024, 6:13 AMMarcin Wisniowski
12/16/2024, 6:32 AMMarcin Wisniowski
12/16/2024, 6:32 AMMarcin Wisniowski
12/16/2024, 6:35 AMp2 solved in 15 min, i should probably optimize thatI wanted to say 15 min is a very good time, but I think that's not what you meant. š
Dan Fingal-Surma
12/16/2024, 6:50 AMDan Fingal-Surma
12/16/2024, 6:53 AMbj0
12/16/2024, 6:56 AMimport networkx
Dan Fingal-Surma
12/16/2024, 7:00 AMPetr Sýkora
12/16/2024, 7:18 AMDan Fingal-Surma
12/16/2024, 7:21 AMkingsley
12/16/2024, 7:27 AMJakub Gwóźdź
12/16/2024, 8:04 AMDan Fingal-Surma
12/16/2024, 8:14 AMDan Fingal-Surma
12/16/2024, 8:19 AMJaap Beetstra
12/16/2024, 8:26 AMDan Fingal-Surma
12/16/2024, 8:32 AMDan Fingal-Surma
12/16/2024, 8:34 AMDan Fingal-Surma
12/16/2024, 9:02 AMval frontier = mutableSetOf(startReindeer)
// loop
val reindeer = frontier.minBy { minScores.getValue(it) }
frontier.remove(reindeer)
to
val frontier = java.util.PriorityQueue<Pair<Reindeer, Int>>() { a, b -> a.second.compareTo(b.second)}
// loop
val (reindeer, score) = frontier.poll()!!
it gets slower by 5-7msJonathan Kolberg
12/16/2024, 9:38 AMphldavies
12/16/2024, 9:39 AMMarcin Wisniowski
12/16/2024, 9:46 AMit gets slower by 5-7msPossibly because the
frontier
has to grow a lot more as you are not removing elements from it. Try remove()
instead of poll()
.Dan Fingal-Surma
12/16/2024, 9:51 AMDan Fingal-Surma
12/16/2024, 9:52 AMDan Fingal-Surma
12/16/2024, 9:52 AMDan Fingal-Surma
12/16/2024, 9:54 AMDan Fingal-Surma
12/16/2024, 9:54 AMwhile (frontier.remove(reindeer)) {}
Dan Fingal-Surma
12/16/2024, 9:55 AMDan Fingal-Surma
12/16/2024, 9:56 AM161
Marcin Wisniowski
12/16/2024, 9:59 AMDan Fingal-Surma
12/16/2024, 10:00 AMmutableHashSetOf
is faster that HashSet
, I thought the former was LinkedHashSet
which Iād expect to have more overheadDan Fingal-Surma
12/16/2024, 10:00 AMPriorityQueue
benefits you more as the frontier gets biggerDan Fingal-Surma
12/16/2024, 10:00 AMMarcin Wisniowski
12/16/2024, 10:01 AMDan Fingal-Surma
12/16/2024, 10:02 AMDan Fingal-Surma
12/16/2024, 10:03 AMDan Fingal-Surma
12/16/2024, 10:03 AMDan Fingal-Surma
12/16/2024, 10:03 AMDan Fingal-Surma
12/16/2024, 10:05 AMDan Fingal-Surma
12/16/2024, 10:06 AMDan Fingal-Surma
12/16/2024, 10:09 AMDan Fingal-Surma
12/16/2024, 10:14 AMJakub Gwóźdź
12/16/2024, 1:37 PMPair<Pos,Dir>
allowed me to come to:
Parsing took 669.75us
Part 1 took 4.437250ms, result is 109516
Part 2 took 26.895375ms, result is 568
which is probably not yet optimal, but good enough to stop and start working on the visualization šJakub GwóźdÅŗ
12/16/2024, 1:48 PMclass PriorityQueue<E : Any>(val comparator: Comparator<E>, vararg initial: E) {
private var backingList = mutableListOf<E>().apply { addAll(initial) }
val size get() = backingList.size
fun isNotEmpty(): Boolean = size > 0
fun poll(): E {
check(size > 0)
return backingList.removeAt(0)
}
fun offer(e: E) {
val index = backingList.binarySearch(e, comparator).let {
if (it < 0) -it - 1 else it
}
backingList.add(index, e)
}
override fun toString(): String = backingList.toString()
}
Michael de Kaste
12/16/2024, 4:13 PMnerses
12/16/2024, 5:20 PMDan Fingal-Surma
12/16/2024, 5:46 PMbj0
12/16/2024, 5:52 PMDan Fingal-Surma
12/16/2024, 5:53 PMbj0
12/16/2024, 5:53 PMDan Fingal-Surma
12/16/2024, 5:56 PMbj0
12/16/2024, 5:56 PMDan Fingal-Surma
12/16/2024, 5:56 PMDan Fingal-Surma
12/16/2024, 5:57 PMDan Fingal-Surma
12/16/2024, 5:57 PMDan Fingal-Surma
12/16/2024, 5:59 PMDan Fingal-Surma
12/16/2024, 5:59 PM.filterNot { it.p in settled.map { it.p } }
bj0
12/16/2024, 5:59 PMDan Fingal-Surma
12/16/2024, 6:00 PMbj0
12/16/2024, 6:00 PMDan Fingal-Surma
12/16/2024, 6:00 PMbj0
12/16/2024, 6:01 PMbj0
12/16/2024, 6:01 PMDan Fingal-Surma
12/16/2024, 6:01 PMDan Fingal-Surma
12/16/2024, 6:01 PMDan Fingal-Surma
12/16/2024, 6:01 PM.filterNot { it.p to it.dir in settled.map { it.p to it.dir } }
Dan Fingal-Surma
12/16/2024, 6:01 PMDan Fingal-Surma
12/16/2024, 6:06 PMbj0
12/16/2024, 6:07 PMDan Fingal-Surma
12/16/2024, 6:14 PMDan Fingal-Surma
12/16/2024, 6:16 PMDan Fingal-Surma
12/16/2024, 6:16 PMDan Fingal-Surma
12/16/2024, 6:16 PMnerses
12/16/2024, 6:18 PM#.####
#.....
#.####
#...##
###.##
Dan Fingal-Surma
12/16/2024, 6:18 PMDan Fingal-Surma
12/16/2024, 6:18 PMnerses
12/16/2024, 6:19 PMDan Fingal-Surma
12/16/2024, 6:20 PMDan Fingal-Surma
12/16/2024, 6:20 PMDan Fingal-Surma
12/16/2024, 6:20 PMnerses
12/16/2024, 6:20 PMDan Fingal-Surma
12/16/2024, 6:21 PMnerses
12/16/2024, 6:21 PMnerses
12/16/2024, 6:21 PMDan Fingal-Surma
12/16/2024, 6:26 PMDan Fingal-Surma
12/16/2024, 6:28 PMDan Fingal-Surma
12/16/2024, 6:28 PMDan Fingal-Surma
12/16/2024, 6:28 PMval existing = unsettled.firstOrNull { it.p == n.p }
Dan Fingal-Surma
12/16/2024, 6:28 PMnerses
12/16/2024, 6:29 PMnerses
12/16/2024, 6:33 PMDan Fingal-Surma
12/16/2024, 6:36 PMDan Fingal-Surma
12/16/2024, 6:36 PMDan Fingal-Surma
12/16/2024, 6:37 PMnerses
12/16/2024, 6:41 PM#######
#....E#
#.#####
#.....#
#.###.#
#...#.#
###.#.#
#S....#
#######
4018 instead of 4014 šDan Fingal-Surma
12/16/2024, 6:43 PMDan Fingal-Surma
12/16/2024, 6:44 PMDan Fingal-Surma
12/16/2024, 6:44 PMOOOOO
O
O
O
OOO
O
OOO
vs
OOOOO
O
OOOOO
O
O
O
OOOOO
nerses
12/16/2024, 6:44 PMDan Fingal-Surma
12/16/2024, 6:45 PMMarcin Wisniowski
12/16/2024, 6:52 PMDan Fingal-Surma
12/16/2024, 6:54 PMJakub Gwóźdź
12/16/2024, 7:22 PMDan Fingal-Surma
12/16/2024, 7:27 PMDan Fingal-Surma
12/16/2024, 7:28 PMDan Fingal-Surma
12/16/2024, 7:38 PMDan Fingal-Surma
12/16/2024, 7:39 PMval frontier = mutableSetOf(startReindeer to 0)
// loop
val (reindeer, score) = frontier.minBy { it.second }
frontier.remove(reindeer to score)
instead of
val frontier = mutableSetOf(startReindeer)
// loop
val reindeer = frontier.minBy { minScores.getValue(it) }
frontier.remove(reindeer)
val score = minScores.getValue(reindeer)
Dan Fingal-Surma
12/16/2024, 7:49 PMMarcin Wisniowski
12/16/2024, 7:50 PM80ms
to 0.5ms
Dan Fingal-Surma
12/16/2024, 7:51 PMMarcin Wisniowski
12/16/2024, 7:51 PMunvisited
list, meaning not adding turns that end up facing a wall.Dan Fingal-Surma
12/16/2024, 7:52 PMJakub Gwóźdź
12/16/2024, 7:53 PMMarcin Wisniowski
12/16/2024, 7:56 PMJakub Gwóźdź
12/16/2024, 7:58 PMParsing took 1.253125ms
Part 1 took 5.480791ms, result is 73432
Part 2 took 5.328513417s, result is 496
DaaamnDan Fingal-Surma
12/16/2024, 8:06 PMroman.belov
12/16/2024, 8:06 PMroman.belov
12/16/2024, 8:07 PMphldavies
12/16/2024, 9:11 PMPaul Woitaschek
12/16/2024, 9:53 PMNeil Banman
12/17/2024, 2:05 AMephemient
12/17/2024, 9:32 PMOzioma Ogbe
12/20/2024, 2:40 AMimport common.Direction
import utils.Point
import java.io.File
import java.util.PriorityQueue
fun main() {
val input =
File("input.txt").readText().split("\n")
val points = input.mapIndexed { x, s ->
s.mapIndexed { y, c ->
Point(x, y)
}
}
val start = points.flatten().single { input[it.x][it.y] == 'S' }
val queue = PriorityQueue<State>()
val directionMap = mutableMapOf(
Direction.Right to listOf(
Point(0, 1),
Point(-1, 0),
Point(1, 0)
), Direction.Up to listOf(
Point(-1, 0),
Point(0, 1),
Point(0, -1)
), Direction.Left to listOf(
Point(0, -1),
Point(-1, 0),
Point(1, 0)
), Direction.Down to listOf(
Point(1, 0),
Point(0, 1),
Point(0, -1)
)
)
val visited = mutableSetOf<Pair<Point, Direction>>()
val result = mutableSetOf<Pair<Point, Direction>>()
queue.offer(State(start, Direction.Right, 0, 0).apply {
this.points.add(start to Direction.Right)
})
visited.add(start to Direction.Right)
while (queue.isNotEmpty()) {
val top = queue.poll()
visited.add(top.point to top.direction)
if (input[top.point.x][top.point.y] == 'E') {
println(top.score())
result.addAll(top.points)
} else {
directionMap[top.direction]!!.map {
top.point.copy(x = top.point.x + it.x, y = top.point.y + it.y) to getNewDirection(it)
}.filter {
it.first.x in points.indices && it.first.y in points.first().indices && input[it.first.x][it.first.y] != '#'
}.forEach {
val state = State(
it.first,
it.second,
top.steps + 1,
if (it.second == top.direction) top.turns else top.turns + 1,
).apply {
this.points.addAll(top.points + (it.first to it.second))
}
if (!visited.contains(it.first to it.second)) {
queue.offer(
state
)
}
}
}
}
println(result.map { it.first }.toSet().size)
}
fun getNewDirection(point: Point): Direction {
return when {
point.x == 1 -> Direction.Down
point.x == -1 -> Direction.Up
point.y == 1 -> Direction.Right
point.y == -1 -> Direction.Left
else -> error("")
}
}
private data class State(val point: Point, val direction: Direction, val steps: Int, val turns: Int) :
Comparable<State> {
fun score() = this.turns * 1000 + this.steps
override fun compareTo(other: State) =
(this.score()).compareTo(other.score())
val points = mutableSetOf<Pair<Point, Direction>>()
}
kqr
12/30/2024, 7:54 PM