day 2 part 2
aoc runner takes part as arg and passes to init state fn call refactored day 1 to switch parts dynamically
This commit is contained in:
parent
3f047cd890
commit
680929a20c
4 changed files with 91 additions and 46 deletions
|
@ -3,10 +3,10 @@ defmodule AOCRunner do
|
||||||
(s |> String.trim() |> String.length()) == 0
|
(s |> String.trim() |> String.length()) == 0
|
||||||
end
|
end
|
||||||
|
|
||||||
def run(advent) do
|
def run(advent, part) do
|
||||||
{_, state} = IO.stream() |>
|
{_, state} = IO.stream() |>
|
||||||
Enum.reduce_while(
|
Enum.reduce_while(
|
||||||
{nil, advent.init_state()},
|
{nil, advent.init_state(part)},
|
||||||
fn line, acc -> line
|
fn line, acc -> line
|
||||||
|> then(fn line ->
|
|> then(fn line ->
|
||||||
{u, state} = acc
|
{u, state} = acc
|
||||||
|
|
26
lib/day1.ex
26
lib/day1.ex
|
@ -1,11 +1,18 @@
|
||||||
defmodule Day1 do
|
defmodule Day1 do
|
||||||
def get_answer(state) do
|
def get_answer(state) do
|
||||||
elem(state, 1) |>
|
{_, total, part} = state
|
||||||
Enum.reduce(0, fn i, acc -> i + acc end)
|
total |>
|
||||||
|
then(fn total -> case part do
|
||||||
|
:part1 -> total
|
||||||
|
:part2 -> total |> Enum.reduce(0, fn i, acc -> i + acc end)
|
||||||
|
end end)
|
||||||
end
|
end
|
||||||
|
|
||||||
def init_state() do
|
def init_state(part) do
|
||||||
{nil, [0, 0, 0]}
|
case part do
|
||||||
|
:part1 -> {nil, 0, part}
|
||||||
|
:part2 -> {nil, [0, 0, 0], part}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def execute(line, state) do
|
def execute(line, state) do
|
||||||
|
@ -30,10 +37,10 @@ defmodule Day1 do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp apply_add(n, state) do
|
defp apply_add(n, state) do
|
||||||
{current, total} = state
|
{current, total, part} = state
|
||||||
new_current = n + if is_nil(current) do 0 else current end
|
new_current = n + if is_nil(current) do 0 else current end
|
||||||
|
|
||||||
{new_current, total}
|
{new_current, total, part}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp take_top_three(n, list) do
|
defp take_top_three(n, list) do
|
||||||
|
@ -43,9 +50,12 @@ defmodule Day1 do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp apply_reset(state) do
|
defp apply_reset(state) do
|
||||||
{current, total} = state
|
{current, total, part} = state
|
||||||
if !is_nil(current) do
|
if !is_nil(current) do
|
||||||
{nil, take_top_three(current, total)}
|
case part do
|
||||||
|
:part1 -> {nil, max(total, current), part}
|
||||||
|
:part2 -> {nil, take_top_three(current, total), part}
|
||||||
|
end
|
||||||
else
|
else
|
||||||
state
|
state
|
||||||
end
|
end
|
||||||
|
|
105
lib/day2.ex
105
lib/day2.ex
|
@ -1,23 +1,70 @@
|
||||||
defmodule Day2 do
|
defmodule Day2 do
|
||||||
def init_state() do
|
def init_state(part) do
|
||||||
score_with_points(0)
|
init_state(0, part)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp score_with_points(p) do
|
defp init_state(score, part) do
|
||||||
%{score: p}
|
%{score: score, part: part}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp parse_match(line) do
|
def execute(line, state) do
|
||||||
|
if line |> String.trim() |> String.length == 0 do
|
||||||
|
state
|
||||||
|
else
|
||||||
|
{_, player, outcome} = parse_moves(line, state.part)
|
||||||
|
|
||||||
|
init_state(
|
||||||
|
state.score +
|
||||||
|
points_for_move(player) +
|
||||||
|
points_from_outcome(outcome),
|
||||||
|
state.part)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_answer(state) do
|
||||||
|
state.score
|
||||||
|
end
|
||||||
|
|
||||||
|
defp parse_moves(line, part) do
|
||||||
[p1, p2] = String.split(line, " ") |> Enum.map(&String.trim/1)
|
[p1, p2] = String.split(line, " ") |> Enum.map(&String.trim/1)
|
||||||
match = parse_match(p1, p2)
|
parse_moves(p1, p2, part)
|
||||||
|
|
||||||
match
|
|
||||||
end
|
end
|
||||||
|
|
||||||
defp parse_match(left, right) do
|
defp parse_moves(left, right, :part1) do
|
||||||
{parse_move(left, :left), parse_move(right, :right)}
|
match = {parse_move(left, :left), parse_move(right, :right)}
|
||||||
|
Tuple.append(match, outcome?(match))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp parse_moves(left, right, :part2) do
|
||||||
|
left = parse_move(left, :left)
|
||||||
|
outcome = outcome?(right)
|
||||||
|
right = plan_move(outcome, left)
|
||||||
|
|
||||||
|
{left, right, outcome}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp plan_move(outcome, opposing_move) do
|
||||||
|
if outcome == :draw do
|
||||||
|
opposing_move
|
||||||
|
else
|
||||||
|
case opposing_move do
|
||||||
|
:rock -> case outcome do
|
||||||
|
:win -> :paper
|
||||||
|
:loss -> :scissors
|
||||||
|
end
|
||||||
|
:paper -> case outcome do
|
||||||
|
:win -> :scissors
|
||||||
|
:loss -> :rock
|
||||||
|
end
|
||||||
|
:scissors -> case outcome do
|
||||||
|
:win -> :rock
|
||||||
|
:loss -> :paper
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
defp parse_move(move, side) do
|
defp parse_move(move, side) do
|
||||||
case side do
|
case side do
|
||||||
:left -> case move do
|
:left -> case move do
|
||||||
|
@ -33,10 +80,8 @@ defmodule Day2 do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp points_from_player_move(match) do
|
defp points_for_move(move) do
|
||||||
{_, player_move} = match
|
case move do
|
||||||
|
|
||||||
case player_move do
|
|
||||||
:rock -> 1
|
:rock -> 1
|
||||||
:paper -> 2
|
:paper -> 2
|
||||||
:scissors -> 3
|
:scissors -> 3
|
||||||
|
@ -64,7 +109,7 @@ defmodule Day2 do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp outcome(match) do
|
defp outcome?(match) when is_tuple(match) and tuple_size(match) == 2 do
|
||||||
{opponent, player} = match
|
{opponent, player} = match
|
||||||
case sort_(player, opponent) do
|
case sort_(player, opponent) do
|
||||||
1 -> :win
|
1 -> :win
|
||||||
|
@ -73,29 +118,19 @@ defmodule Day2 do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp points_from_outcome(match) do
|
defp outcome?(plan) do
|
||||||
case outcome(match) do
|
case plan do
|
||||||
|
"X" -> :loss
|
||||||
|
"Y" -> :draw
|
||||||
|
"Z" -> :win
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp points_from_outcome(outcome) do
|
||||||
|
case outcome do
|
||||||
:win -> 6
|
:win -> 6
|
||||||
:draw -> 3
|
:draw -> 3
|
||||||
:loss -> 0
|
:loss -> 0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def execute(line, state) do
|
|
||||||
if line |> String.trim() |> String.length == 0 do
|
|
||||||
state
|
|
||||||
else
|
|
||||||
match = parse_match(line)
|
|
||||||
|
|
||||||
score_with_points(
|
|
||||||
state.score +
|
|
||||||
points_from_player_move(match) +
|
|
||||||
points_from_outcome(match))
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_answer(state) do
|
|
||||||
state.score
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
2
main.exs
2
main.exs
|
@ -1 +1 @@
|
||||||
AOCRunner.run(Day2)
|
AOCRunner.run(Day2, :part2)
|
||||||
|
|
Loading…
Add table
Reference in a new issue