Skip to content

Commit

Permalink
refacotr: cleanup main
Browse files Browse the repository at this point in the history
  • Loading branch information
manhunto committed Nov 30, 2024
1 parent e6c9c39 commit 8d09ec4
Show file tree
Hide file tree
Showing 22 changed files with 152 additions and 139 deletions.
32 changes: 32 additions & 0 deletions src/commands/input.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use crate::utils::day_number::DayNumber;
use crate::utils::file_system::{read_input, write_input};
use crate::utils::year::Year;
use aoc_client::AocClient;

pub fn download_input(day_number: DayNumber, year: Year) {
let input = read_input(day_number.to_string().as_str(), year.clone());

match input {
Ok(_) => println!("Input already exists."),
Err(_) => {
println!("Downloading...");
let session = std::env::var("SESSION_COOKIE_ENV_VAR").unwrap();

let client = AocClient::builder()
.session_cookie(session)
.unwrap()
.year(year.clone() as i32)
.unwrap()
.day(u32::from(day_number))
.unwrap()
.build()
.unwrap();

let input = client.get_input().unwrap();

write_input(&day_number.to_string(), year.clone(), &input).unwrap();

println!("Input downloaded");
}
}
}
2 changes: 2 additions & 0 deletions src/commands/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod input;
pub mod solve;
81 changes: 81 additions & 0 deletions src/commands/solve.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
use crate::solutions::solution;
use crate::utils::day_number::DayNumber;
use crate::utils::file_system::{read_input, read_output};
use crate::utils::year::Year;
use std::fmt::{Display, Formatter};
use std::time::{Duration, Instant};

pub fn solve(day_number: &DayNumber, year: Year) {
let solution = solution(*day_number, year.clone());

let input = match read_input(day_number.to_string().as_str(), year.clone()) {
Ok(val) => val,
Err(_) => panic!("Failed to read input. Download it first."), // todo better handle errors
};

let output = read_output(day_number.to_string().as_str(), year);

let expected: Vec<String> = output
.unwrap_or(String::from(""))
.lines()
.map(|s| s.to_string())
.collect();

let expected_part_one = expected.first();
let expected_part_two = expected.get(1);

println!(
"{}",
run("one", &|| solution.part_one(&input), expected_part_one)
);
println!(
"{}",
run("two", &|| solution.part_two(&input), expected_part_two)
);
}

fn run<'a>(
part: &str,
solve_fn: &'a dyn Fn() -> String,
expected: Option<&'a String>,
) -> SolutionResult<'a> {
let start = Instant::now();
let current: String = solve_fn();
let elapsed = start.elapsed();

SolutionResult {
part: part.to_string(),
expected,
current,
elapsed,
}
}

struct SolutionResult<'a> {
part: String,
expected: Option<&'a String>,
current: String,
elapsed: Duration,
}

impl Display for SolutionResult<'_> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let result = match self.expected {
None => "❔",
Some(value) => {
if value == &self.current {
"✅"
} else {
"❌"
}
}
};
let elapsed_in_ms = self.elapsed.as_nanos() as f64 / 1000.0 / 1000.0;

write!(
f,
"Part {}: {} ({:.3}ms) {}",
self.part, self.current, elapsed_in_ms, result
)
}
}
112 changes: 5 additions & 107 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
use crate::solutions::solution;
use crate::commands::input::download_input;
use crate::commands::solve::solve;
use crate::utils::year::Year;
use clap::{Parser, Subcommand};
use std::fmt::{Display, Formatter};
use std::time::{Duration, Instant};
use aoc_client::{AocClient};
use dotenv::dotenv;
use utils::day_number::DayNumber;
use utils::file_system::{read_input, read_output};
use utils::year::Year::Year2023;
use crate::utils::file_system::write_input;

mod commands;
mod solutions;
mod utils;

