Yea ok there are some elegant solutions in here, wow Made me almost not post mine
Regardless, I had some fun with and learned about String.myers_difference and Enum.frequencies
defmodule ExAOC2022.Day3 do
@input "./lib/day3_input.txt"
def puzzle1() do
prio = priority_map([?a..?z, ?A..?Z])
@input
|> file_by_line()
|> Enum.map(&by_compartment/1)
|> Enum.map(&eq/1)
|> Enum.map(&Keyword.get(prio, String.to_atom(&1)))
|> Enum.sum()
end
def puzzle2() do
prio = priority_map([?a..?z, ?A..?Z])
@input
|> file_by_line()
|> Enum.chunk_every(3)
|> Enum.map(&find_common_chars/1)
|> Enum.map(&Keyword.get(prio, String.to_atom(&1)))
|> Enum.sum()
end
# PRIVATE SHENANIGANS
defp by_compartment(content) do
mid_len = content |> String.length() |> div(2)
content |> String.split_at(mid_len)
end
defp eq({str1, str2}), do: String.myers_difference(str1, str2)[:eq]
defp find_common_chars(list_of_strings) do
list_of_strings
|> Enum.map(&uniq/1)
|> Enum.join()
|> String.graphemes()
|> Enum.frequencies()
|> Map.filter(fn {_k, v} -> v == 3 end)
|> Map.keys()
|> List.first()
end
defp uniq(str) do
str
|> String.graphemes()
|> Enum.uniq()
|> Enum.join()
end
defp priority_map(ranges) do
ranges
|> Enum.map(&priority/1)
|> Enum.concat()
|> Enum.with_index(1)
end
defp priority(range) do
range
|> Enum.map(&String.to_atom(<<&1::utf8>>))
end
defp file_by_line(file) do
file
|> File.read!()
|> String.split(~r/\R/, trim: true)
end
end
I made a small change to the ReqAOC fetch! function signature because I thought it looked nicer
Originally I was going to handle the session token behind the scenes, but Livebook is soooo good that the explicit version arguably provides better UX:
When I tested earlier today I had no problem, but now I’m getting “(Argument Error) unknown registry: Req.Finch” when I try to compile. Any idea what that’s about?
Not a specific idea, but anytime I have issues like that in Livebook first I try closing and re-opening the session and if that doesn’t working then I try forcing a reinstall with Mix.install(packages, force: true).
Can you post a minimal example somewhere? I’d be happy to take a closer look. Req starts its own default Finch pool on application start so if you’re trying to use ReqAOC at compile-time it may require some extra steps.
Oh, yeah. I’m a doofus. Set up the project as a lib but at the bottom of my day4.ex file I’m just outright calling the functions defined in that file. So at compile time no application is started. If I remove those and just run iex -S mix I can make it work. Thanks for helping me think it through.
Like some other people in this thread, I also went with code points to calculate the item priorities, but I took an exotic approach with List.myers_difference/2 for part 1. Before getting to part 2, I didn’t even know that MapSet exists… . Oh well, like in the previous days, I’m always happy to get feedback. It’s a great help to improve as I’m starting with Elixir.
I got the same feeling as you, but let’s take this as a learning opportunity . I also took myers_difference, but from List.myers_difference/2. I didn’t even know it was in String.