Refactor into cli and lib packages
This commit is contained in:
parent
4b1b27e2c6
commit
a622539277
18 changed files with 95 additions and 72 deletions
10
Cargo.lock
generated
10
Cargo.lock
generated
|
@ -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"
|
||||
|
|
19
Cargo.toml
19
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"
|
9
cli/Cargo.toml
Normal file
9
cli/Cargo.toml
Normal file
|
@ -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" }
|
|
@ -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::<Duration>::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;
|
13
lib/Cargo.toml
Normal file
13
lib/Cargo.toml
Normal file
|
@ -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"
|
|
@ -3,19 +3,33 @@ use crate::utils::Day;
|
|||
#[derive(Debug, Default)]
|
||||
pub struct Day10 {
|
||||
pub input: String,
|
||||
pub parsed: Vec<Vec<char>>
|
||||
pub parsed: Vec<Vec<char>>,
|
||||
}
|
||||
|
||||
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::<usize>();
|
||||
let dots_before = self
|
||||
.parsed
|
||||
.iter()
|
||||
.map(|line| line.iter().filter(|&&c| c == '.').count())
|
||||
.sum::<usize>();
|
||||
|
||||
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()
|
||||
|
@ -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::<usize>();
|
||||
let inner = dots_before
|
||||
- std::mem::take(&mut self.parsed)
|
||||
.into_iter()
|
||||
.map(|line| line.into_iter().filter(|&c| c == '+').count())
|
||||
.sum::<usize>();
|
||||
|
||||
inner.to_string()
|
||||
}
|
|
@ -90,13 +90,3 @@ pub async fn fetch_example(auth: String, day: u8, part: u8) -> (String, Option<S
|
|||
|
||||
(input, solution)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::fetcher;
|
||||
|
||||
#[tokio::test]
|
||||
async fn fetches_large_data() {
|
||||
fetcher::fetch_large(6, 1).await;
|
||||
}
|
||||
}
|
13
lib/src/lib.rs
Normal file
13
lib/src/lib.rs
Normal file
|
@ -0,0 +1,13 @@
|
|||
pub mod fetcher;
|
||||
pub mod utils;
|
||||
|
||||
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;
|
Loading…
Reference in a new issue