human_binary/
lib.rs

1pub fn add(left: u64, right: u64) -> u64 {
2    left + right
3}
4
5const WORDS: [&str; 10] = [
6    "zero", "one", "two", "four", "hex", "byte", "int", "long", "overlong", "byteplex",
7];
8
9pub fn to_binary_string(num: u64, short: bool) -> String {
10    if num == 0 {
11        return "zero".to_string();
12    }
13    let mut result = Vec::new();
14    recurse(num, &mut result);
15    
16    if short {
17        result.join(" ").replace("two one", "three")
18    } else {
19        result.join(" ")
20    }
21}
22
23fn recurse(num: u64, result: &mut Vec<String>) {
24    if num == 1 {
25        result.push(WORDS[1].to_string());
26        return;
27    }
28
29    let maxdoublepowerof2 = num.ilog2().ilog2();
30    let shift = 2u64.pow(maxdoublepowerof2);
31
32    //split at that bit
33    let highbits = num >> shift;
34    let lowbits = num & (1 << shift) - 1;
35
36    let power = WORDS[(maxdoublepowerof2 + 2) as usize].to_string();
37    if highbits > 1 {
38        recurse(highbits, result);
39    }
40
41    result.push(power);
42
43    if lowbits > 0 {
44        recurse(lowbits, result);
45    }
46}
47
48#[cfg(test)]
49mod tests {
50    use super::*;
51
52    #[test]
53    fn long_form_works() {
54        let result = to_binary_string(123, false);
55        assert_eq!(result, "four two one hex two four two one");
56    }
57    
58    #[test]
59    fn short_form_works() {
60        let result = to_binary_string(123, true);
61        assert_eq!(result, "four three hex two four three");
62    }
63}