6 changed files with 236 additions and 0 deletions
@ -1,4 +1,14 @@ |
|||
[[package]] |
|||
name = "adventofcode2015" |
|||
version = "0.1.0" |
|||
dependencies = [ |
|||
"md5 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", |
|||
] |
|||
|
|||
[[package]] |
|||
name = "md5" |
|||
version = "0.3.7" |
|||
source = "registry+https://github.com/rust-lang/crates.io-index" |
|||
|
|||
[metadata] |
|||
"checksum md5 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "daa1004633f76cdcd5a9d83ffcfe615e30ca7a2a638fcc8b8039a2dac21289d7" |
|||
|
|||
@ -0,0 +1 @@ |
|||
bgvyzdsv |
|||
@ -0,0 +1,184 @@ |
|||
extern crate md5; |
|||
|
|||
use std; |
|||
use std::sync::{Arc, Mutex}; |
|||
use std::thread; |
|||
use std::sync::mpsc::channel; |
|||
|
|||
pub struct Data { |
|||
base: String, |
|||
} |
|||
|
|||
|
|||
struct SharedData { |
|||
dig: md5::Digest, |
|||
i: u64, |
|||
valid: bool, |
|||
} |
|||
|
|||
struct Slice { |
|||
next: u64, |
|||
size: u64, |
|||
run: bool, |
|||
} |
|||
|
|||
impl Data { |
|||
pub fn new() -> Data { |
|||
Data { |
|||
base: String::new(), |
|||
} |
|||
} |
|||
|
|||
pub fn parse(&mut self, input: String) { |
|||
self.base = input; |
|||
} |
|||
|
|||
|
|||
pub fn mine5(&mut self) -> u64 { |
|||
for i in 0..std::u64::MAX { |
|||
let key = format!("{}{}",self.base, i.to_string()); |
|||
let res = md5::compute(key.as_bytes()); |
|||
if res[0] == 0 && res[1] == 0 && (res[2] & 0xF0) == 0 { |
|||
println!("{}: {} -> {:x}", i, key, res); |
|||
return i; |
|||
} |
|||
} |
|||
0 |
|||
} |
|||
|
|||
pub fn mine5_mt(&mut self) -> u64 { |
|||
let threads = 16; |
|||
let (tx, rx) = channel(); |
|||
let mut slice = Slice{next: 0, size: 100, run: true}; |
|||
let slice_mut = Arc::new(Mutex::new(slice)); |
|||
let mut result : u64 = 0; |
|||
|
|||
for i in 0 .. threads { |
|||
let local_base = self.base.clone(); |
|||
let local_tx = tx.clone(); |
|||
let local_slice = slice_mut.clone(); |
|||
thread::spawn(move || { |
|||
let mut count : u64; |
|||
let mut target : u64; |
|||
let mut run = true; |
|||
let mut result = SharedData { |
|||
i: 0, |
|||
dig: md5::compute(b"0"), |
|||
valid: false, |
|||
}; |
|||
while run { |
|||
{ |
|||
let mut local_slice_mut = local_slice.lock().unwrap(); |
|||
run = local_slice_mut.run; |
|||
count = local_slice_mut.next; |
|||
if count <= (std::u64::MAX - local_slice_mut.size) { |
|||
target = count + local_slice_mut.size; |
|||
} else { |
|||
target = std::u64::MAX; |
|||
} |
|||
local_slice_mut.next = target; |
|||
} |
|||
|
|||
while run && count < target { |
|||
let key = format!("{}{}", local_base, count.to_string()); |
|||
result.dig = md5::compute(key.as_bytes()); |
|||
if result.dig[0] == 0 && result.dig[1] == 0 && (result.dig[2] & 0xF0) == 0 { |
|||
println!("{}: {} -> {:x}", count, key, result.dig); |
|||
result.i = count; |
|||
result.valid = true; |
|||
run = false; |
|||
let mut local_slice_mut = local_slice.lock().unwrap(); |
|||
local_slice_mut.run = false; |
|||
} else { |
|||
count += 1; |
|||
} |
|||
} |
|||
} |
|||
local_tx.send(result); |
|||
|
|||
}); |
|||
} |
|||
|
|||
for _ in 0 .. threads { |
|||
let res = rx.recv(); |
|||
match res { |
|||
Ok(val) => { |
|||
if val.valid && (result == 0 || result > val.i) { |
|||
result = val.i; |
|||
} |
|||
}, |
|||
Err(_) => (), |
|||
} |
|||
} |
|||
result |
|||
|
|||
} |
|||
|
|||
pub fn mine6_mt(&mut self) -> u64 { |
|||
let threads = 16; |
|||
let (tx, rx) = channel(); |
|||
let mut slice = Slice{next: 0, size: 100, run: true}; |
|||
let slice_mut = Arc::new(Mutex::new(slice)); |
|||
let mut result : u64 = 0; |
|||
|
|||
for i in 0 .. threads { |
|||
let local_base = self.base.clone(); |
|||
let local_tx = tx.clone(); |
|||
let local_slice = slice_mut.clone(); |
|||
thread::spawn(move || { |
|||
let mut count : u64; |
|||
let mut target : u64; |
|||
let mut run = true; |
|||
let mut result = SharedData { |
|||
i: 0, |
|||
dig: md5::compute(b"0"), |
|||
valid: false, |
|||
}; |
|||
while run { |
|||
{ |
|||
let mut local_slice_mut = local_slice.lock().unwrap(); |
|||
run = local_slice_mut.run; |
|||
count = local_slice_mut.next; |
|||
if count <= (std::u64::MAX - local_slice_mut.size) { |
|||
target = count + local_slice_mut.size; |
|||
} else { |
|||
target = std::u64::MAX; |
|||
} |
|||
local_slice_mut.next = target; |
|||
} |
|||
|
|||
while run && count < target { |
|||
let key = format!("{}{}", local_base, count.to_string()); |
|||
result.dig = md5::compute(key.as_bytes()); |
|||
if result.dig[0] == 0 && result.dig[1] == 0 && result.dig[2] == 0 { |
|||
println!("{}: {} -> {:x}", count, key, result.dig); |
|||
result.i = count; |
|||
result.valid = true; |
|||
run = false; |
|||
let mut local_slice_mut = local_slice.lock().unwrap(); |
|||
local_slice_mut.run = false; |
|||
} else { |
|||
count += 1; |
|||
} |
|||
} |
|||
} |
|||
local_tx.send(result); |
|||
|
|||
}); |
|||
} |
|||
|
|||
for _ in 0 .. threads { |
|||
let res = rx.recv(); |
|||
match res { |
|||
Ok(val) => { |
|||
if val.valid && (result == 0 || result > val.i) { |
|||
result = val.i; |
|||
} |
|||
}, |
|||
Err(_) => (), |
|||
} |
|||
} |
|||
result |
|||
|
|||
} |
|||
} |
|||
Loading…
Reference in new issue