Mostly code

# Advent of Code 2019: Day 4

05 Dec 2019 This one didn’t seem too bad, but I can’t help but feel there’s a “clever” solution that alludes me. Some sort of funky math theorizing that I just don’t know about.

## Puzzle 1 Oh, you only want a count of possible ones? That shouldn’t be too hard.

First, a function to check if the `digits/2` of the password match the rules.

``````  def p1_possible(y) do
length(y) == 6 and Enum.sort(y) == y and check_doubles(y)
end
``````

While I feel like there should be some fancy way to check if doubles exist, I decided `chunk_every/4` would work great here.

``````  defp check_doubles(y) do
y
|> Enum.any?(fn [a, b] -> a == b end)
end
``````

Similar to yesterday’s puzzle, I am taking two adjacent digits and making sure they are equal. All that’s left is to count up the good ones.

``````  def compute_possibles([s, e]) do
Enum.reduce(s..e, 0, fn x, acc ->
y = Integer.digits(x)

if p1_possible(y) do
acc + 1
else
acc
end
end)
end
``````

Boom, HACKED ## Puzzle 2

Puzzle 2 has a nice little spin on the original problem, declaring that there is definitely at least one set of just doubles in the password.

• `111111` is no good, as there isn’t a set of doubles all on its own
• `111122` is good, because the `22` is a double.

I can already re-use `p1_possible/1`, as all of those rules apply as well. To see if there is a unique set of doubles, I can use `chunk_while/4` to only emit chunks when the current digit is different than the last one.

``````  defp check_unique_doubles(y) do
y
|> Enum.chunk_while(
[],
fn
x, [] -> {:cont, [x]}
x, [x | _t] = acc -> {:cont, [x | acc]}
x, [_y | _t] = acc -> {:cont, acc, [x]}
end,
fn x -> {:cont, x, []} end
)
|> Enum.any?(fn x -> length(x) == 2 end)
end
``````

I also decided it would be easiest to use pattern matching in the anonymous function, to avoid any extra `if`s or `cond`s. I’m not really sure what the last parameter is for, titled `after_fun`. It says that it runs after iteration is done, but I don’t understand what the difference is between returning ```{:cont, element, acc}``` and `{:cont, acc}` is. Something to look into at a later time!

After that, I just need to check if any chunk has a length of 2.

The solution is the same as before, but with the new `p2_possible/1` instead.

``````  def compute_possibles([s, e]) do
Enum.reduce(s..e, 0, fn x, acc ->
y = Integer.digits(x)

if p2_possible(y) do
acc + 1
else
acc
end
end)
end

def p2_possible(y) do
p1_possible(y) and check_unique_doubles(y)
end
``````

Calculating… calculating… .20 seconds is pretty quick still! I’m pleasantly surprised. received. ## Conclusion

I, uh, actually didn’t write any tests for this one. It was pretty straight-forward and I manged to solve each puzzle on the first try, which is always nice. I can’t help but think that there’s a better way to do this than brute-forcing things, but, hey, it finished really quick.

That’s all today! On to day 5!