Add solutions for 2022:4-5
This commit is contained in:
parent
93d014893f
commit
c98303d0c1
4 changed files with 242 additions and 0 deletions
57
2022-elixir/lib/solutions/day_04.ex
Normal file
57
2022-elixir/lib/solutions/day_04.ex
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
defmodule Aoc.Solution.Day04 do
|
||||
import Aoc.Utils
|
||||
|
||||
@name "Day 4: Camp Cleanup"
|
||||
@behaviour Solution
|
||||
|
||||
@impl Solution
|
||||
def get_name, do: @name
|
||||
|
||||
@impl Solution
|
||||
def present(solution), do: "#{solution} assignment pairs overlap"
|
||||
|
||||
@impl Solution
|
||||
def present_again(solution), do: "Solution is #{solution}"
|
||||
|
||||
@impl Solution
|
||||
def parse!(raw) do
|
||||
raw
|
||||
|> split_lines()
|
||||
|> Enum.map(fn l -> parse_values(l, ",") end)
|
||||
end
|
||||
|
||||
@impl Solution
|
||||
def solve(pairs) do
|
||||
pairs
|
||||
|> ranges()
|
||||
|> overlaps()
|
||||
|> Enum.count()
|
||||
end
|
||||
|
||||
@impl Solution
|
||||
def solve_again(pairs) do
|
||||
pairs
|
||||
|> ranges()
|
||||
|> strict_overlaps()
|
||||
|> Enum.count()
|
||||
end
|
||||
|
||||
def ranges(rows) when length(rows) > 2 do
|
||||
Enum.map(rows, &ranges/1)
|
||||
end
|
||||
|
||||
def ranges(pairs) do
|
||||
Enum.map(pairs, fn p ->
|
||||
[start, stop] = parse_values(p, "-") |> Enum.map(&String.to_integer/1)
|
||||
MapSet.new(start..stop)
|
||||
end)
|
||||
end
|
||||
|
||||
def overlaps(ranges), do: Enum.filter(ranges, &overlap?/1)
|
||||
|
||||
def overlap?([a, b]), do: MapSet.subset?(a, b) or MapSet.subset?(b, a)
|
||||
|
||||
def strict_overlaps(ranges), do: Enum.filter(ranges, &strict_overlap?/1)
|
||||
|
||||
def strict_overlap?([a, b]), do: MapSet.intersection(a, b) |> Enum.count() > 0
|
||||
end
|
||||
122
2022-elixir/lib/solutions/day_05.ex
Normal file
122
2022-elixir/lib/solutions/day_05.ex
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
defmodule Aoc.Solution.Day05 do
|
||||
import Aoc.Utils
|
||||
|
||||
@name "Day 5: Supply Stacks"
|
||||
@behaviour Solution
|
||||
|
||||
@impl Solution
|
||||
def get_name, do: @name
|
||||
|
||||
@impl Solution
|
||||
def present(solution), do: "On 9000, top crate on each stack is #{solution}"
|
||||
|
||||
@impl Solution
|
||||
def present_again(solution), do: "On 9001, top crate on each stack is #{solution}"
|
||||
|
||||
@impl Solution
|
||||
def parse!(raw) do
|
||||
[initial_state, instructions] = raw |> String.split("\n\n")
|
||||
|
||||
{
|
||||
initial_state |> String.split("\n") |> Enum.drop(-1) |> parse_state(),
|
||||
instructions |> String.trim() |> split_lines() |> parse_instructions()
|
||||
}
|
||||
end
|
||||
|
||||
@impl Solution
|
||||
def solve({state, instructions}) do
|
||||
state
|
||||
|> move(instructions, 9000)
|
||||
|> topmost()
|
||||
end
|
||||
|
||||
@impl Solution
|
||||
def solve_again({state, instructions}) do
|
||||
state
|
||||
|> move(instructions, 9001)
|
||||
|> topmost()
|
||||
end
|
||||
|
||||
def parse_state(state) do
|
||||
blank = "[-]"
|
||||
len = Enum.map(state, &String.length/1) |> Enum.max()
|
||||
|
||||
Enum.map(state, fn line ->
|
||||
line
|
||||
|> String.pad_trailing(len)
|
||||
|> String.pad_leading(len + 1)
|
||||
|> String.replace(" ", " #{blank}")
|
||||
end)
|
||||
|> Enum.map(fn l ->
|
||||
l
|
||||
|> String.trim()
|
||||
|> String.split()
|
||||
end)
|
||||
|> Enum.zip()
|
||||
|> Enum.map(fn t ->
|
||||
t
|
||||
|> Tuple.to_list()
|
||||
|> Enum.reject(fn v -> v == blank end)
|
||||
|> Enum.map(fn v ->
|
||||
v
|
||||
|> String.slice(1..-2)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
def parse_instructions(lines) do
|
||||
Enum.map(lines, fn "move " <> line ->
|
||||
[steps, _f, from, _t, to] = String.split(line)
|
||||
Enum.map([steps, from, to], &String.to_integer/1)
|
||||
end)
|
||||
end
|
||||
|
||||
def move(state, [], _), do: state
|
||||
|
||||
def move(state, [[n, from, to] | remaining], model) do
|
||||
move(
|
||||
case model do
|
||||
9000 -> _move_9000(state, from - 1, to - 1, n)
|
||||
9001 -> _move_9001(state, from - 1, to - 1, n)
|
||||
end,
|
||||
remaining,
|
||||
model
|
||||
)
|
||||
end
|
||||
|
||||
def _move_9001(state, from, to, n) do
|
||||
{pre, rem} = state |> Enum.at(from) |> Enum.split(n)
|
||||
|
||||
state
|
||||
|> List.update_at(from, fn _ -> rem end)
|
||||
|> List.update_at(to, fn l -> pre ++ l end)
|
||||
end
|
||||
|
||||
def _move_9000(state, _from, _to, 0) do
|
||||
state
|
||||
end
|
||||
|
||||
def _move_9000(state, from, to, n) do
|
||||
case Enum.at(state, from) do
|
||||
[a | rem] ->
|
||||
_move_9000(
|
||||
state
|
||||
|> List.update_at(from, fn _ -> rem end)
|
||||
|> List.update_at(to, fn l -> [a | l] end),
|
||||
from,
|
||||
to,
|
||||
n - 1
|
||||
)
|
||||
|
||||
[] ->
|
||||
state
|
||||
|
||||
nil ->
|
||||
state
|
||||
end
|
||||
end
|
||||
|
||||
def topmost(state) do
|
||||
state |> Enum.map(&List.first/1) |> Enum.join("")
|
||||
end
|
||||
end
|
||||
30
2022-elixir/test/solutions/day_04_test.exs
Normal file
30
2022-elixir/test/solutions/day_04_test.exs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
defmodule Day04Test do
|
||||
use ExUnit.Case
|
||||
doctest Aoc.Solution.Day04
|
||||
import Aoc.Solution.Day04
|
||||
|
||||
@input ~s(
|
||||
2-4,6-8
|
||||
2-3,4-5
|
||||
5-7,7-9
|
||||
2-8,3-7
|
||||
6-6,4-6
|
||||
2-6,4-8
|
||||
)
|
||||
|
||||
test "04: Camp Cleanup, part 1" do
|
||||
expected = 2
|
||||
|
||||
result = @input |> parse!() |> solve()
|
||||
|
||||
assert result == expected
|
||||
end
|
||||
|
||||
test "04: Camp Cleanup, part 2" do
|
||||
expected = 4
|
||||
|
||||
result = @input |> parse!() |> solve_again()
|
||||
|
||||
assert result == expected
|
||||
end
|
||||
end
|
||||
33
2022-elixir/test/solutions/day_05_test.exs
Normal file
33
2022-elixir/test/solutions/day_05_test.exs
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
defmodule Day05Test do
|
||||
use ExUnit.Case
|
||||
doctest Aoc.Solution.Day05
|
||||
import Aoc.Solution.Day05
|
||||
|
||||
@input ~s(
|
||||
[D]
|
||||
[N] [C]
|
||||
[Z] [M] [P]
|
||||
1 2 3
|
||||
|
||||
move 1 from 2 to 1
|
||||
move 3 from 1 to 3
|
||||
move 2 from 2 to 1
|
||||
move 1 from 1 to 2
|
||||
)
|
||||
|
||||
test "05: Supply Stacks, part 1" do
|
||||
expected = "CMZ"
|
||||
|
||||
result = @input |> parse!() |> solve()
|
||||
|
||||
assert result == expected
|
||||
end
|
||||
|
||||
test "05: Supply Stacks, part 2" do
|
||||
expected = "MCD"
|
||||
|
||||
result = @input |> parse!() |> solve_again()
|
||||
|
||||
assert result == expected
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Reference in a new issue