Help Santa choose his new password.
Wow, corporate password policies are getting out of hand! But let's help Santa out with this lazy solution:
const input = 'cqjxjnds'
run()
async function run() {
const part1 = await getNextPassword(input)
console.log('Part 1:', part1)
}
async function getNextPassword(password) {
let nextLetters = [...password]
for (let i = 0; true; i++) {
if (i % 100_000 === 0) await new Promise((resolve) => setTimeout(resolve))
nextLetters = increment(nextLetters)
if (isValid(nextLetters)) return nextLetters.join('')
}
}
function increment(letters) {
const newLetters = [...letters]
for (let i = newLetters.length - 1; i >= 0; i--) {
const letter = newLetters[i]
// Overflow
if (letter === 'z') {
newLetters[i] = 'a'
continue
}
const newLetter = String.fromCharCode(letter.charCodeAt(0) + 1)
// Forbidden letters
if (newLetter === 'i') newLetters[i] = 'j'
else if (newLetter === 'l') newLetters[i] = 'm'
else if (newLetter === 'o') newLetters[i] = 'p'
// Ok
else newLetters[i] = newLetter
break
}
return newLetters
}
function isValid(letters) {
const charCodes = letters.map((letter) => letter.charCodeAt(0))
const hasIncreasingStraightOfThreeLetters = charCodes.find(
(charCode, i) =>
charCodes[i + 1] === charCode + 1 && charCodes[i + 2] === charCode + 2
)
// Return here as needed
// so we don't have to run the code for the second condition
// → speed!
if (!hasIncreasingStraightOfThreeLetters) return false
const hasTwoPairsOfLetters = letters.join('').match(/(\w)\1/g)?.length >= 2
return hasTwoPairsOfLetters
}
Flems link in Part 2.
Could be faster and clearer, but eh, whatever.
I had to use the
setTimeout()
trick from the 2015/04 puzzle
to avoid "Too much recursion" error.
Help Santa a second time.
async function run() {
const part1 = await getNextPassword(input)
console.log('Part 1:', part1)
+
+ const part2 = await getNextPassword(part1)
+ console.log('Part 2:', part2)
}
Try out the final code on flems.io
Nothing. 🐒