Advent of Code 2015 Day 5
Part 1
- The final - and first -
regex
gauntlet? - A trio of
regex
-
reduce()
andevery()
to wrap it all up
The final - and first - regex
gauntlet?
- Input is a list of strings
- Some strings are
valid
- Others are not
- Discerning a string's proper category likely requires the use of one or more
regular expression
s
There have been several thus far.
They've all been preparing me for this one!
A trio of regex
contains at least three vowels
The regex
to match a single vowel character is:
/[aeiou]/
When combined with matchAll()
, the number of matches better be at least 3:
[...text.matchAll(/[aeiou]/)].length >= 3
contains at least one letter that appears twice in a row
The regex
to match any letter twice in a row is:
/(\w)\1/
When combined with matchAll()
, the number of matches better be at least 1:
[...text.matchAll(/(\w)\1/)].length > 0
does not contain the strings ab, cd, pq, or xy, even if they are part of one of the other requirements
The regex
to match ab
, cd
, pq
or xy
is:
/ab|cd|pq|xy/
When combined with matchAll()
, the number of matches better be 0:
[...text.matchAll(/ab|cd|pq|xy].length == 0
reduce()
and every()
to wrap it all up
-
reduce()
to accumulate a count ofnice
strings -
every()
to ensure all of the tests passed
My algorithm in JavaScript:
input.reduce(
(nice, text) =>
nice += [
[...text.matchAll(/[aeiou]/)].length >= 3,
[...text.matchAll(/(\w)\1/)].length > 0,
[...text.matchAll(/ab|cd|pq|xy/)].length == 0
].every(el => el == true) ? 1 : 0
, 0)
It generated the correct answer!
Part 1, a year ago
- When I discovered Advent of Code, I attempted a few Days' puzzles, starting with 2015
- Day 5 was where I stopped
- I only completed Part 1
Here's how I did it back then.
contains at least three vowels
Count each vowel, character by character:
function hasMin3Vowels(str) {
let vowels = ['a','e','i','o','u']
let numVowels = 0
str.split("").forEach(char => {
if (vowels.includes(char)) {
numVowels += 1
}
})
return numVowels >= 3
}
contains at least one letter that appears twice in a row
Check for where the next character matches the current one:
function hasOneLetterTwiceInARow(str) {
let matches = 0
str.split("").forEach((char, idx) => {
if (idx !== str.length - 1) {
if (char == str[idx + 1]) {
matches += 1
}
}
})
return matches > 0
}
does not contain the strings ab, cd, pq, or xy, even if they are part of one of the other requirements
Check the string for the existence of any bad pair:
function hasNoDisallowedStrings(str) {
let output = 0;
let disallowedStrings = ['ab', 'cd', 'pq', 'xy']
disallowedStrings.forEach(bad => {
if (str.indexOf(bad) !== -1) {
output += 1
}
})
return output == 0;
}
A wrapper function:
function isNice(str) {
return hasMin3Vowels(str) && hasOneLetterTwiceInARow(str) && hasNoDisallowedStrings(str)
}
A wrapping iterator:
input.map(str => isNice(str))
.filter(str => str == true)
.length
Looking bad on this code, I'm very proud of how I solved it this round.
Part 2
A duo of regex
contains a pair of any two letters that appears at least twice in the string without overlapping
The regex
to match a consecutive, non-overlapping letter pair is:
/(\w)(\w).*\1\2/
When combined with matchAll()
, the number of matches better be at least 1:
[...text.matchAll(/(\w)(\w).*\1\2/)].length > 0
contains at least one letter which repeats with exactly one letter between them
The regex
to match a three characters in the pattern A*A is:
/(\w)(\w)\1/
When combined with matchAll()
, the number of matches better be at least 1:
[...text.matchAll(/(\w)(\w)\1/)].length > 0
My updated algorithm in JavaScript:
input.reduce(
(nice, text) =>
nice += [
[...text.matchAll(/(\w)(\w).*\1\2/)].length > 0,
[...text.matchAll(/(\w)(\w)\1/)].length > 0
].every(el => el == true) ? 1 : 0
, 0)
It generated the correct answer!
I did it!!
- I solved both parts!
- Using five different
regex
!
This puzzle was undeniable proof of my newfound comfortability crafting regular expressions
.
When I attempted it nearly a year ago - after first discovering AoC - I barely solved Part 1 using non-regex
methods...and didn't even attempt Part 2.
On this day, however, I completed this puzzle in under a half hour. It felt almost easy!
Well done, self. Well done.
Top comments (0)