mafinar

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

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

Rainer

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

mafinar

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)

Where Next?

Popular Backend topics Top

DevotionGeo
I know that these benchmarks might not be the exact picture of real-world scenario, but still I expect a Rust web framework performing a ...
New
AstonJ
I’ve seen more and more people get into Rust recently, so thought it would be cool to have a thread for people to share what they like ab...
New
New
First poster: bot
Rust 2021 Roadmap by Mark-Simulacrum · Pull Request #3037 · rust-lang/rfcs. The focus of this year is on project health, specifically as...
New
AstonJ
Just discovered Fika - looks pretty neat! fn sum(a: Int, b: Int) : Float do a + b end I quite like the syntax, though would probably ...
New
Jsdr3398
I really need developers to help create my messaging platform but I’m not sure how much they want etc. I’ve never hired anyone before :s...
New
mafinar
This is going to be a long an frequently posted thread. While talking to a friend of mine who has taken data structure and algorithm cou...
New
jaeyson
Sorry for the very vague noob question, I really want to ask this: When do we use async or sync code in the context of Elixir? AFAIK gen...
New
KnowledgeIsPower
Do you just use plain Terraform alone? Do you use CDK for Terraform or other supporting tools (e.g. Terraform Cloud ) for Terraform?
New
lucasvegi
Hello guys! Perhaps some of you have already seen this invitation on other channels in the Elixir community or even responded to our sur...
New

Other popular topics Top

DevotionGeo
I know that these benchmarks might not be the exact picture of real-world scenario, but still I expect a Rust web framework performing a ...
New
Exadra37
I am thinking in building or buy a desktop computer for programing, both professionally and on my free time, and my choice of OS is Linux...
New
Exadra37
Oh just spent so much time on this to discover now that RancherOS is in end of life but Rancher is refusing to mark the Github repo as su...
New
AstonJ
If you are experiencing Rails console using 100% CPU on your dev machine, then updating your development and test gems might fix the issu...
New
Margaret
Hello everyone! This thread is to tell you about what authors from The Pragmatic Bookshelf are writing on Medium.
1147 28379 760
New
New
PragmaticBookshelf
Develop, deploy, and debug BEAM applications using BEAMOps: a new paradigm that focuses on scalability, fault tolerance, and owning each ...
New
CommunityNews
A Brief Review of the Minisforum V3 AMD Tablet. Update: I have created an awesome-minisforum-v3 GitHub repository to list information fo...
New
PragmaticBookshelf
Explore the power of Ash Framework by modeling and building the domain for a real-world web application. Rebecca Le @sevenseacat and ...
New
NewsBot
Node.js v22.14.0 has been released. Link: Release 2025-02-11, Version 22.14.0 'Jod' (LTS), @aduh95 · nodejs/node · GitHub
New