rustgym 0.2.0

rustgym solutions
Documentation
struct Solution;
use std::collections::HashSet;

impl Solution {
    fn open_lock(deadends: Vec<String>, target: String) -> i32 {
        let mut visited: HashSet<u32> = deadends.into_iter().map(Self::s2x).collect();
        let target = Self::s2x(target);
        let start = 0;
        if visited.contains(&start) {
            return -1;
        }
        let mut begin: HashSet<u32> = HashSet::new();
        let mut end: HashSet<u32> = HashSet::new();
        begin.insert(start);
        end.insert(target);
        let mut level = 0;
        while !begin.is_empty() && !end.is_empty() {
            let mut temp: HashSet<u32> = HashSet::new();
            for x in begin {
                if end.contains(&x) {
                    return level;
                } else {
                    visited.insert(x);
                    for y in Self::adj(x) {
                        if !visited.contains(&y) {
                            temp.insert(y);
                        }
                    }
                }
            }
            level += 1;
            begin = end;
            end = temp
        }
        -1
    }

    fn s2x(s: String) -> u32 {
        let mut res = 0;
        for (i, b) in s.bytes().map(|b| (b - b'0') as u32).enumerate() {
            res |= b << (i * 8);
        }
        res
    }

    fn x2s(x: u32) -> String {
        let mut v: Vec<u8> = vec![0; 4];
        for i in 0..4 {
            v[i] = ((x >> (i * 8)) & 0xff) as u8;
        }
        v.into_iter().map(|b| (b + b'0') as char).collect()
    }

    fn adj(x: u32) -> Vec<u32> {
        let mut res = vec![];
        for i in 0..4 {
            let b1 = (((x >> (i * 8) & 0xff) + 1) % 10) << (i * 8);
            let b2 = (((x >> (i * 8) & 0xff) + 9) % 10) << (i * 8);
            let mask = !(0xff << (i * 8));
            res.push((x & mask) | b1);
            res.push((x & mask) | b2);
        }
        res
    }
}

#[test]
fn test() {
    let deadends = vec_string!["0201", "0101", "0102", "1212", "2002"];
    let target = "0202".to_string();
    let res = 6;
    assert_eq!(Solution::open_lock(deadends, target), res);
}