[2016][rust][6.0]
change znwysmxnswmyouuowxkvxztkptolltpy
commit cedf55c3cd51a27f72fbbde0a4f4b8f00d0abf43
author Alpha Chen <alpha.chen@gmail.com>
date
parent zzpnvxmx
diff --git a/2016/rust/Cargo.lock b/2016/rust/Cargo.lock
index 5a18724..898e07f 100644
--- a/2016/rust/Cargo.lock
+++ b/2016/rust/Cargo.lock
@@ -4,6 +4,7 @@ version = "0.1.0"
 dependencies = [
  "error-chain 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -86,6 +87,14 @@ dependencies = [
  "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "rand"
+version = "0.3.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "regex"
 version = "0.1.80"
@@ -103,11 +112,28 @@ name = "regex-syntax"
 version = "0.3.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
+[[package]]
+name = "rust-crypto"
+version = "0.2.36"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "gcc 0.3.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-serialize 0.3.21 (registry+https://github.com/rust-lang/crates.io-index)",
+ "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "rustc-demangle"
 version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
+[[package]]
+name = "rustc-serialize"
+version = "0.3.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 name = "thread-id"
 version = "2.0.0"
@@ -125,6 +151,16 @@ dependencies = [
  "thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "time"
+version = "0.1.35"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "utf8-ranges"
 version = "0.1.3"
@@ -151,11 +187,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
 "checksum libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "a51822fc847e7a8101514d1d44e354ba2ffa7d4c194dcab48870740e327cac70"
 "checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20"
+"checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d"
 "checksum regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4fd4ace6a8cf7860714a2c2280d6c1f7e6a413486c13298bbc86fd3da019402f"
 "checksum regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957"
+"checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a"
 "checksum rustc-demangle 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1430d286cadb237c17c885e25447c982c97113926bb579f4379c0eca8d9586dc"
+"checksum rustc-serialize 0.3.21 (registry+https://github.com/rust-lang/crates.io-index)" = "bff9fc1c79f2dec76b253273d07682e94a978bd8f132ded071188122b2af9818"
 "checksum thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9539db560102d1cef46b8b78ce737ff0bb64e7e18d35b2a5688f7d097d0ff03"
 "checksum thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8576dbbfcaef9641452d5cf0df9b0e7eeab7694956dd33bb61515fb8f18cfdd5"
+"checksum time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "3c7ec6d62a20df54e07ab3b78b9a3932972f4b7981de295563686849eb3989af"
 "checksum utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f"
 "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
 "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
diff --git a/2016/rust/Cargo.toml b/2016/rust/Cargo.toml
index 6f439f1..7ed1c86 100644
--- a/2016/rust/Cargo.toml
+++ b/2016/rust/Cargo.toml
@@ -6,3 +6,4 @@ authors = ["Alpha Chen <alpha.chen@gmail.com>"]
 [dependencies]
 error-chain = "0.7"
 regex = "0.1"
+rust-crypto = "0.2"
diff --git a/2016/rust/src/day_05.rs b/2016/rust/src/day_05.rs
new file mode 100644
index 0000000..d513244
--- /dev/null
+++ b/2016/rust/src/day_05.rs
@@ -0,0 +1,64 @@
+use std::char;
+
+use crypto::digest::Digest;
+use crypto::md5::Md5;
+
+use errors::*;
+
+pub fn solve(input: &str) -> Result<String> {
+  let pw = Password::new(input.trim());
+  Ok(pw.take(8).collect())
+}
+
+struct Password {
+  id: String,
+  index: usize,
+  md5: Md5,
+}
+
+impl Password {
+  fn new(id: &str) -> Self {
+    Password{id: id.into(), index: 0, md5: Md5::new()}
+  }
+}
+
+impl Iterator for Password {
+  // we will be counting with usize
+  type Item = char;
+
+  // next() is the only required method
+  fn next(&mut self) -> Option<char> {
+    let mut result = None;
+    let mut hash = [0; 16];
+
+    while result.is_none() {
+      let input = format!("{}{}", self.id, self.index);
+      self.index += 1;
+
+      self.md5.input_str(&input);
+      self.md5.result(&mut hash);
+      self.md5.reset();
+
+      if self.index % 1000000 == 0 {
+        println!("{}", self.index);
+      }
+
+      if hash[0] as u16 + hash[1] as u16 + (hash[2] >> 4) as u16 == 0 {
+        result = Some(char::from_digit((hash[2] & 0b00001111) as u32, 16).unwrap());
+        break
+      }
+    }
+    result
+  }
+}
+
+#[test]
+fn test_password() {
+  let mut pw = Password{id: "abc".into(), index: 3231928, md5: Md5::new()};
+  assert_eq!(pw.next(), Some('1'.into()));
+  assert_eq!(pw.index, 3231930);
+
+  let mut pw = Password{id: "abc".into(), index: 5017308, md5: Md5::new()};
+  assert_eq!(pw.next(), Some('8'.into()));
+  assert_eq!(pw.next(), Some('f'.into()));
+}
diff --git a/2016/rust/src/lib.rs b/2016/rust/src/lib.rs
index 2d76c5b..cef1563 100644
--- a/2016/rust/src/lib.rs
+++ b/2016/rust/src/lib.rs
@@ -3,9 +3,11 @@
 #[macro_use]
 extern crate error_chain;
 extern crate regex;
+extern crate crypto;
 
-mod errors;
+pub mod errors;
 pub mod day_01;
 pub mod day_02;
 pub mod day_03;
 pub mod day_04;
+pub mod day_05;
diff --git a/2016/rust/src/main.rs b/2016/rust/src/main.rs
index 512d3d0..99c3f8f 100644
--- a/2016/rust/src/main.rs
+++ b/2016/rust/src/main.rs
@@ -3,10 +3,27 @@ use std::io::Read;
 
 extern crate advent_of_code_2016;
 use advent_of_code_2016::*;
+use advent_of_code_2016::errors::*;
 
 fn main() {
-  let mut input = String::new();
-  io::stdin().read_to_string(&mut input).ok();
+  run(|| {
+    let mut input = String::new();
+    io::stdin().read_to_string(&mut input).ok();
 
-  println!("{}", day_04::solve(&input).unwrap());
+    let solution = day_05::solve(&input)?;
+    println!("{}", solution);
+
+    Ok(())
+  });
+}
+
+fn run<F>(f: F)
+  where F: Fn() -> Result<()>
+{
+  if let Err(error) = f() {
+    for error in error.iter() {
+      println!("{}", error);
+    }
+    std::process::exit(1);
+  }
 }