import AOC aoc 2015, 11 do def is_valid_password?(password) do includes_increasing_straight_of_three(password) and does_not_contain_iol(password) and includes_two_pairs_of_double_letters(password) end def includes_increasing_straight_of_three(b) when is_binary(b), do: String.to_charlist(b) |> includes_increasing_straight_of_three() def includes_increasing_straight_of_three([a, b, c | _]) when a == b - 1 and b == c - 1, do: true def includes_increasing_straight_of_three([_ | rest]), do: includes_increasing_straight_of_three(rest) def includes_increasing_straight_of_three(_), do: false def does_not_contain_iol(password) do not String.match?(password, ~r/[iol]/) end def includes_two_pairs_of_double_letters(password) do String.match?(password, ~r/(\w)\1.*(\w)\2/) end def increment_password(password) when is_binary(password), do: password |> String.to_charlist() |> Enum.reverse() |> increment_password() |> Enum.reverse() |> IO.chardata_to_string() def increment_password([]), do: [?a] def increment_password([?z | rest]), do: [?a | increment_password(rest)] def increment_password([c | rest]), do: [c + 1 | rest] def compute_next_password(current_password) do candidate = increment_password(current_password) if is_valid_password?(candidate) do candidate else compute_next_password(candidate) end end def p1 do input_string() |> String.trim() |> compute_next_password() end def p2 do end end