DEV Community

Discussion on: AoC Day 2: Inventory Management System

Collapse
 
yordiverkroost profile image
Yordi Verkroost

My solution to day 2, in Elixir. The double for-loop in part 2 is certainly not optimal, but it works. The available time was short today. :)

Part one:

defmodule AoC.DayTwo.PartOne do
  alias AoC.DayTwo.Common

  def main() do
    "lib/day2/input.txt"
    |> Common.read_input()
    |> Enum.map(&count_characters/1)
    |> Enum.map(&Map.values/1)
    |> get_multiplicants()
    |> Enum.reduce(1, fn x, acc -> acc * x end)
  end

  defp count_characters(box_id) do
    box_id
    |> String.graphemes()
    |> Enum.reduce(%{}, fn x, acc -> Map.put(acc, x, (acc[x] || 0) + 1) end)
  end

  defp get_multiplicants(occurrences_lists) do
    twos = get_multiplicant(occurrences_lists, 2)
    threes = get_multiplicant(occurrences_lists, 3)
    [twos, threes]
  end

  defp get_multiplicant(occurrences_lists, count) do
    multiplicant =
      Enum.reduce(occurrences_lists, 0, fn x, acc ->
        if Enum.member?(x, count), do: acc + 1, else: acc
      end)
  end
end

Part two:

defmodule AoC.DayTwo.PartTwo do
  alias AoC.DayTwo.Common

  def main() do
    "lib/day2/input.txt"
    |> Common.read_input()
    |> find_correct_boxes()

    receive do
      {x, y} -> get_common_characters(x, y)
    end
  end

  defp find_correct_boxes(box_ids) do
    for x <- box_ids do
      for y <- box_ids do
        zipped = Enum.zip(String.graphemes(x), String.graphemes(y))

        differences =
          Enum.reduce(zipped, 0, fn {z1, z2}, acc -> if z1 == z2, do: acc, else: acc + 1 end)

        if(differences == 1) do
          send(self(), {x, y})
        end
      end
    end
  end

  defp get_common_characters(x, y) do
    Enum.zip(String.graphemes(x), String.graphemes(y))
    |> Enum.reduce("", fn {x1, x2}, acc -> if x1 == x2, do: acc <> x1, else: acc end)
  end
end

Common:

defmodule AoC.DayTwo.Common do
  def read_input(path) do
    path
    |> File.stream!()
    |> Stream.map(&String.trim_trailing/1)
    |> Enum.to_list()
  end
end