diff --git a/bram/rust/.envrc b/bram/rust/.envrc new file mode 100644 index 0000000..65326bb --- /dev/null +++ b/bram/rust/.envrc @@ -0,0 +1 @@ +use nix \ No newline at end of file diff --git a/bram/rust/Cargo.toml b/bram/rust/Cargo.toml new file mode 100644 index 0000000..5b62c31 --- /dev/null +++ b/bram/rust/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "aoc2025" +version = "0.1.0" +edition = "2024" + +[dependencies] +colored = "3.0.0" diff --git a/bram/rust/inputs/01.txt b/bram/rust/inputs/01.txt new file mode 100644 index 0000000..e69de29 diff --git a/bram/rust/inputs/02.txt b/bram/rust/inputs/02.txt new file mode 100644 index 0000000..e69de29 diff --git a/bram/rust/inputs/03.txt b/bram/rust/inputs/03.txt new file mode 100644 index 0000000..e69de29 diff --git a/bram/rust/inputs/04.txt b/bram/rust/inputs/04.txt new file mode 100644 index 0000000..e69de29 diff --git a/bram/rust/inputs/05.txt b/bram/rust/inputs/05.txt new file mode 100644 index 0000000..e69de29 diff --git a/bram/rust/inputs/06.txt b/bram/rust/inputs/06.txt new file mode 100644 index 0000000..e69de29 diff --git a/bram/rust/inputs/07.txt b/bram/rust/inputs/07.txt new file mode 100644 index 0000000..e69de29 diff --git a/bram/rust/inputs/08.txt b/bram/rust/inputs/08.txt new file mode 100644 index 0000000..e69de29 diff --git a/bram/rust/inputs/09.txt b/bram/rust/inputs/09.txt new file mode 100644 index 0000000..e69de29 diff --git a/bram/rust/inputs/10.txt b/bram/rust/inputs/10.txt new file mode 100644 index 0000000..e69de29 diff --git a/bram/rust/inputs/11.txt b/bram/rust/inputs/11.txt new file mode 100644 index 0000000..e69de29 diff --git a/bram/rust/inputs/12.txt b/bram/rust/inputs/12.txt new file mode 100644 index 0000000..e69de29 diff --git a/bram/rust/shell.nix b/bram/rust/shell.nix new file mode 100644 index 0000000..2db320f --- /dev/null +++ b/bram/rust/shell.nix @@ -0,0 +1,9 @@ +{ pkgs ? import {} }: +pkgs.mkShell { + nativeBuildInputs = with pkgs; [ rustc cargo gcc rustfmt clippy valgrind ]; + + # Certain Rust tools won't work without this + # This can also be fixed by using oxalica/rust-overlay and specifying the rust-src extension + # See https://discourse.nixos.org/t/rust-src-not-found-and-other-misadventures-of-developing-rust-on-nixos/11570/3?u=samuela. for more details. + RUST_SRC_PATH = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}"; +} \ No newline at end of file diff --git a/bram/rust/src/day_01/mod.rs b/bram/rust/src/day_01/mod.rs new file mode 100644 index 0000000..cdbf3ed --- /dev/null +++ b/bram/rust/src/day_01/mod.rs @@ -0,0 +1,5 @@ +use crate::utils; + +pub fn answer(text : String) ->( u32, u32 ) { + ( 0, 0 ) +} diff --git a/bram/rust/src/lib.rs b/bram/rust/src/lib.rs new file mode 100644 index 0000000..5848ac2 --- /dev/null +++ b/bram/rust/src/lib.rs @@ -0,0 +1,88 @@ +mod day_01; +// mod day_02; +// mod day_03; +// mod day_04; +// mod day_05; +// mod day_06; +// mod day_07; +// mod day_08; +// mod day_09; +// mod day_10; +// mod day_11; +mod utils; + +use std::time::Duration; +use crate::utils::read_from_file; +use crate::utils::diagnostics; + +type DailyOutput = ( u128, u128, Duration ); + +pub fn day_01() -> DailyOutput { + let s : String = read_from_file("inputs/01.txt"); + let ( p1, p2, d ) = diagnostics::benchmark(s, day_01::answer); + + ( p1 as u128, p2 as u128, d ) +} + +// pub fn day_02() -> DailyOutput { +// let s : String = read_from_file("inputs/02.txt"); +// let (p1, p2, d) = diagnostics::benchmark(s, day_02::answer); + +// ( p1 as u128, p2 as u128, d ) +// } + +// pub fn day_03() -> DailyOutput { +// let s : String = read_from_file("inputs/03.txt"); +// let (p1, p2, d) = diagnostics::benchmark(s, day_03::answer); + +// ( p1 as u128, p2 as u128, d ) +// } + +// pub fn day_04() -> DailyOutput { +// let s : String = read_from_file("inputs/04.txt"); +// let (p1, p2, d) = diagnostics::benchmark(s, day_04::answer); + +// ( p1 as u128, p2 as u128, d ) +// } + +// pub fn day_05() -> DailyOutput { +// let s : String = read_from_file("inputs/05.txt"); +// let (p1, p2, d) = diagnostics::benchmark(s, day_05::answer); + +// ( p1 as u128, p2 as u128, d ) +// } + +// pub fn day_07() -> DailyOutput { +// let s : String = read_from_file("inputs/07.txt"); +// let (p1, p2, d) = diagnostics::benchmark(s, day_07::answer); + +// ( p1 as u128, p2 as u128, d ) +// } + +// pub fn day_08() -> DailyOutput { +// let s : String = read_from_file("inputs/08.txt"); +// let (p1, p2, d) = diagnostics::benchmark(s, day_08::answer); + +// ( p1 as u128, p2 as u128, d ) +// } + +// pub fn day_09() -> DailyOutput { +// let s : String = read_from_file("inputs/09.txt"); +// let (p1, p2, d) = diagnostics::benchmark(s, day_09::answer); + +// ( p1 as u128, p2 as u128, d ) +// } + +// pub fn day_10() -> DailyOutput { +// let s : String = read_from_file("inputs/10.txt"); +// let (p1, p2, d) = diagnostics::benchmark(s, day_10::answer); + +// ( p1 as u128, p2 as u128, d ) +// } + +// pub fn day_11() -> DailyOutput { +// let s : String = read_from_file("inputs/11.txt"); +// let (p1, p2, d) = diagnostics::benchmark(s, day_11::answer); + +// ( p1 as u128, p2 as u128, d ) +// } diff --git a/bram/rust/src/main.rs b/bram/rust/src/main.rs new file mode 100644 index 0000000..ea1e574 --- /dev/null +++ b/bram/rust/src/main.rs @@ -0,0 +1,20 @@ +mod utils; + +fn main() { + let mut aoc = crate::utils::diagnostics::AdventOfCode::new(); + + aoc.insert(1, aoc2025::day_01()); + // aoc.insert(2, aoc2025::day_02()); + // aoc.insert(3, aoc2025::day_03()); + // aoc.insert(4, aoc2025::day_04()); + // aoc.insert(5, aoc2025::day_05()); + // aoc.insert(6, aoc2025::day_06()); + // aoc.insert(7, aoc2025::day_07()); + // aoc.insert(8, aoc2025::day_08()); + // aoc.insert(9, aoc2025::day_09()); + // aoc.insert(10, aoc2025::day_10()); + // aoc.insert(11, aoc2025::day_11()); + // aoc.insert(12, aoc2025::day_12()); + + aoc.show_diagnostics(); +} diff --git a/bram/rust/src/utils/diagnostics.rs b/bram/rust/src/utils/diagnostics.rs new file mode 100644 index 0000000..542cdff --- /dev/null +++ b/bram/rust/src/utils/diagnostics.rs @@ -0,0 +1,100 @@ +use colored::Colorize; +use std::time::{Duration, Instant}; + +const MAX_MS_ON_SCREEN : u128 = 100; +const BAR_WIDTH_UNIT : f32 = 10.0; + +pub struct AdventOfCode { + days : [ Option; 12 ], +} +impl AdventOfCode { + pub fn insert(&mut self, i : usize, (p1, p2, d ) : ( u128, u128, Duration )) { + self.days[i - 1] = Some( + DayResults{ part_1 : p1, part_2 : p2, duration : d } + ); + } + + pub fn new() -> AdventOfCode { + AdventOfCode{ + // If I don't do it like this, the compiler wants me to define + // the Copy trait for the DayResults struct. + days : [ + None, None, None, None, + None, None, None, None, + None, None, None, None, + ] + } + } + + pub fn show_diagnostics(&self) { + println!("| | {: ^15} | {: ^15} | Duration |", + "Part 1", "Part 2" + ); + + let total : u128 = self.days + .iter() + .enumerate() + .map(|(day, result)| { + match result { + Some(r) => { + println!("{}", r.to_string(day + 1, MAX_MS_ON_SCREEN)); + r.duration.as_millis() + }, + None => { + println!("{}", empty_diagnostic(day + 1)); + 0 + }, + } + }) + .sum(); + + println!(""); + println!("Total duration: {total} ms"); + } +} + +struct DayResults { + part_1 : u128, + part_2 : u128, + duration : Duration, +} +impl DayResults { + fn to_string(&self, day : usize, max_duration : u128) -> String { + let duration = self.duration.as_millis(); + let fraction = duration as f32 / max_duration as f32; + + let g = horizontal_bar('#', ' ', 4.0 * BAR_WIDTH_UNIT * fraction, 2.0 * BAR_WIDTH_UNIT); + let o = horizontal_bar('#', ' ', 4.0 * BAR_WIDTH_UNIT * (fraction - 0.50), BAR_WIDTH_UNIT); + let r = horizontal_bar('#', ' ', 4.0 * BAR_WIDTH_UNIT * (fraction - 0.75), BAR_WIDTH_UNIT); + + format!( + "| Day {: >2} | {: >15} | {: >15} | {: >6}ms | [{: <}{: <6}{: <6}", + day, self.part_1, self.part_2, self.duration.as_millis(), + g.as_str().green(), o.as_str().yellow(), r.as_str().red() + ) + } +} + +pub fn benchmark(s : String, f : fn(String) -> ( A, B )) -> ( A, B, Duration ) { + let now = Instant::now(); + + let ( a, b ) = f(s); + + ( a, b, now.elapsed() ) +} + +fn empty_diagnostic(day : usize) -> String { + format!("| Day {: >2} | {:->15} | {:->15} | {:->8} | [", day, "", "", "") +} + +fn horizontal_bar(full : char, empty : char, width : f32, max_width : f32) -> String { + (0..(max_width.floor() as u32)) + .map(|w| { + if (w as f32) < width { + full + } else { + empty + } + }) + .collect() +} diff --git a/bram/rust/src/utils/mod.rs b/bram/rust/src/utils/mod.rs new file mode 100644 index 0000000..a3ff9d9 --- /dev/null +++ b/bram/rust/src/utils/mod.rs @@ -0,0 +1,33 @@ +use std::fs; + +pub mod diagnostics; + +pub fn char_to_u64(s : char) -> Option { + s.to_string().parse::().ok() +} + +pub fn read_from_file(name : &str) -> String { + match fs::read_to_string(name) { + Err(error) => { + println!("Failed to read file {name}: {error}"); + String::new() + }, + Ok(s) => s, + } +} + +pub fn str_to_i32(s : &str) -> Option { + s.trim().to_string().parse::().ok() +} + +pub fn str_to_u8(s : &str) -> Option { + s.trim().to_string().parse::().ok() +} + +pub fn str_to_u32(s : &str) -> Option { + s.trim().to_string().parse::().ok() +} + +pub fn str_to_u64(s : &str) -> Option { + s.trim().to_string().parse::().ok() +}