8 Commits

Author SHA1 Message Date
f413b08da6 Very quick implementation for day 1 2021-12-01 09:30:03 +01:00
10531e3422 Merge pull request #3 from bertptrs/prepare/2021 2021-12-01 09:08:43 +01:00
2e0a7ea81d Update READMEs for 2021. 2021-11-29 20:31:29 +01:00
2c64028978 Enable debug information for release 2021-11-28 17:13:27 +01:00
89159137fe Add other days 2021-11-28 17:12:26 +01:00
186d91d1b7 Use function pointers over dyn traits 2021-11-28 16:49:37 +01:00
c985ba8a1a Add CI for 2021 2021-11-22 18:51:59 +01:00
cece8439a7 Initial 2021 runner 2021-11-20 11:57:32 +01:00
34 changed files with 2514 additions and 1 deletions

46
.github/workflows/2021.yml vendored Normal file
View File

@@ -0,0 +1,46 @@
on:
- push
name: Advent of Code 2021
jobs:
ci:
strategy:
matrix:
toolchain:
- stable
- beta
experimental: [false]
include:
- toolchain: nightly
experimental: true
name: Continuous Integration
runs-on: ubuntu-latest
continue-on-error: ${{ matrix.experimental }}
steps:
- uses: actions/checkout@v2
- name: Install toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: ${{ matrix.toolchain }}
override: true
components: rustfmt, clippy
- name: Build binaries
working-directory: 2021
run: >
cargo build --all-targets
- name: Run tests
working-directory: 2021
run: >
cargo test
- name: Run clippy
working-directory: 2021
run: >
cargo clippy -- --deny warnings

3
.gitignore vendored
View File

@@ -56,3 +56,6 @@ docs/_build/
# PyBuilder
target/
*.swp
# Rust lock
*.lock

12
2021/Cargo.toml Normal file
View File

@@ -0,0 +1,12 @@
[package]
name = "aoc-2021"
version = "0.1.0"
edition = "2021"
[dependencies]
clap = "3.0.0-beta.5"
[profile.release]
# Keep debug information in release for better flamegraphs
debug = true

22
2021/README.md Normal file
View File

@@ -0,0 +1,22 @@
# Advent of Code 2021
This folder contains the solution runner for Advent of Code 2021. All days will be solved in Rust,
with the goal of having a total time across all puzzles of one second or less.
```
aoc-2021
Advent of Code 2021 runner
USAGE:
aoc-2021 [OPTIONS] <DAY>
ARGS:
<DAY> Which day to run
OPTIONS:
-2, --part2 Run part 2 instead of part 1
-h, --help Print help information
-i, --input <INPUT> Read input from the given file instead of stdin
-t, --time Print time taken
```

2000
2021/inputs/01.txt Normal file

File diff suppressed because it is too large Load Diff

63
2021/src/day01.rs Normal file
View File

@@ -0,0 +1,63 @@
use std::io::BufRead;
use std::io::BufReader;
use std::io::Read;
fn read_input(input: &mut dyn Read) -> Vec<u32> {
let reader = BufReader::new(input);
// TODO: optimize allocations out
reader
.lines()
.map(|l| l.unwrap().parse().unwrap())
.collect()
}
pub fn part1(input: &mut dyn Read) -> String {
let numbers = read_input(input);
numbers
.windows(2)
.filter(|w| w[1] > w[0])
.count()
.to_string()
}
pub fn part2(input: &mut dyn Read) -> String {
let numbers = read_input(input);
let mut last = None;
numbers
.windows(3)
.filter(|w| {
let sum: u32 = w.iter().sum();
let prev = last.replace(sum);
match prev {
Some(n) if n < sum => true,
_ => false,
}
})
.count()
.to_string()
}
#[cfg(test)]
mod tests {
use crate::test_implementation;
use super::*;
const SAMPLE: &[u8] = include_bytes!("samples/01.txt");
#[test]
fn sample_part1() {
test_implementation(part1, SAMPLE, 7);
}
#[test]
fn sample_part2() {
test_implementation(part2, SAMPLE, 5);
}
}

9
2021/src/day02.rs Normal file
View File

@@ -0,0 +1,9 @@
use std::io::Read;
pub fn part1(_input: &mut dyn Read) -> String {
todo!()
}
pub fn part2(_input: &mut dyn Read) -> String {
todo!()
}

9
2021/src/day03.rs Normal file
View File

@@ -0,0 +1,9 @@
use std::io::Read;
pub fn part1(_input: &mut dyn Read) -> String {
todo!()
}
pub fn part2(_input: &mut dyn Read) -> String {
todo!()
}

9
2021/src/day04.rs Normal file
View File

@@ -0,0 +1,9 @@
use std::io::Read;
pub fn part1(_input: &mut dyn Read) -> String {
todo!()
}
pub fn part2(_input: &mut dyn Read) -> String {
todo!()
}

