It was 12 days and the first time I’ve ever finished it.
- 0 Posts
- 83 Comments
chunkystyles@sopuli.xyzto
Advent Of Code@programming.dev•❄ - 2025 DAY 12 SOLUTIONS - ❄English
3·1 month agoKotlin
Looking at the puzzle, I knew that I had no clue how to solve it. So I came here to see if I was missing something or if there were any hints.
And the hint I saw was to do the simplest check possible, so I gave it a shot.
And that got the test input wrong, but I ran it against the real input anyway just to see if it was right. And it was.
I think if I had gone on my instincts and just tried to solve this, I could have gone around in circles for hours or days trying to get it right.
fun main() { val input = getInput(12) val (gifts, regions) = parseInput1(input) var total = 0 for (i in regions.indices) { val totalAreaOfGifts = regions[i].gifts.mapIndexed { index, count -> count * gifts[index].area }.sum() if (totalAreaOfGifts <= regions[i].area) { total++ } } println(total) } data class Gift(val shape: List<List<Char>>, val area: Int) data class Region(val width: Int, val height: Int, val area: Int, val gifts: List<Int>) fun parseInput1(input: String): Pair<List<Gift>, List<Region>> { val gifts: MutableList<Gift> = mutableListOf() val regions: MutableList<Region> = mutableListOf() val lines = input.lines() lines.forEachIndexed { index, line -> if (line.contains(":")) { if (line.contains("x")) { val split = line.split(" ") val shape = split.first().replace(":", "").split("x") val width = shape.first().toInt() val height = shape.last().toInt() regions.add( Region( width, height, width * height, split.slice(1..<split.size).map { str -> str.toInt() }) ) } else { var nextBlankLineIndex = 0 for (i in index + 1..<lines.size) { if (lines[i].isBlank()) { nextBlankLineIndex = i break } } val shape = lines.slice(index + 1..<nextBlankLineIndex).map { it.toCharArray().toList() } val area = shape.flatten().filter { it == '#' }.size gifts.add(Gift(shape, area)) } } } return gifts to regions }
chunkystyles@sopuli.xyzto
Advent Of Code@programming.dev•🍗 - 2025 DAY 10 SOLUTIONS - 🍗English
2·1 month agoI think I got pretty lucky that the Java library I used was pretty straightforward and had good docs.
This was definitely an unfulfilling way to solve a puzzle. I did take linear algebra in college, but I really struggled in that class and retained none of it.
chunkystyles@sopuli.xyzto
Advent Of Code@programming.dev•🍗 - 2025 DAY 10 SOLUTIONS - 🍗English
2·1 month agoKotlin
Part 1 had me assuming, like a lot of other folks, that Part 2 would be a simple weighted graph. So I coded Part 1 as a non-weighted graph and it was great.
Part 2 looked simple enough, but different. Part 1 was breadth first, I assumed depth first would work for Part 2. When it worked great on the test input, but took 12 seconds, I knew I was in trouble. So I added caching. And it was super quick on the test input.
Real input was a whole 'nother story. I watched my system resources balloon. At last count it was using 8GB of RAM before I killed it. And that was before solving even the first line.
So I went online to find what I’m missing to see people saying it’s a linear algebra problem, and that it’s best to use some kind of library for it.
I will admit that I leaned pretty heavily on asking Gemini questions to figure out how to use the Google OR-Tools library.
So here’s my Part 2 code:
import com.google.ortools.Loader import com.google.ortools.linearsolver.MPSolver import com.google.ortools.linearsolver.MPVariable import utils.* fun main() { val input = getInput(10) val machines = parseInput1(input) Loader.loadNativeLibraries() var total = 0 for (machine in machines) { val buttons = machine.buttons val joltages = machine.joltages val solver = MPSolver.createSolver("SCIP") ?: throw Exception("Could not create solver") val x = arrayOfNulls<MPVariable>(machine.buttons.size) for (i in buttons.indices) { x[i] = solver.makeIntVar(0.0, Double.POSITIVE_INFINITY, "x$i") } val target = joltages.map { it.toDouble() } val aMatrix = joltages.indices.map { joltageToArray(it, buttons) }.toTypedArray() for (j in joltages.indices) { val ct = solver.makeConstraint(target[j], target[j], "joltage_constraint_$j") for (i in buttons.indices) { ct.setCoefficient(x[i], aMatrix[j][i]) } } val objective = solver.objective() for (i in buttons.indices) { objective.setCoefficient(x[i], 1.0) } objective.setMinimization() val resultStatus = solver.solve() if (resultStatus == MPSolver.ResultStatus.OPTIMAL) { val result = objective.value().toInt() total += result } else { println("Problem could not be solved.") } } println(total) } data class Machine(val configuration: List<Boolean>, val buttons: List<List<Int>>, val joltages: List<Int>) fun parseInput1(input: String): List<Machine> { return input.lines() .filter { it.isNotBlank() } .map { val split = it.split(" ") val configuration = split.first().toCharArray() .slice(1..<split.first().length - 1) .map { char -> when (char) { '#' -> true else -> false } } val buttons = split.slice(1..<split.size - 1) .map { str -> str.slice(1..<str.length - 1) .split(",") .map { number -> number.toInt() } } val joltages = split.last() .slice(1..<split.last().length - 1) .split(",") .map { number -> number.toInt() } Machine(configuration, buttons, joltages) } } fun joltageToArray(joltageIndex: Int, buttons: List<List<Int>>): Array<Double> { val array = DoubleArray(buttons.size) { 0.0 }.toTypedArray() for (i in buttons.indices) { if (joltageIndex in buttons[i]) { array[i] = 1.0 } } return array }
chunkystyles@sopuli.xyzto
Advent Of Code@programming.dev•🧦 - 2025 DAY 11 SOLUTIONS - 🧦English
2·1 month agoKotlin
This was substantially easier than yesterday’s problem. Especially considering I still haven’t done Part 2 from yesterday.
Anyway, here is my Part 2 solution for today. Given how quickly Part 1 ran without a cache, I didn’t think Part 2 would be much different, until my computer fans spun up and stayed there for over a minute. So I added a cache and re-ran it and it ran in 31ms.
const val end = "out" var map: Map<String, List<String>>? = null val problemVertices = "dac" to "fft" val cache: MutableMap<Pair<String, Pair<Boolean, Boolean>>, Long> = mutableMapOf() fun main() { val input = getInput(11) map = parseInput1(input) val total = countPaths2("svr", false to false).first println(total) } fun countPaths2(vertex: String, problemVerticesEncountered: Pair<Boolean, Boolean>): Pair<Long, Pair<Boolean, Boolean>> { val otherVertices = map!![vertex]!! var total = 0L val nextProblemVerticesEncountered = (problemVerticesEncountered.first || vertex == problemVertices.first) to (problemVerticesEncountered.second || vertex == problemVertices.second) for (otherVertex in otherVertices) { val key = otherVertex to nextProblemVerticesEncountered if (cache.contains(key)) { total += cache[key]!! } else if (otherVertex == end) { if (nextProblemVerticesEncountered.first && nextProblemVerticesEncountered.second) { total++ } } else { total += countPaths2(otherVertex, nextProblemVerticesEncountered).first } } cache[vertex to nextProblemVerticesEncountered] = total return total to nextProblemVerticesEncountered } fun parseInput1(input: String): Map<String, List<String>> = input.lines() .filter { it.isNotBlank() } .associate { val split = it.split(": ") split[0] to split[1].split(" ").toList() }
chunkystyles@sopuli.xyzto
Advent Of Code@programming.dev•🎁 - 2025 DAY 9 SOLUTIONS - 🎁English
3·1 month agoKotlin
My solution can’t be very good because it took over a minute to run part 2. I used a ray casting algorithm to determine if a point was in the main polygon. I did that for the 2 corners of each rectangle that weren’t given as input. If both of those corners were in the polygon, then I checked each point of each edge of that rectangle.
My first stab at this didn’t consider the edge points of the rectangle, and after looking at some visualizations of the polygon, I could see where I was going wrong. I wouldn’t have considered a rectangle with all 4 corners in the polygon could have an edge that goes outside the polygon without looking at a visualization.
Part 2 code:
fun main() { val input = getInput(9) val polygon = parseInput1(input) val rectangles: MutableList<Rectangle> = mutableListOf() for (i in polygon.indices) { for (j in i + 1..<polygon.size) { rectangles.add(Rectangle(polygon[i], polygon[j])) } } rectangles.sortByDescending { it.area } var answer: Rectangle? = null for (rectangle in rectangles) { if (isInsidePolygon(rectangle.corner3, polygon) && isInsidePolygon(rectangle.corner4, polygon) ) { val edgePoints: MutableList<Pair<Long, Long>> = mutableListOf() edgePoints.addAll(getAllPointsBetween(rectangle.corner1, rectangle.corner3)) edgePoints.addAll(getAllPointsBetween(rectangle.corner1, rectangle.corner4)) edgePoints.addAll(getAllPointsBetween(rectangle.corner2, rectangle.corner3)) edgePoints.addAll(getAllPointsBetween(rectangle.corner2, rectangle.corner4)) var isInside = true for (edgePoint in edgePoints) { if (!isInsidePolygon(edgePoint, polygon)) { isInside = false break } } if (isInside) { answer = rectangle break } } } println(answer?.area ?: "Whoops") } fun parseInput1(input: String): List<Pair<Long, Long>> = input.lines() .filter { it.isNotBlank() } .map { val split = it.split(",") split[0].toLong() to split[1].toLong() } data class Rectangle(val corner1: Pair<Long, Long>, val corner2: Pair<Long, Long>) { val corner3: Pair<Long, Long> = corner1.first to corner2.second val corner4: Pair<Long, Long> = corner2.first to corner1.second val area: Long = (1 + abs(corner1.first - corner2.first)) * (1 + abs(corner1.second - corner2.second)) } fun isInsidePolygon(point: Pair<Long, Long>, polygon: List<Pair<Long, Long>>): Boolean { val x = point.first val y = point.second var intersectionCount = 0L for (i in polygon.indices) { val p1 = polygon[i] val p2 = polygon[(i + 1) % polygon.size] if (point == p1 || point == p2 || isOnEdge(point, p1, p2)) { return true } val y1 = p1.second val y2 = p2.second val crossesRay = (y in y1..<y2) || (y in y2..<y1) if (crossesRay) { val x1 = p1.first val x2 = p2.first val xIntersect = (x2 - x1) * (y - y1).toDouble() / (y2 - y1) + x1 if (x < xIntersect) { intersectionCount++ } } } return intersectionCount % 2L != 0L } fun isOnEdge(p: Pair<Long, Long>, p1: Pair<Long, Long>, p2: Pair<Long, Long>): Boolean { val crossProduct = (p.second - p1.second) * (p2.first - p1.first) - (p.first - p1.first) * (p2.second - p1.second) if (crossProduct != 0L) { return false } val isBetweenX = p.first in minOf(p1.first, p2.first)..maxOf(p1.first, p2.first) val isBetweenY = p.second in minOf(p1.second, p2.second)..maxOf(p1.second, p2.second) return isBetweenX && isBetweenY } fun getAllPointsBetween(left: Pair<Long, Long>, right: Pair<Long, Long>): List<Pair<Long, Long>> { if (right.first == left.first) { val max = maxOf(left.second, right.second) val min = minOf(left.second, right.second) return (min + 1..<max).toList().map { right.first to it } } else if (right.second == left.second) { val max = maxOf(left.first, right.first) val min = minOf(left.first, right.first) return (min + 1..<max).toList().map { it to right.second } } else { throw Exception("Whoops") } }
chunkystyles@sopuli.xyzto
Advent Of Code@programming.dev•🤶 - 2025 DAY 8 SOLUTIONS - 🤶English
2·1 month agoIt can be confusing, for sure. But I really like Pairs and Triples.
answer = distance.first.first.first * distance.first.second.firstis not very elegant, lol.
chunkystyles@sopuli.xyzto
Advent Of Code@programming.dev•🤶 - 2025 DAY 8 SOLUTIONS - 🤶English
2·1 month agoThat’s interesting. I found part 1 to be the hard part and part 2 was just simplifying part 1. They ran in about the same time for me, too.
Part 1 run time:
Input IO: 0m 0s 10ms Input Parse: 0m 0s 21ms Algorithm: 0m 0s 250ms Total: 0m 0s 281msPart 2 run time:
Input IO: 0m 0s 11ms Input Parse: 0m 0s 22ms Algorithm: 0m 0s 255ms Total: 0m 0s 288msCode:
const val connectionsLimit = 1000 const val circuitsLimit = 3 fun part1() { val input = getInput(8) val circuits: MutableList<MutableSet<Triple<Int, Int, Int>>> = parseInput1(input) val distances: MutableList<Pair<Pair<Triple<Int, Int, Int>, Triple<Int, Int, Int>>, Double>> = mutableListOf() val tempList = circuits.toList() for (i in tempList.indices) { val left = tempList[i].first() for (j in i + 1..<tempList.size) { val right = tempList[j].first() val distance = calculateDistance(left, right) val coordinates = left to right distances.add(coordinates to distance) } } distances.sortBy { it.second } // Parts 1 and 2 are the same until here for (i in 0..<connectionsLimit) { val distance = distances[i] val leftCircuit = circuits.first { it.contains(distance.first.first) } val rightCircuit = circuits.first { it.contains(distance.first.second) } if (leftCircuit != rightCircuit) { leftCircuit.addAll(rightCircuit) circuits.remove(rightCircuit) } } val sizes = circuits.map { it.size.toLong() }.sortedDescending().slice(0..<circuitsLimit) val total = sizes.reduce { acc, i -> acc * i } println(total) } fun part2() { val input = getInput(8) val circuits: MutableList<MutableSet<Triple<Int, Int, Int>>> = parseInput1(input) val distances: MutableList<Pair<Pair<Triple<Int, Int, Int>, Triple<Int, Int, Int>>, Double>> = mutableListOf() val tempList = circuits.toList() for (i in tempList.indices) { val left = tempList[i].first() for (j in i + 1..<tempList.size) { val right = tempList[j].first() val distance = calculateDistance(left, right) val coordinates = left to right distances.add(coordinates to distance) } } distances.sortBy { it.second } // Part 2 differs starting here var answer = 0 for (distance in distances) { val leftCircuit = circuits.first { it.contains(distance.first.first) } val rightCircuit = circuits.first { it.contains(distance.first.second) } if (leftCircuit != rightCircuit) { leftCircuit.addAll(rightCircuit) circuits.remove(rightCircuit) if (circuits.size == 1) { answer = distance.first.first.first * distance.first.second.first break } } } println(answer) } fun parseInput1(input: String): MutableList<MutableSet<Triple<Int, Int, Int>>> { return input.lines() .filter { it.isNotBlank() } .map { val split = it.split(",") mutableSetOf(Triple(split[0].toInt(), split[1].toInt(), split[2].toInt())) } .toMutableList() } fun calculateDistance(left: Triple<Int, Int, Int>, right: Triple<Int, Int, Int>): Double { val dx = (left.first - right.first).toDouble() val dy = (left.second - right.second).toDouble() val dz = (left.third - right.third).toDouble() val distanceSquared = dx.pow(2) + dy.pow(2) + dz.pow(2) return sqrt(distanceSquared) }
chunkystyles@sopuli.xyzto
Advent Of Code@programming.dev•👪 - 2025 DAY 7 SOLUTIONS - 👪English
2·1 month agoI 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 }
chunkystyles@sopuli.xyzto
Advent Of Code@programming.dev•💃 - 2025 DAY 6 SOLUTIONS - 💃English
2·1 month agoI also thought about trying to rotate, but not for very long. Mine would be a bit simpler if I’d done what you did and build the number string and then check if it’s blank.
fun main() { val input = getInput(6) val output = parseInput2(input) var total = 0L for ((numbers, operator) in output) { when (operator) { '+' -> { total += numbers.sum() } '*' -> { total += numbers.reduce { acc, number -> acc * number }} } } println(getElapsedTime()) println(total) } fun parseInput2(input: String): List<Pair<List<Long>, Char>> { val rows = input.lines() .filter { it.isNotBlank() } .map { it.toCharArray() } val output: MutableList<Pair<List<Long>, Char>> = mutableListOf() val numberRowCount = rows.size - 1 var isNewProblem = true var currentNumbers: MutableList<Long> = mutableListOf() var operator = ' ' for (column in rows[0].indices) { if (!isNewProblem && isColumnEmpty(rows, column)) { isNewProblem = true output.add(currentNumbers to operator) continue } if (isNewProblem) { isNewProblem = false currentNumbers = mutableListOf() operator = rows.last()[column] } var number = "" for (row in 0..<numberRowCount) { if (rows[row][column] != ' ') { number += rows[row][column] } } currentNumbers.add(number.toLong()) } if (!isNewProblem) { output.add(currentNumbers to operator) } return output } fun isColumnEmpty(rows: List<CharArray>, column: Int): Boolean { for (i in rows.indices) { if (rows[i][column] != ' ') { return false } } return true }
chunkystyles@sopuli.xyzto
Advent Of Code@programming.dev•🎄 - 2025 DAY 4 SOLUTIONS - 🎄English
2·1 month agoEdit: looking at your code, I had forgotten about
.indices. That would have made this a little easier to write.I completely forgot to do the puzzle yesterday somehow. I struggled a bit on this one for a while because I’d used a
<= 4where I should have used a< 4. Just a complete brainfart of thinking, “It needs to be 4 or less”. I wasted more time on that than I’d like to admit.My first stab at this set all of the adjacency counts to 0, and that lead to a few rolls that had no rolls adjacent to them staying on the map by accident.
const val toiletPaperRoll = '@' const val adjacentLimit = 4 var height = 0 var width = 0 fun main() { val input = getInput(4) val map = parseInput1(input) height = map.size width = map[0].size val adjacencyMap = createAdjacencyMap(map) var anyRemoved = true var count = 0 while (anyRemoved) { anyRemoved = false for (y in 0..<height) { for (x in 0..<width) { if (adjacencyMap[y][x] in 0..<adjacentLimit) { count++ anyRemoved = true removeToiletPaperRoll(adjacencyMap, x, y) } } } } println(count) } fun parseInput1(input: String): List<List<Char>> = input .lines() .filter { it.isNotBlank() } .map { it.toCharArray().toList() } fun createAdjacencyMap(map: List<List<Char>>): List<MutableList<Int>> { val adjacencyMap = List(height) { MutableList(width) { -1 } } for (y in 0..<height) { for (x in 0..<width) { if (map[y][x] != toiletPaperRoll) { continue } adjacencyMap[y][x]++ for (y2 in y - 1..y + 1) { for (x2 in x - 1..x + 1) { if (y == y2 && x == x2 || (y2 < 0 || x2 < 0 || y2 >= height || x2 >= width)) { continue } if (map[y2][x2] == toiletPaperRoll) { adjacencyMap[y2][x2]++ } } } } } return adjacencyMap } fun removeToiletPaperRoll(adjacencyMap: List<MutableList<Int>>, x: Int, y: Int) { adjacencyMap[y][x] = -1 for (y2 in y - 1..y + 1) { for (x2 in x - 1..x + 1) { if (y == y2 && x == x2 || (y2 < 0 || x2 < 0 || y2 >= height || x2 >= width)) { continue } if (adjacencyMap[y2][x2] >= adjacentLimit) { adjacencyMap[y2][x2]-- } } } }
chunkystyles@sopuli.xyzto
Advent Of Code@programming.dev•🎄 - 2025 DAY 5 SOLUTIONS - 🎄English
1·1 month agoIt’s amusing just how similar our solutions are today. The only real issue I had today was not considering both sides of each range and only taking the last part of the range in the sort order.
var ingredientRanges: MutableList<LongRange> = mutableListOf() var ingredients: MutableList<Long> = mutableListOf() fun main() { val input = getInput(5) parseInput1(input) var count = 0L ingredientRanges.sortBy { it.first } var i = 0 while (i < ingredientRanges.size) { var j = i + 1 while (j < ingredientRanges.size && doRangesOverlap(ingredientRanges[i], ingredientRanges[j])) { ingredientRanges[i] = LongRange(ingredientRanges[i].first, max(ingredientRanges[i].last, ingredientRanges[j].last)) j++ } count += ingredientRanges[i].last - ingredientRanges[i].first + 1 i = j } println(count) } fun parseInput1(input: String) { val split = input.split("\n\n") split[0].lines() .filter { it.isNotBlank() } .forEach { val range = it.split("-") ingredientRanges.add(LongRange(range[0].toLong(), range[1].toLong())) } split[1].lines() .filter { it.isNotBlank() } .forEach { ingredients.add(it.toLong()) } } fun doRangesOverlap(left: LongRange, right: LongRange): Boolean = right.first in left || right.first - 1 == left.last
chunkystyles@sopuli.xyzto
Advent Of Code@programming.dev•💃 - 2025 DAY 3 SOLUTIONS - 💃English
21·1 month agoI was curious, so I ran yours and it is only like 3-4ms slower. I was honestly surprised it was that close.
Just goes to show that we’re often wrong when estimating and the only real way to know is to benchmark.
chunkystyles@sopuli.xyzto
Advent Of Code@programming.dev•💃 - 2025 DAY 3 SOLUTIONS - 💃English
2·1 month agoToday was interesting. My first thought was that part 2 would be a lot more complex at first glance. But I realized that my solution for part 1 worked almost out of the box for part 2.
I was also pleased to see that the algorithm ran in 1ms, which was a good deal faster than just parsing the input.
fun main() { val input = getInput(3) val banks = parseInput(input) var total = 0L banks.forEach { bank -> var location = 0 var joltage = 0L for (power in 11 downTo 0) { val multiplier = 10.toDouble().pow(power).toLong() val batteryLocation = findBattery(bank, location, bank.size - power - 1) val battery = bank[batteryLocation] location = batteryLocation + 1 joltage += battery.toLong() * multiplier } total += joltage } println(total) } fun parseInput(input: String): List<List<Int>> = input .split("\n") .filter { it.isNotBlank() } .map { it.toCharArray() } .map { it.map { digit -> digit.digitToInt() } } fun findBattery(bank: List<Int>, start: Int, end: Int): Int { var max = 0 var location = 0 for (i in start..end) { val battery = bank[i] if (battery > max) { max = battery location = i if (battery == 9) { break } } } return location }
chunkystyles@sopuli.xyzto
Advent Of Code@programming.dev•🧑 - 2025 DAY 2 SOLUTIONS - 🧑English
2·1 month agoMy part 2 Kotlin solution:
val factors = intArrayOf(2, 3, 5, 7) fun main() { var total = 0L val input = getInput(2) val ranges = parseInput1(input) ranges.forEach { val start = it.first.toLong() val end = it.second.toLong() for (id in start..end) { val idString = id.toString() if (isIdInvalid2(idString)) { total += id } } } println(total) } fun parseInput1(input: String): List<Pair<String, String>> { return input.split(",") .filter { it.isNotBlank() } .map { val secondSplit = it.split("-") secondSplit.first().trim() to secondSplit.last().trim() } } fun isIdInvalid2(id: String): Boolean { for (factor in factors) { if (id.length % factor == 0) { val gap = id.length / factor var areAllMatching = true for (i in 0..<gap) { val end = (factor - 1) * gap + i if (!areCharactersTheSame(id, gap, i, end)) { areAllMatching = false break } } if (areAllMatching) { return true } } } return false } fun areCharactersTheSame(string: String, gap: Int, start: Int, end: Int): Boolean { val character = string[start] for (i in start + gap..end step gap) { if (character != string[i]) { return false } } return true }I didn’t look closely enough at the input to know how big an entire list of IDs would be huge or not. But I assumed it was. So instead I just did ranges as Pairs.
I also only considered the prime factors up to 7, because there weren’t any IDs that needed any higher.
Edit: I also worried that a brute force solution might be slow, but being day 2, I might have been a little too worried about that. The main algorithm ran in 68ms.
chunkystyles@sopuli.xyzto
Advent Of Code@programming.dev•🔒 - 2025 DAY 1 SOLUTIONS -🔒English
1·1 month agoHere’s my Kotlin version for Part 2.
fun main() { var currentDialPosition = 50 var password = 0 val input = getInput(1) val turns = parseInput2(input) turns.forEach { if (it.second > 0) { password += it.second } var newDialPosition = currentDialPosition + it.first if (newDialPosition < 0) { newDialPosition += 100 if (currentDialPosition != 0) { password++ } } else if (newDialPosition > 99) { newDialPosition %= 100 password++ } else if (newDialPosition == 0) { password++ } currentDialPosition = newDialPosition } println(password) } fun parseInput2(input: String): List<Pair<Int, Int>> = input .split("\n") .filter { it.isNotBlank() } .map { val direction = it.first() val number = it.slice(1..<it.length).toInt() val clicks = number % 100 val fullTurns = number / 100 if (direction == 'L') { clicks * -1 to fullTurns } else { clicks to fullTurns } }
chunkystyles@sopuli.xyzto
Programmer Humor@programming.dev•What are some of the worst code you have seen in a production environment?English
4·2 months agoI hate vibe coding. However, this is the best use of it. I’ve done it several times for scripts and basic HTML dashboards.
chunkystyles@sopuli.xyzto
Programmer Humor@programming.dev•What are some of the worst code you have seen in a production environment?English
2·2 months agoUnless I’m missing something, this is a pretty bog standard SQL injection, yeah?
chunkystyles@sopuli.xyzto
Programmer Humor@programming.dev•What are some of the worst code you have seen in a production environment?English
1·2 months agoJavaScript might be more widely appliable. Java is good to learn, too. If you learn Java, you can also learn Kotlin which is a glorious language to work with.

AntiX is nothing like Omarchy from my quick look at it. It’s Debian vs Arch (btw) and systemd-free.