start = String.trim(File.read!("inputs/day11.txt")) startCharlist = String.to_charlist(start) startNums = Enum.reverse(startCharlist) defmodule A do def incrementPassword([head | tail]) do if decreasingStraight?(tail) do simpleIncrementPassword([head | tail]) else [second | _] = tail if head < second && second < ?z && !(second >= ?h && second <= ?n) do [second + 1 | tail] else [?a | simpleIncrementPassword(tail)] end end end def simpleIncrementPassword([?z | tail]) do [?a | simpleIncrementPassword(tail)] end def simpleIncrementPassword([?h | tail]) do [?j | tail] end def simpleIncrementPassword([?n | tail]) do [?p | tail] end def simpleIncrementPassword([?k | tail]) do [?m | tail] end def simpleIncrementPassword([head | tail]) do [head + 1 | tail] end def decreasingStraight?([]) do false end def decreasingStraight?([_]) do false end def decreasingStraight?([_, _]) do false end def decreasingStraight?([a, b, c | _]) when b === a - 1 and c === a - 2 do true end def decreasingStraight?([_ | tail]) do decreasingStraight?(tail) end def twoDifferentPairs?(list) do differentPairs = Enum.zip(list, Enum.drop(list, 1)) |> Enum.flat_map(fn {a, a} -> [a] {_, _} -> [] end) |> Enum.dedup() |> Enum.count() differentPairs >= 2 end end validPasswords = Stream.iterate(startNums, &A.incrementPassword(&1)) |> Stream.filter(fn password -> A.decreasingStraight?(password) && A.twoDifferentPairs?(password) end) nextPasswords = Enum.take(validPasswords, 2) |> Enum.map(&Enum.reverse(&1)) |> Enum.join("\n") IO.puts("New passwords:\n#{nextPasswords}")