9
2021/src/day05.rs Normal file
View File

@@ -0,0 +1,9 @@
use std::io::Read;
pub fn part1(_input: &mut dyn Read) -> String {
todo!()
}
pub fn part2(_input: &mut dyn Read) -> String {
todo!()
}

9
2021/src/day06.rs Normal file
View File

@@ -0,0 +1,9 @@
use std::io::Read;
pub fn part1(_input: &mut dyn Read) -> String {
todo!()
}
pub fn part2(_input: &mut dyn Read) -> String {
todo!()
}

9
2021/src/day07.rs Normal file
View File

@@ -0,0 +1,9 @@
use std::io::Read;
pub fn part1(_input: &mut dyn Read) -> String {
todo!()
}
pub fn part2(_input: &mut dyn Read) -> String {
todo!()
}

9
2021/src/day08.rs Normal file
View File

@@ -0,0 +1,9 @@
use std::io::Read;
pub fn part1(_input: &mut dyn Read) -> String {
todo!()
}
pub fn part2(_input: &mut dyn Read) -> String {
todo!()
}

9
2021/src/day09.rs Normal file
View File

@@ -0,0 +1,9 @@
use std::io::Read;
pub fn part1(_input: &mut dyn Read) -> String {
todo!()
}
pub fn part2(_input: &mut dyn Read) -> String {
todo!()
}

9
2021/src/day10.rs Normal file
View File

@@ -0,0 +1,9 @@
use std::io::Read;
pub fn part1(_input: &mut dyn Read) -> String {
todo!()
}
pub fn part2(_input: &mut dyn Read) -> String {
todo!()
}

9
2021/src/day11.rs Normal file
View File

@@ -0,0 +1,9 @@
use std::io::Read;
pub fn part1(_input: &mut dyn Read) -> String {
todo!()
}
pub fn part2(_input: &mut dyn Read) -> String {
todo!()
}

9
2021/src/day12.rs Normal file
View File

@@ -0,0 +1,9 @@
use std::io::Read;
pub fn part1(_input: &mut dyn Read) -> String {
todo!()
}
pub fn part2(_input: &mut dyn Read) -> String {
todo!()
}

9
2021/src/day13.rs Normal file
View File

@@ -0,0 +1,9 @@
use std::io::Read;
pub fn part1(_input: &mut dyn Read) -> String {
todo!()
}
pub fn part2(_input: &mut dyn Read) -> String {
todo!()
}

9
2021/src/day14.rs Normal file
View File

@@ -0,0 +1,9 @@
use std::io::Read;
pub fn part1(_input: &mut dyn Read) -> String {
todo!()
}
pub fn part2(_input: &mut dyn Read) -> String {
todo!()
}

9
2021/src/day15.rs Normal file
View File

@@ -0,0 +1,9 @@
use std::io::Read;
pub fn part1(_input: &mut dyn Read) -> String {
todo!()
}
pub fn part2(_input: &mut dyn Read) -> String {
todo!()
}

9
2021/src/day16.rs Normal file
View File

@@ -0,0 +1,9 @@
use std::io::Read;
pub fn part1(_input: &mut dyn Read) -> String {
todo!()
}
pub fn part2(_input: &mut dyn Read) -> String {
todo!()
}

9
2021/src/day17.rs Normal file
View File

@@ -0,0 +1,9 @@
use std::io::Read;
pub fn part1(_input: &mut dyn Read) -> String {
todo!()
}
pub fn part2(_input: &mut dyn Read) -> String {
todo!()
}

9
2021/src/day18.rs Normal file
View File

@@ -0,0 +1,9 @@
use std::io::Read;
pub fn part1(_input: &mut dyn Read) -> String {
todo!()
}
pub fn part2(_input: &mut dyn Read) -> String {
todo!()
}

9
2021/src/day19.rs Normal file
View File

@@ -0,0 +1,9 @@
use std::io::Read;
pub fn part1(_input: &mut dyn Read) -> String {
todo!()
}
pub fn part2(_input: &mut dyn Read) -> String {
todo!()
}

9
2021/src/day20.rs Normal file
View File

@@ -0,0 +1,9 @@
use std::io::Read;
pub fn part1(_input: &mut dyn Read) -> String {
todo!()
}
pub fn part2(_input: &mut dyn Read) -> String {
todo!()
}

9
2021/src/day21.rs Normal file
View File

@@ -0,0 +1,9 @@
use std::io::Read;
pub fn part1(_input: &mut dyn Read) -> String {
todo!()
}
pub fn part2(_input: &mut dyn Read) -> String {
todo!()
}

9
2021/src/day22.rs Normal file
View File

@@ -0,0 +1,9 @@
use std::io::Read;
pub fn part1(_input: &mut dyn Read) -> String {
todo!()
}
pub fn part2(_input: &mut dyn Read) -> String {
todo!()
}

9
2021/src/day23.rs Normal file
View File

