Day 18 Part 1

This commit is contained in:
Adam Millerchip 2020-12-18 17:27:16 +09:00
parent 7a1ed0c974
commit 1a687a0036
3 changed files with 74 additions and 1 deletions

View file

@ -2,7 +2,7 @@
My (attempted) solutions to [Advent of Code 2020](https://adventofcode.com/2020) in Elixir. My (attempted) solutions to [Advent of Code 2020](https://adventofcode.com/2020) in Elixir.
<img width="978" alt="image" src="https://user-images.githubusercontent.com/498229/102344641-8e255400-3fdf-11eb-9231-7256ec6d747b.png"> <img width="983" alt="image" src="https://user-images.githubusercontent.com/498229/102591989-31987500-4156-11eb-8d21-2ea88021c9b0.png">
## Strategy ## Strategy

34
day18/README Normal file
View file

@ -0,0 +1,34 @@
Day 18 Notes
+--------+
| Part 1 |
+--------+
$ elixir day18part1.exs
<will add later>
Thoughts:
Since the order of precedence is the same, we can walk the token list, building up a left operand
and operator as we go, then applying the operator as soon as we get the right operand. For groups,
use recursion to resolve the group, and push the result back onto the beginning of the token list.
+--------+
| Part 2 |
+--------+
$ elixir day18part2.exs
Thoughts:
Now the order of precedence is relevant, so can no longer just walk the token list, need to know the
full context.
Addition basically becomes implicit brackets.
Will do this part later.
+------------------+
| Overall Thoughts |
+------------------+

39
day18/day18part1.exs Normal file
View file

@ -0,0 +1,39 @@
defmodule Day18Part1 do
def run do
File.stream!("input")
|> Stream.map(&parse_line/1)
|> Stream.map(&evaluate/1)
|> Enum.sum()
|> IO.puts()
end
def parse_line(line) do
line
|> String.graphemes()
|> Stream.reject(fn char -> char in [" ", "\n"] end)
|> Enum.map(fn
"*" -> :multiply
"+" -> :add
"(" -> :start_group
")" -> :end_group
num -> String.to_integer(num)
end)
end
def evaluate(command), do: evaluate(command, nil, 0)
def evaluate([], nil, acc), do: acc
def evaluate([:multiply | rest], nil, acc), do: evaluate(rest, :multiply, acc)
def evaluate([:add | rest], nil, acc), do: evaluate(rest, :add, acc)
def evaluate([:start_group | rest], op, acc) do
{remaining, group_result} = evaluate(rest, nil, 0)
evaluate([group_result | remaining], op, acc)
end
def evaluate([:end_group | rest], _op, acc), do: {rest, acc}
def evaluate([num | rest], :multiply, acc), do: evaluate(rest, nil, acc * num)
def evaluate([num | rest], :add, acc), do: evaluate(rest, nil, acc + num)
def evaluate([num | rest], nil, 0), do: evaluate(rest, nil, num)
end
Day18Part1.run()