bjorng

bjorng

Erlang Core Team

Advent of Code 2021 - Day 10

This topic is about Day 10 of the Advent of Code 2021.

We have a private leaderboard (shared with users of Erlang Forums ):

https://adventofcode.com/2021/leaderboard/private/view/370884

The entry code is:
370884-a6a71927

Most Liked

ruslandoga

ruslandoga

I used a bit of metaprogramming to define the line processor that worked on binaries:

defp process_line(line) do
  process_line(line, _stack = [])
end

for <<open, close>> <- ["[]", "()", "{}", "<>"] do
  defp process_line(<<unquote(close), rest::bytes>>, [unquote(close) | stack]) do
    process_line(rest, stack)
  end

  defp process_line(<<unquote(open), rest::bytes>>, stack) do
    process_line(rest, [unquote(close) | stack])
  end
end

defp process_line(<<>>, []), do: :valid
defp process_line(<<>>, stack), do: {:incomplete, stack}
defp process_line(<<char, _rest::bytes>>, _stack), do: {:corrupted, char}

Full solution

mexicat

mexicat

Today’s problem seemed like a good match for Elixir.

defmodule AdventOfCode.Day10 do
  @chunks %{
    "(" => ")",
    "[" => "]",
    "{" => "}",
    "<" => ">"
  }

  def part1(input) do
    input
    |> parse_input()
    |> Enum.map(&eval_line/1)
    |> Enum.filter(&(elem(&1, 0) == :error))
    |> Enum.map(fn {_, v} -> v end)
    |> Enum.sum()
  end

  def part2(input) do
    results =
      input
      |> parse_input()
      |> Enum.map(&eval_line/1)
      |> Enum.filter(&(elem(&1, 0) == :ok))
      |> Enum.map(fn {_, v} -> v end)
      |> Enum.sort()

    middle = results |> length() |> div(2)
    Enum.at(results, middle)
  end

  def eval_line(line, open \\ [])

  def eval_line([head | tail], open) when head in ["(", "[", "{", "<"] do
    eval_line(tail, [head | open])
  end

  def eval_line([head | tail], [open_head | open_tail]) do
    if head == @chunks[open_head] do
      eval_line(tail, open_tail)
    else
      {:error, score_error(head)}
    end
  end

  def eval_line(_, open) do
    score =
      Enum.reduce(open, 0, fn char, acc ->
        acc * 5 + score_ac(@chunks[char])
      end)

    {:ok, score}
  end

  def score_error(")"), do: 3
  def score_error("]"), do: 57
  def score_error("}"), do: 1197
  def score_error(">"), do: 25137

  def score_ac(")"), do: 1
  def score_ac("]"), do: 2
  def score_ac("}"), do: 3
  def score_ac(">"), do: 4

  def parse_input(input) do
    input
    |> String.split("\n", trim: true)
    |> Enum.map(&String.codepoints/1)
  end
end
ruslandoga

ruslandoga

I think it is equivalent except that my implementation for part2 needs to be updated to score openers instead of closers (since stack contains openers for incomplete lines). I rerun the tests with these two changes and they passed.

As for your original question,

Any reason it is better to match on insertion into the stack rather than on popping off the stack?

I don’t think I had any particular reason, at the moment it just made sense to add closers to the stack.

Where Next?

Popular in Challenges Top

bjorng
Note: This topic is to talk about Day 12 of the Advent of Code 2019. There is a private leaderboard for elixirforum members. You can joi...
New
adamu
I said I was on a break, but I took a sneak peak and it looked fun so… Part 1 completes in half a millisecond with a single pass of the ...
New
bjorng
This topic is about Day 17 of the Advent of Code 2020 . Thanks to @egze, we have a private leaderboard: https://adventofcode.com/2020/l...
New
bjorng
Here is my solution for day 2 of Advent of Code: https://github.com/bjorng/advent-of-code/blob/main/2024/day02/lib/day02.ex
New
Aetherus
This topic is about Day 7 of the Advent of Code 2020 . Thanks to @egze, we have a private leaderboard: https://adventofcode.com/2020/le...
New
sneako
Note by the Moderators: This topic is to talk about the first day of the Advent of Code. For general discussion about the Advent of Code...
New
shritesh
This was way too easy after the last few days. Simple map, filter and count. https://github.com/shritesh/advent/blob/main/2023/06.livemd
New
Aetherus
Don’t know why the regex ~r/[\W &amp;&amp; [^\.]]/x does not work in Elixir. It works pretty well in Ruby. Anyway, here is my solution: ...
New
bjorng
Note: This topic is to talk about Day 13 of the Advent of Code 2019. There is a private leaderboard for elixirforum members. You can joi...
New
christhekeele
Thought I’d kick today’s thread off! Parsing Enum rocks, so most of my code was actually in parsing input. ▶ Preprocessing input Part 1...
New

Other popular topics Top

9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 30877 112
New
jaysoifer
Is there a way to rollback a specific migration and only that one (“skipping” all the other ones)? Would mix ecto.rollback -v 200809061...
New
nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New
saif
Hello everyone, Long time lurker first time poster here. I’ve recently begun working on Elixir full-time again! :raised_hands: It’s been...
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement