1.7 KiB
1.7 KiB
Day 4: Secure Container
We need to find a password. We don't know the password itself, but we do know that it follows certain rules. The total rules are:
- it's six digits
- the value is between two bounds given in the input
- two adjacent digits are the same, but they are not within a larger group of 3 or 4 digits.
- going from left to right, each digit is less than or equal to the one following
I converted each numeric password to a Text
to make it easier to get the digits, then implemented the checks like this:
.aoc.day4> view isValidPassword
isValidPassword : [Char] -> Boolean
isValidPassword password =
case password of
[a, b, c, d, e, f] ->
hasAdjacentDigits =
(((((a == b) && (ne b c))
||
(((b == c) && (ne a b)) && (ne c d)))
||
(((c == d) && (ne b c)) && (ne d e)))
||
(((d == e) && (ne c d)) && (ne e f)))
||
((e == f) && (ne d e))
neverDecreases =
((((a <= b) && (b <= c)) && (c <= d)) && (d <= e))
&&
(e <= f)
hasAdjacentDigits && neverDecreases
_ -> false
That weird ne
thing is because Unison doesn't have !=
defined for anything but text yet.
Fortunately, it does have (==) : a -> a -> Boolean
and I just want the reverse, so...
.aoc> view ne
ne : a -> a -> Boolean
ne a b = not (a == b)
And that lets us calculate the answer like this:
.aoc.day4> view answer
answer : Nat
answer =
List.flatMap
(num ->
(if isValidPassword (toCharList (Nat.toText num)) then
[num]
else []))
(range 109165 576723)
|> List.size