prepping for my #adventofcode2024 experience already by doing #adventofcode2015 and on
I'm committing to getting it DONE done this year.

day 3-1 of AOC2015 is literally going to send me to planes undiscovered

this feels like i should not be this weird, im likely overengineering it, will update
#adventofcode #adventofcode2015 #adventofcode2015day3 #aoc2015

#AdventOfCode #AoC

I completed #Day14 of #AdventOfCode2015, just for the fun of it.

Part 1:
- Difficulty: 2/10
- Workout: 3/10

Part 2:
- Difficulty: 2/10
- Workout: 2/10

About 1.5 hour of work. Not bad for a easy-ish problem.

Almost trivial parsing, with regex. Instead of simulating all reindeers at once, I simulated each one separately, collecting distances, for each second, into a list. The reindeers' lists were extended beyond the maximum time required; then, part 1 was just taking the max of the lists at the maximum time.

Given the lists, part 2 was straightforward: make the reindeers' lists parallel, and mark 1 point to the leaders at each second.

Unit testing for the win!

#AdventOfCode #AoC

I completed #Day13 of #AdventOfCode2015, just for the fun of it.

Part 1:
- Difficulty: 3/10
- Workout: 3/10

Part 2:
- Difficulty: 1/10
- Workout: 1/10

About 3.5 hours of work, spread over two days.

I enjoyed doing this one. I got to implement my own permutation function (no ordering of permutations, sorry), and added several new functions to my bag of utilities.

The "Aha!" of this one was arranging an adequate data structure. Let A, B, C, D, ..., X be people, *in this order*, and V(A, B) the happiness of A being near B; V(B, A) != V(A, B), in general. Then, arrange this list:

A - V(A, B) - V(B, A) -
B - V(B, C) - V(C, B) -
C - V(C, D) - ... -
X - V(X, A) - V(A, X)

And close it back to A. Note that it has 3k elements, where k is the number of people, and people are in positions of index % 3 == 0. Shift the indexes by 1, and you get

V(A, X) - A - V(A, B) -
V(B, A) - B - V(B, C) -
V(C, B) - C - V(C, D) -
... - X - V(X, A) -

Making the sum of happiness of each person a simple index fiddling.

Brute forcing part 2 worked: the 9! = 362880 permutations ran in about 30 seconds in my mobile phone.

In both test data and real data, adding an indifferent person lowered the total happiness. Is it a lesson for real life?

#AdventOfCode #AoC

I completed #Day12 of #AdventOfCode2015, just for the fun of it.

Part 1:
- Difficulty: 1/10
- Workout: 2/10

Part 2:
- Difficulty: 1/10
- Workout: 1/10

Done in less than 1 hour. The hardest part of this one should be parsing JSON, which I have for free with JSON.parse().

The solution is a recursive function, for a recursive data structure. Unit tests were very needed. Part 2 is just a sneaky conditional clause, for when the argument is an object.

Here is the relevant code.

const U = require("../lib/util.js");

const has_red = function(obj) {
let b = false;
for (let prop in obj) {
if (Object.hasOwn(obj, prop)) {
b = b || (obj[prop] === "red");
}
}
return b;
}

const sum_numbers = function(
obj, is_part2 = false) {

let result = 0;

if (obj === Number(obj)) {
result = obj;

} else if (Array.isArray(obj)) {
result = U.sum(obj.map(
(e) => sum_numbers(e, is_part2)));

} else if (obj === (new Object(obj))) {
if (is_part2 && has_red(obj)) {
result = 0;

} else {
let sum = 0;
for (let prop in obj) {
if (Object.hasOwn(obj, prop)) {
sum += sum_numbers(
obj[prop], is_part2);
}
}
result = sum;
}

} else {
result = 0;
}

return result;
}

#AdventOfCode #AoC

I completed #Day11 of #AdventOfCode2015, just for the fun of it.

Part 1:
- Difficulty: 2/10
- Workout: 3/10

Part 2:
- Difficulty: 0/10
- Workout: 1/10

Another easy one, took me just over 1 hour to solve. I think that the puzzles' author was testing the waters in the first year; more complicated puzzles would come in later years.

Advancing to the next possible password (ignoring rules) is a fiddling mess of number/char manipulation, mapping from a..z to 0..p, taking as base 26 numbers, adding 1, and mapping back. Unit tests for the win!

The big hint for skipping i, l, o was taken: jump from xxxi*** to xxxjaaa, for instance. Just string manipulation.

#AdventOfCode #AoC

I completed #Day10 of #AdventOfCode2015, just for the fun of it.

Part 1:
- Difficulty: 2/10
- Workout: 1/10

Part 2:
- Difficulty: 0/10
- Workout: 0/10

Another easy problem. The only challenging detail was to find a regex to match repeated chars, *and* getting which one, at the start of a string. Here's the entire function, in JavaScript:

const look_say = function(s) {
let look = ""+s; // Copy
let say = "";
const re = /^(.)(\1*)/;
while (look !== "") {
let m = re.exec(look);
let count = m[1].length;
if (m[2] !== undefined) {
count += m[2].length;
}
let char = m[1];
let t = String(count) + char;
say += t;
look = look.replace(re, "");
}
return say;
}

Plus some unit tests for guaranteeing correct behavior. The function could stand some refactoring and golfing, but it's good as-is.

Given that, part 1 was applying the function 40 times, and part 2 50 times. I think that, in the last iterations, the computer came close to hanging - running along a 2 MB string, with regexes, must waste much memory.

#AdventOfCode #AoC

I completed #Day09 of #AdventOfCode2015, just for the fun of it.

Part 1:
- Difficulty: 2/10
- Workout: 3/10

Part 2:
- Difficulty: 0/10
- Workout: 0/10

At first, I thought that the problem would require graph traversing for the shortest path; not so. Checking on people's AoC archives from 2015, I found that part 2 is trivial from part 1 (change min to max). So, for 7 cities, no graph needed; brute force is enough to generate all 7! = 5040 paths, then calculate their lengths.

The workout in part 1 is due to me finding, and trying to implement, Dijkstra's algorithm, and writing a permutation function (to my surprise, i wrote it almost from memory, and it works!)

#AdventOfCode #AoC

I completed #Day08 of #AdventOfCode2015, just for the fun of it.

Part 1:
- Difficulty: 2/10
- Workout: 1/10

Part 2:
- Difficulty: 1/10
- Workout: 0/10

Bloody, tricky, quotes! :-P
Just kidding: easy one, done in just 1 hour.

The hardest part was quoting both searches, regexes and substitutions on strings, while the terms were quoted themselves. I have a lot of experience with that, from when I generate code by metaprogramming. The order of substitutions do matter.

The program itself was easy: for each line, do replaces, and compare lengths.

#AdventOfCode #AoC

I completed #Day07 of #AdventOfCode2015, just for the fun of it.

Part 1:
- Difficulty: 3/10
- Workout: 5/10

Part 2:
- Difficulty: 1/10
- Workout: 2/10

I've done it in upwards of 6 hours, spread at 2 or 3 different days. It's a direct simulation: create all the wires (entries in a Map), map each line to an logic operation (with arguments validation), then run the operations. Each operation, when called, only runs if all arguments are available (not null).

The operation loop is a double one. While there are "not done" operations, loop executing them, marking each as done/not done. Eventually, all operations will be done.

The harder part was rewriting the class/function structure for operations (from full-featured class to collection of static methods) and for wires (Map of classes, to Map from String to number). KISS. Could be refactored further for size, but I'm shot of it.