diff --git a/2018/.gitignore b/2018/.gitignore new file mode 100644 index 0000000..fa8d85a --- /dev/null +++ b/2018/.gitignore @@ -0,0 +1,2 @@ +Cargo.lock +target diff --git a/2018/Cargo.toml b/2018/Cargo.toml new file mode 100644 index 0000000..a6afa63 --- /dev/null +++ b/2018/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "aoc-2018" +version = "0.1.0" +authors = ["Bert Peters "] + +[dependencies] +clap = "2.32" diff --git a/2018/README.md b/2018/README.md new file mode 100644 index 0000000..25e0b3c --- /dev/null +++ b/2018/README.md @@ -0,0 +1,8 @@ +# Advent of Code 2018 + +Once again, I will be attempting to complete the challenges in Rust. +However, this this I will be focussing on having idiomatic code and +having everything in a single executable. + +To run day 1: `cargo run -- 1`. Other options can be seen with the +`--help` flag. The program will by default read its input from stdin. diff --git a/2018/src/common.rs b/2018/src/common.rs new file mode 100644 index 0000000..880400f --- /dev/null +++ b/2018/src/common.rs @@ -0,0 +1,63 @@ +use std::io; + +/// Apply Erathostenes's sieve to the supplied array +/// +/// # Arguments +/// +/// * `dest` - the destination slice to fill with the sieve. This is +/// assumed to be filled with "true" before being handed to this +/// method. +pub fn prime_sieve(dest: &mut[bool]) { + if dest.len() >= 1 { + dest[0] = false; + } + + if dest.len() >= 2 { + dest[1] = false; + } + + let limit = (dest.len() as f64).sqrt() as usize; + + for i in 1..(limit + 1) { + if !dest[i] { + continue + } + + for j in ((i * i)..(dest.len())).step_by(i) { + dest[j] = false; + } + } +} + +/// Solution trait +/// +/// Every day's solution should implement this function so that it can +/// be easily run from the main program. +pub trait Solution { + /// Solve the first part of the day + fn part1(&mut self, input: Box); + + /// Solve the second part of the day + fn part2(&mut self, input: Box); +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_prime_sieve() { + let mut input = [true; 10]; + prime_sieve(&mut input); + + let output = [ + false, false, + true, true, + false, true, + false, true, + false, false + ]; + + assert_eq!(output, input); + } +} diff --git a/2018/src/day1.rs b/2018/src/day1.rs new file mode 100644 index 0000000..bf413b9 --- /dev/null +++ b/2018/src/day1.rs @@ -0,0 +1,21 @@ +use std::io; +use common; + +pub struct Day1 { +} + +impl Day1 { + pub fn new() -> Day1 { + Day1{} + } +} + +impl common::Solution for Day1 { + fn part1(&mut self, input: Box) { + println!("Not implemented"); + } + + fn part2(&mut self, input: Box) { + println!("Not implemented"); + } +} diff --git a/2018/src/main.rs b/2018/src/main.rs new file mode 100644 index 0000000..5e373e6 --- /dev/null +++ b/2018/src/main.rs @@ -0,0 +1,65 @@ +extern crate clap; +use clap::{Arg, App}; +use std::fs; +use std::io; + +pub mod common; +pub mod day1; + +fn get_impl(day: i32) -> Box { + match day { + 1 => { Box::new(day1::Day1::new()) } + _ => { + panic!("Unimplemented day {}", day) + } + } +} + +fn main() { + let matches = App::new("Advent of Code") + .version("2018") + .author("Bert Peters ") + .arg(Arg::with_name("day") + .value_name("DAY") + .help("Number of the day to execute") + .required(true) + .takes_value(true)) + .arg(Arg::with_name("part2") + .short("2") + .help("Whether to run part 2") + .long("part2")) + .arg(Arg::with_name("input") + .short("i") + .long("input") + .help("Optional input file, stdin otherwise") + .takes_value(true)) + .get_matches(); + + let day: i32 = (&matches.value_of("day").unwrap()).parse() + .expect("Invalid int"); + let mut implementation = get_impl(day); + let data: Box = match matches.value_of("input") { + Some(filename) => { Box::new(fs::File::open(filename).unwrap()) } + None => { Box::new(io::stdin()) } + }; + + if matches.is_present("part2") { + implementation.part2(data) + } else { + implementation.part1(data) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_get_impl() { + // Verify that we can load all days + let last_implemented = 1; + for d in 1..(last_implemented + 1) { + get_impl(d); + } + } +} diff --git a/README.md b/README.md index a55c876..e13df85 100644 --- a/README.md +++ b/README.md @@ -5,3 +5,4 @@ This repository contains my solutions for Advent of Code. See: - [2015 edition](./2015) - [2016 edition](./2016) - [2017 edition](./2017) +- [2018 edition](./2018)