Skip to content

Latest commit

 

History

History
102 lines (74 loc) · 3.53 KB

11.md

File metadata and controls

102 lines (74 loc) · 3.53 KB

Day 11

Part 1

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.

Part 2

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

What did I learn?

Nothing. 🐒