Skip to content

Instantly share code, notes, and snippets.

@qubyte
Last active December 4, 2017 22:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save qubyte/fdfd5d78b1a03065714d59e1fa7dbc7d to your computer and use it in GitHub Desktop.
Save qubyte/fdfd5d78b1a03065714d59e1fa7dbc7d to your computer and use it in GitHub Desktop.
// Usage: node advent-of-code-2017-d04p2-boring.js /path/to/input.txt
// This boring version works by lexicographically sorting the characters
// in each word of the pass phrase, and then adding them all to a set.
// If the size of the set is less than the number of words in the
// passphrase, then at least one pair of words were anagrams of each
// other and the passphrase invalid.
'use strict';
const input = require('fs').readFileSync(process.argv[2], 'utf8').trim();
function sortCharactersInWord(word) {
// Default sort is, for once, exactly what we need!
return Array.from(word).sort().join('');
}
let valid = 0;
for (const line of input.split('\n')) {
const wordsList = line.trim().split(/\s+/);
const sortedCharactersWordsList = wordsList.map(sortCharactersInWord);
const sortedCharactersWordsSet = new Set(sortedCharactersWordsList);
// Sets contain only unique values, which I exploit here to find duplicates.
if (sortedCharactersWordsSet.size === sortedCharactersWordsList.length) {
valid++;
}
}
console.log(valid);
// Usage: node advent-of-code-2017-d04p2.js /path/to/input.txt
// Take care, works for shortish words only (fine for this problem),
// at least until arbitrary sized integers make it into JS.
'use strict';
const input = require('fs').readFileSync(process.argv[2], 'utf8').trim();
// Assign a prime to each letter. The product of primes for a word will
// equal another word only if they are anagrams of each other.
const letterPrimes = {
a: 2, b: 3, c: 5, d: 7, e: 11, f: 13, g: 17,
h: 19, i: 23, j: 29, k: 31, l: 37, m: 41, n: 43,
o: 47, p: 53, q: 59, r: 61, s: 67, t: 71, u: 73,
v: 79, w: 83, x: 89, y: 97, z: 101
};
function calculateWordValue(word) {
return [...word].reduce((total, letter) => total *= letterPrimes[letter], 1);
}
let valid = 0;
for (const line of input.split('\n')) {
const wordsList = line.trim().split(/\s+/);
const valuesList = wordsList.map(word => calculateWordValue(word));
const valuesSet = new Set(valuesList);
// Sets contain only unique values, which I exploit here to find duplicates.
if (valuesSet.size === valuesList.length) {
valid++;
}
}
console.log(valid);
@qubyte
Copy link
Author

qubyte commented Dec 4, 2017

Two solutions. One boring one based upon sorting the characters in each word of a passphrase, and one more intersting (but which breaks for larger words than encountered in the input) based on products of primes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment