Advent of Code 2024 - Day 02
Mix.install([
{:kino_aoc, "~> 0.1.7"}
])
Introduction
2024 - Day 02
Puzzle
{:ok, puzzle_input} =
KinoAOC.download_puzzle("2024", "2", System.fetch_env!("LB_AOC_SESSION"))
Parser
Code - Parser
defmodule Parser do
@reg ~r/\s+/
def parse(input) do
input
|> String.split("\n", trim: true)
|> Enum.map(fn s ->
s
|> String.split(@reg)
|> Enum.map(&(String.to_integer/1))
end)
end
end
Tests - Parser
ExUnit.start(autorun: false)
defmodule ParserTest do
use ExUnit.Case, async: true
import Parser
@input """
7 6 4 2 1
1 2 7 8 9
"""
@expected [[7, 6, 4, 2, 1], [1, 2, 7, 8, 9]]
test "parse test" do
actual = parse(@input)
assert actual == @expected
end
end
ExUnit.run()
Shared
defmodule Shared do
def is_safe(report) do
report
|> Enum.chunk_every(2, 1, :discard)
|> Enum.reduce_while(nil, fn [a, b], prev_level ->
level = a - b
cond do
abs(level) < 1 or abs(level) > 3 -> {:halt, false}
prev_level != nil and sign(prev_level) != sign(level) -> {:halt, false}
true -> {:cont, level}
end
end)
end
defp sign(x) when x > 0, do: "+"
defp sign(x) when x < 0, do: "-"
end
Part One
Code - Part 1
defmodule PartOne do
def solve(input) do
IO.puts("--- Part One ---")
IO.puts("Result: #{run(input)}")
end
def run(input) do
input
|> Parser.parse()
|> Enum.count(&Shared.is_safe/1)
end
end
Tests - Part 1
ExUnit.start(autorun: false)
defmodule PartOneTest do
use ExUnit.Case, async: true
import PartOne
@input """
7 6 4 2 1
1 2 7 8 9
9 7 6 2 1
1 3 2 4 5
8 6 4 4 1
1 3 6 7 9
"""
@expected 2
test "part one" do
actual = run(@input)
assert actual == @expected
end
end
ExUnit.run()
Solution - Part 1
PartOne.solve(puzzle_input)
Part Two
Code - Part 2
defmodule PartTwo do
def solve(input) do
IO.puts("--- Part Two ---")
IO.puts("Result: #{run(input)}")
end
def run(input) do
input
|> Parser.parse()
|> Enum.count(&is_safe/1)
end
defp is_safe(report) do
Enum.count(report)..0
|> Enum.any?(fn i ->
report
|> List.delete_at(i)
|> Shared.is_safe()
end)
end
end
Tests - Part 2
ExUnit.start(autorun: false)
defmodule PartTwoTest do
use ExUnit.Case, async: true
import PartTwo
@input """
7 6 4 2 1
1 2 7 8 9
9 7 6 2 1
1 3 2 4 5
8 6 4 4 1
1 3 6 7 9
"""
@expected 4
test "part two" do
actual = run(@input)
assert actual == @expected
end
end
ExUnit.run()
Solution - Part 2
PartTwo.solve(puzzle_input)