Day 19 of Advent of Code is here! This one was tough. I got my code working against the example, but when that was taking over 10 mins to complete with my data, I decided to go searching for someone else’s example.
I found this example that I copied, thank you eQueline! This is really impressive as it uses regex and it’s remarkably fast. I started thinking down this road, but found it too complex to do, but happy this person was more capable than me ;)
See all of my other solutions here. If you’re interested, check out what my colleagues at Slalom are doing with their Advent of Code! You can see this and my other solutions on github.
Day 19: Monster Messages
Part I & II
The code I copied does both parts 1 and 2 in the same script, and it’s super fast. But first, here’s our data:

And the code!
//ref https://github.com/eQueline/Advent-of-Code-2020/blob/main/AoC%2019.js
const fs = require('fs');
console.log('Start');
let testInput = fs.readFileSync('./input.txt', 'utf-8').trim()
var input = testInput.split('\n\n').map(a => a.split('\n'));
var messages = input[1];
var rules = [];
input[0].forEach(a=>rules[a.split(': ')[0]] = a.split(': ')[1]);
rules = rules.map(a=>a.replace(/"/g,''));
function expandAll(str) {
while (str.match(/\d/)) {
let expList = (str.match(/(?<!\d)\d+(?!\d)/g) || []);
expList = expList.filter((a,i,ar)=>ar.findIndex(b=>b==a)==i);
expList.forEach((exp)=>{
str = str.replace(new RegExp(`(?<!\\d)${exp}(?!\\d)`, 'g'), (rules[exp].includes('|')?(`(${rules[exp]})`):rules[exp]));
});
}
return str.replace(/\s/g, '');
}
// 0: 8 11
// 8: 42
// 11: 42 31
// 0:= 42{2} 31
var rule42 = expandAll('42');
console.log('Expanded 42');
var rule31 = expandAll('31');
console.log('Expanded 31');
var loopRule = new RegExp(`^${rule42}{2}${rule31}$`);
console.log(`Answer 1: ${messages.filter(a=>loopRule.test(a)).length}`);
// 0: 8 11
// 8: 42 | 42 8
// 11: 42 31 | 42 11 31
// 0:= 42+ 42{i} 31{i}
var valid = [];
for (let i=1; i<5; i++) {
loopRule = new RegExp(`^${rule42}+${rule42}{${i}}${rule31}{${i}}$`);
valid.push(...messages.filter(a=>!valid.includes(a)&&loopRule.test(a)));
}
console.log(`Answer 2: ${valid.length}`);
So good!
How did it go for you?
Did you find the answer on your own? How did you do it? Anything stump you? I’d love to hear how you did! Please comment below! I have also loaded up just the challenge and code from this and my other days on github, you can follow along there too: pretty Git pages or the code in the repo.