array_generator

Function array_generator 

Source
pub fn array_generator(
    min_n: i32,
    max_n: i32,
    min_x: i32,
    max_x: i32,
) -> impl Fn() -> String
Expand description

This function returns a function that generates an array of integers.

The array will have a length between min_n and max_n (inclusive). The values in the array will be between min_x and max_x (inclusive).

Examples found in repository?
examples/example2.rs (line 56)
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
Hide additional examples
examples/example1.rs (line 113)
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}