christhekeele
Thought I’d kick today’s thread off!
Parsing
Enum rocks, so most of my code was actually in parsing input.
Preprocessing input
Data model is:
%{
id :: integer() => [
pull :: %{
red: integer(),
green: integer(),
blue: integer()
}
]
}
I modeled each pull as a struct rather than a bare map, just so I didn’t have to write any extra code to hydrate my maps with default 0 values where input was empty for a color.
Source available here.
defmodule AoC.Day.Two.Input do
defmodule Pull do
defstruct red: 0, green: 0, blue: 0
end
def parse(input_file \\ System.fetch_env!("INPUT_FILE")) do
input_file
|> File.read!()
|> String.split("\n")
|> Enum.reject(&(&1 == ""))
|> Enum.map(&parse_game/1)
|> Map.new()
end
def parse_game("Game " <> game) do
{id, rest} = Integer.parse(game)
<<": ">> <> pulls = rest
pulls =
pulls
|> String.trim()
|> String.split(";")
|> Enum.map(&String.trim/1)
|> Enum.map(&parse_pull/1)
{id, pulls}
end
def parse_pull(pull) do
result =
pull
|> String.split(",")
|> Enum.map(&String.trim/1)
|> Enum.map(&parse_pull_color/1)
struct!(Pull, result)
end
def parse_pull_color(result) do
case Integer.parse(result) do
{num, " red"} -> {:red, num}
{num, " green"} -> {:green, num}
{num, " blue"} -> {:blue, num}
end
end
end
Part 1
Solution
input |> Enum.filter(Enum.all?) |> Enum.map |> Enum.sum. Source available here.
defmodule AoC.Day.Two.Part.One do
@red_limit 12
@green_limit 13
@blue_limit 14
def solve(input) do
input
|> Enum.filter(fn {_id, pulls} ->
Enum.all?(pulls, fn
%{red: red, green: green, blue: blue}
when red <= @red_limit and green <= @green_limit and blue <= @blue_limit ->
true
_ ->
false
end)
end)
|> Enum.map(fn {id, _} -> id end)
|> Enum.sum()
end
end
Part 2
Solution
Simpler still. Could have avoided iterating over pulls 3 times, but not too fussed about it. Source available here.
defmodule AoC.Day.Two.Part.Two do
def solve(input) do
input
|> Enum.map(fn {id, pulls} ->
min_red = pulls |> Enum.map(&Map.fetch!(&1, :red)) |> Enum.max()
min_green = pulls |> Enum.map(&Map.fetch!(&1, :green)) |> Enum.max()
min_blue = pulls |> Enum.map(&Map.fetch!(&1, :blue)) |> Enum.max()
{id, min_red * min_green * min_blue}
end)
|> Enum.map(fn {_id, power} -> power end)
|> Enum.sum()
end
end
Trending in Challenges
Other Trending Topics
I am happy to introduce the very α version of the new programming language compiled to BEAM.
Welcome Cure.
It has literally three kille...
New
Hi there! We created Gust: A task orchestrator inspired by Airflow.
For those who have never heard about Aiflow, it’s a Python-based wor...
New
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself.
My main conc...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #ai
- #elixirconf-us
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
adamu
After seeing part 2, we know that both parts only need the aggregate of all the rounds, so for each game I used a single map representing the maximum number of cubes seen.
https://git.adamu.jp/adam/AdventOfCode/src/branch/main/2023/day2.exs
christhekeele
That
Map.merge/3is a very elegant way to get all maxes in one iteration, I wouldn’t’ve thought of it!Aetherus
I was thinking maybe this puzzle could be solved using nimble_parsec, but when I tried, I just got lost because I couldn’t understand the documentation and the examples
Maybe I should just go for yecc.
christhekeele
I struggle with the docs for both every time I have to pick them up
. Would love to see that incarnation if you get around to it!
Aetherus
I have to attend my sister’s wedding ceremony now. Maybe later.
seeplusplus
I was able to knock this one out much quicker than yesterday’s
Edit: really impressed with the brevity from some of the solutions I’ve seen for the last two days. Great stuff all.
midouest
Did a little more work than I needed to in part 1, but it made the modifications for part 2 pretty easy! This was a nice day 2 problem
Part 1
Part 2
mexicat
Quite straightforward with
Regex.scanandEnum.group_by:https://github.com/mexicat/aoc-2023/blob/main/lib/aoc/day_02.ex
kip
I also elected in part 1 to build a map that kept the maxima for each color for each game. Which meant that part 2 was really trivial. This kind of “one off” multi-level parsing is a bit tricky to produce easily readable code and @christhekeele definitely did better than I did.
Pre-processing
Part 1
With the maxima already stored it was straight forward to calculate the games. I tend to reach for
Enum/reduce/3in these cases more than most (it seems).Part 2
This is trivial since the data is already in the right format. Again I find `Enum.reduce` super handy because it already accumulates.herisson
Very elegant, I miss a lot of training with pattern matching.
I did not know one could pattern match on the string directly. That must me a good advantage comparing to other programming langages