@@ -0,0 +1,9 @@
use std::io::Read;
pub fn part1(_input: &mut dyn Read) -> String {
todo!()
}
pub fn part2(_input: &mut dyn Read) -> String {
todo!()
}

9
2021/src/day24.rs Normal file
View File

@@ -0,0 +1,9 @@
use std::io::Read;
pub fn part1(_input: &mut dyn Read) -> String {
todo!()
}
pub fn part2(_input: &mut dyn Read) -> String {
todo!()
}

5
2021/src/day25.rs Normal file
View File

@@ -0,0 +1,5 @@
use std::io::Read;
pub fn part1(_input: &mut dyn Read) -> String {
todo!()
}

97
2021/src/lib.rs Normal file
View File

@@ -0,0 +1,97 @@
use std::io::Read;
type Solution = fn(&mut dyn Read) -> String;
mod day01;
mod day02;
mod day03;
mod day04;
mod day05;
mod day06;
mod day07;
mod day08;
mod day09;
mod day10;
mod day11;
mod day12;
mod day13;
mod day14;
mod day15;
mod day16;
mod day17;
mod day18;
mod day19;
mod day20;
mod day21;
mod day22;
mod day23;
mod day24;
mod day25;
pub fn get_implementation(day: usize, part2: bool) -> Solution {
if !part2 {
match day {
1 => day01::part1,
2 => day02::part1,
3 => day03::part1,
4 => day04::part1,
5 => day05::part1,
6 => day06::part1,
7 => day07::part1,
8 => day08::part1,
9 => day09::part1,
10 => day10::part1,
11 => day11::part1,
12 => day12::part1,
13 => day13::part1,
14 => day14::part1,
15 => day15::part1,
16 => day16::part1,
17 => day17::part1,
18 => day18::part1,
19 => day19::part1,
20 => day20::part1,
21 => day21::part1,
22 => day22::part1,
23 => day23::part1,
24 => day24::part1,
25 => day25::part1,
_ => panic!("Unsupported part one for day {}", day),
}
} else {
match day {
1 => day01::part2,
2 => day02::part2,
3 => day03::part2,
4 => day04::part2,
5 => day05::part2,
6 => day06::part2,
7 => day07::part2,
8 => day08::part2,
9 => day09::part2,
10 => day10::part2,
11 => day11::part2,
12 => day12::part2,
13 => day13::part2,
14 => day14::part2,
15 => day15::part2,
16 => day16::part2,
17 => day17::part2,
18 => day18::part2,
19 => day19::part2,
20 => day20::part2,
21 => day21::part2,
22 => day22::part2,
23 => day23::part2,
24 => day24::part2,
_ => panic!("Unsupported part two for day {}", day),
}
}
}
#[cfg(test)]
fn test_implementation(solution: Solution, data: impl AsRef<[u8]>, answer: impl ToString) {
let result = solution(&mut data.as_ref());
assert_eq!(answer.to_string(), result);
}

47
2021/src/main.rs Normal file
View File

@@ -0,0 +1,47 @@
use std::fs::File;
use std::io::Read;
use std::num::NonZeroUsize;
use std::path::PathBuf;
use std::time::Instant;
use clap::Parser;
use aoc_2021::get_implementation;
/// Advent of Code 2021 runner
#[derive(Parser)]
struct Opts {
/// Which day to run
day: NonZeroUsize,
/// Print time taken
#[clap(short, long)]
time: bool,
/// Run part 2 instead of part 1
#[clap(short = '2', long)]
part2: bool,
/// Read input from the given file instead of stdin
#[clap(short, long)]
input: Option<PathBuf>,
}
fn main() {
let opts: Opts = Opts::parse();
let mut input: Box<dyn Read> = if let Some(input) = opts.input {
Box::new(File::open(&input).expect("Failed to open input"))
} else {
Box::new(std::io::stdin())
};
let begin = Instant::now();
let result = get_implementation(opts.day.get(), opts.part2)(&mut *input);
if opts.time {
eprintln!("Execution time: {:?}", Instant::now().duration_since(begin));
}
println!("{}", result);
}

10
2021/src/samples/01.txt Normal file
View File

@@ -0,0 +1,10 @@
199
200
208
210
200
207
240
269
260
263

View File

@@ -1,6 +1,6 @@
# Advent of Code
[![Build Status](https://travis-ci.org/bertptrs/adventofcode.svg?branch=master)](https://travis-ci.org/bertptrs/adventofcode)
[![Advent of Code 2021](https://github.com/bertptrs/adventofcode/actions/workflows/2021.yml/badge.svg)](https://github.com/bertptrs/adventofcode/actions/workflows/2021.yml)
This repository contains my solutions for Advent of Code. See:
@@ -10,3 +10,4 @@ This repository contains my solutions for Advent of Code. See:
- [2018 edition](./2018)
- [2019 edition](./2019)
- [2020 edition](./2020)
- [2021 edition](./2021)