diff --git a/aoc2024/Cargo.lock b/aoc2024/Cargo.lock index 4c609b5..e57694d 100644 --- a/aoc2024/Cargo.lock +++ b/aoc2024/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + [[package]] name = "aho-corasick" version = "1.1.3" @@ -47,7 +62,7 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -57,7 +72,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" dependencies = [ "anstyle", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -66,9 +81,11 @@ version = "0.1.0" dependencies = [ "clap 4.5.21", "criterion", + "miette", "nom", - "owo-colors", + "owo-colors 3.5.0", "rstest", + "toml", ] [[package]] @@ -88,12 +105,42 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "backtrace" +version = "0.3.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets", +] + +[[package]] +name = "backtrace-ext" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "537beee3be4a18fb023b570f80e3ae28003db9167a751266b259926e25539d50" +dependencies = [ + "backtrace", +] + [[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + [[package]] name = "bumpalo" version = "3.16.0" @@ -118,8 +165,8 @@ version = "2.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ - "bitflags", - "textwrap", + "bitflags 1.3.2", + "textwrap 0.11.0", "unicode-width", ] @@ -257,6 +304,22 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + [[package]] name = "futures" version = "0.3.31" @@ -352,12 +415,24 @@ dependencies = [ "slab", ] +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + [[package]] name = "half" version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" + [[package]] name = "heck" version = "0.5.0" @@ -373,6 +448,16 @@ dependencies = [ "libc", ] +[[package]] +name = "indexmap" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" +dependencies = [ + "equivalent", + "hashbrown", +] + [[package]] name = "is_ci" version = "1.2.0" @@ -422,6 +507,12 @@ version = "0.2.167" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc" +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + [[package]] name = "log" version = "0.4.22" @@ -434,12 +525,52 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "miette" +version = "7.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317f146e2eb7021892722af37cf1b971f0a70c8406f487e24952667616192c64" +dependencies = [ + "backtrace", + "backtrace-ext", + "cfg-if", + "miette-derive", + "owo-colors 4.1.0", + "supports-color 3.0.2", + "supports-hyperlinks", + "supports-unicode", + "terminal_size", + "textwrap 0.16.1", + "thiserror", + "unicode-width", +] + +[[package]] +name = "miette-derive" +version = "7.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23c9b935fbe1d6cbd1dac857b54a688145e2d93f48db36010514d0f612d0ad67" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + [[package]] name = "minimal-lexical" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + [[package]] name = "nom" version = "7.1.3" @@ -459,6 +590,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "object" +version = "0.36.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.20.2" @@ -477,9 +617,15 @@ version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" dependencies = [ - "supports-color", + "supports-color 1.3.1", ] +[[package]] +name = "owo-colors" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb37767f6569cd834a413442455e0f066d0d522de8630436e2a1761d9726ba56" + [[package]] name = "pin-project-lite" version = "0.2.15" @@ -613,6 +759,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + [[package]] name = "rustc_version" version = "0.4.1" @@ -622,6 +774,19 @@ dependencies = [ "semver", ] +[[package]] +name = "rustix" +version = "0.38.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" +dependencies = [ + "bitflags 2.6.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + [[package]] name = "ryu" version = "1.0.18" @@ -685,6 +850,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +dependencies = [ + "serde", +] + [[package]] name = "slab" version = "0.4.9" @@ -710,6 +884,27 @@ dependencies = [ "is_ci", ] +[[package]] +name = "supports-color" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c64fc7232dd8d2e4ac5ce4ef302b1d81e0b80d055b9d77c7c4f51f6aa4c867d6" +dependencies = [ + "is_ci", +] + +[[package]] +name = "supports-hyperlinks" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "804f44ed3c63152de6a9f90acbea1a110441de43006ea51bcce8f436196a288b" + +[[package]] +name = "supports-unicode" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2" + [[package]] name = "syn" version = "1.0.109" @@ -732,6 +927,16 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "terminal_size" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5352447f921fda68cf61b4101566c0bdb5104eff6804d0678e5227580ab6a4e9" +dependencies = [ + "rustix", + "windows-sys 0.59.0", +] + [[package]] name = "textwrap" version = "0.11.0" @@ -741,6 +946,36 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "textwrap" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" +dependencies = [ + "unicode-linebreak", + "unicode-width", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + [[package]] name = "tinytemplate" version = "1.2.1" @@ -751,12 +986,52 @@ dependencies = [ "serde_json", ] +[[package]] +name = "toml" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + [[package]] name = "unicode-ident" version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" +[[package]] +name = "unicode-linebreak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" + [[package]] name = "unicode-width" version = "0.1.14" @@ -866,7 +1141,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -875,6 +1150,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-sys" version = "0.59.0" @@ -947,3 +1231,12 @@ name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +dependencies = [ + "memchr", +] diff --git a/aoc2024/Cargo.toml b/aoc2024/Cargo.toml index 5041e92..7adbfbb 100644 --- a/aoc2024/Cargo.toml +++ b/aoc2024/Cargo.toml @@ -9,6 +9,8 @@ edition = "2021" [dependencies] clap = { version = "4.0.29", features = ["derive"] } criterion = "0.3.6" +miette = { version = "7.4.0", features = ["fancy"] } nom = "7.1.3" owo-colors = { version = "3.5.0", features = ["supports-colors"] } rstest = "0.16.0" +toml = "0.8.19" diff --git a/aoc2024/src/days/day01.rs b/aoc2024/src/days/day01.rs index 84a82e4..7b0ec46 100644 --- a/aoc2024/src/days/day01.rs +++ b/aoc2024/src/days/day01.rs @@ -2,32 +2,33 @@ use std::collections::HashMap; use crate::Solution; -fn parse_day1(input: &str) -> (Vec, Vec) { - let mut first = input +fn parse_day1(input: &str) -> miette::Result<(Vec, Vec)> { + let mut first: Vec = input .lines() .map(|line| { line.split_whitespace() .next() - .unwrap() + .ok_or_else(|| miette::miette!("Missing first value in line"))? .parse::() - .unwrap() + .map_err(|e| miette::miette!("Failed to parse first value as i32: {}", e)) }) - .collect::>(); + .collect::, _>>()?; - let mut second = input + let mut second: Vec = input .lines() .map(|line| { line.split_whitespace() .nth(1) - .unwrap() + .ok_or_else(|| miette::miette!("Missing second value in line"))? .parse::() - .unwrap() + .map_err(|e| miette::miette!("Failed to parse second value as i32: {}", e)) }) - .collect::>(); + .collect::, _>>()?; + first.sort(); second.sort(); - (first, second) + Ok((first, second)) } fn distance(it: (i32, i32)) -> i32 { @@ -36,26 +37,26 @@ fn distance(it: (i32, i32)) -> i32 { pub struct Problem; impl Solution for Problem { - fn part_one(&self, input: &str) -> String { - let (first, second) = parse_day1(input); - Iterator::zip(first.into_iter(), second) + fn part_one(&self, input: &str) -> miette::Result { + let (first, second) = parse_day1(input)?; + Ok(Iterator::zip(first.into_iter(), second) .map(distance) .sum::() - .to_string() + .to_string()) } - fn part_two(&self, input: &str) -> String { - let (first, second) = parse_day1(input); + fn part_two(&self, input: &str) -> miette::Result { + let (first, second) = parse_day1(input)?; let mut m: HashMap = HashMap::new(); for x in second { *m.entry(x).or_default() += 1; } - first + Ok(first .iter() .map(|v| (*v as usize) * m.get(v).unwrap_or(&0)) .sum::() - .to_string() + .to_string()) } } @@ -68,21 +69,21 @@ mod tests { #[test] fn part1_test() { - assert_eq!(Problem.part_one(TEST_INPUT), "11"); + assert_eq!(Problem.part_one(TEST_INPUT).unwrap(), "11"); } #[test] fn part2_test() { - assert_eq!(Problem.part_two(TEST_INPUT), "31"); + assert_eq!(Problem.part_two(TEST_INPUT).unwrap(), "31"); } #[test] fn part1() { - assert_eq!(Problem.part_one(INPUT), "2066446"); + assert_eq!(Problem.part_one(INPUT).unwrap(), "2066446"); } #[test] fn part2() { - assert_eq!(Problem.part_two(INPUT), "24931009"); + assert_eq!(Problem.part_two(INPUT).unwrap(), "24931009"); } } diff --git a/aoc2024/src/days/day02.rs b/aoc2024/src/days/day02.rs index 3143e3d..8f55b9e 100644 --- a/aoc2024/src/days/day02.rs +++ b/aoc2024/src/days/day02.rs @@ -38,26 +38,26 @@ fn is_safe(sequence: &[i32], mut dampener_levels: usize) -> bool { pub struct Problem; impl Solution for Problem { - fn part_one(&self, input: &str) -> String { + fn part_one(&self, input: &str) -> miette::Result { let reports = parse(input); - reports + Ok(reports .iter() .map(|levels| is_safe(levels, 0)) .filter(|&e| e) .count() - .to_string() + .to_string()) } - fn part_two(&self, input: &str) -> String { + fn part_two(&self, input: &str) -> miette::Result { let reports = parse(input); - reports + Ok(reports .iter() .map(|levels| is_safe(levels, 1)) .filter(|&e| e) .count() - .to_string() + .to_string()) } } @@ -70,21 +70,21 @@ mod tests { #[test] fn part1_test() { - assert_eq!(Problem.part_one(TEST_INPUT), "2"); + assert_eq!(Problem.part_one(TEST_INPUT).unwrap(), "2"); } #[test] fn part2_test() { - assert_eq!(Problem.part_two(TEST_INPUT), "5"); + assert_eq!(Problem.part_two(TEST_INPUT).unwrap(), "5"); } #[test] fn part1() { - assert_eq!(Problem.part_one(INPUT), "326"); + assert_eq!(Problem.part_one(INPUT).unwrap(), "326"); } #[test] fn part2() { - assert_eq!(Problem.part_two(INPUT), "381"); + assert_eq!(Problem.part_two(INPUT).unwrap(), "381"); } } diff --git a/aoc2024/src/days/day03.rs b/aoc2024/src/days/day03.rs index 567cd28..034bf1f 100644 --- a/aoc2024/src/days/day03.rs +++ b/aoc2024/src/days/day03.rs @@ -47,23 +47,25 @@ enum Process { pub struct Problem; impl Solution for Problem { - fn part_one(&self, input: &str) -> String { - let (_, instrs) = parse(input).unwrap(); + fn part_one(&self, input: &str) -> miette::Result { + let (_, instrs) = parse(input).map_err(|err| miette::miette!("Parsing failed: {:?}", err))?; - instrs + let res = instrs .iter() .map(|instr| match instr { Instruction::Mul(x, y) => x * y, _ => 0, }) .sum::() - .to_string() + .to_string(); + + Ok(res) } - fn part_two(&self, input: &str) -> String { - let (_input, instructions) = parse(input).unwrap(); + fn part_two(&self, input: &str) -> miette::Result { + let (_, instructions) = parse(input).map_err(|err| miette::miette!("Parsing failed: {:?}", err))?; - instructions + let res = instructions .iter() .fold((Process::DoProcess, 0), |(process, acc), ins| match ins { Instruction::Mul(a, b) => { @@ -77,7 +79,9 @@ impl Solution for Problem { Instruction::Dont => (Process::DontProcess, acc), }) .1 - .to_string() + .to_string(); + + Ok(res) } } @@ -91,21 +95,21 @@ mod tests { #[test] fn part1_test() { - assert_eq!(Problem.part_one(TEST_INPUT), "161"); + assert_eq!(Problem.part_one(TEST_INPUT).unwrap(), "161"); } #[test] fn part2_test() { - assert_eq!(Problem.part_two(TEST_INPUT_2), "48"); + assert_eq!(Problem.part_two(TEST_INPUT_2).unwrap(), "48"); } #[test] fn part1() { - assert_eq!(Problem.part_one(INPUT), "178886550"); + assert_eq!(Problem.part_one(INPUT).unwrap(), "178886550"); } #[test] fn part2() { - assert_eq!(Problem.part_two(INPUT), "87163705"); + assert_eq!(Problem.part_two(INPUT).unwrap(), "87163705"); } } diff --git a/aoc2024/src/days/day04.rs b/aoc2024/src/days/day04.rs index b5a35f6..d1b8617 100644 --- a/aoc2024/src/days/day04.rs +++ b/aoc2024/src/days/day04.rs @@ -4,7 +4,7 @@ const SUB: &str = "XMAS"; pub struct Problem; impl Solution for Problem { - fn part_one(&self, input: &str) -> String { + fn part_one(&self, input: &str) -> miette::Result { let mtx: Vec> = input.lines().map(|line| line.chars().collect()).collect(); let mut permutations: Vec = vec![]; @@ -64,10 +64,10 @@ impl Solution for Problem { .count(); } - count.to_string() + Ok(count.to_string()) } - fn part_two(&self, input: &str) -> String { + fn part_two(&self, input: &str) -> miette::Result { // thank god part 2 is WAY easier. let mtx: Vec> = input.lines().map(|line| line.chars().collect()).collect(); @@ -103,7 +103,7 @@ impl Solution for Problem { } } - count.to_string() + Ok(count.to_string()) } } @@ -116,21 +116,21 @@ mod tests { #[test] fn part1_test() { - assert_eq!(Problem.part_one(TEST_INPUT), "18"); + assert_eq!(Problem.part_one(TEST_INPUT).unwrap(), "18"); } #[test] fn part2_test() { - assert_eq!(Problem.part_two(TEST_INPUT), "9"); + assert_eq!(Problem.part_two(TEST_INPUT).unwrap(), "9"); } #[test] fn part1() { - assert_eq!(Problem.part_one(INPUT), "2547"); + assert_eq!(Problem.part_one(INPUT).unwrap(), "2547"); } #[test] fn part2() { - assert_eq!(Problem.part_two(INPUT), "1939"); + assert_eq!(Problem.part_two(INPUT).unwrap(), "1939"); } } diff --git a/aoc2024/src/lib.rs b/aoc2024/src/lib.rs index ce612b9..e007a72 100644 --- a/aoc2024/src/lib.rs +++ b/aoc2024/src/lib.rs @@ -2,8 +2,8 @@ #![feature(iter_intersperse)] pub trait Solution { - fn part_one(&self, input: &str) -> String; - fn part_two(&self, input: &str) -> String; + fn part_one(&self, input: &str) -> miette::Result; + fn part_two(&self, input: &str) -> miette::Result; } pub fn get_input(day_num: usize, test: bool) -> String { diff --git a/aoc2024/src/main.rs b/aoc2024/src/main.rs index 43885f2..f9c7198 100644 --- a/aoc2024/src/main.rs +++ b/aoc2024/src/main.rs @@ -2,62 +2,94 @@ #![feature(iter_intersperse)] pub mod dayselect; +const YEAR: u16 = 2024; use aoc2024::*; -use clap::{arg, Parser}; +use clap::{arg, Parser, Subcommand}; use owo_colors::{OwoColorize, Stream::Stdout}; -fn run_all_days(test: bool) { +fn run_all_days(test: bool) -> miette::Result<()> { let days = (1..25).filter_map(dayselect::select_day); for (day_num, sol) in days.into_iter().enumerate() { let day_num = day_num + 1; - run_day(sol, day_num, test); + run_day(sol, day_num, test)?; } + + Ok(()) } -pub fn run_day(day: Box, day_num: usize, test: bool) { +pub fn run_day(day: Box, day_num: usize, test: bool) -> miette::Result<()> { println!("****** Solutions for day {day_num} ******"); let input = get_input(day_num, test); let part1 = day.part_one(&input); - println!( - "Part 1: {}", - part1.if_supports_color(Stdout, |text| text.bright_blue()) - ); + match part1 { + Ok(res) => println!( + "Part 1: {}", + res.if_supports_color(Stdout, |text| text.bright_blue()) + ), + Err(e) => eprintln!("Day {} part 1 failed running:\n{:?}", day_num, e) + } let part2 = day.part_two(&input); - println!( - "Part 2: {}", - part2.if_supports_color(Stdout, |text| text.bright_blue()) - ); + match part2 { + Ok(res) => println!( + "Part 2: {}", + res.if_supports_color(Stdout, |text| text.bright_blue()) + ), + Err(e) => eprintln!("Day {} part 2 failed running:\n{}", day_num, e) + } + Ok(()) } #[derive(Parser, Debug)] #[command(author, version, about, long_about = None)] struct Args { - /// Day to run - #[arg(short, long)] - day: Option, + #[command(subcommand)] + command: Command, +} - /// Flag to enable test input - #[arg(short, long, default_value_t = false)] - test: bool, +#[derive(Debug, Subcommand)] +enum Command { + Run { + /// Day to run + #[arg(short, long)] + day: Option, + /// Flag to enable test input + #[arg(short, long, default_value_t = false)] + test: bool, + }, + Template { + /// Day to generate template for + #[arg(short, long)] + day: usize, + }, } -fn main() { +fn main() -> miette::Result<()> { let args = Args::parse(); - if let Some(day) = args.day { - let solution = dayselect::select_day(day); - match solution { - Some(sol) => run_day(sol, day, args.test), - None => { - eprintln!( - "{}", - "No solution for day found for given day." - .if_supports_color(Stdout, |text| text.bright_red()) - ); - std::process::exit(1); + match args.command { + Command::Run { day, test } => { + if let Some(day) = day { + let solution = dayselect::select_day(day); + match solution { + Some(sol) => run_day(sol, day, test)?, + None => { + eprintln!( + "{}", + "No solution found for given day." + .if_supports_color(Stdout, |text| text.bright_red()) + ); + std::process::exit(1); + } + } + } else { + run_all_days(test)?; } } - } else { - run_all_days(args.test); + Command::Template { day } => { + todo!(); + } } + Ok(()) } + +pub fn template_file() {}