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
Put on your hacker gloves, it’s time to crack some passwords!

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.chunk_every(2, 1, :discard)
    |> 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.
111111is no good, as there isn’t a set of doubles all on its own111122is good, because the22is 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 ifs or conds. 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!