diff options
Diffstat (limited to 'aoc-2019-elixir')
-rw-r--r-- | aoc-2019-elixir/.formatter.exs | 3 | ||||
-rw-r--r-- | aoc-2019-elixir/lib/day01.ex | 32 | ||||
-rw-r--r-- | aoc-2019-elixir/lib/day02.ex | 65 | ||||
-rw-r--r-- | aoc-2019-elixir/lib/util.ex | 26 | ||||
-rw-r--r-- | aoc-2019-elixir/mix.exs | 13 |
5 files changed, 139 insertions, 0 deletions
diff --git a/aoc-2019-elixir/.formatter.exs b/aoc-2019-elixir/.formatter.exs new file mode 100644 index 0000000..d304ff3 --- /dev/null +++ b/aoc-2019-elixir/.formatter.exs @@ -0,0 +1,3 @@ +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/aoc-2019-elixir/lib/day01.ex b/aoc-2019-elixir/lib/day01.ex new file mode 100644 index 0000000..6545f19 --- /dev/null +++ b/aoc-2019-elixir/lib/day01.ex @@ -0,0 +1,32 @@ +defmodule Day01 do + @spec part1([integer]) :: integer + def part1(input) do + input + |> Enum.map(&naive_fuel_requirement/1) + |> Enum.sum() + end + + @spec part2([integer]) :: integer + def part2(input) do + input + |> Enum.map(&recursive_fuel_requirement/1) + |> Enum.sum() + end + + defp naive_fuel_requirement(mass) do + div(mass, 3) - 2 + end + + defp recursive_fuel_requirement(mass) do + fuel_mass = div(mass, 3) - 2 + + case fuel_mass do + n when n <= 0 -> 0 + _ -> fuel_mass + recursive_fuel_requirement(fuel_mass) + end + end +end + +input = Util.Input.read_numbers("day01") +input |> Day01.part1() |> IO.inspect() +input |> Day01.part2() |> IO.inspect() diff --git a/aoc-2019-elixir/lib/day02.ex b/aoc-2019-elixir/lib/day02.ex new file mode 100644 index 0000000..46f64bd --- /dev/null +++ b/aoc-2019-elixir/lib/day02.ex @@ -0,0 +1,65 @@ +defmodule Day02 do + @add_opcode 1 + @mul_opcode 2 + @ret_opcode 99 + @noun_address 1 + @verb_address 2 + + @spec part1(binary) :: list + def part1(input) do + run(input, 12, 2) + end + + @spec part2(binary) :: integer + def part2(input) do + for( + n <- 0..100, + v <- 0..100, + do: {n, v, run(input, n, v)} + ) + |> Enum.find(&(elem(&1, 2) == 19_690_720)) + |> then(fn {n, v, _} -> n * 100 + v end) + end + + defp run(input, noun, verb) do + input + |> parse() + |> List.replace_at(@noun_address, noun) + |> List.replace_at(@verb_address, verb) + |> execute() + |> hd() + end + + defp binary_op(program, op, a, b, out) do + program |> List.replace_at(out, op.(Enum.at(program, a), Enum.at(program, b))) + end + + defp execute(program, pc \\ 0) do + instruction = program |> Enum.drop(pc) |> Enum.take(4) + + case instruction do + [@add_opcode, a, b, out] -> + program + |> binary_op(&+/2, a, b, out) + |> execute(pc + 4) + + [@mul_opcode, a, b, out] -> + program + |> binary_op(&*/2, a, b, out) + |> execute(pc + 4) + + [@ret_opcode | _] -> + program + end + end + + defp parse(input) do + input + |> String.split(",") + |> Enum.map(&Util.Integer.parse!/1) + end +end + +input = Util.Input.read_text("day02") +input |> Day02.part1() |> IO.inspect() +input |> Day02.part2() |> IO.inspect() diff --git a/aoc-2019-elixir/lib/util.ex b/aoc-2019-elixir/lib/util.ex new file mode 100644 index 0000000..ada31be --- /dev/null +++ b/aoc-2019-elixir/lib/util.ex @@ -0,0 +1,26 @@ +defmodule Util.Integer do + @spec parse!(binary) :: integer + def parse!(binary) do + {integer, _remainder} = Integer.parse(binary) + integer + end +end + +defmodule Util.Input do + @spec read_text(binary) :: binary + def read_text(filename) do + File.read!("data/#{filename}.txt") + end + + @spec read_lines(binary) :: [binary] + def read_lines(filename) do + filename |> read_text() |> String.split() + end + + @spec read_numbers(binary) :: [integer] + def read_numbers(filename) do + filename + |> read_lines() + |> Enum.map(&Util.Integer.parse!/1) + end +end diff --git a/aoc-2019-elixir/mix.exs b/aoc-2019-elixir/mix.exs new file mode 100644 index 0000000..7389989 --- /dev/null +++ b/aoc-2019-elixir/mix.exs @@ -0,0 +1,13 @@ +defmodule Aoc2019Elixir.MixProject do + use Mix.Project + + def project do + [ + app: :aoc_2019_elixir, + version: "0.1.0", + elixir: "~> 1.14", + start_permanent: Mix.env() == :prod, + deps: [] + ] + end +end |