Skip to content

Commit

Permalink
Finish 2024 day 18 both parts
Browse files Browse the repository at this point in the history
  • Loading branch information
tymscar committed Dec 18, 2024
1 parent 25e613e commit 150322a
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 2 deletions.
2 changes: 2 additions & 0 deletions 2024/kotlin/src/main/kotlin/Main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import com.tymscar.day14.solve as day14
import com.tymscar.day15.solve as day15
import com.tymscar.day16.solve as day16
import com.tymscar.day17.solve as day17
import com.tymscar.day18.solve as day18

fun main() {
day01()
Expand All @@ -36,4 +37,5 @@ fun main() {
day15()
day16()
day17()
day18()
}
60 changes: 59 additions & 1 deletion 2024/kotlin/src/main/kotlin/com/tymscar/day18/part1/part1.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,63 @@
package com.tymscar.day18.part1

import java.util.PriorityQueue

const val MAP_SIZE = 71
const val NUM_BYTES = 1024

private typealias Map = HashMap<Vec2, MemoryType>

private data class Vec2(var x: Int, var y: Int) {
constructor(list: List<Int>) : this(list[0], list[1])

fun getValidNeighbours(): List<Vec2> {
return listOf(
Vec2(x + 1, y),
Vec2(x - 1, y),
Vec2(x, y + 1),
Vec2(x, y - 1)
).filter { it.x in 0 until MAP_SIZE && it.y in 0 until MAP_SIZE }
}
}

private enum class MemoryType { CORRUPTED, SAFE }

private fun dijkstra(start: Vec2, end: Vec2, map: Map): Int {
val visited = HashSet<Vec2>()
val costs = HashMap<Vec2, Int>()
val queue = PriorityQueue<Pair<Vec2, Int>>(compareBy { it.second })

queue.add(start to 0)
while (queue.isNotEmpty()) {
val (currPos, currCost) = queue.poll()
if (currPos == end) return currCost

if (visited.contains(currPos)) continue
visited.add(currPos)

val neighbours = currPos.getValidNeighbours()
for (neighbour in neighbours) {
if (map.getOrDefault(
neighbour,
MemoryType.SAFE
) == MemoryType.CORRUPTED || visited.contains(neighbour)
) continue
val nextCost = currCost + 1
if (nextCost < costs.getOrDefault(neighbour, Int.MAX_VALUE)) {
costs[neighbour] = nextCost
queue.add(neighbour to nextCost)
}
}
}
return Int.MAX_VALUE
}

fun solve(input: String): String {
return input
val bytes = input.lines().map { Vec2(it.split(",").map { it.toInt() }) }
val map = (0 until NUM_BYTES).associate { bytes[it] to MemoryType.CORRUPTED }.toMap()

val start = Vec2(0, 0)
val end = Vec2(MAP_SIZE - 1, MAP_SIZE - 1)

return dijkstra(start, end, map as Map).toString()
}
69 changes: 68 additions & 1 deletion 2024/kotlin/src/main/kotlin/com/tymscar/day18/part2/part2.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,72 @@
package com.tymscar.day18.part2

import java.util.PriorityQueue

const val MAP_SIZE = 71
const val NUM_BYTES = 1024

private typealias Map = HashMap<Vec2, MemoryType>

private data class Vec2(var x: Int, var y: Int) {
constructor(list: List<Int>) : this(list[0], list[1])

fun getValidNeighbours(): List<Vec2> {
return listOf(
Vec2(x + 1, y),
Vec2(x - 1, y),
Vec2(x, y + 1),
Vec2(x, y - 1)
).filter { it.x in 0 until MAP_SIZE && it.y in 0 until MAP_SIZE }
}

override fun toString(): String = "$x,$y"
}

private enum class MemoryType { CORRUPTED, SAFE }

private fun canFindPath(start: Vec2, end: Vec2, map: Map): Boolean {
val visited = HashSet<Vec2>()
val costs = HashMap<Vec2, Int>()
val queue = PriorityQueue<Pair<Vec2, Int>>(compareBy { it.second })

queue.add(start to 0)
while (queue.isNotEmpty()) {
val (currPos, currCost) = queue.poll()
if (currPos == end) return true

if (visited.contains(currPos)) continue
visited.add(currPos)

val neighbours = currPos.getValidNeighbours()
for (neighbour in neighbours) {
if (map.getOrDefault(
neighbour,
MemoryType.SAFE
) == MemoryType.CORRUPTED || visited.contains(neighbour)
) continue
val nextCost = currCost + 1
if (nextCost < costs.getOrDefault(neighbour, Int.MAX_VALUE)) {
costs[neighbour] = nextCost
queue.add(neighbour to nextCost)
}
}
}
return false
}

fun solve(input: String): String {
return input
val bytes = input.lines().map { Vec2(it.split(",").map { it.toInt() }) }
val map = (0 until NUM_BYTES).associate { bytes[it] to MemoryType.CORRUPTED }.toMutableMap()

val start = Vec2(0, 0)
val end = Vec2(MAP_SIZE - 1, MAP_SIZE - 1)

var currentByte = NUM_BYTES - 1

while (canFindPath(start, end, map as Map)) {
map[bytes[currentByte]] = MemoryType.CORRUPTED
currentByte++
}

return bytes[currentByte - 1].toString()
}

0 comments on commit 150322a

Please sign in to comment.