
mafinar
Advent of Code 2021
Hello folks! We had a pretty fun thread here around the same time last year - talking about Advent of Code problems. That also happened to be the first (and only so far) year I solved all Advent of Code problems on time and did not lazy myself out of it.
So, it is still a few days more to go, but wanted to open up a thread on it again and bring back the friends, old and new to tackle the puzzles in a language (or more) of choice!
I’ll be doing some “warm-up” exercises when I have some time and start a conversation around them early on.
Looking forward to December 1 and talking with y’all!
Most Liked

OvermindDL1
I built a framework yesterday to waaaaaaay overdesign handling these instead of my normal per-problem-program style, unsure why, but it’s fun and I get great CLI help, lol. It’s available at:
2021-01 is at:
The first part of the function is just opening the file and parsing it with way too much error checking (which is entirely unnecessary for an AoC, but again, overdesigned, lol). The part that solves each part is just (nums is the array of integers, yes I know I could have solved them while parsing without storing anything, and I did that originally, but I like how pretty this even if a couple microseconds slower, lol):
println!(
"Step 1: {}",
nums.iter()
.tuple_windows()
.map(|(a, b)| a < b)
.filter(|&x| x)
.count()
);
println!(
"Step 2: {}",
nums.iter()
.tuple_windows()
.map(|(a, b, c)| a + b + c)
.tuple_windows()
.map(|(a, b)| a < b)
.filter(|&x| x)
.count()
);
And my result times:
❯ cargo run --release -- -v 2021 1 ./inputs/2021/day1.input
Compiling advent_of_code v0.1.0 (/home/overminddl1/rust/advent_of_code)
Finished release [optimized] target(s) in 14.08s
Running `target/release/advent_of_code -v 2021 1 ./inputs/2021/day1.input`
AocApp { verbose: 1, command: Run(Year2021 { day: Day1(Day1 { input_file: "./inputs/2021/day1.input" }) }) }
Step 1: 1448
Step 2: 1471
Time Taken: 97.823µs
(The original version that didn’t store the integers and rather just calculated as it went was at just over 92µs, so that’s the extra cost of the allocations and such.)
EDIT1: Broke out the file reading/parsing code into a standalone module for all the tasks to share (my all generic helpers
name, lol), so now my complete 2021-01 code is now:
use crate::aoc::helpers::*;
use clap::Parser;
use itertools::Itertools;
use std::path::PathBuf;
#[derive(Debug, Parser)]
pub struct Day1 {
/// The input file of "depths"
pub input_file: PathBuf,
}
impl Day1 {
pub fn run(&self) -> anyhow::Result<()> {
let nums =
map_trimmed_nonempty_lines_of_file(
&self.input_file,
|line| Ok(line.parse::<usize>()?),
)?;
println!(
"Step 1: {}",
nums.iter()
.tuple_windows()
.map(|(a, b)| a < b)
.filter(|&x| x)
.count()
);
println!(
"Step 2: {}",
nums.iter()
.tuple_windows()
.map(|(a, b, c)| a + b + c)
.tuple_windows()
.map(|(a, b)| a < b)
.filter(|&x| x)
.count()
);
Ok(())
}
}
EDIT2: And by pretty help messages I mean like this:
❯ ./target/release/advent_of_code 2021 1 --help
advent_of_code-2021-1
Advent of Code 2021, Day 1 - Sonar Sweep
USAGE:
advent_of_code 2021 1 <INPUT_FILE>
ARGS:
<INPUT_FILE> The input file of "depths"
OPTIONS:
-h, --help Print help information
Each year and day are a command subtask as well, so each has it’s own help too:
❯ ./target/release/advent_of_code 2021 --help
advent_of_code-2021
Advent of Code 2021
USAGE:
advent_of_code 2021 <SUBCOMMAND>
OPTIONS:
-h, --help Print help information
SUBCOMMANDS:
1 Advent of Code 2021, Day 1 - Sonar Sweep
help Print this message or the help of the given subcommand(s)
And the top-most help:
❯ ./target/release/advent_of_code --help
advent_of_code
USAGE:
advent_of_code [OPTIONS] <SUBCOMMAND>
OPTIONS:
-h, --help Print help information
-v, --verbose Level of verbosity, can be used multiple times for more verbosity
SUBCOMMANDS:
2015 Advent of Code 2015
2016 Advent of Code 2016
2017 Advent of Code 2017
2018 Advent of Code 2018
2019 Advent of Code 2019
2020 Advent of Code 2020
2021 Advent of Code 2021
help Print this message or the help of the given subcommand(s)
tui
(It’s far more pretty in the terminal with it’s colorization and all too)
Like I said, waaaaaaay overdesigned this, lol.
EDIT3: Added ability to run all known solutions with the default inputs in the input
directory, and the output:
Year2015
Year2015 Time Taken: 70ns
Year2016
Year2016 Time Taken: 70ns
Year2017
Year2017 Time Taken: 70ns
Year2016
Year2016 Time Taken: 70ns
Year2019
Year2019 Time Taken: 80ns
Year2020
Day1
Step 1: 731731
Step 2: 116115990
Day1 Time Taken: 187.376µs
Day2
Step 1: 515
Step 2: 711
Day2 Time Taken: 485.364µs
Year2020 Time Taken: 709.758µs
Year2021
Day1
Step 1: 1448
Step 2: 1471
Day1 Time Taken: 239.692µs
Year2021 Time Taken: 253.871µs
All Time Taken: 1.005027ms
(The times are because I have verbose mode showing with -v
.)