#[derive(Parser, Debug)]
#[clap(author, version, about, long_about = None)]
struct Args {
struct Cli {
#[command(subcommand)]
command: Option<Command>,
#[clap(short, long)]
Expand Down Expand Up @@ -46,7 +43,7 @@ fn parse_day(s: &str) -> Result<u8, String> {
fn main() {
dotenv().ok();

let cli = Args::parse();
let cli = Cli::parse();
let command = cli.command.unwrap_or(Command::Solve);
let day = cli.day.unwrap_or(1);
let day_number: DayNumber = DayNumber::try_from(day.to_string()).unwrap();
Expand All @@ -60,102 +57,3 @@ fn main() {
Command::Input => download_input(day_number, year),
}
}

fn solve(day_number: &DayNumber, year: Year) {
let solution = solution(&day_number, year.clone());

let input = match read_input(day_number.to_string().as_str(), year.clone()) {
Ok(val) => val,
Err(_) => panic!("Failed to read input. Download it first."), // todo better handle errors
};

let output = read_output(day_number.to_string().as_str(), year);

let expected: Vec<String> = output
.unwrap_or(String::from(""))
.lines()
.map(|s| s.to_string())
.collect();

let expected_part_one = expected.first();
let expected_part_two = expected.get(1);

println!(
"{}",
run("one", &|| solution.part_one(&input), expected_part_one)
);
println!(
"{}",
run("two", &|| solution.part_two(&input), expected_part_two)
);
}

fn download_input(day_number: DayNumber, year: Year) {
let input = read_input(day_number.to_string().as_str(), year.clone());

match input {
Ok(_) => println!("Input already exists."),
Err(_) => {
println!("Downloading...");
let session = std::env::var("SESSION_COOKIE_ENV_VAR").unwrap();

let client = AocClient::builder()
.session_cookie(session).unwrap()
.year(year.clone() as i32).unwrap()
.day(u32::from(day_number)).unwrap()
.build().unwrap();

let input = client.get_input().unwrap();

write_input(&day_number.to_string(), year.clone(), &input).unwrap();

println!("Input downloaded");
}
}
}

fn run<'a>(
part: &str,
solve_fn: &'a dyn Fn() -> String,
expected: Option<&'a String>,
) -> SolutionResult<'a> {
let start = Instant::now();
let current: String = solve_fn();
let elapsed = start.elapsed();

SolutionResult {
part: part.to_string(),
expected,
current,
elapsed,
}
}

struct SolutionResult<'a> {
part: String,
expected: Option<&'a String>,
current: String,
elapsed: Duration,
}

impl Display for SolutionResult<'_> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let result = match self.expected {
None => "❔",
Some(value) => {
if value == &self.current {
"✅"
} else {
"❌"
}
}
};
let elapsed_in_ms = self.elapsed.as_nanos() as f64 / 1000.0 / 1000.0;

