day 3
Mix.install([
{:kino, "~> 0.8.0"}
])
setup
input = Kino.Input.textarea("drop yo text input here")
scratch
?a..?z
|> Enum.to_list()
|> List.to_string()
|> String.split("", trim: true)
|> Enum.with_index(fn e, i -> {e, i + 1} end)
|> Enum.into(%{})
test_input = """
vJrwpWtwJgWrhcsFMMfFFhFp
jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
PmmdzqPrVvPwwTWBwg
wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
ttgJtRGJQctTZtZT
CrZsJsPPZsGzwwsLwLmpwMDw
"""
MapSet.intersection(MapSet.new([1, 2, 3]), MapSet.new([2, 3, 3])) |> Enum.into([])
part 1
defmodule P1 do
defguard double_list(a, b) when is_list(a) and is_list(b)
defguard double_map(a, b) when is_map(a) and is_map(b)
def sum(items) do
az_lower_case = alpha_range(?a..?z, 1)
az_upper_case = alpha_range(?A..?Z, 27)
items
|> Enum.reduce(0, fn i, acc ->
l = Map.get(az_lower_case, i, 0)
u = Map.get(az_upper_case, i, 0)
acc + l + u
end)
end
def parse(input_str) do
input_str
|> String.split("\n", trim: true)
|> Enum.map(&process_line/1)
|> Enum.sum()
end
defp process_line(sack) do
items =
sack
|> String.split("", trim: true)
{left, right} =
items
|> Enum.split(div(length(items), 2))
intersect(left, right)
|> sum()
end
defp intersect(a, b) when double_list(a, b) do
intersect(MapSet.new(a), MapSet.new(b))
end
defp intersect(a, b) when double_map(a, b) do
MapSet.intersection(a, b)
|> Enum.into([])
end
defp alpha_range(range, offset) do
range
|> Enum.to_list()
|> List.to_string()
|> String.split("", trim: true)
|> Enum.with_index(fn e, i -> {e, i + offset} end)
|> Enum.into(%{})
end
end
"""
vJrwpWtwJgWrhcsFMMfFFhFp
jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
PmmdzqPrVvPwwTWBwg
wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
ttgJtRGJQctTZtZT
CrZsJsPPZsGzwwsLwLmpwMDw
"""
|> P1.parse()
input
|> Kino.Input.read()
|> P1.parse()
test 1
ExUnit.start(auto_run: false)
defmodule P1Test do
use ExUnit.Case, async: false
test "parse" do
assert 157 ==
"""
vJrwpWtwJgWrhcsFMMfFFhFp
jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
PmmdzqPrVvPwwTWBwg
wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
ttgJtRGJQctTZtZT
CrZsJsPPZsGzwwsLwLmpwMDw
"""
|> P1.parse()
end
end
ExUnit.run()
part 2
defmodule P2 do
defguard double_list(a, b) when is_list(a) and is_list(b)
defguard double_map(a, b) when is_map(a) and is_map(b)
def sum(items) do
az_lower_case = alpha_range(?a..?z, 1)
az_upper_case = alpha_range(?A..?Z, 27)
items
|> Enum.reduce(0, fn i, acc ->
l = Map.get(az_lower_case, i, 0)
u = Map.get(az_upper_case, i, 0)
acc + l + u
end)
end
def parse(input_str) do
sacks =
input_str
|> String.split("\n", trim: true)
|> Enum.chunk_every(3)
sacks
|> Enum.map(fn b -> process_line(b) end)
|> Enum.sum()
end
defp process_line(group) do
lines =
group
|> Enum.map(fn s -> String.split(s, "", trim: true) end)
[a, b, c] = lines
ab = inter(a, b)
ac = inter(a, c)
inter(ab, ac) |> sum()
end
def inter(a, b) when double_list(a, b) do
inter(MapSet.new(a), MapSet.new(b))
end
def inter(a, b) when double_map(a, b) do
MapSet.intersection(a, b)
|> Enum.into([])
end
defp alpha_range(range, offset) do
range
|> Enum.to_list()
|> List.to_string()
|> String.split("", trim: true)
|> Enum.with_index(fn e, i -> {e, i + offset} end)
|> Enum.into(%{})
end
end
a = ["P", "m", "m", "d", "z", "q", "P", "r", "V", "v", "P", "w", "w", "T", "W", "B", "w", "g"]
b = [
"j",
"q",
"H",
"R",
"N",
"q",
"R",
"j",
"q",
"z",
"j",
"G",
"D",
"L",
"G",
"L",
"r",
"s",
"F",
"M",
"f",
"F",
"Z",
"S",
"r",
"L",
"r",
"F",
"Z",
"s",
"S",
"L"
]
c = [
"v",
"J",
"r",
"w",
"p",
"W",
"t",
"w",
"J",
"g",
"W",
"r",
"h",
"c",
"s",
"F",
"M",
"M",
"f",
"F",
"F",
"h",
"F",
"p"
]
ab = P2.inter(a, b)
ac = P2.inter(a, c)
# intersection of ab + ac
P2.inter(ab, ac)
"""
vJrwpWtwJgWrhcsFMMfFFhFp
jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
PmmdzqPrVvPwwTWBwg
wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
ttgJtRGJQctTZtZT
CrZsJsPPZsGzwwsLwLmpwMDw
"""
|> P2.parse()
input
|> Kino.Input.read()
|> P2.parse()
I asked ChatGPT to explain intesersection sets to me :)
> In set theory, an intersection is a combination of two or more sets that contains only the elements that are common to all of the sets. For example, if you have the sets A = {1, 2, 3} and B = {2, 3, 4}, the intersection of these sets would be the set C = {2, 3}. This is because the set C contains only the elements that are common to both set A and set B. In other words, the intersection of two sets is the set of elements that belong to both sets.
test 2
ExUnit.start(auto_run: false)
defmodule P1Test do
use ExUnit.Case, async: false
test "parse" do
assert 70 ==
"""
vJrwpWtwJgWrhcsFMMfFFhFp
jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
PmmdzqPrVvPwwTWBwg
wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
ttgJtRGJQctTZtZT
CrZsJsPPZsGzwwsLwLmpwMDw
"""
|> P2.parse()
end
end
ExUnit.run()