rustgym 0.2.0

rustgym solutions
Documentation
struct Solution;

use std::collections::HashMap;
use std::collections::HashSet;
use std::collections::VecDeque;

impl Solution {
    fn is_printable(target_grid: Vec<Vec<i32>>) -> bool {
        let n = target_grid.len();
        let m = target_grid[0].len();
        let mut color: HashMap<i32, usize> = HashMap::new();
        for i in 0..n {
            for j in 0..m {
                let size = color.len();
                color.entry(target_grid[i][j]).or_insert(size);
            }
        }
        let c = color.len();
        let mut left: Vec<usize> = vec![m - 1; c];
        let mut right: Vec<usize> = vec![0; c];
        let mut top: Vec<usize> = vec![n - 1; c];
        let mut bottom: Vec<usize> = vec![0; c];
        for i in 0..n {
            for j in 0..m {
                let u = color[&target_grid[i][j]];
                left[u] = left[u].min(j);
                right[u] = right[u].max(j);
                top[u] = top[u].min(i);
                bottom[u] = bottom[u].max(i);
            }
        }
        let mut adj: Vec<HashSet<usize>> = vec![HashSet::new(); c];
        for i in 0..n {
            for j in 0..m {
                let u = color[&target_grid[i][j]];
                for v in 0..c {
                    if v == u {
                        continue;
                    }
                    if left[v] <= j && j <= right[v] && top[v] <= i && i <= bottom[v] {
                        adj[v].insert(u);
                    }
                }
            }
        }
        let mut indegree = vec![0; c];
        for u in 0..c {
            for &v in &adj[u] {
                indegree[v] += 1;
            }
        }
        let mut queue: VecDeque<usize> = VecDeque::new();
        let mut visited = 0;
        for u in 0..c {
            if indegree[u] == 0 {
                visited += 1;
                queue.push_back(u);
            }
        }
        while let Some(u) = queue.pop_front() {
            for &v in &adj[u] {
                indegree[v] -= 1;
                if indegree[v] == 0 {
                    visited += 1;
                    queue.push_back(v);
                }
            }
        }
        visited == c
    }
}

#[test]
fn test() {
    let target_grid = vec_vec_i32![[1, 1, 1, 1], [1, 2, 2, 1], [1, 2, 2, 1], [1, 1, 1, 1]];
    let res = true;
    assert_eq!(Solution::is_printable(target_grid), res);
    let target_grid = vec_vec_i32![[1, 1, 1, 1], [1, 1, 3, 3], [1, 1, 3, 4], [5, 5, 1, 4]];
    let res = true;
    assert_eq!(Solution::is_printable(target_grid), res);
    let target_grid = vec_vec_i32![[1, 2, 1], [2, 1, 2], [1, 2, 1]];
    let res = false;
    assert_eq!(Solution::is_printable(target_grid), res);
    let target_grid = vec_vec_i32![[1, 1, 1], [3, 1, 3]];
    let res = false;
    assert_eq!(Solution::is_printable(target_grid), res);
}