

I really wish the community would use a different word. It’s bad at communicating its meaning just to start.


I really wish the community would use a different word. It’s bad at communicating its meaning just to start.


Most of the people I gifted it to never really got into it like I did.


Genuinely not trying to one up you. But I was so excited for the game I played the leaked alpha before it released.
I used to buy 4 packs of the game to give away.


As sharp as a bowling ball.


On the one hand, this is very funny. On the other hand, however, it’s still very funny, but also maybe we shouldn’t turn running full speed into a house of religion, no matter how hokey that religion may be, into a trend? Yes, the whole enterprise is shady at best, and they believe in some weird space alien magic. They also have a history of harassing former members and anyone who dares to pull back the veil on the secretive organization’s scare tactics.
Fuck off with this whitewashing. Scientology isn’t “hokey” or “shady”. It’s outright evil.


I’m thinking about finding an alternative to ntfy. The maintainers are increasingly vibe coding it.


There’s also an image for Copyparty if you’re already hosting stuff as containers. It’s super handy.


This is very different from my experience, but I’ve purposely lagged behind in adoption and I often do things the slow way because I like programming and I don’t want to get too lazy and dependent.
I just recently started using Claude Code CLI. With how I use it: asking it specific questions and often telling it exactly what files and lines to analyze, it feels more like taking to an extremely knowledgeable programmer who has very narrow context and often makes short-sighted decisions.
I find it super helpful in troubleshooting. But it also feels like a trap, because I can feel it gaining my trust and I know better than to trust it.


No, what I’m looking for is an example of a project in Voiden that is mature. As-in, a project that a team has been collaborating on for a while.
So how does a team structure their project in Voiden efficiently.


I installed it yesterday, and the biggest issue I’m having is envisioning what a mature project would look like in it. I have not gone looking for examples like that, but if you know of any, i’d love to see some.


I would use Debian for servers, except that the version of Podman (at least on Debian 12) was old enough that it couldn’t do quadlets. So I went with Fedora.
I pushed my team to use trunk based development. We did cherry-picks from trunk to release branches for a couple years with no issues. Since then, I’ve written a GitHub action that automates the cherry-picks based on tickets in the commit messages.
But even before the automation, it drastically improved our dev processes.
We weren’t on Git Flow exactly, but it was a bastardized version of it.
Having used TBD successfully for like 5-6 years now. I can’t imagine using Git Flow.


My wife and I yelled at the same time when that ad played. Insanely dystopian.
AntiX is nothing like Omarchy from my quick look at it. It’s Debian vs Arch (btw) and systemd-free.
It was 12 days and the first time I’ve ever finished it.


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
}


I 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.


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
}


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()
}
I can confirm the dev is great. I had two feature requests and they did a great job communicating and then implementing those requests.