diff --git a/2017/rust/Cargo.lock b/2017/rust/Cargo.lock
index ab5c52d..1808e55 100644
--- a/2017/rust/Cargo.lock
+++ b/2017/rust/Cargo.lock
@@ -3,6 +3,7 @@ name = "advent_of_code_2017"
version = "0.1.0"
dependencies = [
"failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -75,6 +76,11 @@ dependencies = [
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "lazy_static"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
[[package]]
name = "libc"
version = "0.2.34"
@@ -141,6 +147,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82"
"checksum failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cdda555bb90c9bb67a3b670a0f42de8e73f5981524123ad8578aafec8ddb8b"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
+"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d"
"checksum libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)" = "36fbc8a8929c632868295d0178dd8f63fc423fd7537ad0738372bd010b3ac9b0"
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
"checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e"
diff --git a/2017/rust/Cargo.toml b/2017/rust/Cargo.toml
index 9f0a3e9..91a9f32 100644
--- a/2017/rust/Cargo.toml
+++ b/2017/rust/Cargo.toml
@@ -5,3 +5,4 @@ authors = ["Alpha Chen <alpha.chen@gmail.com>"]
[dependencies]
failure = "0.1"
+lazy_static = "1.0"
diff --git a/2017/rust/src/day_01.rs b/2017/rust/src/day_01.rs
index fdd0cd2..b526084 100644
--- a/2017/rust/src/day_01.rs
+++ b/2017/rust/src/day_01.rs
@@ -13,15 +13,13 @@ pub fn solve(input: &str) -> Result<String, Error> {
let offset = input.len() / 2;
let offset_iter = input.iter().cycle().skip(offset);
- Ok(
- input
- .iter()
- .zip(offset_iter)
- .filter(|&a| a.0 == a.1)
- .map(|a| a.0)
- .sum::<u32>()
- .to_string(),
- )
+ Ok(input
+ .iter()
+ .zip(offset_iter)
+ .filter(|&a| a.0 == a.1)
+ .map(|a| a.0)
+ .sum::<u32>()
+ .to_string())
}
#[test]
diff --git a/2017/rust/src/day_02.rs b/2017/rust/src/day_02.rs
index 8c0da5c..fda9222 100644
--- a/2017/rust/src/day_02.rs
+++ b/2017/rust/src/day_02.rs
@@ -1,19 +1,18 @@
use failure::*;
+#[allow(dead_code)]
pub fn solve(input: &str) -> Result<String, Error> {
- Ok(
- input
- .trim()
- .split('\n')
- .map(|row| {
- row.split('\t')
- .map(|x| x.parse::<usize>().unwrap())
- .collect::<Vec<_>>()
- })
- .map(|row| checksum(&row))
- .sum::<usize>()
- .to_string(),
- )
+ Ok(input
+ .trim()
+ .split('\n')
+ .map(|row| {
+ row.split('\t')
+ .map(|x| x.parse::<usize>().unwrap())
+ .collect::<Vec<_>>()
+ })
+ .map(|row| checksum(&row))
+ .sum::<usize>()
+ .to_string())
}
fn checksum(row: &[usize]) -> usize {
@@ -24,9 +23,9 @@ fn checksum(row: &[usize]) -> usize {
row.iter()
.flat_map(|x| row.iter().map(|y| (x, y)).collect::<Vec<_>>())
- .filter(|&(a,b)| a != b)
- .filter(|&(&a,&b)| (a as f64) % (b as f64) == 0.0)
- .map(|(&a,&b)| a / b)
+ .filter(|&(a, b)| a != b)
+ .filter(|&(&a, &b)| (a as f64) % (b as f64) == 0.0)
+ .map(|(&a, &b)| a / b)
.next()
.unwrap()
}
diff --git a/2017/rust/src/day_03.rs b/2017/rust/src/day_03.rs
new file mode 100644
index 0000000..20f05a7
--- /dev/null
+++ b/2017/rust/src/day_03.rs
@@ -0,0 +1,86 @@
+use std::collections::HashMap;
+use std::iter;
+use failure::*;
+
+pub fn solve(input: &str) -> Result<String, Error> {
+ let input: usize = input.trim().parse()?;
+
+ // 1
+ // spiral()
+ // .zip(1..)
+ // .find(|&(_, i)| i == (square - 1))
+ // .map(|(coord, _)| (coord.0 + coord.1).to_string())
+ // .ok_or_else(|| format_err!(""))
+
+ // 2
+ let mut grid = HashMap::new();
+ grid.insert(Coord(0, 0), 1);
+ spiral()
+ .map(|coord| {
+ let sum = coord.neighbors().iter().filter_map(|x| grid.get(x)).sum();
+ grid.insert(coord, sum);
+ sum
+ })
+ .find(|value| value > &input)
+ .map(|value| value.to_string())
+ .ok_or_else(|| format_err!(""))
+}
+
+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
+struct Coord(isize, isize);
+
+impl Coord {
+ fn neighbors(&self) -> Vec<Coord> {
+ vec![
+ [-1, 1],
+ [0, 1],
+ [1, 1],
+ [-1, 0],
+ [1, 0],
+ [-1, -1],
+ [0, -1],
+ [1, -1],
+ ].iter()
+ .map(|delta| Coord(self.0 + delta[0], self.1 + delta[1]))
+ .collect()
+ }
+}
+
+#[derive(Clone, Copy, Debug, PartialEq)]
+enum Dir {
+ Right,
+ Up,
+ Left,
+ Down,
+}
+
+lazy_static! {
+ static ref DIRS: Vec<Dir> = vec![Dir::Right, Dir::Up, Dir::Left, Dir::Down];
+}
+
+fn spiral() -> impl Iterator<Item = Coord> {
+ (1..)
+ .flat_map(|x| iter::repeat(x).take(2))
+ .zip(DIRS.iter().cycle())
+ .flat_map(|(steps, dir)| iter::repeat(dir).take(steps))
+ .scan(Coord(0, 0), |state, &dir| {
+ *state = match dir {
+ Dir::Right => Coord(state.0 + 1, state.1),
+ Dir::Up => Coord(state.0, state.1 + 1),
+ Dir::Left => Coord(state.0 - 1, state.1),
+ Dir::Down => Coord(state.0, state.1 - 1),
+ };
+ Some(*state)
+ })
+}
+
+#[test]
+fn test_coords() {
+ let mut spiral = spiral();
+ assert_eq!(spiral.next(), Some(Coord(1, 0)));
+ assert_eq!(spiral.next(), Some(Coord(1, 1)));
+ assert_eq!(spiral.next(), Some(Coord(0, 1)));
+ assert_eq!(spiral.next(), Some(Coord(-1, 1)));
+ assert_eq!(spiral.next(), Some(Coord(-1, 0)));
+ assert_eq!(spiral.next(), Some(Coord(-1, -1)));
+}
diff --git a/2017/rust/src/main.rs b/2017/rust/src/main.rs
index 1dc42c1..522e2c0 100644
--- a/2017/rust/src/main.rs
+++ b/2017/rust/src/main.rs
@@ -1,4 +1,8 @@
+#![feature(conservative_impl_trait)]
+
extern crate failure;
+#[macro_use]
+extern crate lazy_static;
use std::io::{self, Read};
@@ -6,6 +10,7 @@ use failure::Error;
mod day_01;
mod day_02;
+mod day_03;
fn main() {
if let Err(e) = run() {
@@ -17,7 +22,7 @@ fn run() -> Result<(), Error> {
let mut input = String::new();
io::stdin().read_to_string(&mut input)?;
- let solution = day_02::solve(&input)?;
+ let solution = day_03::solve(&input)?;
println!("{}", solution);
Ok(())