summaryrefslogtreecommitdiff
path: root/2018/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to '2018/src/main.rs')
-rw-r--r--2018/src/main.rs86
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),