re: AoC Day 5: Alchemical Reduction VIEW POST

VIEW FULL DISCUSSION
 

My day 5 solutions in Elixir. I'm actually pretty happy with how the code turned out this time, might be the cleanest of all days up until now.

The main idea of the implementation of part one is to put characters on a stack, and then compare the head of the stack with the next element to determine if the head and the new element should stay or go.

Part two is a wrapper around the first part, where the input is preprocessed (e.g. units are removed) before being fed to the implementation of the first part. The units to remove are based on unicode numbers.

Common:


defmodule AoC.DayFive.Common do
  @lower_upper_unicode_difference 32

  def read_input(path) do
    path
    |> File.read!()
    |> String.graphemes()
  end

  def process(polymer) do
    polymer
    |> Enum.reduce([], fn unit, result -> process_unit(unit, result) end)
  end

  def get_lower_upper_unicode_difference() do
    @lower_upper_unicode_difference
  end

  defp process_unit(unit, []) do
    [unit]
  end

  defp process_unit(unit, polymer) do
    [head | rest] = polymer
    <<h::utf8>> = head
    <<u::utf8>> = unit

    case abs(h - u) do
      @lower_upper_unicode_difference -> rest
      _ -> [unit | polymer]
    end
  end
end

Part one:

defmodule AoC.DayFive.PartOne do
  alias AoC.DayFive.Common

  def main() do
    "lib/day5/input.txt"
    |> Common.read_input()
    |> Common.process()
    |> Enum.count()
  end
end

Part two:

defmodule AoC.DayFive.PartTwo do
  alias AoC.DayFive.Common

  @lower_a 97
  @lower_z 122

  def main() do
    "lib/day5/input.txt"
    |> Common.read_input()
    |> process()
  end

  defp process(polymer) do
    Enum.reduce(@lower_a..@lower_z, Enum.count(polymer), fn lower_unicode, length ->
      higher_unicode = lower_unicode - Common.get_lower_upper_unicode_difference()
      lower_character = <<lower_unicode::utf8>>
      higher_character = <<higher_unicode::utf8>>

      polymer_length =
        polymer
        |> Enum.filter(fn x -> x != lower_character and x != higher_character end)
        |> Common.process()
        |> Enum.count()

      min(polymer_length, length)
    end)
  end
end
code of conduct - report abuse