First day
authorGreg Burri <greg.burri@gmail.com>
Sat, 4 Dec 2021 16:10:50 +0000 (17:10 +0100)
committerGreg Burri <greg.burri@gmail.com>
Sat, 4 Dec 2021 16:10:50 +0000 (17:10 +0100)
.gitignore [new file with mode: 0644]
Cargo.toml [new file with mode: 0644]
README.md [new file with mode: 0644]
src/common.rs [new file with mode: 0644]
src/day01.rs [new file with mode: 0644]
src/main.rs [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..088ba6b
--- /dev/null
@@ -0,0 +1,10 @@
+# Generated by Cargo
+# will have compiled files and executables
+/target/
+
+# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
+# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
+Cargo.lock
+
+# These are backup files generated by rustfmt
+**/*.rs.bk
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644 (file)
index 0000000..5e26f12
--- /dev/null
@@ -0,0 +1,14 @@
+[package]
+name = "advent_of_code_2021"
+version = "0.1.0"
+authors = ["Greg Burri <greg.burri@gmail.com>"]
+edition = "2018"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+itertools = "0.10"
+threadpool = "1.8"
+regex = "1"
+num = "0.4"
+num_enum = "0.5"
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..0a6796a
--- /dev/null
+++ b/README.md
@@ -0,0 +1,27 @@
+# AdventOfCode2021
+
+https://adventofcode.com/2021
+
+
+# Running tests
+
+Example for day 1 tests:
+
+~~~
+cargo test day01 -- --nocapture
+~~~
+
+All tests:
+
+~~~
+cargo test -- --nocapture
+~~~
+
+
+# Running a day code
+
+~~~
+cargo run -- n
+~~~
+
+Where 'n' is a number from 1 to 25
diff --git a/src/common.rs b/src/common.rs
new file mode 100644 (file)
index 0000000..737ca8c
--- /dev/null
@@ -0,0 +1,13 @@
+use std::fs;
+use std::path::Path;
+use std::str::FromStr;
+
+pub fn read_list_of_numbers<P, T>(file: P, sep: &str) -> Vec<T>
+where
+    P: AsRef<Path>,
+    T: FromStr,
+    T::Err: std::fmt::Debug
+
+{
+    fs::read_to_string(file).unwrap().split(sep).map(|line| line.trim().parse::<T>().unwrap()).collect()
+}
\ No newline at end of file
diff --git a/src/day01.rs b/src/day01.rs
new file mode 100644 (file)
index 0000000..d4f1889
--- /dev/null
@@ -0,0 +1,35 @@
+pub fn count_number_of_decreased_values(report: &[i32], window_size: usize) -> i32 {
+    let mut n = 0;
+
+    let sum = |i: usize| -> i32 {
+        let mut s = 0;
+        for j in i..i+window_size {
+            s += report[j];
+        }
+        s
+    };
+
+    for i in 0..report.len() - window_size {
+        if sum(i+1) > sum(i) {
+            n += 1;
+        }
+    }
+    n
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn part1() {
+        let sea_floor_report = [ 199, 200, 208, 210, 200, 207, 240, 269, 260, 263 ];
+        assert_eq!(count_number_of_decreased_values(&sea_floor_report, 1), 7);
+    }
+
+    #[test]
+    fn part2() {
+        let sea_floor_report = [ 199, 200, 208, 210, 200, 207, 240, 269, 260, 263 ];
+        assert_eq!(count_number_of_decreased_values(&sea_floor_report, 3), 5);
+    }
+}
\ No newline at end of file
diff --git a/src/main.rs b/src/main.rs
new file mode 100644 (file)
index 0000000..d3592a1
--- /dev/null
@@ -0,0 +1,55 @@
+use std::env;
+use std::time::Instant;
+
+mod common;
+mod day01;
+
+fn day01() -> String {
+    let report = common::read_list_of_numbers("data/day01.input", "\n");
+    format!("part1: {}, part2: {}", day01::count_number_of_decreased_values(&report, 1), day01::count_number_of_decreased_values(&report, 3))
+}
+
+fn format_micros(t: u128) -> String {
+    if t < 10_000 {
+        format!("{} μs", t)
+    } else if t < 10_000_000u128 {
+        format!("{} ms", t / 1_000u128)
+    } else {
+        format!("{} s", t / 1_000_000u128)
+    }
+}
+
+fn do_day(days: &[fn() -> String], day: usize) {
+    let now = Instant::now();
+    println!("Result of day {:02}: {} (time: {})", day, days[day - 1](), format_micros(now.elapsed().as_micros()));
+}
+
+fn main() {
+    println!("https://adventofcode.com/2021");
+
+    let days: Vec<fn() -> String> = vec!(
+        day01,
+    );
+
+    let args: Vec<String> = env::args().skip(1).collect();
+
+    // No argument -> execute all day problems.
+    if args.is_empty() {
+        let now = Instant::now();
+        for i in 1 ..= days.len() {
+            do_day(&days, i)
+        }
+        println!("Time to execute all days: {}", format_micros(now.elapsed().as_micros()));
+    } else {
+        for arg in args {
+            match arg.parse::<usize>() {
+                Ok(day) if day >= 1 && day <= days.len() =>
+                    do_day(&days, day),
+                Ok(day) =>
+                    println!("Unknown day: {}", day),
+                Err(error) =>
+                    println!("Unable to parse day number: \"{}\", error: {}", arg, error)
+            }
+        }
+    }
+}