Aetherus

Aetherus

Advent of Code 2020 - Day 7

This topic is about Day 7 of the Advent of Code 2020 .

Thanks to @egze, we have a private leaderboard:
https://adventofcode.com/2020/leaderboard/private/view/39276

The join code is:
39276-eeb74f9a

I become busy this week, so I may not be able to create such topics in time. Apologies in advance.

Most Liked Switch mode

code-shoily

code-shoily

I used :digraph for the first one :smiley: still doing the second one (the way I found ended up counting leaves), your solution does give me a little hint :wink: so thank you.

kwando

kwando

I tried a too clever solution first.. but I rolled back to this one.. took some tries to get right, so it is not that polished yet :slight_smile:

defmodule Aoc2020.Day07 do
  def part1(input) do
    rules =
      input
      |> Enum.into(%{})

    for {color, specs} <- rules, color != "shiny gold", reduce: 0 do
      sum ->
        if find(rules, specs, "shiny gold") do
          sum + 1
        else
          sum
        end
    end
  end

  def part2(input) do
    rules =
      input
      |> Enum.into(%{})

    count_bags(rules, "shiny gold") - 1
  end

  def find(rules, [], _), do: false
  def find(rules, [{_, color} | rest], color), do: true

  def find(rules, [{_, child_color} | rest], color),
    do: find(rules, rest, color) || find(rules, Map.get(rules, child_color, []), color)

  def count_bags(rules, color) do
    specs = Map.get(rules, color, [])

    for {quantity, color} <- specs, reduce: 1 do
      sum ->
        sum + quantity * count_bags(rules, color)
    end
  end

  def input_stream(path) do
    File.stream!(path)
    |> Stream.map(&parse/1)
  end

  def parse(line) do
    line
    |> String.replace(["bags", "contain", "bag"], "")
    |> String.replace(~r/\s+|\./, " ")
    |> String.trim()
    |> String.split(",")
    |> Enum.map(fn part -> String.trim(part) |> String.split(" ") end)
    |> create_rule()
  end

  def create_rule([[mod, color | rule] | rules]) do
    {"#{mod} #{color}", parse_spec([rule | rules])}
  end

  defp parse_spec([["no", "other"]]), do: []
  defp parse_spec([]), do: []

  defp parse_spec([[quantity, mod, color] | rest]) do
    [{String.to_integer(quantity), "#{mod} #{color}"} | parse_spec(rest)]
  end
end

input = Aoc2020.Day07.input_stream("input.txt")

Aoc2020.Day07.part1(input)
|> IO.inspect(label: "part1")

Aoc2020.Day07.part2(input)
|> IO.inspect(label: "part2")

Last Post!

Aetherus

Aetherus

Actually, your code is quite readable.

Where Next?

Trending in Challenges Top

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge &amp; Solve. They are GUI (Emerge) and State management (S...
New
ausimian
Emily is an Elixir library that runs Nx computations on Apple’s MLX. Install it as the default Nx backend and Nx, defn, Axon, Nx.Serving,...
New
type1fool
I just stumbled on a newly redesigned elixir-lang.org. :tada: It looks like @Software_Mansion did the work, and I think it is generally a...
New
akoutmos
@hugobarauna and I (Alex Koutmos) have been hard at work on writing a book on Nerves that takes you from simply blinking LEDs to building...
New

We're in Beta

About us Mission Statement