Rust, Day 3.0

wip
Alpha Chen 9 years ago
parent f1eea338c3
commit fd5dcaa3e1

File diff suppressed because one or more lines are too long

@ -1,6 +1,6 @@
use std::io; use std::io;
pub trait Day { pub trait Day {
fn new(String) -> Self; fn new(&String) -> Self;
fn solve(self) -> io::Result<i32>; fn solve(&self) -> io::Result<i32>;
} }

@ -8,12 +8,12 @@ pub struct Day01 {
} }
impl Day for Day01 { impl Day for Day01 {
fn new(input: String) -> Day01 { fn new(input: &String) -> Day01 {
Day01 { input: input } Day01 { input: input.clone() }
} }
fn solve(self) -> io::Result<i32> { fn solve(&self) -> io::Result<i32> {
let elevator = Elevator::new(self.input); let elevator = Elevator::new(&self.input);
Ok(1 + elevator.run().position(|f| f == -1).unwrap_or(0) as i32) Ok(1 + elevator.run().position(|f| f == -1).unwrap_or(0) as i32)
} }
} }
@ -23,8 +23,8 @@ struct Elevator {
} }
impl<'a> Elevator { impl<'a> Elevator {
fn new(input: String) -> Self { fn new(input: &String) -> Self {
Elevator { instructions: input } Elevator { instructions: input.clone() }
} }
fn run(self: &'a Self) -> ElevatorIterator<'a> { fn run(self: &'a Self) -> ElevatorIterator<'a> {

@ -7,12 +7,12 @@ pub struct Day02 {
} }
impl Day for Day02 { impl Day for Day02 {
fn new(input: String) -> Day02 { fn new(input: &String) -> Day02 {
let presents = input.split("\n").map(|line| Present::new(line)); let presents = input.split("\n").map(|line| Present::new(line));
Day02 { presents: presents.collect::<Vec<Present>>() } Day02 { presents: presents.collect::<Vec<Present>>() }
} }
fn solve(self) -> io::Result<i32> { fn solve(&self) -> io::Result<i32> {
Ok(self.presents.iter().fold(0u32, |acc, present| acc + present.ribbon()) as i32) Ok(self.presents.iter().fold(0u32, |acc, present| acc + present.ribbon()) as i32)
} }
} }

@ -0,0 +1,140 @@
use std::cmp::Eq;
use std::collections::HashMap;
use std::fmt;
use std::io;
use std::ops::Add;
use std::str::Chars;
use day::Day;
pub struct Day03 {
directions: String,
}
impl Day for Day03 {
fn new(input: &String) -> Day03 {
Day03 { directions: input.clone() }
}
fn solve(&self) -> io::Result<i32> {
let houses = Santa::houses_visited(&self.directions);
Ok(houses.len() as i32)
}
}
struct Santa<'a> {
location: Point,
directions: Chars<'a>,
}
impl<'a> Santa<'a> {
fn new(directions: &str) -> Santa {
Santa {
location: Point::origin(),
directions: directions.chars(),
}
}
fn houses_visited(directions: &str) -> HashMap<Point, u32> {
let santa = Santa::new(directions);
let mut houses = HashMap::new();
houses.insert(Point::origin(), 1);
for point in santa {
*houses.entry(point).or_insert(0) += 1;
}
houses
}
}
impl<'a> Iterator for Santa<'a> {
type Item = Point;
fn next(&mut self) -> Option<Point> {
let offset = match self.directions.next() {
Some('^') => Point { x: 0, y: 1 },
Some('v') => Point { x: 0, y: -1 },
Some('>') => Point { x: 1, y: 0 },
Some('<') => Point { x: -1, y: 0 },
_ => return None,
};
self.location = self.location.clone() + offset;
Some(self.location.clone())
}
}
#[test]
fn test_one() {
let directions = ">";
let santa = Santa::new(directions);
let points = santa.collect::<Vec<Point>>();
let expected = vec![Point { x: 1, y: 0 }];
assert_eq!(expected, points);
let houses = Santa::houses_visited(directions);
assert_eq!(2, houses.len());
assert_eq!(&1, houses.get(&Point::origin()).unwrap());
assert_eq!(&1, houses.get(&Point { x: 1, y: 0 }).unwrap());
}
#[test]
fn test_two() {
let directions = "^>v<";
let houses = Santa::houses_visited(directions);
assert_eq!(4, houses.len());
assert_eq!(&2, houses.get(&Point::origin()).unwrap());
assert_eq!(&1, houses.get(&Point { x: 1, y: 0 }).unwrap());
}
#[test]
fn test_three() {
let directions = "^v^v^v^v^v";
let houses = Santa::houses_visited(directions);
assert_eq!(2, houses.len());
assert_eq!(&6, houses.get(&Point::origin()).unwrap());
assert_eq!(&5, houses.get(&Point { x: 0, y: 1 }).unwrap());
}
#[derive(Clone,Debug,Eq,Hash)]
struct Point {
x: i32,
y: i32,
}
impl Point {
fn origin() -> Point {
Point { x: 0, y: 0 }
}
}
impl Add for Point {
type Output = Point;
fn add(self, other: Point) -> Point {
Point {
x: self.x + other.x,
y: self.y + other.y,
}
}
}
impl fmt::Display for Point {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "({}, {})", self.x, self.y)
}
}
impl PartialEq for Point {
fn eq(&self, other: &Self) -> bool {
self.x == other.x && self.y == other.y
}
}
#[test]
fn test_point() {
let point = Point { x: 10, y: -10 };
let offset = Point { x: -10, y: 10 };
assert_eq!(Point::origin(), point + offset);
}

@ -9,4 +9,5 @@ macro_rules! import_day {
import_day!(day, import_day!(day,
day_01, day_01,
day_02); day_02,
day_03);

@ -19,7 +19,7 @@ fn read_input(filename: &str) -> Result<String, io::Error> {
} }
fn main() { fn main() {
let input = read_input("day_02").unwrap(); let input = read_input("day_03").unwrap();
let day = Day02::new(input); let day = Day03::new(&input);
println!("{}", day.solve().unwrap()); println!("{}", day.solve().unwrap());
} }

Loading…
Cancel
Save