Skip to content

Instantly share code, notes, and snippets.

@scottgw
Created June 21, 2016 07:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save scottgw/1702cda28a5519e8f861423276e4ef03 to your computer and use it in GitHub Desktop.
Save scottgw/1702cda28a5519e8f861423276e4ef03 to your computer and use it in GitHub Desktop.
A combination of aatch and the PairHash improvements, minus the explicit size initialization of the sets.
use std::collections::HashSet;
use std::hash::BuildHasherDefault;
use std::default::Default;
use std::hash::Hasher;
pub struct FnvHasher(u64);
impl Default for FnvHasher {
#[inline]
fn default() -> FnvHasher {
FnvHasher(0xcbf29ce484222325)
}
}
impl Hasher for FnvHasher {
#[inline]
fn finish(&self) -> u64 {
self.0
}
#[inline]
fn write(&mut self, bytes: &[u8]) {
panic!("Don't use, only for pairs")
}
#[inline]
fn write_i32(&mut self, value: i32) {
self.0 <<= 10;
self.0 ^= value as u64;
}
}
type Set = HashSet<(i32, i32), BuildHasherDefault<FnvHasher>>;
fn new_set() -> Set {
let fnv = BuildHasherDefault::<FnvHasher>::default();
HashSet::with_hasher(fnv)
}
fn iterNeighbors<F>(mut f: F, (i, j): (i32, i32)) -> ()
where F: FnMut((i32, i32)) -> ()
{
f((i-1, j));
f((i+1, j));
f((i, j-1));
f((i, j+1));
}
fn nthLoop(n: usize, mut s0: Set, s1: Set, mut s2: Set) -> Set {
if n == 0 {
return s1;
} else {
for &p in &s1 {
let add = |p| {
if !s2.contains(&p) && !s1.contains(&p) {
s0.insert(p);
}
};
iterNeighbors(add, p);
}
s2.clear();
return nthLoop(n-1, s2, s0, s1);
}
}
fn nth(n: usize, p: (i32, i32)) -> Set {
let mut s1 = new_set();
let s2 = new_set();
let mut s0 = new_set();
s1.insert(p);
nthLoop(n, s0, s1, s2)
}
fn main() {
let s = nth(7000, (0, 0));
println!("{}", s.len());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment