AoC2022/01
Mix.install([
{:memoize, "~> 1.4"},
{:tesla, "~> 1.4"}
])
defmodule Api do
use Tesla
use Memoize
@session System.fetch_env!("AOC_SESSION_COOKIE")
plug(Tesla.Middleware.BaseUrl, "https://adventofcode.com/2022/day/")
plug(Tesla.Middleware.Headers, [
{"cookie", "session=#{@session}"}
])
defmemo get_input(day) do
{:ok, response} = get("#{day}/input")
response.body
end
end
Day 1
calories_per_elf =
Api.get_input(1)
|> String.split("\n\n")
|> Enum.map(fn inventory ->
inventory
|> String.split("\n", trim: true)
|> Enum.map(fn item ->
String.to_integer(item)
end)
|> Enum.sum()
end)
p1 = calories_per_elf |> Enum.max()
p2 = calories_per_elf |> Enum.sort(:desc) |> Enum.take(3) |> Enum.sum()
{p1, p2}
Day 2
require Integer
# Replace rock(A|X), paper(B|Y) and scissors(C|Z) with corresponding points
# rock = 1, paper = 2, scissors = 3
processed_input =
Api.get_input(2)
|> String.split("\n", trim: true)
|> Enum.map(fn fight ->
String.replace(fight, ~r/(A|X)/, "1")
|> String.replace(~r/(B|Y)/, "2")
|> String.replace(~r/(C|Z)/, "3")
|> String.split(" ", trim: true)
|> Enum.map(fn x -> String.to_integer(x) end)
end)
p1 =
processed_input
|> Enum.map(fn [x, y] ->
v = x - y
isEven = Integer.is_even(v)
case v do
0 -> y + 3
v when v > 0 -> if isEven, do: y + 6, else: y
v when v < 0 -> if !isEven, do: y + 6, else: y
end
end)
|> Enum.sum()
# [rock, paper, scissors]
status = [1, 2, 3]
# Next element loses with the previous one:
# rock < paper < scissors < rock
# 1 < 2 < 3 < 1
p2 =
processed_input
|> Enum.map(fn [x, y] ->
case y do
1 -> Enum.at(status, rem(x + 1, 3))
2 -> x + 3
3 -> Enum.at(status, rem(x, 3)) + 6
end
end)
|> Enum.sum()
{p1, p2}
Day 3
# Starts with 0 so priority list index correspond to item priority
priority = "0abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
input = Api.get_input(3)
p1 =
input
|> String.split("\n", trim: true)
|> Enum.map(fn rucksack ->
{compartment1, compartment2} =
rucksack
|> String.split_at(div(String.length(rucksack), 2))
Enum.find(String.codepoints(compartment1), fn itemInCompartment1 ->
Enum.find(String.codepoints(compartment2), fn itemInCompartment2 ->
itemInCompartment1 == itemInCompartment2
end)
end)
end)
|> Enum.map(fn item ->
String.codepoints(priority)
|> Enum.find_index(fn p -> p == item end)
end)
|> Enum.sum()
p2 =
input
|> String.split("\n", trim: true)
|> Enum.chunk_every(3)
|> Enum.map(fn [rucksack1, rucksack2, rucksack3] ->
Enum.find(String.codepoints(rucksack1), fn itemInRucksack1 ->
Enum.find(String.codepoints(rucksack2), fn itemInRucksack2 ->
Enum.find(String.codepoints(rucksack3), fn itemInRucksack3 ->
itemInRucksack1 == itemInRucksack2 and
itemInRucksack2 == itemInRucksack3
end)
end)
end)
end)
|> Enum.map(fn item ->
String.codepoints(priority)
|> Enum.find_index(fn p -> p == item end)
end)
|> Enum.sum()
{p1, p2}
Day 4
test_input = "2-4,6-8
2-3,4-5
5-7,7-9
2-8,3-7
6-6,4-6
2-6,4-8"
input = Api.get_input(4)
p1 =
input
|> String.split("\n", trim: true)
|> Enum.map(fn pair -> String.split(pair, ",") end)
|> Enum.map(fn [d1, d2] ->
[x1, x2] = String.split(d1, "-") |> Enum.map(&String.to_integer(&1))
[y1, y2] = String.split(d2, "-") |> Enum.map(&String.to_integer(&1))
(x1 <= y1 and x2 >= y2) or
(x1 >= y1 and x2 <= y2)
end)
|> Enum.map(fn dup -> if dup, do: 1, else: 0 end)
|> Enum.sum()
p2 =
input
|> String.split("\n", trim: true)
|> Enum.map(fn pair -> String.split(pair, ",") end)
|> Enum.map(fn [d1, d2] ->
[x1, x2] = String.split(d1, "-") |> Enum.map(&String.to_integer(&1))
[y1, y2] = String.split(d2, "-") |> Enum.map(&String.to_integer(&1))
(x1 <= y1 and x2 >= y1) or
(x1 >= y1 and x1 <= y2)
end)
|> Enum.map(fn dup -> if dup, do: 1, else: 0 end)
|> Enum.sum()
{p1, p2}