regex = ~r{\A(\d+)-(\d+) (\w): (\w+)\z} list = File.read!("input.txt") |> String.split("\n") |> Enum.map(&Regex.run(regex, &1, capture: :all_but_first)) # "all but first" removes matching substring, leaving only capture groups |> Enum.map( fn [n1, n2, character, password] -> { String.to_integer(n1), String.to_integer(n2), character, String.graphemes(password) # into array of letters } end ) IO.puts "Part 1: " list |> Enum.filter( fn {minimum, maximum, character, password} -> count = Enum.count(password, &(&1 == character)) minimum <= count and count <= maximum end ) |> Enum.count() |> IO.puts() IO.puts "Part 2: " list |> Enum.filter( fn {p1, p2, character, password} -> first = Enum.at(password, p1-1) == character second = Enum.at(password, p2-1) == character first != second # exclusive or is equivalent to two things not matching (not both true or both false) end ) |> Enum.count() |> IO.puts()