1- use std:: collections:: { HashMap , HashSet } ;
21use std:: fs;
32
43use anyhow:: Error ;
@@ -7,7 +6,7 @@ use task_maker_diagnostics::{CodeSpan, Diagnostic};
76
87use crate :: ioi:: IOITask ;
98use crate :: sanity_checks:: { make_sanity_check, SanityCheck , SanityCheckCategory } ;
10- use crate :: { list_files, EvaluationData , SolutionCheckResult } ;
9+ use crate :: { list_files, EvaluationData } ;
1110
1211/// The default maximum score of a task.
1312const DEFAULT_TASK_MAX_SCORE : f64 = 100.0 ;
@@ -129,143 +128,6 @@ impl SanityCheck for NoBitsStdCpp {
129128 }
130129}
131130
132- /// Check that "implied" subtasks dependecies do not form cycles.
133- #[ derive( Debug , Default ) ]
134- pub struct SubtaskDependencies ;
135- make_sanity_check ! ( SubtaskDependencies ) ;
136-
137- impl SanityCheck for SubtaskDependencies {
138- type Task = IOITask ;
139-
140- fn name ( & self ) -> & ' static str {
141- "SubtaskDependencies"
142- }
143-
144- fn category ( & self ) -> SanityCheckCategory {
145- SanityCheckCategory :: Task
146- }
147-
148- fn pre_hook ( & self , task : & Self :: Task , eval : & mut EvaluationData ) -> Result < ( ) , Error > {
149- let non_zero_sts = task
150- . subtasks
151- . keys ( )
152- . copied ( )
153- . filter ( |st| task. subtasks [ st] . max_score > 0.0 )
154- . collect :: < Vec < _ > > ( ) ;
155-
156- let mut st_dependencies = HashSet :: new ( ) ;
157- for & st1 in & non_zero_sts {
158- for & st2 in & non_zero_sts {
159- if st1 != st2 {
160- st_dependencies. insert ( ( st1, st2) ) ;
161- }
162- }
163- }
164-
165- let mut any_st_check = false ;
166- for sol in & eval. solutions {
167- let mut score_range = HashMap :: new ( ) ;
168- for check in & sol. checks {
169- any_st_check = true ;
170-
171- let val = match check. result {
172- SolutionCheckResult :: Accepted => ( 1.0 , 1.0 ) ,
173- SolutionCheckResult :: PartialScore => ( 0.0 , 1.0 ) ,
174- _ => ( 0.0 , 0.0 ) ,
175- } ;
176-
177- for subtask in task. find_subtasks_by_pattern_name ( & check. subtask_name_pattern ) {
178- score_range. insert ( subtask. id , val) ;
179- }
180- }
181-
182- for & st1 in & non_zero_sts {
183- for & st2 in & non_zero_sts {
184- if let ( Some ( v1) , Some ( v2) ) = ( score_range. get ( & st1) , score_range. get ( & st2) ) {
185- if v1. 1 > v2. 0 {
186- st_dependencies. remove ( & ( st1, st2) ) ;
187- }
188- }
189- }
190- }
191- }
192-
193- if !any_st_check {
194- return Ok ( ( ) ) ;
195- }
196-
197- ' outer: for & st1 in & non_zero_sts {
198- let mut sts = vec ! [ st1] ;
199- for & st2 in & non_zero_sts {
200- if st_dependencies. contains ( & ( st1, st2) ) && st_dependencies. contains ( & ( st2, st1) ) {
201- if st1 < st2 {
202- sts. push ( st2) ;
203- } else {
204- continue ' outer;
205- }
206- }
207- }
208- if sts. len ( ) > 1 {
209- sts. sort ( ) ;
210- let st_names: Vec < _ > = sts
211- . iter ( )
212- . map ( |st| {
213- task. subtasks [ st]
214- . name
215- . as_ref ( )
216- . map ( |s| s as & dyn std:: fmt:: Debug )
217- . unwrap_or ( st)
218- } )
219- . collect ( ) ;
220- eval. add_diagnostic (
221- Diagnostic :: warning ( format ! (
222- "Subtasks {st_names:?} are solved by the same set of solutions" ,
223- ) )
224- . with_note ( "Add a solution that solves only one of them" ) ,
225- ) ?;
226- }
227- }
228-
229- let mut to_swap = Vec :: new ( ) ;
230- for & st1 in & non_zero_sts {
231- for & st2 in & non_zero_sts {
232- if st1 < st2
233- && st_dependencies. contains ( & ( st1, st2) )
234- && !st_dependencies. contains ( & ( st2, st1) )
235- {
236- to_swap. push ( ( st1, st2) ) ;
237- }
238- }
239- }
240-
241- if !to_swap. is_empty ( ) {
242- let to_swap_names = to_swap
243- . iter ( )
244- . map ( |( st1, st2) | {
245- let st1_name = task. subtasks [ st1]
246- . name
247- . as_ref ( )
248- . map ( |s| s as & dyn std:: fmt:: Debug )
249- . unwrap_or ( st1) ;
250- let st2_name = task. subtasks [ st2]
251- . name
252- . as_ref ( )
253- . map ( |s| s as & dyn std:: fmt:: Debug )
254- . unwrap_or ( st2) ;
255- ( st1_name, st2_name)
256- } )
257- . collect :: < Vec < _ > > ( ) ;
258- eval. add_diagnostic (
259- Diagnostic :: warning ( "Subtasks are not in order of difficulty" ) . with_note ( format ! (
260- "Based on the current solutions the following pairs of subtasks seems to be ordered incorrectly {to_swap_names:?}"
261- ) ) ,
262- ) ?;
263- }
264-
265- Ok ( ( ) )
266- }
267- }
268-
269131/// Check that the task title is not emtpy.
270132#[ derive( Debug , Default ) ]
271133pub struct EmptyTitle ;
0 commit comments