

This is what I do - well, I back up there entire container. But functionally the same.
There’s only a few pieces of media that I have backed up manually due to their rarity, but even those I don’t really care about.
Nice. Software developer, gamer, occasionally 3d printing, coffee lover.


This is what I do - well, I back up there entire container. But functionally the same.
There’s only a few pieces of media that I have backed up manually due to their rarity, but even those I don’t really care about.


I generally like trying the brute force approach first (though in the latter days it just wastes time). After exhausting 32GB of RAM I changed approaches.
Admittedly I don’t really understand these algorithms as well as I would like, and I also will admit I inadvertently was LLM assisted :(. When I was trying to figure out what algo I should use and the AI summary in Google’s search spoiled me. But I did learn alot.
One interesting observation, unrelated to the solution itself, is the solutions runs about 30% faster in Firefox than it does via Node (25.2.1 and 24.11.1) on my machine.
const input = require('fs').readFileSync('input-day9.txt', 'utf-8');
/** @type {Array<[number, number]} */
const points = input.split("\n").map(r => r.split(',').map(v => parseInt(v, 10)));
let largest = 0;
let largestInside = 0;
for (const [startX, startY] of points) {
for (const [nextX, nextY] of points) {
if (startX === nextX && startY === nextY) continue;
const minX = Math.min(startX, nextX);
const maxX = Math.max(startX, nextX);
const minY = Math.min(startY, nextY);
const maxY = Math.max(startY, nextY);
const area = (maxX - minX + 1) * (maxY - minY + 1);
if (area > largest) {
largest = area;
}
if (area <= largestInside) continue;
// center point check, ala https://en.wikipedia.org/wiki/Even%E2%80%93odd_rule
const centerX = (minX + maxX) / 2;
const centerY = (minY + maxY) / 2;
let inside = false;
for (const [i, [aX, aY]] of points.entries()) {
const [bX, bY] = points[i - 1] ?? points[points.length - 1];
if (centerX === aX && centerY === aY) {
inside = true;
break;
}
if ((aY > centerY) !== (bY > centerY)) {
const slope = (centerX - aX) * (bY - aY) - (bX - aX) * (centerY - aY);
if (slope === 0) {
inside = true;
break;
}
if ((slope < 0) !== (bY < aY)) {
inside = !inside;
}
}
}
if (!inside) continue;
// check for edge intersections, ala https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection
let intersects = false;
for (const [i, [aX, aY]] of points.entries()) {
const [bX, bY] = points[i - 1] ?? points[points.length - 1];
if (aX === bX) {
if (aX > minX && aX < maxX) {
const wallMinY = Math.min(aY, bY);
const wallMaxY = Math.max(aY, bY);
if (Math.max(minY, wallMinY) < Math.min(maxY, wallMaxY)) {
intersects = true;
break;
}
}
} else if (aY === bY) {
if (aY > minY && aY < maxY) {
const wallMinX = Math.min(aX, bX);
const wallMaxX = Math.max(aX, bX);
if (Math.max(minX, wallMinX) < Math.min(maxX, wallMaxX)) {
intersects = true;
break;
}
}
}
}
if (intersects) continue;
if (area > largestInside) {
largestInside = area;
}
}
}
console.log(`Part 1 Answer: ${largest}`);
console.log(`Part 2 Answer: ${largestInside}`);


Cookie consent dialogs can fuck off and die in general. Always using dark patterns to try and trick you into choosing the worst option.


Short and sweet. Basically just handle all the range overlaps for part 2 and then do basic subtraction to get the answer.
const input = require('fs').readFileSync('input-day5.txt', 'utf-8');
/** @typedef {[number, number]} Range */
/** @type {[Range[], number[]]} */
const [freshRanges, availableIngredients] = input.split("\n\n").map(l => l.split("\n")).map((l, i) => (i === 1) ? l.map(v => parseInt(v, 10)) : l.map(v => v.split('-').map(vv => parseInt(vv, 10))));
let freshOnHand = 0;
for (const ingredient of availableIngredients) {
for (const [start, stop] of freshRanges) {
if (ingredient >= start && ingredient <= stop) {
freshOnHand += 1;
break;
}
}
}
console.log(`Part 1 Answer: ${freshOnHand}`);
const sortedRanges = [...freshRanges].sort((a, b) => a[0] - b[0]);
const mergedRanges = [];
let current = sortedRanges[0];
for (let i = 1; i < sortedRanges.length; i++) {
const [nextStart, nextEnd] = sortedRanges[i];
if (nextStart <= current[1] + 1) {
current = [current[0], Math.max(current[1], nextEnd)];
} else {
mergedRanges.push(current);
current = [nextStart, nextEnd];
}
}
mergedRanges.push(current);
const freshIngredientCount = mergedRanges.reduce((acc, [start, stop]) => acc + ((stop + 1) - start), 0)
console.log(`Part 2 Answer: ${freshIngredientCount}`);
Saved this. My doggo is nearly 15 and whole he’s still healthy I am much too afraid of losing him. I suspect I’ll need a reminder like this in the future.


After smashing out a functional version in 20 minutes, I converted it into a OOP approach for a more appealing solution.
const input = require('fs').readFileSync('input-day4.txt', 'utf-8');
class PrintingDepartmentMap {
/** @param {string} input */
constructor(input) {
/** @type {number[][]} */
this.map = input.split("\n").map(r => r.split('').map(v => v === '@' ? 1 : 0));
}
/**
* @param {number} x
* @param {number} y
* @returns {number} the value of that tile, or -1 if invalid
*/
getCoord(x, y) {
if (x < 0 || y < 0 || x >= this.map[0].length || y >= this.map.length) {
return -1;
}
return this.map[y][x];
}
/**
* @param {number} x
* @param {number} y
* @returns {number} the number of adjacent tiles that are >= 1
*/
countAdjacent(x, y) {
return [
// top-left
this.getCoord(x - 1, y - 1) >= 1,
// top
this.getCoord(x, y - 1) >= 1,
// top-right
this.getCoord(x + 1, y - 1) >= 1,
// right
this.getCoord(x + 1, y) >= 1,
// bottom-right
this.getCoord(x + 1, y + 1) >= 1,
// bottom
this.getCoord(x, y + 1) >= 1,
// bottom-left
this.getCoord(x - 1, y + 1) >= 1,
// left
this.getCoord(x - 1, y) >= 1
].reduce((acc, v) => !!v ? acc + 1 : acc, 0);
}
/**
* transform in place the map replacing any rolls (1) with (2) if they are accessible
* @returns {PrintingDepartmentMap}
*/
markAccessable() {
for (let y = 0; y < this.map.length; y += 1) {
for (let x = 0; x < this.map[0].length; x += 1) {
if (this.map[y][x] < 1) continue;
if (this.countAdjacent(x, y) < 4) {
this.map[y][x] = 2;
}
}
}
return this;
}
/** @returns {number} the number of removed rolls */
removeAccessable() {
let removed = 0;
for (let y = 0; y < this.map.length; y += 1) {
for (let x = 0; x < this.map[0].length; x += 1) {
if (this.map[y][x] === 2) {
removed += 1;
this.map[y][x] = 0;
}
}
}
return removed;
}
}
const map = new PrintingDepartmentMap(input);
let removed = 0;
while (true) {
const justRemoved = map.markAccessable().removeAccessable();
if (removed === 0) {
console.log(`Part 1 Answer: ${justRemoved}`);
}
if (justRemoved === 0) break;
removed += justRemoved;
}
console.log(`Part 2 Answer: ${removed}`);


Sure, which makes the transition suck even lol.


:(
Time to switch to yarn or something.


More bruteforcing! There are probably better ways to do this but I’m happy enough with this lol.
You can replace the require(‘fs’) on the first line with the input and run it in your browser console as well.
const input = require('fs').readFileSync('input-day2.txt', 'utf-8');
let idsPart1 = [];
let idsPart2 = [];
input.split(',').forEach(range => {
const [start, end] = range.split('-').map(v => parseInt(v, 10));
let cursor = start;
while (cursor <= end) {
const cursorString = cursor.toString(10);
// part 1 check
let halfLength = Math.floor(cursorString.length / 2);
let left = cursorString.slice(0, halfLength);
let right = cursorString.slice(halfLength, cursorString.length);
if (left === right) {
idsPart1.push(cursor);
}
// part 2 check
let sequenceLength = 1;
while (sequenceLength <= halfLength) {
const sequence = cursorString.slice(0, sequenceLength);
let builtString = sequence;
while (builtString.length < cursorString.length) {
builtString = `${builtString}${sequence}`;
}
if (builtString === cursorString) {
idsPart2.push(cursor);
break;
}
sequenceLength += 1;
}
cursor += 1;
}
})
const answer1 = idsPart1.flat().reduce((acc, cur) => acc += cur, 0);
const answer2 = idsPart2.flat().reduce((acc, cur) => acc += cur, 0);
console.log(`Part 1 Answer: ${answer1}`);
console.log(`Part 2 Answer: ${answer2}`);


A straightforward day 1 for a Javascript / NodeJS solution.
let position = 50;
let answer1 = 0;
let answer2 = 0;
const sequence = require('fs').readFileSync('input-day1.txt', 'utf-8');
sequence.split('\n').forEach(instruction => {
const turn = instruction.charAt(0);
let distance = parseInt(instruction.slice(1), 10);
while (distance > 0) {
distance -= 1;
if (turn === 'L') {
position -= 1;
} else if (turn === 'R') {
position += 1;
}
if (position >= 100) {
position -= 100;
} else if (position < 0) {
position += 100;
}
if (position === 0) {
answer2 += 1;
}
}
if (position === 0) {
answer1 += 1;
}
});
console.log(`Part 1 Answer: ${answer1}`);
console.log(`Part 2 Answer: ${answer2}`);


Does not appear to be the correct MR. Comments on the issue allude to “they never pushed it” so sounds like there never was an MR. Watching the announcement where they demo’d it, it wrote much more than is in that MR. Not to defend OpenAI, I hate vibe coded solutions that add so many useless comments.
Write. Readable. Code.


Just block them and move on.


Your connection being fine during downtime is a new detail not in your original post that changes the dynamics. That being said I believe my other response should be helpful.


Well, it can’t hurt to cross it off. You don’t need to get a domain from a registrar that offers dynamic DNS, you just need to register a domain (or try another dynamic DNS like the other user suggested) and use a DNS provider that is free and offers an API. I personally use Cloudflare, there are plenty of guides for setting up a dynamic record on CF.
For registering a domain you can use an affordable registrar, I’m a Porkbun customer - for a .com domain it’s like $11 for a year. No need to spend monthly.


Ha, if he said duckDNS I was going to recommend something more reliable like freedns.afraid.org.
That being said, the description in his post doesn’t make it seem that way.


Let’s back up some - a free dynDNS provider would not cause connection issues, unless DNS resolution itself stopped working - which is unlikely. It sounds more like the Internet you’re running off of itself has issues. What in particular is making you blame the dynDNS? Who is it?


I’m unsure, but I’m an avid user of Mihon (formerly Tachiyomi). Basically God’s gift to Android. Would recommend giving it a look!
Even back then caddy was being talked about. I don’t use caddy because, at least back then, it was only free for non commercial use (unless you compile it yourself).
I’ve been using Traefik for even longer though and haven’t ran into any major issues. Definitely recommend it.


Pretty much my experience, though I didn’t want to give the guy I was replying to any personal anecdotes lol.
I used to run a public link shortener. Once the scammers catch wind and add it to their rotation all bets are off. I got inundated with reports and my standing with my web host would have been at risk as well (long story). I now use Shlink on those domains lol.