Password Philosophy
Tags: adventofcode, algorithms, computerscience, programming
Published: 2022-04-15 20:08:18

## [Advent of Code 2020 Day 2](https://adventofcode.com/2020/day/2)

## Task: Solve for X where...
```
X = the number of valid passwords
```

### Example input
```
1-3 a: abcde
1-3 b: cdefg
2-9 c: ccccccccc
```

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
```

Using `split` required me to:
Separate at ': '
```js
['1-3 a', 'abcde']
```
Separate the first item at ' ' and flatten
```js
['1-3','a', 'abcde']
```
Separate the first item in the first item at '-' and flatten
```js
['1','3','a','abcde']
```

Using `regex` offered a simpler approach:
Match each capture group in the following RegEx
```js
/(\d+)-(\d+) (\w): (\w+)/g
```

### 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
```
The range is `1,2,3`

For this line:
```
2-9 c: ccccccccc
```
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:

```js
const createRange = (lower, upper) => {
    return new Array(upper - (lower - 1)).fill(0).map((item, index) => index + lower)
}
```

### 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
```

Here's a visualization of my algorithm:
![Visualization of Part 1 algorithm](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jpy9pnjsg05rp8umzagv.gif)

## 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
```

Here's a visualization of my algorithm:
![Visualization of Part 2 algorithm](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q971tahjuvr37ooeexdv.gif)

## 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