This topic is about Day 1 of the Advent of Code 2021.
We have a private leaderboard (shared with users of Erlang Forums):
https://adventofcode.com/2021/leaderboard/private/view/370884
The entry code is:
370884-a6a71927
This topic is about Day 1 of the Advent of Code 2021.
We have a private leaderboard (shared with users of Erlang Forums):
https://adventofcode.com/2021/leaderboard/private/view/370884
The entry code is:
370884-a6a71927
Here is my solution in Elixir:
And over at the Erlang Forums is my solution in Erlang:
Here’s mine:
advent_of_code/day_01.ex at master · code-shoily/advent_of_code (github.com)
Observations:
chunk_by
and chunk_while
-s document. Everytime something needs chunking, I reach out for chunk_by
and end up using chunk
or chunk_every
chunk_every
's :discard
My solution using chunk_every/4
Part 1
#!/usr/bin/env elixir
File.stream!("input.txt")
|> Stream.map(&String.trim/1)
|> Stream.map(&String.to_integer/1)
|> Stream.chunk_every(2, 1, :discard)
|> Enum.count(fn [a, b] -> a < b end)
|> IO.inspect()
Part 2
#!/usr/bin/env elixir
File.stream!("input.txt")
|> Stream.map(&String.trim/1)
|> Stream.map(&String.to_integer/1)
|> Stream.chunk_every(3, 1, :discard)
|> Stream.map(&Enum.sum/1)
|> Stream.chunk_every(2, 1, :discard)
|> Enum.count(fn [a, b] -> a < b end)
|> IO.inspect()
omg … why did I not think about a < b
and used b - a > 0
instead? Not just the first time but also afterwards when I was looking at it through F#
Actually, I did the same thing in Part 1, and realized that I can just write a < b
in Part 2
I took the questions quite literally in my head and on code. I was more obsessed with getting in the leaderboard so I can forgive myself for the first time. But I totally should have seen it the second time.
Also, glad to see your code again @Aetherus … I remember taking help from some of your solutions last year
Really? I’m flattered. I had a hard time solving problems in the later days of AoC, maybe I need to polish my programming skills more.
I have been randomly solving Advent of Code problems throughout the year, with Elixir. But whenever I see a problem involving 2D arrays or dynamic programming, regardless of practice, I start to panic. One example that comes to mind is Year 2017, Day 3. The idea of solving that gets me nervous lol.
TIL Enum.zip_reduce/3
def parse(path) do
File.stream!(path)
|> Enum.map(&String.trim(&1))
|> Enum.map(&String.to_integer(&1))
end
def depth_increment_count(input, step \\ 1) do
Enum.zip_reduce([input, Enum.drop(input, step)], 0, fn [a, b], acc ->
if b > a do
acc + 1
else
acc
end
end)
end
def trios_increment(input) do
depth_increment_count(input, 3)
end
Edited for DRYing.
Exactly. I just worked out the answer to part 1. Part 2 is scary. I can’t find a non-brute-force way of solving it.
Yet another function in Enum
I didn’t know
In comparison of A1 + A2 + A3 and B1 + B2 + B3 you really only compare A1 and B3 b/c A2 == B1 and A3 == B2. I think that counts as “non brute force”.
Nice point. Based on your suggestion, I reimplemented part 2:
#!/usr/bin/env elixir
File.stream!("input.txt")
|> Stream.map(&String.trim/1)
|> Stream.map(&String.to_integer/1)
|> Stream.chunk_every(4, 1, :discard) # <-- Now the window size is 4
|> Enum.count(fn [a, _, _, d] -> a < d end) # <-- and just compare the first and last elements in each window
|> IO.inspect()
No sum at all.
Did not know about zip_with
Hi again, great to see everyone for another year of AoC!
Haven’t been coding Elixir in a while so was a bit rusty but ended up with a similar solution. However I didn’t come to think about using chunk_every
for the first chunking and instead did a l |> Enum.zip(Enum.drop(l, 1))
, will try to internalise that
def run1(data) do
parse_input(data)
|> sum_increases()
end
def run2(data) do
parse_input(data)
|> Enum.chunk_every(3, 1, :discard)
|> Enum.map(fn l -> Enum.sum(l) end)
|> sum_increases()
end
defp parse_input(data) do
data
|> String.trim()
|> String.split()
|> Enum.map(&String.to_integer/1)
end
defp sum_increases(numbers) do
numbers
|> Enum.zip(Enum.drop(numbers, 1))
|> Enum.map(fn {last, current} -> if current > last, do: :increased, else: :decreased end)
|> Enum.filter(fn i -> i == :increased end)
|> Enum.count()
end
Unfortunately it looks like the leaderboard is now full
Anyway, yet another solution using chunk_every
:
defmodule Aoc2021.Day1 do
def part1(input) do
input
|> parse()
|> sliding_windows(2)
|> Enum.count(fn [prev, curr] -> curr > prev end)
end
def part2(input) do
input
|> parse()
|> sliding_windows(3)
|> Enum.map(&Enum.sum/1)
|> sliding_windows(2)
|> Enum.count(fn [prev, curr] -> curr > prev end)
end
defp parse(input) do
input
|> String.split()
|> Enum.map(&String.to_integer/1)
end
defp sliding_windows(enumerable, size), do: Enum.chunk_every(enumerable, size, 1, :discard)
end
There’s a private leaderboard at the top of this topic. I don’t know if there’s a member limit on each private leaderboard.
That private leaderboard has been used for several years and the limit of 200 users has been reached. I have posted the link and code for a new private leaderboard.
Just donated 5 dollars to AoC