2017/10-11

This commit is contained in:
2017-12-11 08:09:56 +01:00
parent 02718ba05f
commit d63b1a7e84
8 changed files with 237 additions and 0 deletions

4
2017/11/Cargo.lock generated Normal file
View File

@@ -0,0 +1,4 @@
[[package]]
name = "day-11"
version = "0.1.0"

6
2017/11/Cargo.toml Normal file
View File

@@ -0,0 +1,6 @@
[package]
name = "day-11"
version = "0.1.0"
authors = ["logaritmisk <anders.e.olsson@gmail.com>"]
[dependencies]

1
2017/11/input.txt Normal file

File diff suppressed because one or more lines are too long

134
2017/11/src/main.rs Normal file
View File

@@ -0,0 +1,134 @@
use std::str::FromStr;
use std::io::{self, Read};
#[derive(Clone, Copy, Debug, PartialEq)]
enum Direction {
Nw,
N,
Ne,
Se,
S,
Sw,
}
impl Direction {
fn delta(&self) -> (i32, i32) {
match *self {
Direction::Nw => (-1, 1),
Direction::N => (0, 1),
Direction::Ne => (1, 0),
Direction::Se => (1, -1),
Direction::S => (0, -1),
Direction::Sw => (-1, 0),
}
}
}
impl FromStr for Direction {
type Err = ();
fn from_str(input: &str) -> Result<Direction, Self::Err> {
match input {
"nw" => Ok(Direction::Nw),
"n" => Ok(Direction::N),
"ne" => Ok(Direction::Ne),
"se" => Ok(Direction::Se),
"s" => Ok(Direction::S),
"sw" => Ok(Direction::Sw),
_ => Err(()),
}
}
}
fn parse(input: &str) -> Vec<Direction> {
input
.split(',')
.filter_map(|dir| Direction::from_str(dir).ok())
.collect::<Vec<_>>()
}
fn distance(a: (i32, i32), b: (i32, i32)) -> usize {
let dx = b.0 - a.0;
let dy = b.1 - a.1;
if dx.signum() == dy.signum() {
(dx + dy).abs() as usize
} else {
usize::max(dx.abs() as usize, dy.abs() as usize)
}
}
fn main() {
let mut input = String::new();
io::stdin()
.read_to_string(&mut input)
.expect("faild to read input");
for line in input.lines().filter(|line| !line.is_empty()) {
let position = parse(line)
.iter()
.map(|dir| dir.delta())
.fold((0, 0), |p, d| (p.0 + d.0, p.1 + d.1));
println!("part_one={}", distance((0, 0), position));
let max = parse(line)
.iter()
.map(|dir| dir.delta())
.scan((0, 0), |p, d| {
p.0 += d.0;
p.1 += d.1;
Some(distance((0, 0), *p))
})
.max();
if let Some(distance) = max {
println!("part_two={}", distance);
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_direction() {
assert_eq!("nw".parse(), Ok(Direction::Nw));
assert_eq!("n".parse(), Ok(Direction::N));
assert_eq!("ne".parse(), Ok(Direction::Ne));
assert_eq!("se".parse(), Ok(Direction::Se));
assert_eq!("s".parse(), Ok(Direction::S));
assert_eq!("sw".parse(), Ok(Direction::Sw));
}
#[test]
fn test_parse() {
assert_eq!(
parse("ne,ne,ne"),
vec![Direction::Ne, Direction::Ne, Direction::Ne]
);
assert_eq!(
parse("ne,ne,sw,sw"),
vec![Direction::Ne, Direction::Ne, Direction::Sw, Direction::Sw]
);
}
#[test]
fn test_distance() {
assert_eq!(distance((0, 0), (0, 3)), 3);
assert_eq!(distance((0, 0), (-3, 3)), 3);
assert_eq!(distance((0, 0), (-3, 0)), 3);
assert_eq!(distance((0, 0), (0, -3)), 3);
assert_eq!(distance((0, 0), (3, -3)), 3);
assert_eq!(distance((0, 0), (3, 0)), 3);
assert_eq!(distance((0, 0), (-2, 1)), 2);
}
}