{replacements, medicine} = File.stream!("inputs/day19.txt") |> Stream.map(&String.trim/1) |> Stream.filter(&(&1 != "")) |> Stream.map(fn line -> case Regex.run(~r/(\w+) => (\w+)/, line) do [_, from, to] -> {:replacement, from, to} _ -> {:start, line} end end) |> Enum.reduce({[], nil}, fn {:replacement, from, to}, {replacements, start} -> {[{from, to} | replacements], start} {:start, start}, {replacements, _start} -> {replacements, start} end) nextGen = fn start -> Enum.flat_map(0..(String.length(start) - 1), fn offset -> {beforeReplace, replaceStart} = String.split_at(start, offset) Enum.filter(replacements, fn {from, _} -> String.starts_with?(replaceStart, from) end) |> Enum.map(fn {from, to} -> {^from, afterReplace} = String.split_at(replaceStart, String.length(from)) < to <> afterReplace>> end) end) |> Enum.uniq() end calibration = nextGen.(medicine) IO.puts("Calibration size: #{length(calibration)}") medicineGeneration = Stream.iterate(["e"], fn gen -> Enum.flat_map(gen, &nextGen.(&1)) |> Enum.uniq() end) |> Enum.find_index(fn gen -> Enum.any?(gen, &(&1 == medicine)) end) IO.puts("The Medicine generation: #{medicineGeneration}")