Last active
December 4, 2017 22:20
-
-
Save qubyte/fdfd5d78b1a03065714d59e1fa7dbc7d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.