From 748e0a231179618918ae352b8b75a7a7f056712b Mon Sep 17 00:00:00 2001 From: Adam Millerchip Date: Fri, 2 Dec 2022 19:59:40 +0900 Subject: [PATCH] 2022 day 2 --- 2022/README.md | 2 +- 2022/day2.exs | 100 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 2022/day2.exs diff --git a/2022/README.md b/2022/README.md index a861917..a50b346 100644 --- a/2022/README.md +++ b/2022/README.md @@ -2,7 +2,7 @@ My (attempted) solutions to [Advent of Code 2022](https://adventofcode.com/2022) in Elixir. -image +image ## Running: diff --git a/2022/day2.exs b/2022/day2.exs new file mode 100644 index 0000000..f598a29 --- /dev/null +++ b/2022/day2.exs @@ -0,0 +1,100 @@ +defmodule Day2 do + def part1(input) do + input + |> Enum.map(fn + {opponent, "X"} -> {opponent, :rock} + {opponent, "Y"} -> {opponent, :paper} + {opponent, "Z"} -> {opponent, :scissors} + end) + |> Enum.map(&play/1) + |> Enum.sum() + end + + @rock 1 + @paper 2 + @scissors 3 + @lose 0 + @draw 3 + @win 6 + + defp play({:rock, :rock}), do: @rock + @draw + defp play({:paper, :rock}), do: @rock + @lose + defp play({:scissors, :rock}), do: @rock + @win + defp play({:rock, :paper}), do: @paper + @win + defp play({:paper, :paper}), do: @paper + @draw + defp play({:scissors, :paper}), do: @paper + @lose + defp play({:rock, :scissors}), do: @scissors + @lose + defp play({:paper, :scissors}), do: @scissors + @win + defp play({:scissors, :scissors}), do: @scissors + @draw + + def part2(input) do + input + |> Enum.map(fn + {opponent, "X"} -> {opponent, :lose} + {opponent, "Y"} -> {opponent, :draw} + {opponent, "Z"} -> {opponent, :win} + end) + |> Enum.map(&play2/1) + |> Enum.sum() + end + + defp play2({:rock, :win}), do: @win + @paper + defp play2({:paper, :win}), do: @win + @scissors + defp play2({:scissors, :win}), do: @win + @rock + defp play2({:rock, :draw}), do: @draw + @rock + defp play2({:paper, :draw}), do: @draw + @paper + defp play2({:scissors, :draw}), do: @draw + @scissors + defp play2({:rock, :lose}), do: @lose + @scissors + defp play2({:paper, :lose}), do: @lose + @rock + defp play2({:scissors, :lose}), do: @lose + @paper + + def input do + with [input_filename] <- System.argv(), + {:ok, input} <- File.read(input_filename) do + input + |> String.split([" ", "\n"], trim: true) + |> Enum.map(fn + "A" -> :rock + "B" -> :paper + "C" -> :scissors + me -> me + end) + |> Enum.chunk_every(2) + |> Enum.map(&List.to_tuple/1) + else + _ -> :error + end + end + + ####################### + # HERE BE BOILERPLATE # + ####################### + + def run do + case input() do + :error -> print_usage() + input -> run_parts_with_timer(input) + end + end + + defp run_parts_with_timer(input) do + run_with_timer(1, fn -> part1(input) end) + run_with_timer(2, fn -> part2(input) end) + end + + defp run_with_timer(part, fun) do + {time, result} = :timer.tc(fun) + IO.puts("Part #{part} (completed in #{format_time(time)}):\n") + IO.puts("#{result}\n") + end + + defp format_time(μsec) when μsec < 1_000, do: "#{μsec}μs" + defp format_time(μsec) when μsec < 1_000_000, do: "#{μsec / 1000}ms" + defp format_time(μsec), do: "#{μsec / 1_000_000}s" + + defp print_usage do + IO.puts("Usage: elixir day2.exs input_filename") + end +end + +Day2.run()