write!(
f,
"Part {}: {} ({:.3}ms) {}",
self.part, self.current, elapsed_in_ms, result
)
}
}
8 changes: 4 additions & 4 deletions src/solutions/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::utils::day_number::DayNumber;
use crate::solutions::year2023::day19;
use crate::utils::day_number::DayNumber;
use crate::utils::year::Year;
use year2023::{
day01, day02, day03, day04, day05, day06, day07, day08, day09, day10, day11, day12, day13,
Expand All @@ -13,8 +13,8 @@ pub trait Solution {
fn part_two(&self, input: &str) -> String;
}

pub fn solution(day: &DayNumber, year: Year) -> Box<dyn Solution> {
let i: u8 = (*day).into();
pub fn solution(day: DayNumber, year: Year) -> Box<dyn Solution> {
let i: u8 = day.into();

match year {
Year::Year2023 => match i {
Expand Down Expand Up @@ -45,6 +45,6 @@ pub fn solution(day: &DayNumber, year: Year) -> Box<dyn Solution> {
25 => Box::new(day25::Day25),
_ => panic!("Day not exist"),
},
Year::Year2024 => todo!("2024 is not implemented yet")
Year::Year2024 => todo!("2024 is not implemented yet"),
}
}
4 changes: 2 additions & 2 deletions src/solutions/year2023/day05.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::utils::range::Range;
use crate::solutions::Solution;
use crate::utils::range::Range;
use std::collections::HashMap;
use std::str;

Expand Down Expand Up @@ -189,10 +189,10 @@ impl MapRange {

#[cfg(test)]
mod tests {
use crate::utils::range::Range;
use crate::solutions::year2023::day05::{parse_input_part_one, Day05, Map, MapRange};
use crate::solutions::year2023::read_2023_example;
use crate::solutions::Solution;
use crate::utils::range::Range;
use std::vec;

#[test]
Expand Down
2 changes: 1 addition & 1 deletion src/solutions/year2023/day08.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::solutions::Solution;
use crate::utils::chain_pattern_finder::Chain;
use crate::utils::math::lcm;
use crate::solutions::Solution;
use regex::Regex;
use std::collections::hash_map::Entry::Vacant;
use std::collections::HashMap;
Expand Down
4 changes: 2 additions & 2 deletions src/solutions/year2023/day10.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::solutions::Solution;
use crate::utils::direction::Direction;
use crate::utils::grid::Grid;
use crate::utils::point::Point;
use crate::utils::shoelace_formula::shoelace_formula;
use crate::solutions::Solution;
use std::fmt;
use std::fmt::Display;
use std::ops::{Div, Sub};
Expand Down Expand Up @@ -157,10 +157,10 @@ impl Display for Tile {

#[cfg(test)]
mod tests {
use crate::utils::point::Point;
use crate::solutions::year2023::day10::{Day10, Tile};
use crate::solutions::year2023::read_2023_example;
use crate::solutions::Solution;
use crate::utils::point::Point;

#[test]
fn part_one_example_test() {
Expand Down
2 changes: 1 addition & 1 deletion src/solutions/year2023/day11.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::solutions::Solution;
use crate::utils::grid::Grid;
use crate::utils::pair_generator::pairs;
use crate::utils::point::Point;
use crate::solutions::Solution;
use std::cmp::{max, min};
use std::collections::BTreeMap;
use std::ops::Mul;
Expand Down
4 changes: 2 additions & 2 deletions src/solutions/year2023/day13.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::solutions::Solution;
use crate::utils::grid::Grid;
use crate::utils::point::Point;
use crate::utils::range::Range;
use crate::solutions::Solution;
use std::collections::BTreeMap;
use std::fmt::{Display, Formatter};

Expand Down Expand Up @@ -171,10 +171,10 @@ impl Display for Type {

#[cfg(test)]
mod tests {
use crate::utils::grid::Grid;
use crate::solutions::year2023::day13::{Day13, Type};
use crate::solutions::year2023::read_2023_example;
use crate::solutions::Solution;
use crate::utils::grid::Grid;

#[test]
fn part_one_example_test() {
Expand Down
4 changes: 2 additions & 2 deletions src/solutions/year2023/day14.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use crate::solutions::Solution;
use crate::utils::direction::Direction;
use crate::utils::direction::Direction::{East, North, South, West};
use crate::utils::grid::Grid;
use crate::utils::point::Point;
use crate::utils::range::Range;
use crate::solutions::Solution;
use crate::utils::surface_range::SurfaceRange;
use itertools::Itertools;
use std::collections::hash_map::DefaultHasher;
Expand Down Expand Up @@ -244,10 +244,10 @@ impl From<Vec<Point>> for Rocks {

#[cfg(test)]
mod tests {
use crate::utils::grid::Grid;
use crate::solutions::year2023::day14::{Day14, Rocks};
use crate::solutions::year2023::read_2023_example;
use crate::solutions::Solution;
use crate::utils::grid::Grid;

#[test]
fn part_one_example_test() {
Expand Down
2 changes: 1 addition & 1 deletion src/solutions/year2023/day16.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::solutions::Solution;
use crate::utils::direction::Direction;
use crate::utils::grid::Grid;
use crate::utils::point::Point;
use crate::solutions::Solution;
use crate::utils::vector::Vector;
use itertools::Itertools;
use std::collections::VecDeque;
Expand Down
Loading

0 comments on commit 8d09ec4

Please sign in to comment.