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
- What is this?: Here is a post with a large amount of details: https://programming.dev/post/6637268
- Where do I participate?: https://adventofcode.com/
- Is there a leaderboard for the community?: We have a programming.dev leaderboard with the info on how to join in this post: https://programming.dev/post/6631465


Kotlin
Tried recursive for part1, didn’t work. LUCKILY for once I was smart and committed anyway, as it was the right solution for part2! I was losing my mind for a bit though as I had originally written my method with Integers…
Solution
class Day07 : Puzzle { val grid = mutableListOf<MutableList<Char>>() val partTwoCache = mutableMapOf<Pair<Int, Int>, Long>() override fun readFile() { val input = readInputFromFile(2025, 7, false) for (line in input.lines().filter { it.isNotBlank() }) { grid.add(line.toCharArray().toMutableList()) } } override fun solvePartOne(): String { grid[1][grid[0].indexOf('S')] = '|' var splits = 0 for (r in 1..<grid.size - 1) { for (c in 0..<grid[r].size) { if (grid[r][c] == '|') { if (grid[r+1][c] == '.') { grid[r+1][c] = '|' } else if (grid[r+1][c] == '^') { grid[r+1][c-1] = '|' grid[r+1][c+1] = '|' splits++ } } } } return splits.toString() } override fun solvePartTwo(): String { val start = grid[0].indexOf('S') return (1 + processBeamPartTwo(1, start)).toString() // don't forget to count the original timeline } private fun processBeamPartTwo(row: Int, column: Int): Long { if (partTwoCache.contains(Pair(row, column))) { return partTwoCache[Pair(row, column)]!! } if (row == grid.size) return 0L if (column == grid[row].size || column < 0) return 0L val out = if (grid[row][column] == '^') { // splitter 1L + processBeamPartTwo(row, column - 1) + processBeamPartTwo(row, column + 1) } else { processBeamPartTwo(row + 1, column) } partTwoCache[Pair(row, column)] = out return out } }full code on Codeberg
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 }