Rainer
Well, then maybe also LFE would be worth a try?

mafinar
Advent of Code Day 1 completed. Took me 3 minutes to complete yet I did not get a position in the leaderboard.
I started with Elixir, then went ahead and did F# as well.
The Elixir one:
defmodule AdventOfCode.Y2021.Day01 do
@moduledoc """
--- Day 1: Sonar Sweep ---
Problem Link: https://adventofcode.com/2021/day/1
"""
use AdventOfCode.Helpers.InputReader, year: 2021, day: 1
def run_1, do: input!() |> parse() |> depth_increase()
def run_2, do: input!() |> parse() |> sliding_window() |> depth_increase()
def parse(data) do
data
|> String.split("\n")
|> Enum.map(&String.to_integer/1)
end
defp depth_increase(measurements) do
measurements
|> Enum.chunk_every(2, 1, :discard)
|> Enum.count(fn [a, b] -> b - a > 0 end)
end
defp sliding_window(measurements) do
measurements
|> Enum.chunk_every(3, 1, :discard)
|> Enum.map(&Enum.sum/1)
end
end
The F# One:
/// Advent of Code 2021
/// Day 1: Sonar Sweep
/// Description: https://adventofcode.com/2021/day/1
module Year2021Day01
open AdventOfCode.FSharp.Utils
module Solution =
let increase =
Seq.pairwise
>> Seq.filter (fun (a, b) -> b - a > 0)
>> Seq.length
let solvePart1 = ints >> increase >> output
let solvePart2 =
let slidingWindow =
Seq.pairwise
>> Seq.pairwise
>> Seq.map (fun ((a, b), (_, d)) -> a + b + d)
ints >> slidingWindow >> increase >> output
let solve (input: string seq) = (solvePart1 input, solvePart2 input)
Popular Backend topics










Other popular topics









Latest in Backend
Latest (all)
Categories:
Popular Portals
- /elixir
- /rust
- /wasm
- /ruby
- /erlang
- /phoenix
- /keyboards
- /js
- /rails
- /python
- /security
- /go
- /swift
- /vim
- /clojure
- /java
- /haskell
- /emacs
- /svelte
- /onivim
- /typescript
- /crystal
- /c-plus-plus
- /tailwind
- /kotlin
- /gleam
- /react
- /flutter
- /elm
- /ocaml
- /vscode
- /opensuse
- /ash
- /centos
- /php
- /deepseek
- /scala
- /zig
- /html
- /debian
- /nixos
- /lisp
- /agda
- /react-native
- /textmate
- /sublime-text
- /kubuntu
- /arch-linux
- /revery
- /ubuntu
- /manjaro
- /spring
- /django
- /diversity
- /nodejs
- /lua
- /slackware
- /julia
- /c
- /neovim