6 changed files with 236 additions and 0 deletions
@ -1,4 +1,14 @@ |
|||||
[[package]] |
[[package]] |
||||
name = "adventofcode2015" |
name = "adventofcode2015" |
||||
version = "0.1.0" |
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