diff --git a/Cargo.lock b/Cargo.lock index b819ebb..7a1d570 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,7 +21,6 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" name = "advent" version = "0.1.0" dependencies = [ - "clap", "num-bigint", "num-irrational", "num-rational", @@ -31,6 +30,15 @@ dependencies = [ "tokio", ] +[[package]] +name = "advent-cli" +version = "0.1.0" +dependencies = [ + "advent", + "clap", + "tokio", +] + [[package]] name = "ahash" version = "0.8.6" diff --git a/Cargo.toml b/Cargo.toml index 19e3b28..d7351b1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,16 +1,3 @@ -[package] -name = "advent" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -clap = { version = "4.4.10", features = ["derive"] } -num-bigint = "0.4.4" -num-irrational = { version = "0.3.0", features = ["num-bigint"] } -num-rational = { version = "0.4.1", features = ["num-bigint"] } -regex = "1.10.2" -reqwest = "0.11.22" -scraper = "0.18.1" -tokio = { version = "1.34.0", features = ["macros", "rt-multi-thread"] } +[workspace] +members = ["cli", "lib"] +resolver = "2" \ No newline at end of file diff --git a/cli/Cargo.toml b/cli/Cargo.toml new file mode 100644 index 0000000..5848904 --- /dev/null +++ b/cli/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "advent-cli" +version = "0.1.0" +edition = "2021" + +[dependencies] +clap = { version = "4.4.10", features = ["derive"] } +tokio = { version = "1.34.0", features = ["macros", "rt-multi-thread"] } +advent = { path = "../lib" } \ No newline at end of file diff --git a/src/main.rs b/cli/src/main.rs similarity index 91% rename from src/main.rs rename to cli/src/main.rs index 9adb645..7fd7e0f 100644 --- a/src/main.rs +++ b/cli/src/main.rs @@ -4,25 +4,11 @@ use std::{ time::{Duration, Instant}, }; -use clap::{Parser, Subcommand, ValueEnum}; - -use crate::{ +use advent::{ day1::Day1, day10::Day10, day2::Day2, day3::Day3, day4::Day4, day5::Day5, day6::Day6, - day7::Day7, day8::Day8, day9::Day9, utils::Day, + day7::Day7, day8::Day8, day9::Day9, fetcher, utils::Day, }; - -pub mod day1; -pub mod day10; -pub mod day2; -pub mod day3; -pub mod day4; -pub mod day5; -pub mod day6; -pub mod day7; -pub mod day8; -pub mod day9; -pub mod fetcher; -pub mod utils; +use clap::{Parser, Subcommand, ValueEnum}; #[derive(Parser)] #[command(author, version, about, long_about = None)] @@ -86,7 +72,6 @@ enum Subcommands { #[tokio::main] async fn main() { let cli = Cli::parse(); - let client = reqwest::Client::new(); let auth = cli .auth .unwrap_or(std::env::var("AOC_SESSION").ok().expect("no auth provided")); @@ -132,7 +117,10 @@ async fn main() { }), 8 => Box::new(Day8 { input }), 9 => Box::new(Day9 { input }), - 10 => Box::new(Day10 { input, parsed: vec![] }), + 10 => Box::new(Day10 { + input, + parsed: vec![], + }), _ => panic!("Invalid day #"), }; let start = std::time::Instant::now(); @@ -198,7 +186,10 @@ async fn main() { }), 8 => Box::new(Day8 { input }), 9 => Box::new(Day9 { input }), - 10 => Box::new(Day10 { input, parsed: vec![] }), + 10 => Box::new(Day10 { + input, + parsed: vec![], + }), _ => panic!("Invalid day #"), }; let mut timings = Vec::::new(); @@ -240,19 +231,7 @@ async fn main() { println!("\nAverage timing: {avg}{avg_units} ± {deviation}{deviation_units}"); } Subcommands::Input { day } => { - let response = client - .get(format!("https://adventofcode.com/2023/day/{day}/input")) - .header("Cookie", format!("session={auth}")) - .send() - .await - .unwrap() - .text() - .await - .unwrap() - .trim_end() - .to_owned(); - - println!("{response}"); + println!("{}", fetcher::fetch_input(auth, day).await); } Subcommands::Example { day, part } => { let (input, solution) = fetcher::fetch_example(auth, day, part).await; diff --git a/lib/Cargo.toml b/lib/Cargo.toml new file mode 100644 index 0000000..de57434 --- /dev/null +++ b/lib/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "advent" +version = "0.1.0" +edition = "2021" + +[dependencies] +num-bigint = "0.4.4" +num-irrational = { version = "0.3.0", features = ["num-bigint"] } +num-rational = { version = "0.4.1", features = ["num-bigint"] } +regex = "1.10.2" +scraper = "0.18.1" +tokio = { version = "1.34.0", features = ["macros", "rt-multi-thread"] } +reqwest = "0.11.22" \ No newline at end of file diff --git a/src/day1/mod.rs b/lib/src/day1/mod.rs similarity index 100% rename from src/day1/mod.rs rename to lib/src/day1/mod.rs diff --git a/src/day10/mod.rs b/lib/src/day10/mod.rs similarity index 86% rename from src/day10/mod.rs rename to lib/src/day10/mod.rs index 6ffbefd..d4300d1 100644 --- a/src/day10/mod.rs +++ b/lib/src/day10/mod.rs @@ -3,19 +3,33 @@ use crate::utils::Day; #[derive(Debug, Default)] pub struct Day10 { pub input: String, - pub parsed: Vec> + pub parsed: Vec>, } impl Day10 { /// Yes I copied this from wikipedia /// https://en.wikipedia.org/wiki/Flood_fill#Stack-based_recursive_implementation_(four-way) pub fn flood_fill(&mut self, start: (usize, usize)) { - if !(self.parsed[start.0][start.1] == '.' || self.parsed[start.0][start.1] == 'x') { return } // If node is not Inside return. - if self.parsed[start.0][start.1] == '.' { self.parsed[start.0][start.1] = '+' } else { self.parsed[start.0][start.1] = '=' } // Set the node - if start.0 != self.parsed.len() - 1 { self.flood_fill((start.0 + 1, start.1)) } // Perform Flood-fill one step to the south of node. - if start.0 != 0 { self.flood_fill((start.0 - 1, start.1)) } // Perform Flood-fill one step to the north of node - if start.1 != 0 { self.flood_fill((start.0, start.1 - 1)) } // Perform Flood-fill one step to the west of node - if start.1 != self.parsed[0].len() - 1 { self.flood_fill((start.0, start.1 + 1)) } // Perform Flood-fill one step to the east of node + if !(self.parsed[start.0][start.1] == '.' || self.parsed[start.0][start.1] == 'x') { + return; + } // If node is not Inside return. + if self.parsed[start.0][start.1] == '.' { + self.parsed[start.0][start.1] = '+' + } else { + self.parsed[start.0][start.1] = '=' + } // Set the node + if start.0 != self.parsed.len() - 1 { + self.flood_fill((start.0 + 1, start.1)) + } // Perform Flood-fill one step to the south of node. + if start.0 != 0 { + self.flood_fill((start.0 - 1, start.1)) + } // Perform Flood-fill one step to the north of node + if start.1 != 0 { + self.flood_fill((start.0, start.1 - 1)) + } // Perform Flood-fill one step to the west of node + if start.1 != self.parsed[0].len() - 1 { + self.flood_fill((start.0, start.1 + 1)) + } // Perform Flood-fill one step to the east of node return; // Return. } } @@ -124,7 +138,8 @@ impl Day for Day10 { self.parsed = self.input.lines().map(|l| l.chars().collect()).collect(); let line_len = self.parsed[0].len(); let height = self.parsed.len(); - let mut pos = self.parsed + let mut pos = self + .parsed .iter() .enumerate() .find_map(|(i, line)| line.iter().position(|&char| char == 'S').map(|v| (i, v))) @@ -232,7 +247,11 @@ impl Day for Day10 { }) .collect(); - let dots_before = self.parsed.iter().map(|line| line.iter().filter(|&&c| c == '.').count()).sum::(); + let dots_before = self + .parsed + .iter() + .map(|line| line.iter().filter(|&&c| c == '.').count()) + .sum::(); let s_tile = match start_connections { [1, 1] => '|', @@ -258,7 +277,8 @@ impl Day for Day10 { 'x' }, ] - }).collect(); + }) + .collect(); // Extend vertically let new = line .iter() @@ -274,7 +294,7 @@ impl Day for Day10 { self.parsed.push(new); } - self.flood_fill((0,0)); + self.flood_fill((0, 0)); // Dbg print lines // println!( @@ -286,7 +306,11 @@ impl Day for Day10 { // .join("\n") // ); - let inner = dots_before - std::mem::take(&mut self.parsed).into_iter().map(|line| line.into_iter().filter(|&c| c == '+').count()).sum::(); + let inner = dots_before + - std::mem::take(&mut self.parsed) + .into_iter() + .map(|line| line.into_iter().filter(|&c| c == '+').count()) + .sum::(); inner.to_string() } diff --git a/src/day2/mod.rs b/lib/src/day2/mod.rs similarity index 100% rename from src/day2/mod.rs rename to lib/src/day2/mod.rs diff --git a/src/day3/mod.rs b/lib/src/day3/mod.rs similarity index 100% rename from src/day3/mod.rs rename to lib/src/day3/mod.rs diff --git a/src/day4/mod.rs b/lib/src/day4/mod.rs similarity index 100% rename from src/day4/mod.rs rename to lib/src/day4/mod.rs diff --git a/src/day5/mod.rs b/lib/src/day5/mod.rs similarity index 100% rename from src/day5/mod.rs rename to lib/src/day5/mod.rs diff --git a/src/day6/mod.rs b/lib/src/day6/mod.rs similarity index 100% rename from src/day6/mod.rs rename to lib/src/day6/mod.rs diff --git a/src/day7/mod.rs b/lib/src/day7/mod.rs similarity index 100% rename from src/day7/mod.rs rename to lib/src/day7/mod.rs diff --git a/src/day8/mod.rs b/lib/src/day8/mod.rs similarity index 100% rename from src/day8/mod.rs rename to lib/src/day8/mod.rs diff --git a/src/day9/mod.rs b/lib/src/day9/mod.rs similarity index 100% rename from src/day9/mod.rs rename to lib/src/day9/mod.rs diff --git a/src/fetcher.rs b/lib/src/fetcher.rs similarity index 95% rename from src/fetcher.rs rename to lib/src/fetcher.rs index 1d66ea4..db19959 100644 --- a/src/fetcher.rs +++ b/lib/src/fetcher.rs @@ -90,13 +90,3 @@ pub async fn fetch_example(auth: String, day: u8, part: u8) -> (String, Option