# Rust, (12, 11) This is basically a line-by-line port of Jonathan Allan's answer, with is already very good. Thanks! I wrote this to practice some Rust. It uses the [nohash-hasher](https://crates.io/crates/nohash-hasher) crate for extremely fast HashMap lookups, with take up the vast majority of the time. [Try it online on rustexplorer.com](https://www.rustexplorer.com/b#LyoKW2RlcGVuZGVuY2llc10Kbm9oYXNoLWhhc2hlciA9ICIwLjIuMCIKKi8KCiMhW3dhcm4oY2xpcHB5OjphbGwpXQoKdXNlIHN0ZDo6Y29sbGVjdGlvbnM6Omhhc2hfbWFwOjpFbnRyeTsKdXNlIHN0ZDo6Y29sbGVjdGlvbnM6OlZlY0RlcXVlOwp1c2Ugc3RkOjp0aW1lOjpJbnN0YW50OwoKdXNlIG5vaGFzaF9oYXNoZXI6OntJbnRNYXAsIEludFNldH07CgpmbiBjb3VudF9maXhlZF9kaXN0YW5jZShzOiAmc3RyLCBrOiB1MzIpIC0+IHVzaXplIHsKICAgIGxldCBuID0gaTMyOjpmcm9tX3N0cl9yYWRpeCgmZm9ybWF0ISgiMXtzfSIpLCAyKS51bndyYXAoKTsKICAgIGxldCBtdXQgZGlzdGFuY2VzID0KICAgICAgICBJbnRNYXA6OndpdGhfY2FwYWNpdHlfYW5kX2hhc2hlcigxIDw8IChzLmxlbigpICsgayBhcyB1c2l6ZSksIERlZmF1bHQ6OmRlZmF1bHQoKSk7CiAgICBkaXN0YW5jZXMuaW5zZXJ0KG4sIDApOwogICAgbGV0IG11dCBxdWV1ZSA9IFZlY0RlcXVlOjpmcm9tKFsobiwgcy5sZW4oKSldKTsKICAgIC8vIGNhcGFjaXR5IGlzIGp1c3QgZXhwZXJpbWVudGF0aW9uCiAgICBsZXQgbXV0IHZhbGlkID0gSW50U2V0Ojp3aXRoX2NhcGFjaXR5X2FuZF9oYXNoZXIoMSA8PCAoayArIDEpLCBEZWZhdWx0OjpkZWZhdWx0KCkpOwogICAgd2hpbGUgbGV0IFNvbWUoKGN1cnJlbnQsIGJpdF9jb3VudCkpID0gcXVldWUucG9wX2Zyb250KCkgewogICAgICAgIGxldCBuZXh0X2Rpc3QgPSBkaXN0YW5jZXMuZ2V0KCZjdXJyZW50KS51bndyYXAoKSArIDE7CiAgICAgICAgbGV0IG11dCBwb3cgPSAwOwogICAgICAgIGZvciBlIGluIDAuLmJpdF9jb3VudCB7CiAgICAgICAgICAgIGxldCBsZWZ0ID0gY3VycmVudCA+PiBlOwogICAgICAgICAgICBsZXQgbGVmdF8xID0gbGVmdCA8PCAxOwogICAgICAgICAgICBwb3cgPSAxIDw8IGU7CiAgICAgICAgICAgIGxldCByaWdodCA9IGN1cnJlbnQgJSBwb3c7CiAgICAgICAgICAgIGxldCBicDEgPSBiaXRfY291bnQgKyAxOwogICAgICAgICAgICBmb3IgKG5leHQsIG5leHRfYml0X2NvdW50KSBpbiBbCiAgICAgICAgICAgICAgICAoKGxlZnQgPj4gMSA8PCBlKSB8IHJpZ2h0LCBiaXRfY291bnQgLSAxKSwKICAgICAgICAgICAgICAgIChjdXJyZW50IF4gcG93LCBiaXRfY291bnQpLAogICAgICAgICAgICAgICAgKChsZWZ0XzEgPDwgZSkgfCByaWdodCwgYnAxKSwKICAgICAgICAgICAgICAgICgoKGxlZnRfMSB8IDEpIDw8IGUpIHwgcmlnaHQsIGJwMSksCiAgICAgICAgICAgIF0gewogICAgICAgICAgICAgICAgbWF0Y2ggZGlzdGFuY2VzLmVudHJ5KG5leHQpIHsKICAgICAgICAgICAgICAgICAgICBFbnRyeTo6VmFjYW50KHZlKSA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZlLmluc2VydChuZXh0X2Rpc3QpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBFbnRyeTo6T2NjdXBpZWQoXykgPT4gY29udGludWUsCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiBuZXh0X2Rpc3QgPCBrIHsKICAgICAgICAgICAgICAgICAgICBxdWV1ZS5wdXNoX2JhY2soKG5leHQsIG5leHRfYml0X2NvdW50KSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHZhbGlkLmluc2VydChuZXh0KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgZm9yIG5leHQgaW4gW3BvdyA8PCAyIHwgY3VycmVudCwgMyA8PCBiaXRfY291bnQgXiBjdXJyZW50XSB7CiAgICAgICAgICAgIG1hdGNoIGRpc3RhbmNlcy5lbnRyeShuZXh0KSB7CiAgICAgICAgICAgICAgICBFbnRyeTo6VmFjYW50KHZlKSA9PiB7CiAgICAgICAgICAgICAgICAgICAgdmUuaW5zZXJ0KG5leHRfZGlzdCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBFbnRyeTo6T2NjdXBpZWQoXykgPT4gY29udGludWUsCiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgbmV4dF9kaXN0IDwgayB7CiAgICAgICAgICAgICAgICBxdWV1ZS5wdXNoX2JhY2soKG5leHQsIGJpdF9jb3VudCArIDEpKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHZhbGlkLmluc2VydChuZXh0KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIHZhbGlkLmxlbigpCn0KCmZuIG1haW4oKSB7CiAgICBsZXQgc3RhcnQgPSBJbnN0YW50Ojpub3coKTsKICAgIGxldCBtdXQgcyA9IFN0cmluZzo6d2l0aF9jYXBhY2l0eSgzMik7CiAgICBzLnB1c2goJzAnKTsKICAgIGxldCBtdXQgdiA9IDA7CiAgICB3aGlsZSBzLmxlbigpIDw9IDEyIHsKICAgICAgICAvLyBhcHByb3ggMiBtaW51dGVzIGZvciBwcm9maWxpbmcKICAgICAgICBmb3IgayBpbiAxLi4ocy5sZW4oKSArIDEpIHsKICAgICAgICAgICAgcHJpbnRsbiEoInt9IHt9IHt9Iiwgcy5sZW4oKSwgaywgY291bnRfZml4ZWRfZGlzdGFuY2UoJnMsIGsgYXMgdTMyKSk7CiAgICAgICAgfQogICAgICAgIHMucHVzaChbJzEnLCAnMScsICcwJywgJzAnXVt2ICUgNF0pOwogICAgICAgIHYgKz0gMTsKICAgICAgICBwcmludGxuISgie30iLCBzKQogICAgfQogICAgcHJpbnRsbiEoInt9IHNlY29uZHMiLCBzdGFydC5lbGFwc2VkKCkuYXNfc2Vjc19mMzIoKSk7Cn0K). Runs an unoptimized debug build, so don't rely on it for measurements. ```rust #![warn(clippy::all)] use std::collections::VecDeque; use std::collections::hash_map::Entry; use std::time::Instant; use nohash_hasher::{IntMap, IntSet}; fn count_fixed_distance(s: &str, k: u32) -> usize { let n = i32::from_str_radix(&format!("1{s}"), 2).unwrap(); let mut distances = IntMap::with_capacity_and_hasher(1 << (s.len() + k as usize), Default::default()); distances.insert(n, 0); let mut queue = VecDeque::from([(n, s.len())]); // capacity is just experimentation let mut valid = IntSet::with_capacity_and_hasher(1 << (k + 1), Default::default()); while let Some((current, bit_count)) = queue.pop_front() { let next_dist = distances.get(¤t).unwrap() + 1; let mut pow = 0; for e in 0..bit_count { let left = current >> e; let left_1 = left << 1; pow = 1 << e; let right = current % pow; let bp1 = bit_count + 1; for (next, next_bit_count) in [ ((left >> 1 << e) | right, bit_count - 1), (current ^ pow, bit_count), ((left_1 << e) | right, bp1), (((left_1 | 1) << e) | right, bp1) ] { match distances.entry(next) { Entry::Vacant(ve) => { ve.insert(next_dist); } Entry::Occupied(_) => continue, } if next_dist < k { queue.push_back((next, next_bit_count)); } else { valid.insert(next); } } } for next in [pow << 2 | current, 3 << bit_count ^ current] { match distances.entry(next) { Entry::Vacant(ve) => { ve.insert(next_dist); } Entry::Occupied(_) => continue, } if next_dist < k { queue.push_back((next, bit_count + 1)); } else { valid.insert(next); } } } valid.len() } fn main() { let start = Instant::now(); let mut s = String::with_capacity(32); s.push('0'); let mut v = 0; while s.len() <= 12 { // approx 2 minutes for profiling for k in 1..(s.len() + 1) { println!("{} {} {}", s.len(), k, count_fixed_distance(&s, k as u32)); } s.push(['1', '1', '0', '0'][v % 4]); v += 1; println!("{}", s) } println!("{} seconds", start.elapsed().as_secs_f32()); } ```