mirror of
https://github.com/bertptrs/adventofcode.git
synced 2025-12-25 21:00:31 +01:00
Set up for AoC 2018.
This commit is contained in:
2
2018/.gitignore
vendored
Normal file
2
2018/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
Cargo.lock
|
||||||
|
target
|
||||||
7
2018/Cargo.toml
Normal file
7
2018/Cargo.toml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
[package]
|
||||||
|
name = "aoc-2018"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Bert Peters <bert@bertptrs.nl>"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
clap = "2.32"
|
||||||
8
2018/README.md
Normal file
8
2018/README.md
Normal file
@@ -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.
|
||||||
63
2018/src/common.rs
Normal file
63
2018/src/common.rs
Normal file
@@ -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<io::Read>);
|
||||||
|
|
||||||
|
/// Solve the second part of the day
|
||||||
|
fn part2(&mut self, input: Box<io::Read>);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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);
|
||||||
|
}
|
||||||
|
}
|
||||||
21
2018/src/day1.rs
Normal file
21
2018/src/day1.rs
Normal file
@@ -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<io::Read>) {
|
||||||
|
println!("Not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part2(&mut self, input: Box<io::Read>) {
|
||||||
|
println!("Not implemented");
|
||||||
|
}
|
||||||
|
}
|
||||||
65
2018/src/main.rs
Normal file
65
2018/src/main.rs
Normal file
@@ -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<common::Solution> {
|
||||||
|
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 <bert@bertptrs.nl>")
|
||||||
|
.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<io::Read> = 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user