DEV Community

Cover image for Password Philosophy
Robert Mion
Robert Mion

Posted on

Password Philosophy

Advent of Code 2020 Day 2

Task: Solve for X where...

X = the number of valid passwords
Enter fullscreen mode Exit fullscreen mode

Example input

1-3 a: abcde
1-3 b: cdefg
2-9 c: ccccccccc
Enter fullscreen mode Exit fullscreen mode

It represents:

  • A password policy, followed by
  • A password

Part 1

  1. Comparing split() with RegEx
  2. Leveraging a helper function from a prior puzzle
  3. Writing a working algorithm

Comparing split() with RegEx

  • I completed both parts of this puzzle when I first discovered it a year ago
  • But my solution used split() because I was far less adept at using regular expressions

Given this line:

1-3 a: abcde
Enter fullscreen mode Exit fullscreen mode

Using split required me to:
Separate at ': '

['1-3 a', 'abcde']
Enter fullscreen mode Exit fullscreen mode

Separate the first item at ' ' and flatten

['1-3','a', 'abcde']
Enter fullscreen mode Exit fullscreen mode

Separate the first item in the first item at '-' and flatten

['1','3','a','abcde']
Enter fullscreen mode Exit fullscreen mode

Using regex offered a simpler approach:
Match each capture group in the following RegEx

/(\d+)-(\d+) (\w): (\w+)/g
Enter fullscreen mode Exit fullscreen mode

Leveraging a helper function from a prior puzzle

Part 1's password policy requires that the specified character be at a location in the string designated by boundaries of a range:

For this line:

1-3 a: abcde
Enter fullscreen mode Exit fullscreen mode

The range is 1,2,3

For this line:

2-9 c: ccccccccc
Enter fullscreen mode Exit fullscreen mode

The range is 2,3,4,5,6,7,8,9

In a puzzle featured earlier in this series - meaning one of the later 2020 puzzles, I wrote an algorithm to generate such a list:

const createRange = (lower, upper) => {
    return new Array(upper - (lower - 1)).fill(0).map((item, index) => index + lower)
}
Enter fullscreen mode Exit fullscreen mode

Writing a working algorithm

Generate a list of matched capture groups for each line using the regular expression above

Filter that list to only include items where the following operations return 'true'
  Create a range of numbers that span the lower and upper designated boundaries from the first and second captured groups
  Check that list of numbers for the inclusion of a number that is equivalent to the number returned from the following operations:
    Split the password string into an array of characters
      Filter the list of characters to only include characters that match the character specified by this item's policy
      Return the length of the filtered list

Return the length of the filtered list
Enter fullscreen mode Exit fullscreen mode

Here's a visualization of my algorithm:
Visualization of Part 1 algorithm

Part 2

Writing a slightly modified, working algorithm

Generate a list of matched capture groups for each line using the regular expression above

Filter that list to only include items where the following operations return 'true'
  Create a 2-element list containing the lower and upper designated boundaries from the first and second captured groups
  Filter that list to include either 0, 1 or both numbers based on the following operations:
    For each of the two numbers:
      Split the password string into an array of characters
        Remove N characters from the beginning of the list where N = the current number minus 1
          Return true if the first character is the one specified in the policy
    Return true if the filtered list only contains one number
Return the length of the filtered list
Enter fullscreen mode Exit fullscreen mode

Here's a visualization of my algorithm:
Visualization of Part 2 algorithm

Accomplishments

  • Feeling confident enough to use RegEx instead of split() to solve this puzzle more eloquently
  • Re-using a helper function from a previous puzzle's solution
  • Writing both parts each as one long chained statement

Top comments (0)