bjorng
Advent of Code 2020 - Day 18
This topic is about Day 18 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
Most Liked
akash-akya
Hacked with elixir quoted expression, this can be called cheating I guess ![]()
Since the input is a valid elixir expression, getting AST is just treating input as elixir code, we dont even have to care about the brackets.
defmodule Advent2020.Day18 do
def input do
File.read!(Path.expand("day18.txt", :code.priv_dir(:advent_2020)))
|> String.split("\n", trim: true)
end
defp replace(str, []), do: str
defp replace(str, [{match, replacement} | rest]),
do: String.replace(str, match, replacement) |> replace(rest)
def parse_with_replcement(line, replace) do
{:ok, quoted} = replace(line, replace) |> Code.string_to_quoted()
quoted
end
defp replace_operation(num, _replacement) when is_integer(num), do: num
defp replace_operation({operator, metadata, [a, b]}, replace) do
{replace[operator] || operator, metadata,
[replace_operation(a, replace), replace_operation(b, replace)]}
end
def run(replace) do
revert = Enum.map(replace, fn {m, r} -> {String.to_atom(r), String.to_atom(m)} end)
Enum.map(input(), fn line ->
{result, []} =
parse_with_replcement(line, replace)
|> replace_operation(revert)
|> Code.eval_quoted()
result
end)
|> Enum.sum()
end
def part_one, do: run([{"*", "-"}])
def part_two, do: run([{"*", "-"}, {"+", "/"}])
end
camilleryr
I originally parsed each equation into an expression tree to evaluate them - which worked, but then I saw on reddit someone mention the shunting yard algorithm - did a bunch of reading on operator precedence parsing and stack based calculators and was able to refactor my code in a really satisfying way. The implementation of the algorithm and the evaluator could use some clean up, but it works, and it works about 10 times faster then the expression tree approach
https://github.com/camilleryr/advent20/blob/main/lib/day_18.ex
bjorng
I spent most of the time in part 1 trying to get the recursive descent parser to make the evaluating order left-to-right. When I solved that part 2 was easy.
Here is my solution.
Popular in Challenges
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









