library_checker/
lib.rs

1//! Verification of [`competitive` crate] by [Library-Checker]
2//!
3//! [verification summary]
4//!
5//! [`competitive` crate]: ../competitive/index.html
6//! [Library-Checker]: https://judge.yosupo.jp
7//! [verification summary]: ?search=verify
8
9pub mod convolution;
10pub mod data_structure;
11pub mod enumerative_combinatorics;
12pub mod graph;
13pub mod linear_algebra;
14pub mod number_theory;
15pub mod other;
16pub mod polynomial;
17pub mod sample;
18pub mod set_power_series;
19pub mod string;
20pub mod tree;
21
22#[cfg(test)]
23mod tests {
24    use std::process::Command;
25
26    fn list_verified_problems() -> Vec<(String, String)> {
27        let output = Command::new("cargo")
28            .args([
29                "test",
30                "-p",
31                "library_checker",
32                "--quiet",
33                "--",
34                "--list",
35                "--ignored",
36            ])
37            .output()
38            .expect("Failed to list verified problems")
39            .stdout;
40        let output = String::from_utf8_lossy(&output);
41        output
42            .lines()
43            .filter_map(|line| {
44                let mut split = line.split("::");
45                let category = split.next().unwrap();
46                if category == "tests" {
47                    return None;
48                }
49                let problem = split.next().unwrap();
50                Some((category.to_string(), problem.to_string()))
51            })
52            .collect()
53    }
54
55    #[test]
56    fn checklist() {
57        let problems = verify::library_checker::get_problem_list().unwrap();
58        let verified_problems = list_verified_problems();
59        let mut total_count = 0;
60        let mut verified_count = 0;
61        for (category, problems) in problems {
62            println!("{}", category);
63            for problem in problems {
64                if verified_problems.contains(&(category.clone(), problem.clone())) {
65                    println!("  ☑ {}", problem);
66                    verified_count += 1;
67                } else {
68                    println!("  ☐ {}", problem);
69                }
70                total_count += 1;
71            }
72        }
73        println!(
74            "Verified {}/{} problems ({:.2}%)\n",
75            verified_count,
76            total_count,
77            100.0 * verified_count as f64 / total_count as f64
78        );
79    }
80
81    #[test]
82    fn check_correct_category() {
83        let problems = verify::library_checker::get_problem_list().unwrap();
84        let verified_problems = list_verified_problems();
85        let mut failed = vec![];
86        for (category, problem) in verified_problems {
87            if let Some((correct_category, _)) = problems
88                .iter()
89                .find(|(_, problems)| problems.contains(&problem))
90            {
91                if &category != correct_category {
92                    println!("{}/{} -> {}", category, problem, correct_category);
93                    failed.push((problem, category, correct_category.clone()));
94                }
95            } else {
96                panic!("Problem not found: {} in {:?}", problem, problems);
97            }
98        }
99        assert!(failed.is_empty(), "Some problems are in wrong category");
100    }
101}