AnnouncementsMatrixEventsFunnyVideosMusicAncapsTechnologyEconomicsPrivacyGIFSCringeAnarchyFilmPicsThemesIdeas4MatrixAskMatrixHelpTop Subs
3

We did this last year. But this year I guess we are already behind. If you don't know what Advent of Code is, it is a series of coding challenges with a new one every day. It would typically run starting on the first until the 25th. But this year they are only going to the twelth.

https://adventofcode.com/

I'm not always sure how to format these. I may just wing it. Folks can share their solutions in code blocks here or give a link to a repo if they would like. Advent of code starts off pretty easy and then ramps up to some genuinely hard problems. So I would encourage people to try the first few even if you are a beginner. You can even pipe it into AI if that is your current level.

Also each day comes in two parts. The second part is usually harder than the first. Because I am starting behind anyone is welcome to start a thread if you are ahead of me.

Comment preview

[-]x0x70(0|0)

Here is my solution to part one:

#!/usr/bin/env node

var fs = require('fs');

module.exports.lineToInt=lineToInt;
function lineToInt(line) {
 var prefix = line.slice(0,1);
 var magnitude = parseInt(line.slice(1));
 if(prefix==='R') return magnitude; 
 if(prefix==='L') return -magnitude;
 throw new Error('Improper prefix');
}

module.exports.readlinesSync=readlinesSync;
function readlinesSync(path) {
 return fs.readFileSync(path,'utf8').split('\n').filter(i=>i);
}

module.exports.circleMod=circleMod;
function circleMod(a,base=100) {
 if(a<0) return base-circleMod(-a,base);
 return a%base;
}


function main() {
 var path = process.argv[2]||'input.txt';
 var inputs = readlinesSync(path);
     //inputs = inputs.map(lineToInt);
 var start = 50;
 var pointer = start;
 var zerocount = 0;
 for(var input of inputs) {
  var numInput = circleMod(lineToInt(input));
  pointer=circleMod(pointer+numInput);
  console.log({input,numInput,pointer});
  if(pointer===0) ++zerocount;
 }
 console.log('Password:',zerocount);
}

if(!module.parent) main();

I've yet to figure it out but for some reason applying circleMod to the input in addition to pointer changed the output. In theory if the circleMod is working correctly it shouldn't make a difference. But this is the nature of advent of code. Get the solution and move on. I'm working on part 2 now.

[-]x0x70(0|0)

Here is my code for part two. The big change was counting every time the dial crosses zero. I like doing things in functional ways even if I'm in a procedural language. This is why I did an extra step of input reduction at the start. Progressive mapping to equivalent more simple states is the heart of how to solve things with functional esoterics. I did fail at my first attempt at part two. The key thing was making a move function that allows isolating code that needs to consider edge cases away from a for loop. Loops should be tight with minimal logic in them. This function also manages a state update to the pointer. It has a dial position as an argument and also treats it as part of a multi-part return value. This is also a classically functional way to do things. It's also close to how it would be done in Elixir in case I feel like translating it.

#!/usr/bin/env node

var fs = require('fs');

module.exports.lineToInt = lineToInt;
function lineToInt(line) {
 var prefix = line.slice(0, 1);
 var magnitude = parseInt(line.slice(1));
 if(prefix === 'R') return magnitude;
 if(prefix === 'L') return -magnitude;
 throw new Error('Improper prefix');
}

module.exports.readlinesSync = readlinesSync;
function readlinesSync(path) {
 return fs.readFileSync(path, 'utf8').split('\n').filter(i => i);
}

module.exports.move = move;
function move(pointer, movement) {
 var base = 100;
 var newPointer = (pointer + movement) % base;
 if(newPointer < 0) newPointer += base;
 var crossCount = 0;
 if(movement > 0) {
  crossCount = Math.floor((pointer + movement) / base) - Math.floor(pointer / base);
 } else if(movement < 0) {
  crossCount = Math.floor((pointer - 1) / base) - Math.floor((pointer + movement - 1) / base);
 }
 return [newPointer, crossCount];
}

function sameSign(a, b) {
 return (a > 0 && b > 0) || (a < 0 && b < 0);
}

module.exports.combineMoves = combineMoves;
function combineMoves(moves) {
 if(moves.length === 0) return [];
 var out = [];
 var prev = moves[0];
 for(var i = 1; i < moves.length; ++i) {
  if(sameSign(prev, moves[i])) prev += moves[i];
  else {
   out.push(prev);
   prev = moves[i];
  }
 }
 out.push(prev);
 return out;
}

function main() {
 var path = process.argv[2] || 'input.txt';
 var inputs = readlinesSync(path);
 var movements = inputs.map(lineToInt);
 var reducedMovements = combineMoves(movements);

 var start = 50;
 var pointer = start;
 var zerocount = 0;

 for(var movement of reducedMovements) {
  var [newPointer, crosses] = move(pointer, movement);
  console.log({ movement, pointer, newPointer, crosses });
  pointer = newPointer;
  zerocount += crosses;
 }
 console.log('Password:', zerocount);
}

if(!module.parent) main();