Skip to main content

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        assert!(
40            output.status.success(),
41            "{}",
42            String::from_utf8_lossy(&output.stderr)
43        );
44        let output = String::from_utf8_lossy(&output.stdout);
45        output
46            .lines()
47            .filter_map(|line| {
48                let mut split = line.split("::");
49                let category = split.next().unwrap();
50                if category == "tests" {
51                    return None;
52                }
53                let problem = split.next().unwrap();
54                Some((category.to_string(), problem.to_string()))
55            })
56            .collect()
57    }
58
59    #[test]
60    fn checklist() {
61        let problems = verify::library_checker::get_problem_list().unwrap();
62        let verified_problems = list_verified_problems();
63        assert!(!verified_problems.is_empty());
64        assert!(!problems.is_empty());
65        let mut total_count = 0;
66        let mut verified_count = 0;
67        for (category, problems) in problems {
68            println!("{}", category);
69            for problem in problems {
70                if verified_problems.contains(&(category.clone(), problem.clone())) {
71                    println!("  ☑ {}", problem);
72                    verified_count += 1;
73                } else {
74                    println!("  ☐ {}", problem);
75                }
76                total_count += 1;
77            }
78        }
79        println!(
80            "Verified {}/{} problems ({:.2}%)\n",
81            verified_count,
82            total_count,
83            100.0 * verified_count as f64 / total_count as f64
84        );
85    }
86
87    #[test]
88    fn check_correct_category() {
89        let problems = verify::library_checker::get_problem_list().unwrap();
90        let verified_problems = list_verified_problems();
91        assert!(!verified_problems.is_empty());
92        assert!(!problems.is_empty());
93        let mut failed = vec![];
94        for (category, problem) in verified_problems {
95            if let Some((correct_category, _)) = problems
96                .iter()
97                .find(|(_, problems)| problems.contains(&problem))
98            {
99                if &category != correct_category {
100                    println!("{}/{} -> {}", category, problem, correct_category);
101                    failed.push((problem, category, correct_category.clone()));
102                }
103            } else {
104                panic!("Problem not found: {} in {:?}", problem, problems);
105            }
106        }
107        assert!(failed.is_empty(), "Some problems are in wrong category");
108    }
109}