Day 7: Laboratories

Megathread guidelines

  • Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
  • You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL

FAQ

  • chunkystyles@sopuli.xyz
    link
    fedilink
    English
    arrow-up
    2
    ·
    3 days ago

    I didn’t do recursion on part 1, so my part 1 and 2 were fairly different.

    const val start = 'S'
    const val empty = '.'
    const val splitter = '^'
    const val beam = '|'
    
    var width: IntRange = IntRange(0, 0)
    var height: IntRange = IntRange(0, 0)
    val cache: MutableMap<Pair<Int, Int>, Long> = mutableMapOf()
    var map: List<List<Char>> = listOf()
    
    fun main() {
        val input = getInput(7)
        map = parseInput1(input)
        height = map.indices
        width = map[0].indices
        val startLocation = map[0].indexOf(start) to 0
        val splits = moveBeam(startLocation) + 1
        println(splits)
    }
    
    fun parseInput1(input: String): List<List<Char>> = input.lines()
        .filter { it.isNotBlank() }
        .map { it.toCharArray().toList() }
    
    fun moveBeam(beamLocation: Pair<Int, Int>): Long {
        if (cache.containsKey(beamLocation)) {
            return cache[beamLocation]!!
        }
        val belowLocation = beamLocation.first to beamLocation.second + 1
        if (belowLocation.second !in height) {
            return 0L
        }
        if (cache.containsKey(belowLocation)) {
            return cache[belowLocation]!!
        }
        val below = map[belowLocation.second][belowLocation.first]
        var splits = 0L
        if (below == empty) {
            splits = moveBeam(belowLocation)
        } else if (below == splitter) {
            splits++
            val leftLocation = belowLocation.first - 1 to belowLocation.second
            val left = if (leftLocation.first in width) map[leftLocation.second][leftLocation.first] else '!'
            if (left == empty || left == splitter) {
                splits += moveBeam(leftLocation)
            }
            val rightLocation = belowLocation.first + 1 to belowLocation.second
            val right = if (rightLocation.first in width) map[rightLocation.second][rightLocation.first] else '!'
            if (right == empty || right == splitter) {
                splits += moveBeam(rightLocation)
            }
        }
        cache[beamLocation] = splits
        return splits
    }