diff options
Diffstat (limited to '2018/src/main.rs')
-rw-r--r-- | 2018/src/main.rs | 86 |
1 files changed, 71 insertions, 15 deletions
diff --git a/2018/src/main.rs b/2018/src/main.rs index 98c0f7b..f9098eb 100644 --- a/2018/src/main.rs +++ b/2018/src/main.rs @@ -3,39 +3,96 @@ extern crate regex; extern crate argparse; use std::io; -use std::io::{BufRead, BufReader, Error, ErrorKind}; +use std::io::{BufRead, BufReader, Error, ErrorKind, Read}; use std::fs::File; use std::process::exit; +use std::time::Instant; use argparse::{ArgumentParser, StoreTrue, Store}; mod day1; mod day2; mod day3; mod day4; +mod day5; -fn day_switch<T: BufRead>(day: i32, reader: T) -> io::Result<()> { +static NUM_DAYS: i32 = 5; + +fn day_switch<T: BufRead>(day: i32, reader: T) -> io::Result<(String, String)> { match day { 1 => day1::main(reader), 2 => day2::main(reader), 3 => day3::main(reader), 4 => day4::main(reader), + 5 => day5::main(reader), _ => Err(Error::new(ErrorKind::Other, "Invalid day")) } } +fn file_for_day(day: i32) -> io::Result<BufReader<File>> { + match File::open(format!("../input/{}.txt", day)) { + Ok(f) => Ok(BufReader::new(f)), + Err(_) => Err(Error::new(ErrorKind::Other, format!("No input file for day {}", day))) + } +} + +fn benchmark_day(day: i32) -> io::Result<f64> { + let num_iters = 100; + + let mut input = Vec::new(); + file_for_day(day)?.read_to_end(&mut input)?; + + let start = Instant::now(); + for _i in 0..num_iters { + day_switch(day, BufReader::new(&input[..]))?; + } + let end = Instant::now(); + + let dur = (end - start) / num_iters; + let secs = dur.as_secs() as f64 + dur.subsec_micros() as f64 / 1000000.0; + + println!("Day {}: {} secs", day, secs); + + Ok(secs) +} + +fn benchmark_all_days() -> io::Result<()> { + let mut total = 0.0; + for day in 1..NUM_DAYS + 1 { + total += benchmark_day(day)?; + } + println!("Total: {} secs", total); + Ok(()) +} + struct Options { use_stdin: bool, + bench: bool, } fn run_day(day: i32, opts: &Options) -> io::Result<()> { - if opts.use_stdin { - let stdin = io::stdin(); - day_switch(day, BufReader::new(stdin)) + let (part1, part2) = if opts.bench { + benchmark_day(day)?; + return Ok(()) + } else if opts.use_stdin { + day_switch(day, BufReader::new(io::stdin()))? + } else { + day_switch(day, file_for_day(day)?)? + }; + + println!("{}", part1); + println!("{}", part2); + Ok(()) +} + +fn run_all_days(opts: &Options) -> io::Result<()> { + if opts.bench { + assert!(!opts.use_stdin); + benchmark_all_days() } else { - match File::open(format!("../input/{}.txt", day)) { - Ok(f) => day_switch(day, BufReader::new(f)), - Err(_) => Err(Error::new(ErrorKind::Other, format!("No input file for day {}", day))) + for day in 1..6 { + run_day(day, &opts)?; } + Ok(()) } } @@ -58,15 +115,17 @@ fn error_handler<F>(func: F) -> io::Result<()> fn main() -> io::Result<()> { let mut day_string = String::new(); let mut options = Options { - use_stdin: false + use_stdin: false, + bench: false, }; { let mut parser = ArgumentParser::new(); parser.set_description("AOC 2018 solutions by Tom Smeding"); parser.refer(&mut options.use_stdin) - .add_option(&["-s", "--stdin"], StoreTrue, - "Read from stdin"); + .add_option(&["-s", "--stdin"], StoreTrue, "Read from stdin"); + parser.refer(&mut options.bench) + .add_option(&["-b", "--bench"], StoreTrue, "Benchmark the given days"); parser.refer(&mut day_string) .add_argument("day", Store, "Day to execute"); parser.parse_args_or_exit(); @@ -74,10 +133,7 @@ fn main() -> io::Result<()> { error_handler(|| if day_string.len() == 0 { - for day in 1..5 { - run_day(day, &options)?; - } - Ok(()) + run_all_days(&options) } else { match day_string.parse::<i32>() { Ok(day) => run_day(day, &options), |