Add Solver trait and move common functionality out of concrete solvers
This commit is contained in:
@@ -1,2 +1,77 @@
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
use std::io::BufRead;
|
||||
use std::path::Path;
|
||||
|
||||
pub mod cafeteria;
|
||||
pub mod printing_department;
|
||||
|
||||
pub trait Solver {
|
||||
fn get_puzzle_index(&self) -> u8;
|
||||
fn get_puzzle_name(&self) -> &str;
|
||||
fn get_input_filename(&self) -> &str;
|
||||
fn get_part1(&self) -> u64;
|
||||
fn get_part2(&self) -> u64;
|
||||
fn process_data(&mut self, lines: io::Lines<io::BufReader<File>>);
|
||||
}
|
||||
|
||||
pub fn run(mut solver: Box<dyn Solver>) {
|
||||
println!(
|
||||
"--- Day {}: {} ---",
|
||||
solver.get_puzzle_index(),
|
||||
solver.get_puzzle_name()
|
||||
);
|
||||
|
||||
// The "../../data" and "../../../data" paths are useful for running the binary from
|
||||
// "target/release/" directory with "data/" directory in package root or parent directory.
|
||||
let paths = vec!["./data", "../data", "../../data", "../../../data"];
|
||||
|
||||
match read_data_file(solver.get_input_filename(), &paths) {
|
||||
Ok(lines) => {
|
||||
solver.process_data(lines);
|
||||
print_result(solver);
|
||||
}
|
||||
Err(error) => eprintln!("{}", error),
|
||||
};
|
||||
}
|
||||
|
||||
fn print_result(solver: Box<dyn Solver>) {
|
||||
println!(
|
||||
"Part 1: {:?}\nPart 2: {:?}\n",
|
||||
solver.get_part1(),
|
||||
solver.get_part2()
|
||||
);
|
||||
}
|
||||
|
||||
fn read_data_file<T>(
|
||||
filename: T,
|
||||
search_paths: &Vec<T>,
|
||||
) -> Result<io::Lines<io::BufReader<File>>, String>
|
||||
where
|
||||
T: AsRef<Path>,
|
||||
{
|
||||
for path in search_paths {
|
||||
if let Ok(lines) = read_lines(path.as_ref().join(&filename)) {
|
||||
return Ok(lines);
|
||||
}
|
||||
}
|
||||
|
||||
let message = search_paths
|
||||
.iter()
|
||||
.map(|path| path.as_ref().join(&filename).display().to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
Err(format!(
|
||||
"Cannot open puzzle input file, searched these paths:\n{}",
|
||||
message
|
||||
))
|
||||
}
|
||||
|
||||
// This code is taken from https://doc.rust-lang.org/stable/rust-by-example/std_misc/file/read_lines.html
|
||||
fn read_lines<T>(filename: T) -> io::Result<io::Lines<io::BufReader<File>>>
|
||||
where
|
||||
T: AsRef<Path>,
|
||||
{
|
||||
let file = File::open(filename)?;
|
||||
Ok(io::BufReader::new(file).lines())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user