library_checker/
lib.rs

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