pub struct Task {
pub tests_path: PathBuf,
pub time_limit: f32,
pub tests_archive_path: PathBuf,
pub get_input_file_name: Box<dyn Fn(i32, i32, i32) -> String>,
pub get_output_file_name: Box<dyn Fn(i32, i32, i32) -> String>,
pub solution_source: String,
pub debug_level: LevelFilter,
/* private fields */
}
Expand description
This struct represents an entire task. You can add subtasks, partial solutions and set the time limit. Once you are done, you can create tests for the task.
Fields§
§tests_path: PathBuf
§time_limit: f32
§tests_archive_path: PathBuf
§get_input_file_name: Box<dyn Fn(i32, i32, i32) -> String>
§get_output_file_name: Box<dyn Fn(i32, i32, i32) -> String>
§solution_source: String
§debug_level: LevelFilter
Implementations§
Source§impl Task
impl Task
Sourcepub fn new(name: &str, path: &Path) -> Self
pub fn new(name: &str, path: &Path) -> Self
This function creates a new task with the given name and path.
The path should be a relative path to the task folder in which the tests will be generated.
The solution should be at solution_path
which is path
/solution.cpp by default but can be changed.
Examples found in repository?
32fn main() {
33 // In this task you have n coins with values a1, a2, ..., an. You need to find the smallest sum, you cannot get using these coins.
34 // For example, if you have coins with values 1, 2 and 4, you can get any sum from 1 to 7, but you cannot get 8.
35
36 let mut task = ezcp::Task::new("Coins", &PathBuf::from("task2"));
37 task.solution_source = SOLUTION.to_owned();
38
39 // Constraint: n = 1
40 let mut subtask1 = ezcp::Subtask::new();
41
42 subtask1.set_checker(|mut input| {
43 let array = input.get_array()?;
44 input.expect_end()?;
45 let n = array.len();
46 if n != 1 {
47 ezcp::bail!("n should be 1");
48 }
49 let x = array[0];
50 if !(1..=1_000_000_000).contains(&x) {
51 ezcp::bail!("all array values should be in range [1, 1_000_000_000]");
52 }
53 Ok(())
54 });
55
56 subtask1.add_test(5, ezcp::array_generator(1, 1, 1, 1000));
57 subtask1.add_test_str("1\n 1\n".to_owned());
58
59 // Constraint: elements in the array are powers of 2 and n <= 30
60 let mut subtask2 = ezcp::Subtask::new();
61
62 subtask2.set_checker(|mut input| {
63 let array = input.get_array()?;
64 input.expect_end()?;
65 let n = array.len();
66 if !(1..=30).contains(&n) {
67 ezcp::bail!("n should be in range [1, 30]");
68 }
69 for (i, x) in array.iter().enumerate() {
70 if *x != 1 << i {
71 ezcp::bail!("all array values should be powers of 2");
72 }
73 }
74 Ok(())
75 });
76
77 subtask2.add_test(5, || {
78 let mut rng = rand::rng();
79 let n = rng.random_range(1..=30);
80 let mut array = Vec::new();
81 for i in 0..n {
82 array.push(1 << i);
83 }
84 ezcp::array_to_string(&array, true)
85 });
86
87 // Constraint: n <= 1000
88 let mut subtask3 = ezcp::Subtask::new();
89
90 subtask3.set_checker(|mut input| {
91 let array = input.get_array()?;
92 input.expect_end()?;
93 let n = array.len();
94 if !(1..=1000).contains(&n) {
95 ezcp::bail!("n should be in range [1, 1000]");
96 }
97 for x in array {
98 if !(1..=1_000_000_000).contains(&x) {
99 ezcp::bail!("all array values should be in range [1, 1_000_000_000]");
100 }
101 }
102 Ok(())
103 });
104
105 subtask3.add_test(5, ezcp::array_generator(1, 1000, 1, 1000));
106 subtask3.add_test(5, ezcp::array_generator(1, 1000, 1, 1_000_000_000));
107 subtask3.add_test(5, ezcp::array_generator(1, 1000, 1, 1));
108 subtask3.add_test(5, ezcp::array_generator(1000, 1000, 1, 1000));
109 subtask3.add_test(5, ezcp::array_generator(1000, 1000, 1, 1_000_000_000));
110 subtask3.add_test(1, ezcp::array_generator(1000, 1000, 1, 1));
111
112 // Constraint: n <= 200_000
113 let mut subtask4 = ezcp::Subtask::new();
114
115 subtask4.set_checker(|mut input| {
116 let array = input.get_array()?;
117 input.expect_end()?;
118 let n = array.len();
119 if !(1..=200_000).contains(&n) {
120 ezcp::bail!("n should be in range [1, 200_000]");
121 }
122 for x in array {
123 if !(1..=1_000_000_000).contains(&x) {
124 ezcp::bail!("all array values should be in range [1, 1_000_000_000]");
125 }
126 }
127 Ok(())
128 });
129
130 subtask4.add_test(5, ezcp::array_generator(1, 200_000, 1, 1000));
131 subtask4.add_test(5, ezcp::array_generator(1, 200_000, 1, 1_000_000_000));
132 subtask4.add_test(5, ezcp::array_generator(1, 200_000, 1, 1));
133 subtask4.add_test(5, ezcp::array_generator(200_000, 200_000, 1, 1000));
134 subtask4.add_test(5, ezcp::array_generator(200_000, 200_000, 1, 1_000_000_000));
135 subtask4.add_test(1, ezcp::array_generator(200_000, 200_000, 1, 1));
136
137 // add subtasks to task
138 let subtask1 = task.add_subtask(subtask1);
139 let subtask2 = task.add_subtask(subtask2);
140 let subtask3 = task.add_subtask(subtask3);
141 let subtask4 = task.add_subtask(subtask4);
142
143 // add dependencies
144 task.add_subtask_dependency(subtask3, subtask1);
145 task.add_subtask_dependency(subtask3, subtask2);
146 task.add_subtask_dependency(subtask4, subtask3);
147
148 task.create_tests().ok();
149}
More examples
36fn main() {
37 // The first task you get an array of integers. You need to find the sum of all elements in the array minus the half of the maximum element.
38 // Also all elements in the array are even.
39
40 let mut task = ezcp::Task::new("Coupon", &PathBuf::from("task1"));
41 //task.debug_level = LevelFilter::Trace;
42
43 task.solution_source = SOLUTION.to_owned();
44
45 // Constraint: n = 1
46 let mut subtask1 = ezcp::Subtask::new();
47
48 // This checker is optional and can be omitted.
49 subtask1.set_checker(|mut input| {
50 // read an array from input
51 let array = input.get_array()?;
52 // expect end of input
53 input.expect_end()?;
54 let n = array.len();
55 if n != 1 {
56 ezcp::bail!("n should be 1");
57 }
58 // check if the only value is even
59 if array[0] % 2 != 0 {
60 ezcp::bail!("all array values should be even");
61 }
62 // check if the only value is in range
63 if !(0..=1_000_000_000).contains(&array[0]) {
64 ezcp::bail!("all array values should be in range [0, 1_000_000_000]");
65 }
66 Ok(())
67 });
68
69 // add 5 tests where an array is generated with length 1 and even values between 0 and 1_000_000_000 (inclusive)
70 subtask1.add_test(5, ezcp::array_generator_custom(1, 1, |rng| rng.random_range(0..=500_000_000) * 2));
71 // this is a faulty test for testing the checker
72 //subtask1.add_test_str("1\n 0 0\n".to_owned());
73
74 // Constraint: all values are the same
75 let mut subtask2 = ezcp::Subtask::new();
76
77 subtask2.set_checker(|mut input| {
78 let array = input.get_array()?;
79 input.expect_end()?;
80 let n = array.len();
81 if !(1..=200_000).contains(&n) {
82 ezcp::bail!("n should be in range [1, 200_000]");
83 }
84 let x = array[0];
85 for i in array {
86 if i != x {
87 ezcp::bail!("all array values should be the same");
88 }
89 if i % 2 != 0 {
90 ezcp::bail!("all array values should be even");
91 }
92 if !(0..=1_000_000_000).contains(&i) {
93 ezcp::bail!("all array values should be in range [0, 1_000_000_000]");
94 }
95 }
96 Ok(())
97 });
98
99 // add 5 random tests where each test is an array of length between 1 and 200_000 (inclusive) and all values are the same even value between 0 and 1_000_000_000 (inclusive)
100 subtask2.add_test(5, || {
101 let mut rng = rand::rng();
102 let n = rng.random_range(1..=200_000);
103 let x = rng.random_range(0..=500_000_000) * 2;
104 ezcp::array_to_string(&vec![x; n as usize], true)
105 });
106
107 // add an edge case where n is maximal
108 let mut rng = rand::rng();
109 let x = rng.random_range(0..=500_000_000) * 2;
110 subtask2.add_test_str(ezcp::array_to_string(&vec![x; 200_000], true));
111
112 // add 3 edge cases where all values are maximal
113 subtask2.add_test(3, ezcp::array_generator(1, 200_000, 1_000_000_000, 1_000_000_000));
114
115 // add an edge case where all values and n are maximal
116 subtask2.add_test_str(ezcp::array_to_string(&vec![1_000_000_000; 200_000], true));
117
118 // No additional constraints
119 let mut subtask3 = ezcp::Subtask::new();
120
121 subtask3.set_checker(|mut input| {
122 let array = input.get_array()?;
123 input.expect_end()?;
124 let n = array.len();
125 if !(1..=200_000).contains(&n) {
126 ezcp::bail!("n should be in range [1, 200_000]");
127 }
128 for i in array {
129 if i % 2 != 0 {
130 ezcp::bail!("all array values should be even");
131 }
132 if !(0..=1_000_000_000).contains(&i) {
133 ezcp::bail!("all array values should be in range [0, 1_000_000_000]");
134 }
135 }
136 Ok(())
137 });
138
139 // add some random tests
140 subtask3.add_test(5, ezcp::array_generator_custom(1, 200_000, |rng| rng.random_range(0..=500_000_000) * 2));
141
142 // add 5 edge cases where n is maximal (other edge cases are handled by subtask2)
143 subtask3.add_test(5, ezcp::array_generator_custom(200_000, 200_000, |rng| rng.random_range(0..=500_000_000) * 2));
144
145 // add subtasks to task
146 let subtask1 = task.add_subtask(subtask1);
147 let subtask2 = task.add_subtask(subtask2);
148 let subtask3 = task.add_subtask(subtask3);
149
150 // add dependencies (dependencies are only if constraints of a dependency are a subset of constraints of a subtask)
151 task.add_subtask_dependency(subtask3, subtask1);
152 task.add_subtask_dependency(subtask3, subtask2);
153
154 // there is a partial solution that only reads 2 integers: n, x and prints x / 2 which is correct for subtask1 but should fail for subtask2 and subtask3
155 task.add_partial_solution(PARTIAL_SOLUTION.to_owned(), &[subtask1]);
156
157 // finally create the tests
158 task.create_tests().ok();
159}
Sourcepub fn add_subtask(&mut self, subtask: Subtask) -> usize
pub fn add_subtask(&mut self, subtask: Subtask) -> usize
This function adds a subtask to the task. The subtask must be ready as it cannot be modified after it is added to the task. The function returns the index of the subtask.
Examples found in repository?
32fn main() {
33 // In this task you have n coins with values a1, a2, ..., an. You need to find the smallest sum, you cannot get using these coins.
34 // For example, if you have coins with values 1, 2 and 4, you can get any sum from 1 to 7, but you cannot get 8.
35
36 let mut task = ezcp::Task::new("Coins", &PathBuf::from("task2"));
37 task.solution_source = SOLUTION.to_owned();
38
39 // Constraint: n = 1
40 let mut subtask1 = ezcp::Subtask::new();
41
42 subtask1.set_checker(|mut input| {
43 let array = input.get_array()?;
44 input.expect_end()?;
45 let n = array.len();
46 if n != 1 {
47 ezcp::bail!("n should be 1");
48 }
49 let x = array[0];
50 if !(1..=1_000_000_000).contains(&x) {
51 ezcp::bail!("all array values should be in range [1, 1_000_000_000]");
52 }
53 Ok(())
54 });
55
56 subtask1.add_test(5, ezcp::array_generator(1, 1, 1, 1000));
57 subtask1.add_test_str("1\n 1\n".to_owned());
58
59 // Constraint: elements in the array are powers of 2 and n <= 30
60 let mut subtask2 = ezcp::Subtask::new();
61
62 subtask2.set_checker(|mut input| {
63 let array = input.get_array()?;
64 input.expect_end()?;
65 let n = array.len();
66 if !(1..=30).contains(&n) {
67 ezcp::bail!("n should be in range [1, 30]");
68 }
69 for (i, x) in array.iter().enumerate() {
70 if *x != 1 << i {
71 ezcp::bail!("all array values should be powers of 2");
72 }
73 }
74 Ok(())
75 });
76
77 subtask2.add_test(5, || {
78 let mut rng = rand::rng();
79 let n = rng.random_range(1..=30);
80 let mut array = Vec::new();
81 for i in 0..n {
82 array.push(1 << i);
83 }
84 ezcp::array_to_string(&array, true)
85 });
86
87 // Constraint: n <= 1000
88 let mut subtask3 = ezcp::Subtask::new();
89
90 subtask3.set_checker(|mut input| {
91 let array = input.get_array()?;
92 input.expect_end()?;
93 let n = array.len();
94 if !(1..=1000).contains(&n) {
95 ezcp::bail!("n should be in range [1, 1000]");
96 }
97 for x in array {
98 if !(1..=1_000_000_000).contains(&x) {
99 ezcp::bail!("all array values should be in range [1, 1_000_000_000]");
100 }
101 }
102 Ok(())
103 });
104
105 subtask3.add_test(5, ezcp::array_generator(1, 1000, 1, 1000));
106 subtask3.add_test(5, ezcp::array_generator(1, 1000, 1, 1_000_000_000));
107 subtask3.add_test(5, ezcp::array_generator(1, 1000, 1, 1));
108 subtask3.add_test(5, ezcp::array_generator(1000, 1000, 1, 1000));
109 subtask3.add_test(5, ezcp::array_generator(1000, 1000, 1, 1_000_000_000));
110 subtask3.add_test(1, ezcp::array_generator(1000, 1000, 1, 1));
111
112 // Constraint: n <= 200_000
113 let mut subtask4 = ezcp::Subtask::new();
114
115 subtask4.set_checker(|mut input| {
116 let array = input.get_array()?;
117 input.expect_end()?;
118 let n = array.len();
119 if !(1..=200_000).contains(&n) {
120 ezcp::bail!("n should be in range [1, 200_000]");
121 }
122 for x in array {
123 if !(1..=1_000_000_000).contains(&x) {
124 ezcp::bail!("all array values should be in range [1, 1_000_000_000]");
125 }
126 }
127 Ok(())
128 });
129
130 subtask4.add_test(5, ezcp::array_generator(1, 200_000, 1, 1000));
131 subtask4.add_test(5, ezcp::array_generator(1, 200_000, 1, 1_000_000_000));
132 subtask4.add_test(5, ezcp::array_generator(1, 200_000, 1, 1));
133 subtask4.add_test(5, ezcp::array_generator(200_000, 200_000, 1, 1000));
134 subtask4.add_test(5, ezcp::array_generator(200_000, 200_000, 1, 1_000_000_000));
135 subtask4.add_test(1, ezcp::array_generator(200_000, 200_000, 1, 1));
136
137 // add subtasks to task
138 let subtask1 = task.add_subtask(subtask1);
139 let subtask2 = task.add_subtask(subtask2);
140 let subtask3 = task.add_subtask(subtask3);
141 let subtask4 = task.add_subtask(subtask4);
142
143 // add dependencies
144 task.add_subtask_dependency(subtask3, subtask1);
145 task.add_subtask_dependency(subtask3, subtask2);
146 task.add_subtask_dependency(subtask4, subtask3);
147
148 task.create_tests().ok();
149}
More examples
36fn main() {
37 // The first task you get an array of integers. You need to find the sum of all elements in the array minus the half of the maximum element.
38 // Also all elements in the array are even.
39
40 let mut task = ezcp::Task::new("Coupon", &PathBuf::from("task1"));
41 //task.debug_level = LevelFilter::Trace;
42
43 task.solution_source = SOLUTION.to_owned();
44
45 // Constraint: n = 1
46 let mut subtask1 = ezcp::Subtask::new();
47
48 // This checker is optional and can be omitted.
49 subtask1.set_checker(|mut input| {
50 // read an array from input
51 let array = input.get_array()?;
52 // expect end of input
53 input.expect_end()?;
54 let n = array.len();
55 if n != 1 {
56 ezcp::bail!("n should be 1");
57 }
58 // check if the only value is even
59 if array[0] % 2 != 0 {
60 ezcp::bail!("all array values should be even");
61 }
62 // check if the only value is in range
63 if !(0..=1_000_000_000).contains(&array[0]) {
64 ezcp::bail!("all array values should be in range [0, 1_000_000_000]");
65 }
66 Ok(())
67 });
68
69 // add 5 tests where an array is generated with length 1 and even values between 0 and 1_000_000_000 (inclusive)
70 subtask1.add_test(5, ezcp::array_generator_custom(1, 1, |rng| rng.random_range(0..=500_000_000) * 2));
71 // this is a faulty test for testing the checker
72 //subtask1.add_test_str("1\n 0 0\n".to_owned());
73
74 // Constraint: all values are the same
75 let mut subtask2 = ezcp::Subtask::new();
76
77 subtask2.set_checker(|mut input| {
78 let array = input.get_array()?;
79 input.expect_end()?;
80 let n = array.len();
81 if !(1..=200_000).contains(&n) {
82 ezcp::bail!("n should be in range [1, 200_000]");
83 }
84 let x = array[0];
85 for i in array {
86 if i != x {
87 ezcp::bail!("all array values should be the same");
88 }
89 if i % 2 != 0 {
90 ezcp::bail!("all array values should be even");
91 }
92 if !(0..=1_000_000_000).contains(&i) {
93 ezcp::bail!("all array values should be in range [0, 1_000_000_000]");
94 }
95 }
96 Ok(())
97 });
98
99 // add 5 random tests where each test is an array of length between 1 and 200_000 (inclusive) and all values are the same even value between 0 and 1_000_000_000 (inclusive)
100 subtask2.add_test(5, || {
101 let mut rng = rand::rng();
102 let n = rng.random_range(1..=200_000);
103 let x = rng.random_range(0..=500_000_000) * 2;
104 ezcp::array_to_string(&vec![x; n as usize], true)
105 });
106
107 // add an edge case where n is maximal
108 let mut rng = rand::rng();
109 let x = rng.random_range(0..=500_000_000) * 2;
110 subtask2.add_test_str(ezcp::array_to_string(&vec![x; 200_000], true));
111
112 // add 3 edge cases where all values are maximal
113 subtask2.add_test(3, ezcp::array_generator(1, 200_000, 1_000_000_000, 1_000_000_000));
114
115 // add an edge case where all values and n are maximal
116 subtask2.add_test_str(ezcp::array_to_string(&vec![1_000_000_000; 200_000], true));
117
118 // No additional constraints
119 let mut subtask3 = ezcp::Subtask::new();
120
121 subtask3.set_checker(|mut input| {
122 let array = input.get_array()?;
123 input.expect_end()?;
124 let n = array.len();
125 if !(1..=200_000).contains(&n) {
126 ezcp::bail!("n should be in range [1, 200_000]");
127 }
128 for i in array {
129 if i % 2 != 0 {
130 ezcp::bail!("all array values should be even");
131 }
132 if !(0..=1_000_000_000).contains(&i) {
133 ezcp::bail!("all array values should be in range [0, 1_000_000_000]");
134 }
135 }
136 Ok(())
137 });
138
139 // add some random tests
140 subtask3.add_test(5, ezcp::array_generator_custom(1, 200_000, |rng| rng.random_range(0..=500_000_000) * 2));
141
142 // add 5 edge cases where n is maximal (other edge cases are handled by subtask2)
143 subtask3.add_test(5, ezcp::array_generator_custom(200_000, 200_000, |rng| rng.random_range(0..=500_000_000) * 2));
144
145 // add subtasks to task
146 let subtask1 = task.add_subtask(subtask1);
147 let subtask2 = task.add_subtask(subtask2);
148 let subtask3 = task.add_subtask(subtask3);
149
150 // add dependencies (dependencies are only if constraints of a dependency are a subset of constraints of a subtask)
151 task.add_subtask_dependency(subtask3, subtask1);
152 task.add_subtask_dependency(subtask3, subtask2);
153
154 // there is a partial solution that only reads 2 integers: n, x and prints x / 2 which is correct for subtask1 but should fail for subtask2 and subtask3
155 task.add_partial_solution(PARTIAL_SOLUTION.to_owned(), &[subtask1]);
156
157 // finally create the tests
158 task.create_tests().ok();
159}
Sourcepub fn add_subtask_dependency(&mut self, subtask: usize, dependency: usize)
pub fn add_subtask_dependency(&mut self, subtask: usize, dependency: usize)
This function adds a dependency between two subtasks. A dependency means, that the first subtask must be solved before the second subtask. In practice that means that all the tests from the dependency subtask will be added before the tests from the subtask. Dependencies apply recursively but do not duplicate tests. The subtask must be added to the task before this function is called.
Examples found in repository?
32fn main() {
33 // In this task you have n coins with values a1, a2, ..., an. You need to find the smallest sum, you cannot get using these coins.
34 // For example, if you have coins with values 1, 2 and 4, you can get any sum from 1 to 7, but you cannot get 8.
35
36 let mut task = ezcp::Task::new("Coins", &PathBuf::from("task2"));
37 task.solution_source = SOLUTION.to_owned();
38
39 // Constraint: n = 1
40 let mut subtask1 = ezcp::Subtask::new();
41
42 subtask1.set_checker(|mut input| {
43 let array = input.get_array()?;
44 input.expect_end()?;
45 let n = array.len();
46 if n != 1 {
47 ezcp::bail!("n should be 1");
48 }
49 let x = array[0];
50 if !(1..=1_000_000_000).contains(&x) {
51 ezcp::bail!("all array values should be in range [1, 1_000_000_000]");
52 }
53 Ok(())
54 });
55
56 subtask1.add_test(5, ezcp::array_generator(1, 1, 1, 1000));
57 subtask1.add_test_str("1\n 1\n".to_owned());
58
59 // Constraint: elements in the array are powers of 2 and n <= 30
60 let mut subtask2 = ezcp::Subtask::new();
61
62 subtask2.set_checker(|mut input| {
63 let array = input.get_array()?;
64 input.expect_end()?;
65 let n = array.len();
66 if !(1..=30).contains(&n) {
67 ezcp::bail!("n should be in range [1, 30]");
68 }
69 for (i, x) in array.iter().enumerate() {
70 if *x != 1 << i {
71 ezcp::bail!("all array values should be powers of 2");
72 }
73 }
74 Ok(())
75 });
76
77 subtask2.add_test(5, || {
78 let mut rng = rand::rng();
79 let n = rng.random_range(1..=30);
80 let mut array = Vec::new();
81 for i in 0..n {
82 array.push(1 << i);
83 }
84 ezcp::array_to_string(&array, true)
85 });
86
87 // Constraint: n <= 1000
88 let mut subtask3 = ezcp::Subtask::new();
89
90 subtask3.set_checker(|mut input| {
91 let array = input.get_array()?;
92 input.expect_end()?;
93 let n = array.len();
94 if !(1..=1000).contains(&n) {
95 ezcp::bail!("n should be in range [1, 1000]");
96 }
97 for x in array {
98 if !(1..=1_000_000_000).contains(&x) {
99 ezcp::bail!("all array values should be in range [1, 1_000_000_000]");
100 }
101 }
102 Ok(())
103 });
104
105 subtask3.add_test(5, ezcp::array_generator(1, 1000, 1, 1000));
106 subtask3.add_test(5, ezcp::array_generator(1, 1000, 1, 1_000_000_000));
107 subtask3.add_test(5, ezcp::array_generator(1, 1000, 1, 1));
108 subtask3.add_test(5, ezcp::array_generator(1000, 1000, 1, 1000));
109 subtask3.add_test(5, ezcp::array_generator(1000, 1000, 1, 1_000_000_000));
110 subtask3.add_test(1, ezcp::array_generator(1000, 1000, 1, 1));
111
112 // Constraint: n <= 200_000
113 let mut subtask4 = ezcp::Subtask::new();
114
115 subtask4.set_checker(|mut input| {
116 let array = input.get_array()?;
117 input.expect_end()?;
118 let n = array.len();
119 if !(1..=200_000).contains(&n) {
120 ezcp::bail!("n should be in range [1, 200_000]");
121 }
122 for x in array {
123 if !(1..=1_000_000_000).contains(&x) {
124 ezcp::bail!("all array values should be in range [1, 1_000_000_000]");
125 }
126 }
127 Ok(())
128 });
129
130 subtask4.add_test(5, ezcp::array_generator(1, 200_000, 1, 1000));
131 subtask4.add_test(5, ezcp::array_generator(1, 200_000, 1, 1_000_000_000));
132 subtask4.add_test(5, ezcp::array_generator(1, 200_000, 1, 1));
133 subtask4.add_test(5, ezcp::array_generator(200_000, 200_000, 1, 1000));
134 subtask4.add_test(5, ezcp::array_generator(200_000, 200_000, 1, 1_000_000_000));
135 subtask4.add_test(1, ezcp::array_generator(200_000, 200_000, 1, 1));
136
137 // add subtasks to task
138 let subtask1 = task.add_subtask(subtask1);
139 let subtask2 = task.add_subtask(subtask2);
140 let subtask3 = task.add_subtask(subtask3);
141 let subtask4 = task.add_subtask(subtask4);
142
143 // add dependencies
144 task.add_subtask_dependency(subtask3, subtask1);
145 task.add_subtask_dependency(subtask3, subtask2);
146 task.add_subtask_dependency(subtask4, subtask3);
147
148 task.create_tests().ok();
149}
More examples
36fn main() {
37 // The first task you get an array of integers. You need to find the sum of all elements in the array minus the half of the maximum element.
38 // Also all elements in the array are even.
39
40 let mut task = ezcp::Task::new("Coupon", &PathBuf::from("task1"));
41 //task.debug_level = LevelFilter::Trace;
42
43 task.solution_source = SOLUTION.to_owned();
44
45 // Constraint: n = 1
46 let mut subtask1 = ezcp::Subtask::new();
47
48 // This checker is optional and can be omitted.
49 subtask1.set_checker(|mut input| {
50 // read an array from input
51 let array = input.get_array()?;
52 // expect end of input
53 input.expect_end()?;
54 let n = array.len();
55 if n != 1 {
56 ezcp::bail!("n should be 1");
57 }
58 // check if the only value is even
59 if array[0] % 2 != 0 {
60 ezcp::bail!("all array values should be even");
61 }
62 // check if the only value is in range
63 if !(0..=1_000_000_000).contains(&array[0]) {
64 ezcp::bail!("all array values should be in range [0, 1_000_000_000]");
65 }
66 Ok(())
67 });
68
69 // add 5 tests where an array is generated with length 1 and even values between 0 and 1_000_000_000 (inclusive)
70 subtask1.add_test(5, ezcp::array_generator_custom(1, 1, |rng| rng.random_range(0..=500_000_000) * 2));
71 // this is a faulty test for testing the checker
72 //subtask1.add_test_str("1\n 0 0\n".to_owned());
73
74 // Constraint: all values are the same
75 let mut subtask2 = ezcp::Subtask::new();
76
77 subtask2.set_checker(|mut input| {
78 let array = input.get_array()?;
79 input.expect_end()?;
80 let n = array.len();
81 if !(1..=200_000).contains(&n) {
82 ezcp::bail!("n should be in range [1, 200_000]");
83 }
84 let x = array[0];
85 for i in array {
86 if i != x {
87 ezcp::bail!("all array values should be the same");
88 }
89 if i % 2 != 0 {
90 ezcp::bail!("all array values should be even");
91 }
92 if !(0..=1_000_000_000).contains(&i) {
93 ezcp::bail!("all array values should be in range [0, 1_000_000_000]");
94 }
95 }
96 Ok(())
97 });
98
99 // add 5 random tests where each test is an array of length between 1 and 200_000 (inclusive) and all values are the same even value between 0 and 1_000_000_000 (inclusive)
100 subtask2.add_test(5, || {
101 let mut rng = rand::rng();
102 let n = rng.random_range(1..=200_000);
103 let x = rng.random_range(0..=500_000_000) * 2;
104 ezcp::array_to_string(&vec![x; n as usize], true)
105 });
106
107 // add an edge case where n is maximal
108 let mut rng = rand::rng();
109 let x = rng.random_range(0..=500_000_000) * 2;
110 subtask2.add_test_str(ezcp::array_to_string(&vec![x; 200_000], true));
111
112 // add 3 edge cases where all values are maximal
113 subtask2.add_test(3, ezcp::array_generator(1, 200_000, 1_000_000_000, 1_000_000_000));
114
115 // add an edge case where all values and n are maximal
116 subtask2.add_test_str(ezcp::array_to_string(&vec![1_000_000_000; 200_000], true));
117
118 // No additional constraints
119 let mut subtask3 = ezcp::Subtask::new();
120
121 subtask3.set_checker(|mut input| {
122 let array = input.get_array()?;
123 input.expect_end()?;
124 let n = array.len();
125 if !(1..=200_000).contains(&n) {
126 ezcp::bail!("n should be in range [1, 200_000]");
127 }
128 for i in array {
129 if i % 2 != 0 {
130 ezcp::bail!("all array values should be even");
131 }
132 if !(0..=1_000_000_000).contains(&i) {
133 ezcp::bail!("all array values should be in range [0, 1_000_000_000]");
134 }
135 }
136 Ok(())
137 });
138
139 // add some random tests
140 subtask3.add_test(5, ezcp::array_generator_custom(1, 200_000, |rng| rng.random_range(0..=500_000_000) * 2));
141
142 // add 5 edge cases where n is maximal (other edge cases are handled by subtask2)
143 subtask3.add_test(5, ezcp::array_generator_custom(200_000, 200_000, |rng| rng.random_range(0..=500_000_000) * 2));
144
145 // add subtasks to task
146 let subtask1 = task.add_subtask(subtask1);
147 let subtask2 = task.add_subtask(subtask2);
148 let subtask3 = task.add_subtask(subtask3);
149
150 // add dependencies (dependencies are only if constraints of a dependency are a subset of constraints of a subtask)
151 task.add_subtask_dependency(subtask3, subtask1);
152 task.add_subtask_dependency(subtask3, subtask2);
153
154 // there is a partial solution that only reads 2 integers: n, x and prints x / 2 which is correct for subtask1 but should fail for subtask2 and subtask3
155 task.add_partial_solution(PARTIAL_SOLUTION.to_owned(), &[subtask1]);
156
157 // finally create the tests
158 task.create_tests().ok();
159}
Sourcepub fn add_partial_solution(
&mut self,
solution_source: String,
passes_subtasks: &[usize],
)
pub fn add_partial_solution( &mut self, solution_source: String, passes_subtasks: &[usize], )
This function adds a partial solution to the task. A partial solution is a solution that only solves a subset of subtasks. When the task is generated, the partial solution will be run on all tests of the subtasks it solves. If the partial solution does not solve the exact subtasks it should, an error will be thrown.
Examples found in repository?
36fn main() {
37 // The first task you get an array of integers. You need to find the sum of all elements in the array minus the half of the maximum element.
38 // Also all elements in the array are even.
39
40 let mut task = ezcp::Task::new("Coupon", &PathBuf::from("task1"));
41 //task.debug_level = LevelFilter::Trace;
42
43 task.solution_source = SOLUTION.to_owned();
44
45 // Constraint: n = 1
46 let mut subtask1 = ezcp::Subtask::new();
47
48 // This checker is optional and can be omitted.
49 subtask1.set_checker(|mut input| {
50 // read an array from input
51 let array = input.get_array()?;
52 // expect end of input
53 input.expect_end()?;
54 let n = array.len();
55 if n != 1 {
56 ezcp::bail!("n should be 1");
57 }
58 // check if the only value is even
59 if array[0] % 2 != 0 {
60 ezcp::bail!("all array values should be even");
61 }
62 // check if the only value is in range
63 if !(0..=1_000_000_000).contains(&array[0]) {
64 ezcp::bail!("all array values should be in range [0, 1_000_000_000]");
65 }
66 Ok(())
67 });
68
69 // add 5 tests where an array is generated with length 1 and even values between 0 and 1_000_000_000 (inclusive)
70 subtask1.add_test(5, ezcp::array_generator_custom(1, 1, |rng| rng.random_range(0..=500_000_000) * 2));
71 // this is a faulty test for testing the checker
72 //subtask1.add_test_str("1\n 0 0\n".to_owned());
73
74 // Constraint: all values are the same
75 let mut subtask2 = ezcp::Subtask::new();
76
77 subtask2.set_checker(|mut input| {
78 let array = input.get_array()?;
79 input.expect_end()?;
80 let n = array.len();
81 if !(1..=200_000).contains(&n) {
82 ezcp::bail!("n should be in range [1, 200_000]");
83 }
84 let x = array[0];
85 for i in array {
86 if i != x {
87 ezcp::bail!("all array values should be the same");
88 }
89 if i % 2 != 0 {
90 ezcp::bail!("all array values should be even");
91 }
92 if !(0..=1_000_000_000).contains(&i) {
93 ezcp::bail!("all array values should be in range [0, 1_000_000_000]");
94 }
95 }
96 Ok(())
97 });
98
99 // add 5 random tests where each test is an array of length between 1 and 200_000 (inclusive) and all values are the same even value between 0 and 1_000_000_000 (inclusive)
100 subtask2.add_test(5, || {
101 let mut rng = rand::rng();
102 let n = rng.random_range(1..=200_000);
103 let x = rng.random_range(0..=500_000_000) * 2;
104 ezcp::array_to_string(&vec![x; n as usize], true)
105 });
106
107 // add an edge case where n is maximal
108 let mut rng = rand::rng();
109 let x = rng.random_range(0..=500_000_000) * 2;
110 subtask2.add_test_str(ezcp::array_to_string(&vec![x; 200_000], true));
111
112 // add 3 edge cases where all values are maximal
113 subtask2.add_test(3, ezcp::array_generator(1, 200_000, 1_000_000_000, 1_000_000_000));
114
115 // add an edge case where all values and n are maximal
116 subtask2.add_test_str(ezcp::array_to_string(&vec![1_000_000_000; 200_000], true));
117
118 // No additional constraints
119 let mut subtask3 = ezcp::Subtask::new();
120
121 subtask3.set_checker(|mut input| {
122 let array = input.get_array()?;
123 input.expect_end()?;
124 let n = array.len();
125 if !(1..=200_000).contains(&n) {
126 ezcp::bail!("n should be in range [1, 200_000]");
127 }
128 for i in array {
129 if i % 2 != 0 {
130 ezcp::bail!("all array values should be even");
131 }
132 if !(0..=1_000_000_000).contains(&i) {
133 ezcp::bail!("all array values should be in range [0, 1_000_000_000]");
134 }
135 }
136 Ok(())
137 });
138
139 // add some random tests
140 subtask3.add_test(5, ezcp::array_generator_custom(1, 200_000, |rng| rng.random_range(0..=500_000_000) * 2));
141
142 // add 5 edge cases where n is maximal (other edge cases are handled by subtask2)
143 subtask3.add_test(5, ezcp::array_generator_custom(200_000, 200_000, |rng| rng.random_range(0..=500_000_000) * 2));
144
145 // add subtasks to task
146 let subtask1 = task.add_subtask(subtask1);
147 let subtask2 = task.add_subtask(subtask2);
148 let subtask3 = task.add_subtask(subtask3);
149
150 // add dependencies (dependencies are only if constraints of a dependency are a subset of constraints of a subtask)
151 task.add_subtask_dependency(subtask3, subtask1);
152 task.add_subtask_dependency(subtask3, subtask2);
153
154 // there is a partial solution that only reads 2 integers: n, x and prints x / 2 which is correct for subtask1 but should fail for subtask2 and subtask3
155 task.add_partial_solution(PARTIAL_SOLUTION.to_owned(), &[subtask1]);
156
157 // finally create the tests
158 task.create_tests().ok();
159}
Sourcepub fn create_tests(&mut self) -> Result<()>
pub fn create_tests(&mut self) -> Result<()>
This creates tests and prints the error message if there is an error.
Examples found in repository?
32fn main() {
33 // In this task you have n coins with values a1, a2, ..., an. You need to find the smallest sum, you cannot get using these coins.
34 // For example, if you have coins with values 1, 2 and 4, you can get any sum from 1 to 7, but you cannot get 8.
35
36 let mut task = ezcp::Task::new("Coins", &PathBuf::from("task2"));
37 task.solution_source = SOLUTION.to_owned();
38
39 // Constraint: n = 1
40 let mut subtask1 = ezcp::Subtask::new();
41
42 subtask1.set_checker(|mut input| {
43 let array = input.get_array()?;
44 input.expect_end()?;
45 let n = array.len();
46 if n != 1 {
47 ezcp::bail!("n should be 1");
48 }
49 let x = array[0];
50 if !(1..=1_000_000_000).contains(&x) {
51 ezcp::bail!("all array values should be in range [1, 1_000_000_000]");
52 }
53 Ok(())
54 });
55
56 subtask1.add_test(5, ezcp::array_generator(1, 1, 1, 1000));
57 subtask1.add_test_str("1\n 1\n".to_owned());
58
59 // Constraint: elements in the array are powers of 2 and n <= 30
60 let mut subtask2 = ezcp::Subtask::new();
61
62 subtask2.set_checker(|mut input| {
63 let array = input.get_array()?;
64 input.expect_end()?;
65 let n = array.len();
66 if !(1..=30).contains(&n) {
67 ezcp::bail!("n should be in range [1, 30]");
68 }
69 for (i, x) in array.iter().enumerate() {
70 if *x != 1 << i {
71 ezcp::bail!("all array values should be powers of 2");
72 }
73 }
74 Ok(())
75 });
76
77 subtask2.add_test(5, || {
78 let mut rng = rand::rng();
79 let n = rng.random_range(1..=30);
80 let mut array = Vec::new();
81 for i in 0..n {
82 array.push(1 << i);
83 }
84 ezcp::array_to_string(&array, true)
85 });
86
87 // Constraint: n <= 1000
88 let mut subtask3 = ezcp::Subtask::new();
89
90 subtask3.set_checker(|mut input| {
91 let array = input.get_array()?;
92 input.expect_end()?;
93 let n = array.len();
94 if !(1..=1000).contains(&n) {
95 ezcp::bail!("n should be in range [1, 1000]");
96 }
97 for x in array {
98 if !(1..=1_000_000_000).contains(&x) {
99 ezcp::bail!("all array values should be in range [1, 1_000_000_000]");
100 }
101 }
102 Ok(())
103 });
104
105 subtask3.add_test(5, ezcp::array_generator(1, 1000, 1, 1000));
106 subtask3.add_test(5, ezcp::array_generator(1, 1000, 1, 1_000_000_000));
107 subtask3.add_test(5, ezcp::array_generator(1, 1000, 1, 1));
108 subtask3.add_test(5, ezcp::array_generator(1000, 1000, 1, 1000));
109 subtask3.add_test(5, ezcp::array_generator(1000, 1000, 1, 1_000_000_000));
110 subtask3.add_test(1, ezcp::array_generator(1000, 1000, 1, 1));
111
112 // Constraint: n <= 200_000
113 let mut subtask4 = ezcp::Subtask::new();
114
115 subtask4.set_checker(|mut input| {
116 let array = input.get_array()?;
117 input.expect_end()?;
118 let n = array.len();
119 if !(1..=200_000).contains(&n) {
120 ezcp::bail!("n should be in range [1, 200_000]");
121 }
122 for x in array {
123 if !(1..=1_000_000_000).contains(&x) {
124 ezcp::bail!("all array values should be in range [1, 1_000_000_000]");
125 }
126 }
127 Ok(())
128 });
129
130 subtask4.add_test(5, ezcp::array_generator(1, 200_000, 1, 1000));
131 subtask4.add_test(5, ezcp::array_generator(1, 200_000, 1, 1_000_000_000));
132 subtask4.add_test(5, ezcp::array_generator(1, 200_000, 1, 1));
133 subtask4.add_test(5, ezcp::array_generator(200_000, 200_000, 1, 1000));
134 subtask4.add_test(5, ezcp::array_generator(200_000, 200_000, 1, 1_000_000_000));
135 subtask4.add_test(1, ezcp::array_generator(200_000, 200_000, 1, 1));
136
137 // add subtasks to task
138 let subtask1 = task.add_subtask(subtask1);
139 let subtask2 = task.add_subtask(subtask2);
140 let subtask3 = task.add_subtask(subtask3);
141 let subtask4 = task.add_subtask(subtask4);
142
143 // add dependencies
144 task.add_subtask_dependency(subtask3, subtask1);
145 task.add_subtask_dependency(subtask3, subtask2);
146 task.add_subtask_dependency(subtask4, subtask3);
147
148 task.create_tests().ok();
149}
More examples
36fn main() {
37 // The first task you get an array of integers. You need to find the sum of all elements in the array minus the half of the maximum element.
38 // Also all elements in the array are even.
39
40 let mut task = ezcp::Task::new("Coupon", &PathBuf::from("task1"));
41 //task.debug_level = LevelFilter::Trace;
42
43 task.solution_source = SOLUTION.to_owned();
44
45 // Constraint: n = 1
46 let mut subtask1 = ezcp::Subtask::new();
47
48 // This checker is optional and can be omitted.
49 subtask1.set_checker(|mut input| {
50 // read an array from input
51 let array = input.get_array()?;
52 // expect end of input
53 input.expect_end()?;
54 let n = array.len();
55 if n != 1 {
56 ezcp::bail!("n should be 1");
57 }
58 // check if the only value is even
59 if array[0] % 2 != 0 {
60 ezcp::bail!("all array values should be even");
61 }
62 // check if the only value is in range
63 if !(0..=1_000_000_000).contains(&array[0]) {
64 ezcp::bail!("all array values should be in range [0, 1_000_000_000]");
65 }
66 Ok(())
67 });
68
69 // add 5 tests where an array is generated with length 1 and even values between 0 and 1_000_000_000 (inclusive)
70 subtask1.add_test(5, ezcp::array_generator_custom(1, 1, |rng| rng.random_range(0..=500_000_000) * 2));
71 // this is a faulty test for testing the checker
72 //subtask1.add_test_str("1\n 0 0\n".to_owned());
73
74 // Constraint: all values are the same
75 let mut subtask2 = ezcp::Subtask::new();
76
77 subtask2.set_checker(|mut input| {
78 let array = input.get_array()?;
79 input.expect_end()?;
80 let n = array.len();
81 if !(1..=200_000).contains(&n) {
82 ezcp::bail!("n should be in range [1, 200_000]");
83 }
84 let x = array[0];
85 for i in array {
86 if i != x {
87 ezcp::bail!("all array values should be the same");
88 }
89 if i % 2 != 0 {
90 ezcp::bail!("all array values should be even");
91 }
92 if !(0..=1_000_000_000).contains(&i) {
93 ezcp::bail!("all array values should be in range [0, 1_000_000_000]");
94 }
95 }
96 Ok(())
97 });
98
99 // add 5 random tests where each test is an array of length between 1 and 200_000 (inclusive) and all values are the same even value between 0 and 1_000_000_000 (inclusive)
100 subtask2.add_test(5, || {
101 let mut rng = rand::rng();
102 let n = rng.random_range(1..=200_000);
103 let x = rng.random_range(0..=500_000_000) * 2;
104 ezcp::array_to_string(&vec![x; n as usize], true)
105 });
106
107 // add an edge case where n is maximal
108 let mut rng = rand::rng();
109 let x = rng.random_range(0..=500_000_000) * 2;
110 subtask2.add_test_str(ezcp::array_to_string(&vec![x; 200_000], true));
111
112 // add 3 edge cases where all values are maximal
113 subtask2.add_test(3, ezcp::array_generator(1, 200_000, 1_000_000_000, 1_000_000_000));
114
115 // add an edge case where all values and n are maximal
116 subtask2.add_test_str(ezcp::array_to_string(&vec![1_000_000_000; 200_000], true));
117
118 // No additional constraints
119 let mut subtask3 = ezcp::Subtask::new();
120
121 subtask3.set_checker(|mut input| {
122 let array = input.get_array()?;
123 input.expect_end()?;
124 let n = array.len();
125 if !(1..=200_000).contains(&n) {
126 ezcp::bail!("n should be in range [1, 200_000]");
127 }
128 for i in array {
129 if i % 2 != 0 {
130 ezcp::bail!("all array values should be even");
131 }
132 if !(0..=1_000_000_000).contains(&i) {
133 ezcp::bail!("all array values should be in range [0, 1_000_000_000]");
134 }
135 }
136 Ok(())
137 });
138
139 // add some random tests
140 subtask3.add_test(5, ezcp::array_generator_custom(1, 200_000, |rng| rng.random_range(0..=500_000_000) * 2));
141
142 // add 5 edge cases where n is maximal (other edge cases are handled by subtask2)
143 subtask3.add_test(5, ezcp::array_generator_custom(200_000, 200_000, |rng| rng.random_range(0..=500_000_000) * 2));
144
145 // add subtasks to task
146 let subtask1 = task.add_subtask(subtask1);
147 let subtask2 = task.add_subtask(subtask2);
148 let subtask3 = task.add_subtask(subtask3);
149
150 // add dependencies (dependencies are only if constraints of a dependency are a subset of constraints of a subtask)
151 task.add_subtask_dependency(subtask3, subtask1);
152 task.add_subtask_dependency(subtask3, subtask2);
153
154 // there is a partial solution that only reads 2 integers: n, x and prints x / 2 which is correct for subtask1 but should fail for subtask2 and subtask3
155 task.add_partial_solution(PARTIAL_SOLUTION.to_owned(), &[subtask1]);
156
157 // finally create the tests
158 task.create_tests().ok();
159}