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), | 
