Skip to content

Latest commit

 

History

History
93 lines (74 loc) · 31.8 KB

02.md

File metadata and controls

93 lines (74 loc) · 31.8 KB

Day 02

Part 1

Count valid passwords. E.g. the first row of the sample input says: the password abcde must contain the letter a 1–3 times.

Regex to the rescue:

const input = `
  1-3 a: abcde
  1-3 b: cdefg
  2-9 c: ccccccccc
`
  .trim()
  .split('\n')

const validPasswords = input.filter((row) => {
  const { min, max, letter, password } = row.match(
    /(?<min>\d+)-(?<max>\d+) (?<letter>[a-z]): (?<password>[a-z]+)/
  ).groups
  const occurrences = password.match(new RegExp(letter, 'g'))?.length
  return occurrences >= min && occurrences <= max
})

console.log(validPasswords.length)

Try it out on flems.io

Part 2

Count valid passwords. E.g. the first row of the sample input says: the password abcde must contain the letter a either in position 1 or in position 3. (The first letter is in position 1, not 0.)

We can use the same regex, but let's rename the first two capturing groups:

const validPasswords = input.filter((row) => {
  const { firstPos, secondPos, letter, password } = row.match(
    /(?<firstPos>\d+)-(?<secondPos>\d+) (?<letter>[a-z]): (?<password>[a-z]+)/
  ).groups
  const firstMatch = password[firstPos - 1] === letter
  const secondMatch = password[secondPos - 1] === letter
  return firstMatch !== secondMatch
})

console.log(validPasswords.length)

flems

What did I learn?

I used named capturing groups in the regexes for the first time. They were easy to use but made the regexes more readable, me thinks. Guess I'll be using them more from now on.

On a second thought, I don't know if they provided much benefit in this particular case:

const { min, max, letter, password } = row.match(
  /(?<min>\d+)-(?<max>\d+) (?<letter>[a-z]): (?<password>[a-z]+)/
).groups
// versus
const [, min, max, letter, password] = row.match(
  /(\d+)-(\d+) ([a-z]): ([a-z]+)/
)

const { firstPos, secondPos, letter, password } = row.match(
  /(?<firstPos>\d+)-(?<secondPos>\d+) (?<letter>[a-z]): (?<password>[a-z]+)/
).groups
// versus
const [, firstPos, secondPos, letter, password] = row.match(
  /(\d+)-(\d+) ([a-z]): ([a-z]+)/
)

But I'm sure they can be useful in more complex cases.