├── 00-prewritten_algorithms ├── array2D.cpp ├── counting_sort.cpp ├── factorial.cpp ├── factorization.cpp ├── fibonacci.cpp ├── gcd.cpp ├── getLeader.cpp ├── log.cpp └── make_next_index_array.cpp ├── 03-TimeComplexity ├── FrogJmp.cpp ├── PermMissingElem.cpp └── TapeEquilibrium.cpp ├── 04-CountingElements ├── FrogRiverOne.cpp ├── MaxCounters.cpp ├── MissingInteger.cpp └── PermCheck.cpp ├── 05-PrefixSums ├── CountDiv.cpp ├── GenomicRangeQuery.cpp ├── MinAvgTwoSlice.cpp └── PassingCars.cpp ├── 06-Sorting ├── Distinct.cpp ├── MaxProductOfThree.cpp ├── NumberofDiscIntersections.cpp └── Triangle.cpp ├── 07-StacksAndQueues ├── Brackets.cpp ├── Fish.cpp ├── Nesting.cpp └── StoneWall.cpp ├── 08-Leader ├── Dominator.cpp └── EquiLeader.cpp ├── 09-MaximumSliceProblem ├── MaxDoubleSliceSum.cpp ├── MaxProfit.cpp └── MaxSliceSum.cpp ├── 10-PrimeAndCompositeNumbers ├── CountFactors.cpp ├── Flags.cpp └── MinPerimeterRectangle.cpp ├── 11-SieveOfEratosthenes ├── CountNonDivisible.cpp └── CountSemiprimes.cpp ├── 12-EuclideanAlgorithm ├── ChocolatesByNumbers.cpp └── CommonPrimeDivisors.cpp ├── 13-Fibonaccinumbers ├── FibFrog.cpp └── Ladder.cpp ├── 14-BinarySearchAlgorithm ├── MinMaxDivision.cpp └── NailingPlanks.cpp ├── 15-CaterpillarMethod ├── AbsDistinct.cpp ├── CountDistinctSlices.cpp ├── CountTriangles.cpp └── MinAbsSumOfTwo.cpp ├── 16-GreedyAlgorithms ├── MaxNonoverlappingSegments.cpp └── TieRopes.cpp ├── 17-DynamicProgramming ├── MinAbsSum.cpp └── NumberSolitaire.cpp ├── 90-TasksFromIndeedPrime-2015-Challenge ├── FloodDepth.cpp └── LongestPassword.cpp ├── 99-FutureTraining ├── StrSymmetryPoint.cpp └── TreeHeight.cpp ├── Docs ├── 1-Iterations.pdf ├── 10-PrimeNumbers.pdf ├── 11-Sieve.pdf ├── 12-Gcd.pdf ├── 13-Fibonacci.pdf ├── 14-BinarySearch.pdf ├── 15-CaterpillarMethod.pdf ├── 16-GreedyAlgorithms.pdf ├── 17-DynamicProgramming.pdf ├── 2-Arrays.pdf ├── 3-TimeComplexity.pdf ├── 4-CountingElements.pdf ├── 5-PrefixSums.pdf ├── 6-Sorting.pdf ├── 7-Stacks.pdf ├── 8-Leader.pdf ├── 9-MaxSlice.pdf └── solutions │ ├── solution-cannonballs.pdf │ ├── solution-clocks.pdf │ ├── solution-count-bounded-slices.pdf │ ├── solution-double-median.pdf │ ├── solution-flags.pdf │ ├── solution-min-abs-sum.pdf │ └── solution-prefix-set.pdf ├── README.md ├── TestUnitForCodility.h └── Todo.md /00-prewritten_algorithms/array2D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class Array2D { 4 | size_t _rows; 5 | size_t _columns; 6 | std::unique_ptr data; 7 | 8 | public: 9 | Array2D(size_t rows, size_t columns) 10 | : _rows{ rows }, 11 | _columns{ columns }, 12 | data{ std::make_unique(rows * columns) } {} 13 | 14 | size_t rows() const { return _rows; } 15 | 16 | size_t columns() const { return _columns; } 17 | 18 | int* operator[](size_t row) { return row * _columns + data.get(); } 19 | 20 | int& operator()(size_t row, size_t column) { 21 | return data[row * _columns + column]; 22 | } 23 | }; -------------------------------------------------------------------------------- /00-prewritten_algorithms/counting_sort.cpp: -------------------------------------------------------------------------------- 1 | void counting_sort(vector &A, int min, int max) { 2 | int offset = 0; 3 | if(min < 0) 4 | offset = -min; 5 | int size = max - min + 1; 6 | vector count(size, 0); 7 | for(int i : A) 8 | count[i + offset] +=1; 9 | 10 | int p = 0; 11 | for(size_t j = 0; j getFactorial(int n) { 2 | vector f(n+1, 0); 3 | f[0] = 1; 4 | for (int i = 1; i <= n; i++) 5 | f[i] = f[i - 1] * i; 6 | return f; 7 | } 8 | -------------------------------------------------------------------------------- /00-prewritten_algorithms/factorization.cpp: -------------------------------------------------------------------------------- 1 | vector getFactArr(int n) { 2 | vector f(n+1, 0); 3 | int i = 2; 4 | while (i * i <= n) { 5 | if (f[i] == 0) { 6 | int k = i * i; 7 | while (k <= n) { 8 | if (f[k] == 0) 9 | f[k] = i; 10 | k+=i; 11 | } 12 | } 13 | i++; 14 | } 15 | return f; 16 | } 17 | 18 | vector factorization(int x) { 19 | vector primeFactors; 20 | vector F = getFactArr(x); 21 | while (F[x] > 0) { 22 | primeFactors.push_back(F[x]); 23 | x /= F[x]; 24 | } 25 | primeFactors.push_back(x); 26 | 27 | return primeFactors; 28 | } 29 | -------------------------------------------------------------------------------- /00-prewritten_algorithms/fibonacci.cpp: -------------------------------------------------------------------------------- 1 | vector fibs={0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025}; 2 | 3 | // only for N <=46 4 | uint64_t getFibonacci(size_t N) { 5 | return static_cast((pow((1.0 + sqrt(5)) / 2.0, N) - pow((1.0 - sqrt(5)) / 2.0, N)) / sqrt(5)); 6 | } 7 | 8 | vector getFibonacciArray(size_t N) { 9 | vector fib(N + 2, 0); 10 | fib[1] = 1; 11 | for (size_t i = 2; i <= N + 1; i++) 12 | fib[i] = fib[i - 1] + fib[i - 2]; 13 | return fib; 14 | } 15 | 16 | vector getFibonacciArrayMax(int MaxNum) { 17 | if (MaxNum == 0) 18 | return vector(1, 0); 19 | vector fib(2, 0); 20 | fib[1] = 1; 21 | for (int i = 2; fib[fib.size()-1] + fib[fib.size() - 2] <= MaxNum; i++) 22 | fib.push_back(fib[i - 1] + fib[i - 2]); 23 | return fib; 24 | } -------------------------------------------------------------------------------- /00-prewritten_algorithms/gcd.cpp: -------------------------------------------------------------------------------- 1 | // call it with gcd(a, b, 1) to calculate gcd(a,b) 2 | 3 | int gcd(int a, int b, int res) { 4 | if (a == b) 5 | return res * a; 6 | else if ((a % 2 == 0) and (b % 2 == 0)) 7 | return gcd(a / 2, b / 2, 2 * res); 8 | else if (a % 2 == 0) 9 | return gcd(a / 2, b, res); 10 | else if (b % 2 == 0) 11 | return gcd(a, b / 2, res); 12 | else if (a > b) 13 | return gcd(a - b, b, res); 14 | else 15 | return gcd(a, b - a, res); 16 | } 17 | 18 | int gcd(int a, int b) { 19 | return gcd(a, b, 1); 20 | } 21 | 22 | int gcdByDivision(int A, int B) { 23 | if (A % B == 0) 24 | return B; 25 | else 26 | return gcdByDivision(B, A % B); 27 | } 28 | -------------------------------------------------------------------------------- /00-prewritten_algorithms/getLeader.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | // #define debug 3 | 4 | #ifdef debug 5 | #define LOG(X) cout << X << endl 6 | #else 7 | #define LOG(X) (void)0 8 | #endif 9 | 10 | pair getLeader(vector &A) { 11 | int candidate = -1; 12 | int size = 0; 13 | 14 | for(size_t i=0; i 0) 27 | { 28 | size_t count = 0; 29 | for(size_t i=0; i A.size() / 2) { 36 | LOG("candidate = " << candidate << " count = " << count); 37 | return make_pair(candidate, count); 38 | } 39 | } 40 | LOG("No candidate"); 41 | return make_pair(-1,0); 42 | } -------------------------------------------------------------------------------- /00-prewritten_algorithms/log.cpp: -------------------------------------------------------------------------------- 1 | #define debug 2 | 3 | #ifdef debug 4 | #define LOG(X) cout << X << endl 5 | #else 6 | #define LOG(X) (void)0 7 | #endif 8 | -------------------------------------------------------------------------------- /00-prewritten_algorithms/make_next_index_array.cpp: -------------------------------------------------------------------------------- 1 | vector getNext(vector& A) { 2 | int n = A.size(); 3 | vector next(n+1, 0); 4 | next[n] = -1; 5 | for (int i = n - 1; i >= 0; i--) 6 | if (A[i] > 0) 7 | next[i] = i; 8 | else 9 | next[i] = next[i + 1]; 10 | return next; 11 | } 12 | -------------------------------------------------------------------------------- /03-TimeComplexity/FrogJmp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int solution(int X, int Y, int D) { 4 | return ceil((Y - X) / (double)D); 5 | } 6 | 7 | int solution2(int X, int Y, int D) { 8 | return (Y - X + D - 1) / D; 9 | } -------------------------------------------------------------------------------- /03-TimeComplexity/PermMissingElem.cpp: -------------------------------------------------------------------------------- 1 | int solution(vector &A) { 2 | vector B(A.size()+1, 0); 3 | 4 | for(size_t i = 0; i < A.size(); i++) 5 | B[A[i]-1] = 1; 6 | 7 | for(size_t i=0; i < B.size(); i++) 8 | if(B[i] == 0) 9 | return i+1; 10 | 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /03-TimeComplexity/TapeEquilibrium.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int solution(vector &A) { 6 | int sum_r = std::accumulate(A.begin(), A.end(), 0); 7 | int min = INT_MAX; 8 | int sum_l = 0; 9 | for(size_t p=1; p &A) { 3 | vector B(X+1,0); 4 | for(size_t i=0; i solution(int N, vector &A) { 2 | 3 | vector c(N, 0); 4 | 5 | int max_c_val = 0; 6 | int max_current_c = 0; 7 | for(size_t i=0; i max_c_val) 12 | max_c_val = c[A[i]-1]; 13 | } 14 | else { 15 | max_current_c = max_c_val; 16 | } 17 | 18 | } 19 | 20 | for(int j=0; j &A) { 2 | 3 | vector c(1'000'000 + 1, false); 4 | for(int i : A) { 5 | if(i>0) 6 | c[i] = true; 7 | } 8 | for(int i=1; i<=1'000'000; i++) 9 | if(c[i] == false) 10 | return i; 11 | return 1; 12 | } 13 | -------------------------------------------------------------------------------- /04-CountingElements/PermCheck.cpp: -------------------------------------------------------------------------------- 1 | int solution(vector &A) { 2 | 3 | int N = A.size(); 4 | vector B(N+1, 0); 5 | 6 | for(int i=0; i MAX_INTERSECTIONS) { 39 | return -1; 40 | } 41 | active += start[i] - end[i]; 42 | } 43 | return intersections; 44 | } 45 | -------------------------------------------------------------------------------- /06-Sorting/Triangle.cpp: -------------------------------------------------------------------------------- 1 | // Reference: https://molchevskyi.medium.com/best-solutions-for-codility-lessons-lesson-6-sorting-770f931b65ad 2 | 3 | #include 4 | 5 | int solution(vector &v) { 6 | 7 | const int v_size = v.size(); 8 | if(v_size < 3) 9 | return 0; 10 | std::sort(v.begin(), v.end()); 11 | for (auto i = 2; i < v_size; ++i) { 12 | if (v[i - 2] > v[i] - v[i - 1]) { 13 | return 1; 14 | } 15 | } 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /07-StacksAndQueues/Brackets.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int solution(string &S) { 4 | if(S.empty()) 5 | return 1; 6 | 7 | if(S.size() % 2) 8 | return 0; 9 | 10 | stack st; 11 | for(char c : S) 12 | { 13 | switch(c) 14 | { 15 | case '}': 16 | if(st.empty() || st.top() != '{') 17 | return 0; 18 | st.pop(); 19 | break; 20 | case ']': 21 | if(st.empty() || st.top() != '[') 22 | return 0; 23 | st.pop(); 24 | break; 25 | case ')': 26 | if(st.empty() || st.top() != '(') 27 | return 0; 28 | st.pop(); 29 | break; 30 | default: 31 | st.push(c); 32 | } 33 | } 34 | return st.empty() ? 1 : 0; 35 | } 36 | -------------------------------------------------------------------------------- /07-StacksAndQueues/Fish.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int solution(vector &A, vector &B) { 4 | 5 | if(A.size() == 1) 6 | return 1; 7 | int alive = A.size(); 8 | 9 | stack F; 10 | 11 | for(size_t i = 0; i A[i]) 22 | alive--; 23 | } 24 | } 25 | 26 | return alive; 27 | } 28 | -------------------------------------------------------------------------------- /07-StacksAndQueues/Nesting.cpp: -------------------------------------------------------------------------------- 1 | int solution(string &S) { 2 | 3 | if(S.empty()) 4 | return 1; 5 | if(S.size() % 2) 6 | return 0; 7 | 8 | int open = 0; 9 | for(auto c : S) { 10 | if(c == '(') { 11 | open++; 12 | } else { 13 | if(open > 0) 14 | open--; 15 | else 16 | return 0; 17 | } 18 | } 19 | 20 | return open==0; 21 | } -------------------------------------------------------------------------------- /07-StacksAndQueues/StoneWall.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // #define debug 4 | 5 | #ifdef debug 6 | #define LOG(X) cout << X << endl 7 | #else 8 | #define LOG(X) (void)0 9 | #endif 10 | 11 | int solution(vector &H) { 12 | if(H.size() == 1) 13 | return 1; 14 | 15 | int count = 0; 16 | stack W; 17 | int current_h = 0; 18 | 19 | for(auto h : H) { 20 | if(W.empty()) { 21 | W.push(h); 22 | current_h = h; 23 | LOG(current_h); 24 | count++; 25 | } else if(current_h == h) { 26 | continue; 27 | } else if(current_h < h) { 28 | LOG(h - current_h); 29 | W.push(h - current_h); 30 | current_h = h; 31 | count++; 32 | } else { 33 | while(!W.empty() && current_h > h) { 34 | current_h -= W.top(); 35 | W.pop(); 36 | } 37 | if(!W.empty() && current_h < h) { 38 | LOG(h - current_h); 39 | W.push(h - current_h); 40 | current_h = h; 41 | count++; 42 | } 43 | if(W.empty()) { 44 | W.push(h); 45 | current_h = h; 46 | LOG(current_h); 47 | count++; 48 | } 49 | } 50 | } 51 | return count; 52 | } 53 | 54 | // ref: https://molchevskyi.medium.com/best-solutions-for-codility-lessons-lesson-7-stacks-and-queues-ef1415898cb 55 | int solution2(const vector &v) { 56 | std::stack stack; 57 | int stones = 0; 58 | for (auto height : v) { 59 | while (!stack.empty() && stack.top() > height) { 60 | stack.pop(); 61 | } 62 | if (!stack.empty() && stack.top() == height) { 63 | continue; 64 | } 65 | stones++; 66 | stack.push(height); 67 | } 68 | return stones; 69 | } 70 | -------------------------------------------------------------------------------- /08-Leader/Dominator.cpp: -------------------------------------------------------------------------------- 1 | // #define debug 2 | 3 | #ifdef debug 4 | #define LOG(X) cout << X << endl 5 | #else 6 | #define LOG(X) (void)0 7 | #endif 8 | 9 | int solution(vector &A) { 10 | // write your code in C++14 (g++ 6.2.0) 11 | int candidate = -1; 12 | int size = 0; 13 | 14 | for(auto a : A) { 15 | if(size == 0) { 16 | size++; 17 | candidate = a; 18 | } else { 19 | if(candidate == a) 20 | size++; 21 | else 22 | size--; 23 | } 24 | } 25 | LOG("Size = " << size); 26 | LOG("candidate = " << candidate); 27 | if(size > 0) 28 | { 29 | int index = -1; 30 | size_t count = 0; 31 | for(size_t i=0; i A.size() / 2) 40 | return index; 41 | } 42 | return -1; 43 | } 44 | -------------------------------------------------------------------------------- /08-Leader/EquiLeader.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | // #define debug 4 | 5 | #ifdef debug 6 | #define LOG(X) cout << X << endl 7 | #else 8 | #define LOG(X) (void)0 9 | #endif 10 | 11 | 12 | pair getLeader(vector &A) { 13 | int candidate = -1; 14 | int size = 0; 15 | 16 | for(size_t i=0; i 0) 29 | { 30 | size_t count = 0; 31 | for(size_t i=0; i A.size() / 2) { 38 | LOG("candidate = " << candidate << " count = " << count); 39 | return make_pair(candidate, count); 40 | } 41 | } 42 | LOG("No candidate"); 43 | return make_pair(-1,0); 44 | } 45 | 46 | 47 | int solution(vector &A) { 48 | if(A.size() == 1) 49 | return 0; 50 | 51 | int equi_count = 0; 52 | pair leader = getLeader(A); 53 | if(leader == make_pair(-1, 0)) 54 | return 0; 55 | 56 | size_t leader_count_left = 0; 57 | size_t leader_count_right = leader.second; 58 | 59 | for(size_t i=0; i 53 | void log_array(vector& A) { 54 | cout << "array = " << A << endl; 55 | } 56 | 57 | class Array2D { 58 | size_t _rows; 59 | size_t _columns; 60 | std::unique_ptr data; 61 | 62 | public: 63 | Array2D(size_t rows, size_t columns) 64 | : _rows{ rows }, 65 | _columns{ columns }, 66 | data{ std::make_unique(rows * columns) } {} 67 | 68 | size_t rows() const { return _rows; } 69 | 70 | size_t columns() const { return _columns; } 71 | 72 | int* operator[](size_t row) { return row * _columns + data.get(); } 73 | 74 | int& operator()(size_t row, size_t column) { 75 | return data[row * _columns + column]; 76 | } 77 | }; 78 | 79 | template 80 | class ArrayInfo { 81 | public: 82 | using AfterInit = std::function& init_vector)>; 83 | 84 | ArrayInfo() = default; 85 | 86 | ArrayInfo(const T minV, const T maxV, bool unique = false, const AfterInit afterInit = nullptr) { 87 | _minV = minV; 88 | _maxV = maxV; 89 | _unique = unique; 90 | _afterInit = afterInit; 91 | } 92 | 93 | vector Make(size_t size) { 94 | return Make(size, _minV, _maxV); 95 | } 96 | 97 | vector Make(size_t size, T minV, T maxV) 98 | { 99 | if (_unique && static_cast(_maxV - _minV + 1) < size) 100 | throw exception("Invalid range"); 101 | 102 | vector a(size); 103 | for (size_t i = 0; i < size; i++) { 104 | a[i] = static_cast(random(static_cast(_minV), static_cast(_maxV))); 105 | if (_unique) { 106 | for (size_t j = 0; j < i; j++) 107 | if (a[j] == a[i]) 108 | i--; 109 | } 110 | } 111 | if (_afterInit) 112 | _afterInit(a); 113 | return a; 114 | } 115 | 116 | T Max() { return _maxV; } 117 | T Min() { return _minV; } 118 | bool UniqueValues() { return _unique; } 119 | 120 | private: 121 | AfterInit _afterInit = nullptr; 122 | T _minV = T(); 123 | T _maxV = T(); 124 | bool _unique = false; 125 | }; 126 | 127 | template 128 | class VarInfo { 129 | public: 130 | using AfterInit = function; 131 | 132 | VarInfo(const T minV, const T maxV, const AfterInit afterInit = nullptr) { 133 | _minV = minV; 134 | _maxV = maxV; 135 | _afterInit = afterInit; 136 | } 137 | 138 | T Make() { 139 | return Make(_minV, _maxV); 140 | } 141 | 142 | T Make(T minV, T maxV) { 143 | T v = random(_minV, _maxV); 144 | if (_afterInit) 145 | _afterInit(v); 146 | return v; 147 | } 148 | 149 | T Max() { return _maxV; } 150 | T Min() { return _minV; } 151 | 152 | private: 153 | AfterInit _afterInit; 154 | T _minV; 155 | T _maxV; 156 | }; 157 | 158 | template 159 | class TestBase { 160 | public: 161 | bool virtual AutoTest(size_t test_count, size_t minN, size_t maxN) = 0; 162 | bool virtual IsEqual(RET& sln, RET& dummy) { return sln == dummy; } 163 | }; 164 | 165 | template 166 | class Test_1a : public TestBase { 167 | public: 168 | using Sln = function&)>; 169 | using BeforeRunningEachTest = function&, const ArrayInfo&)>; 170 | 171 | Test_1a(const Sln& dummy_sln, const Sln& sln, const ArrayInfo& arr_info) : 172 | _dummy_sln(dummy_sln), 173 | _sln(sln), 174 | _arr_info(arr_info) 175 | {} 176 | 177 | void SetBeforeRunningEachTestCallback(const BeforeRunningEachTest beforeRunningEachTest) { 178 | _beforeRunningEachTest = beforeRunningEachTest; 179 | } 180 | 181 | bool Test(vector a1) { 182 | RET rdum = _dummy_sln(a1); 183 | LOG("Dummy test passed."); 184 | RET rsln = _sln(a1); 185 | if (rsln != rdum) { 186 | LOG("Manual test failed: Dummy: " << rdum << " != " << rsln << " :solution"); 187 | log_array(a1); 188 | return false; 189 | } 190 | LOG("Manual test passed."); 191 | return true; 192 | } 193 | 194 | 195 | bool Test(vector a1, RET result) { 196 | RET rdum = _dummy_sln(a1); 197 | if (rdum != result) { 198 | LOG("Dummy test failed: Dummy: " << rdum << " != " << result << " :answer"); 199 | log_array(a1); 200 | return false; 201 | } 202 | else { 203 | LOG("Dummy test passed."); 204 | RET rsln = _sln(a1); 205 | if (rsln != rdum) { 206 | LOG("Manual test failed: Dummy: " << rdum << " != " << rsln << " :solution"); 207 | log_array(a1); 208 | return false; 209 | } 210 | LOG("Manual test passed."); 211 | return true; 212 | } 213 | } 214 | 215 | bool AutoTest(size_t test_count, size_t minN, size_t maxN) { 216 | #ifdef debug 217 | size_t test_number = 100000; 218 | const size_t test_groups = 3; 219 | // check low boundry 220 | for (size_t test = 0; test <= 5; test++) { 221 | vector a = _arr_info.Make(minN + test); 222 | if (!caller(a, test_number)) 223 | return false; 224 | test_number++; 225 | } 226 | 227 | test_number = 200000; 228 | for (size_t test = 1; test <= test_count / test_groups; test++) { 229 | size_t n = rand() % maxN + minN; 230 | vector a = _arr_info.Make(n); 231 | if (!caller(a, test_number)) 232 | return false; 233 | test_number++; 234 | } 235 | // All Max 236 | test_number = 300000; 237 | for (size_t test = 1; test <= test_count / test_groups; test++) { 238 | size_t n = rand() % maxN + minN; 239 | vector a = _arr_info.Make(n, _arr_info.Max()-n, _arr_info.Max()); 240 | if (!caller(a, test_number)) 241 | return false; 242 | test_number++; 243 | } 244 | 245 | // All Min 246 | test_number = 400000; 247 | for (size_t test = 1; test <= test_count / test_groups; test++) { 248 | size_t n = rand() % maxN + minN; 249 | vector a = _arr_info.Make(n, _arr_info.Min(), _arr_info.Min() + n); 250 | if (!caller(a, test_number)) 251 | return false; 252 | test_number++; 253 | } 254 | LOG("All Tests Passed :-)"); 255 | #endif 256 | return true; 257 | } 258 | private: 259 | bool caller(vector &a, size_t test_number) { 260 | if (_beforeRunningEachTest) 261 | _beforeRunningEachTest(a, _arr_info); 262 | 263 | RET ret_sln = _sln(a); 264 | RET ret_dummy = _dummy_sln(a); 265 | 266 | if (!this->IsEqual(ret_sln, ret_dummy)) { 267 | LOG("[x] Test(" << test_number << ") FAILED."); 268 | LOG("solution = (" << ret_sln << ") != (" << ret_dummy << ") dummy_solution"); 269 | LOG("failed on:"); 270 | log_array(a); 271 | return false; 272 | } 273 | else { 274 | LOG("[+] Test(" << test_number << ") Passed."); 275 | } 276 | return true; 277 | } 278 | 279 | ArrayInfo _arr_info; 280 | Sln _dummy_sln; 281 | Sln _sln; 282 | BeforeRunningEachTest _beforeRunningEachTest = NULL; 283 | }; 284 | 285 | 286 | template 287 | class Test_1v : public TestBase { 288 | public: 289 | using Sln = function; 290 | using BeforeRunningEachTest = function&)>; 291 | 292 | Test_1v(const Sln& dummy_sln, const Sln& sln, const VarInfo& var_info) : 293 | _dummy_sln(dummy_sln), 294 | _sln(sln), 295 | _var_info(var_info) 296 | {} 297 | 298 | void SetBeforeRunningEachTestCallback(const BeforeRunningEachTest beforeRunningEachTest) { 299 | _beforeRunningEachTest = beforeRunningEachTest; 300 | } 301 | 302 | bool Test(V1 v1) { 303 | RET rdum = _dummy_sln(v1); 304 | LOG("Dummy test passed."); 305 | RET rsln = _sln(v1); 306 | if (rsln != rdum) { 307 | LOG("Manual test failed: Dummy: " << rdum << " != " << rsln << " :solution"); 308 | return false; 309 | } 310 | LOG("Manual test passed."); 311 | return true; 312 | } 313 | 314 | bool Test(V1 v1, RET result) { 315 | RET rdum = _dummy_sln(v1); 316 | if (rdum != result) { 317 | LOG("Dummy test failed: Dummy: " << rdum << " != " << result << " :answer"); 318 | return false; 319 | } 320 | else { 321 | LOG("Dummy test passed."); 322 | RET rsln = _sln(v1); 323 | if (rsln != rdum) { 324 | LOG("Manual test failed: Dummy: " << rdum << " != " << rsln << " :solution"); 325 | return false; 326 | } 327 | LOG("Manual test passed."); 328 | return true; 329 | } 330 | } 331 | 332 | bool AutoTest(size_t test_count, size_t minN, size_t maxN) { 333 | #ifdef debug 334 | size_t test_number = 100000; 335 | const size_t test_groups = 3; 336 | // check low boundry 337 | for (size_t test = 0; test <= 5; test++) { 338 | V1 v1 = _var_info.Make(); 339 | if (!caller(v1, test_number)) 340 | return false; 341 | test_number++; 342 | } 343 | 344 | test_number = 200000; 345 | for (size_t test = 1; test <= test_count / test_groups; test++) { 346 | size_t n = rand() % maxN + minN; 347 | V1 v1 = _var_info.Make(); 348 | if (!caller(v1, test_number)) 349 | return false; 350 | test_number++; 351 | } 352 | // All Max 353 | test_number = 300000; 354 | for (size_t test = 1; test <= test_count / test_groups; test++) { 355 | size_t n = rand() % maxN + minN; 356 | V1 v1 = _var_info.Make(_var_info.Max() - n, _var_info.Max()); 357 | if (!caller(v1, test_number)) 358 | return false; 359 | test_number++; 360 | } 361 | 362 | // All Min 363 | test_number = 400000; 364 | for (size_t test = 1; test <= test_count / test_groups; test++) { 365 | size_t n = rand() % maxN + minN; 366 | V1 v1 = _var_info.Make(_var_info.Min(), _var_info.Min() + n); 367 | if (!caller(v1, test_number)) 368 | return false; 369 | test_number++; 370 | } 371 | LOG("All Tests Passed :-)"); 372 | #endif 373 | return true; 374 | } 375 | 376 | private: 377 | bool caller(V1& v1, size_t test_number) { 378 | if (_beforeRunningEachTest) 379 | _beforeRunningEachTest(v1, _var_info); 380 | 381 | RET ret_sln = _sln(v1); 382 | RET ret_dummy = _dummy_sln(v1); 383 | if (!this->IsEqual(ret_sln, ret_dummy)) { 384 | LOG("[x] Test(" << test_number << ") FAILED."); 385 | LOG("solution = (" << ret_sln << ") != (" << ret_dummy << ") dummy_solution"); 386 | LOG("failed on: " << v1); 387 | return false; 388 | } 389 | else { 390 | LOG("[+] Test(" << test_number << ") Passed."); 391 | } 392 | return true; 393 | } 394 | 395 | VarInfo _var_info; 396 | Sln _dummy_sln; 397 | Sln _sln; 398 | BeforeRunningEachTest _beforeRunningEachTest = nullptr; 399 | }; 400 | 401 | template 402 | class Test_2v : public TestBase { 403 | public: 404 | using Sln = function; 405 | using BeforeRunningEachTest = function&, V2&, const VarInfo&)>; 406 | 407 | Test_2v(const Sln& dummy_sln, const Sln& sln, const VarInfo& var_info1, const VarInfo& var_info2) : 408 | _dummy_sln(dummy_sln), 409 | _sln(sln), 410 | _var_info1(var_info1), 411 | _var_info2(var_info2) 412 | {} 413 | 414 | void SetBeforeRunningEachTestCallback(const BeforeRunningEachTest beforeRunningEachTest) { 415 | _beforeRunningEachTest = beforeRunningEachTest; 416 | } 417 | 418 | bool Test(V1 v1, V2 v2) { 419 | RET rdum = _dummy_sln(v1, v2); 420 | 421 | RET rsln = _sln(v1, v2); 422 | if (rsln != rdum) { 423 | LOG("Manual test failed: Dummy: " << rdum << " != " << rsln << " :solution"); 424 | return false; 425 | } 426 | LOG("Manual test passed."); 427 | return true; 428 | } 429 | 430 | bool Test(V1 v1, V2 v2, RET result) { 431 | RET rdum = _dummy_sln(v1, v2); 432 | if (rdum != result) { 433 | LOG("Dummy test failed: Dummy: " << rdum << " != " << result << " :answer"); 434 | return false; 435 | } 436 | else { 437 | LOG("Dummy test passed."); 438 | RET rsln = _sln(v1, v2); 439 | if (rsln != rdum) { 440 | LOG("Manual test failed: Dummy: " << rdum << " != " << rsln << " :solution"); 441 | return false; 442 | } 443 | LOG("Manual test passed."); 444 | return true; 445 | } 446 | } 447 | 448 | bool AutoTest(size_t test_count, size_t minN, size_t maxN) { 449 | #ifdef debug 450 | size_t test_number = 100000; 451 | const size_t test_groups = 3; 452 | // check low boundry 453 | for (size_t test = 0; test <= 5; test++) { 454 | V1 v1 = _var_info1.Make(); 455 | V2 v2 = _var_info2.Make(); 456 | if (!caller(v1, v2, test_number)) 457 | return false; 458 | test_number++; 459 | } 460 | 461 | test_number = 200000; 462 | for (size_t test = 1; test <= test_count / test_groups; test++) { 463 | size_t n = rand() % maxN + minN; 464 | V1 v1 = _var_info1.Make(); 465 | V2 v2 = _var_info2.Make(); 466 | if (!caller(v1, v2, test_number)) 467 | return false; 468 | test_number++; 469 | } 470 | // All Max 471 | test_number = 300000; 472 | for (size_t test = 1; test <= test_count / test_groups; test++) { 473 | size_t n = rand() % maxN + minN; 474 | V1 v1 = _var_info1.Make(_var_info1.Max() - n, _var_info1.Max()); 475 | V2 v2 = _var_info2.Make(_var_info2.Max() - n, _var_info2.Max()); 476 | if (!caller(v1, v2, test_number)) 477 | return false; 478 | test_number++; 479 | } 480 | 481 | // All Min 482 | test_number = 400000; 483 | for (size_t test = 1; test <= test_count / test_groups; test++) { 484 | size_t n = rand() % maxN + minN; 485 | V1 v1 = _var_info1.Make(_var_info1.Min(), _var_info1.Min() + n); 486 | V2 v2 = _var_info2.Make(_var_info2.Min(), _var_info2.Min() + n); 487 | if (!caller(v1, v2, test_number)) 488 | return false; 489 | test_number++; 490 | } 491 | LOG("All Tests Passed :-)"); 492 | #endif 493 | return true; 494 | } 495 | 496 | private: 497 | bool caller(V1& v1, V2& v2, size_t test_number) { 498 | if (_beforeRunningEachTest) 499 | _beforeRunningEachTest(v1, _var_info1, v2, _var_info2); 500 | 501 | RET ret_sln = _sln(v1, v2); 502 | RET ret_dummy = _dummy_sln(v1, v2); 503 | if (!this->IsEqual(ret_sln, ret_dummy)) { 504 | LOG("[x] Test(" << test_number << ") FAILED."); 505 | LOG("solution = (" << ret_sln << ") != (" << ret_dummy << ") dummy_solution"); 506 | LOG("failed on: " << v1); 507 | return false; 508 | } 509 | else { 510 | LOG("[+] Test(" << test_number << ") Passed."); 511 | } 512 | return true; 513 | } 514 | 515 | VarInfo _var_info1; 516 | VarInfo _var_info2; 517 | Sln _dummy_sln; 518 | Sln _sln; 519 | BeforeRunningEachTest _beforeRunningEachTest = nullptr; 520 | }; 521 | 522 | template 523 | class Test_1a_1v : public TestBase { 524 | public: 525 | using Sln = function&, V1&)> ; 526 | using BeforeRunningEachTest = function&, const ArrayInfo&, V1&, const VarInfo&)> ; 527 | 528 | Test_1a_1v(const Sln& dummy_sln, const Sln& sln, const ArrayInfo& arr_info, const VarInfo& var_info) : 529 | _dummy_sln(dummy_sln), 530 | _sln(sln), 531 | _arr_info(arr_info), 532 | _var_info(var_info) 533 | {} 534 | 535 | void SetBeforeRunningEachTestCallback(const BeforeRunningEachTest beforeRunningEachTest) { 536 | _beforeRunningEachTest = beforeRunningEachTest; 537 | } 538 | 539 | bool Test(vector a1, V1 v1) { 540 | RET rdum = _dummy_sln(a1, v1); 541 | LOG("Dummy test passed."); 542 | RET rsln = _sln(a1, v1); 543 | if (rsln != rdum) { 544 | LOG("Manual test failed: Dummy: " << rdum << " != " << rsln << " :solution"); 545 | log_array(a1); 546 | return false; 547 | } 548 | LOG("Manual test passed."); 549 | return true; 550 | } 551 | 552 | bool Test(vector a1, V1 v1, RET result) { 553 | RET rdum = _dummy_sln(a1, v1); 554 | if (rdum != result) { 555 | LOG("Dummy test failed: Dummy: " << rdum << " != " << result << " :answer"); 556 | log_array(a1); 557 | return false; 558 | } 559 | else { 560 | LOG("Dummy test passed."); 561 | RET rsln = _sln(a1, v1); 562 | if (rsln != rdum) { 563 | LOG("Manual test failed: Dummy: " << rdum << " != " << rsln << " :solution"); 564 | log_array(a1); 565 | return false; 566 | } 567 | LOG("Manual test passed."); 568 | return true; 569 | } 570 | } 571 | 572 | bool AutoTest(size_t test_count, size_t minN, size_t maxN) { 573 | #ifdef debug 574 | size_t test_number = 100000; 575 | const size_t test_groups = 3; 576 | // check low boundry 577 | for (size_t test = 0; test <= 5; test++) { 578 | vector a = _arr_info.Make(minN + test); 579 | V1 v1 = _var_info.Make(); 580 | if (!caller(a, v1, test_number)) 581 | return false; 582 | test_number++; 583 | } 584 | 585 | test_number = 200000; 586 | for (size_t test = 1; test <= test_count / test_groups; test++) { 587 | size_t n = rand() % maxN + minN; 588 | vector a = _arr_info.Make(n); 589 | V1 v1 = _var_info.Make(); 590 | if (!caller(a, v1, test_number)) 591 | return false; 592 | test_number++; 593 | } 594 | // All Max 595 | test_number = 300000; 596 | for (size_t test = 1; test <= test_count / test_groups; test++) { 597 | size_t n = rand() % maxN + minN; 598 | vector a = _arr_info.Make(n, _arr_info.Max() - n, _arr_info.Max()); 599 | V1 v1 = _var_info.Make(_var_info.Max() - n, _var_info.Max()); 600 | if (!caller(a, v1, test_number)) 601 | return false; 602 | test_number++; 603 | } 604 | 605 | // All Min 606 | test_number = 400000; 607 | for (size_t test = 1; test <= test_count / test_groups; test++) { 608 | size_t n = rand() % maxN + minN; 609 | vector a = _arr_info.Make(n, _arr_info.Min(), _arr_info.Min() + n); 610 | V1 v1 = _var_info.Make(_var_info.Min(), _var_info.Min() + n); 611 | if (!caller(a, v1, test_number)) 612 | return false; 613 | test_number++; 614 | } 615 | LOG("All Tests Passed :-)"); 616 | #endif 617 | return true; 618 | } 619 | 620 | private: 621 | bool caller(vector& a, V1& v1, size_t test_number) { 622 | if (_beforeRunningEachTest) 623 | _beforeRunningEachTest(a, _arr_info, v1, _var_info); 624 | 625 | RET ret_sln = _sln(a, v1); 626 | RET ret_dummy = _dummy_sln(a, v1); 627 | if ( !this->IsEqual(ret_sln, ret_dummy)) { 628 | LOG("[x] Test(" << test_number << ") FAILED."); 629 | LOG("solution = (" << ret_sln << ") != (" << ret_dummy << ") dummy_solution"); 630 | LOG("failed on: variable=" << v1 << " and the array:"); 631 | log_array(a); 632 | return false; 633 | } 634 | else { 635 | LOG("[+] Test(" << test_number << ") Passed."); 636 | } 637 | return true; 638 | } 639 | 640 | ArrayInfo _arr_info; 641 | VarInfo _var_info; 642 | Sln _dummy_sln; 643 | Sln _sln; 644 | BeforeRunningEachTest _beforeRunningEachTest = nullptr; 645 | }; 646 | 647 | template 648 | class Test_1a_2v : public TestBase { 649 | public: 650 | using Sln = function&, V1&, V2&)>; 651 | using BeforeRunningEachTest = function&, const ArrayInfo&, V1&, const VarInfo&, V2&, const VarInfo&)>; 652 | 653 | Test_1a_2v(const Sln& dummy_sln, const Sln& sln, const ArrayInfo& arr_info, const VarInfo& var_info1, const VarInfo& var_info2) : 654 | _dummy_sln(dummy_sln), 655 | _sln(sln), 656 | _arr_info(arr_info), 657 | _var_info1(var_info1), 658 | _var_info2(var_info2) 659 | {} 660 | 661 | void SetBeforeRunningEachTestCallback(const BeforeRunningEachTest beforeRunningEachTest) { 662 | _beforeRunningEachTest = beforeRunningEachTest; 663 | } 664 | 665 | bool Test(vector a1, V1 v1, V2 v2) { 666 | RET rdum = _dummy_sln(a1, v1, v2); 667 | LOG("Dummy test passed."); 668 | RET rsln = _sln(a1, v1, v2); 669 | if (rsln != rdum) { 670 | LOG("Manual test failed: Dummy: " << rdum << " != " << rsln << " :solution"); 671 | log_array(a1); 672 | return false; 673 | } 674 | LOG("Manual test passed."); 675 | return true; 676 | 677 | } 678 | 679 | bool Test(vector a1, V1 v1, V2 v2, RET result) { 680 | RET rdum = _dummy_sln(a1, v1, v2); 681 | if (rdum != result) { 682 | LOG("Dummy test failed: Dummy: " << rdum << " != " << result << " :answer"); 683 | log_array(a1); 684 | return false; 685 | } 686 | else { 687 | LOG("Dummy test passed."); 688 | RET rsln = _sln(a1, v1, v2); 689 | if (rsln != rdum) { 690 | LOG("Manual test failed: Dummy: " << rdum << " != " << rsln << " :solution"); 691 | log_array(a1); 692 | return false; 693 | } 694 | LOG("Manual test passed."); 695 | return true; 696 | } 697 | } 698 | 699 | bool AutoTest(size_t test_count, size_t minN, size_t maxN) { 700 | #ifdef debug 701 | size_t test_number = 100000; 702 | const size_t test_groups = 3; 703 | // check low boundry 704 | for (size_t test = 0; test <= 5; test++) { 705 | vector a = _arr_info.Make(minN + test); 706 | V1 v1 = _var_info1.Make(); 707 | V2 v2 = _var_info2.Make(); 708 | if (!caller(a, v1, v2, test_number)) 709 | return false; 710 | test_number++; 711 | } 712 | 713 | test_number = 200000; 714 | for (size_t test = 1; test <= test_count / test_groups; test++) { 715 | size_t n = rand() % maxN + minN; 716 | vector a = _arr_info.Make(n); 717 | V1 v1 = _var_info1.Make(); 718 | V2 v2 = _var_info2.Make(); 719 | if (!caller(a, v1, v2, test_number)) 720 | return false; 721 | test_number++; 722 | } 723 | // All Max 724 | test_number = 300000; 725 | for (size_t test = 1; test <= test_count / test_groups; test++) { 726 | size_t n = rand() % maxN + minN; 727 | vector a = _arr_info.Make(n, _arr_info.Max() - n, _arr_info.Max()); 728 | V1 v1 = _var_info1.Make(_var_info1.Max() - n, _var_info1.Max()); 729 | V2 v2 = _var_info2.Make(_var_info2.Max() - n, _var_info2.Max()); 730 | if (!caller(a, v1, v2, test_number)) 731 | return false; 732 | test_number++; 733 | } 734 | 735 | // All Min 736 | test_number = 400000; 737 | for (size_t test = 1; test <= test_count / test_groups; test++) { 738 | size_t n = rand() % maxN + minN; 739 | vector a = _arr_info.Make(n, _arr_info.Min(), _arr_info.Min() + n); 740 | V1 v1 = _var_info1.Make(_var_info1.Min(), _var_info1.Min() + n); 741 | V2 v2 = _var_info2.Make(_var_info2.Min(), _var_info2.Min() + n); 742 | if (!caller(a, v1, v2, test_number)) 743 | return false; 744 | test_number++; 745 | } 746 | LOG("All Tests Passed :-)"); 747 | #endif 748 | return true; 749 | } 750 | 751 | private: 752 | bool caller(vector& a, V1& v1, V2& v2, size_t test_number) { 753 | if (_beforeRunningEachTest) 754 | _beforeRunningEachTest(a, _arr_info, v1, _var_info1, v2, _var_info2); 755 | 756 | RET ret_sln = _sln(a, v1, v2); 757 | RET ret_dummy = _dummy_sln(a, v1, v2); 758 | if (!this->IsEqual(ret_sln, ret_dummy)) { 759 | LOG("[x] Test(" << test_number << ") FAILED."); 760 | LOG("solution = (" << ret_sln << ") != (" << ret_dummy << ") dummy_solution"); 761 | LOG("failed on: variable=" << v1 << ", " << v2 << ", and the array:"); 762 | log_array(a); 763 | return false; 764 | } 765 | else { 766 | LOG("[+] Test(" << test_number << ") Passed."); 767 | } 768 | return true; 769 | } 770 | 771 | ArrayInfo _arr_info; 772 | VarInfo _var_info1; 773 | VarInfo _var_info2; 774 | Sln _dummy_sln; 775 | Sln _sln; 776 | BeforeRunningEachTest _beforeRunningEachTest = nullptr; 777 | }; 778 | 779 | template 780 | class Test_2a : public TestBase { 781 | public: 782 | using Sln = function&, vector&)>; 783 | using BeforeRunningEachTest = function&, const ArrayInfo&, vector&, const ArrayInfo&)>; 784 | 785 | Test_2a(const Sln& dummy_sln, const Sln& sln, const ArrayInfo& arr_info1, const ArrayInfo& arr_info2) : 786 | _dummy_sln(dummy_sln), 787 | _sln(sln), 788 | _arr_info1(arr_info1), 789 | _arr_info2(arr_info2) 790 | {} 791 | 792 | void SetBeforeRunningEachTestCallback(const BeforeRunningEachTest beforeRunningEachTest) { 793 | _beforeRunningEachTest = beforeRunningEachTest; 794 | } 795 | 796 | bool Test(vector a1, vector a2) { 797 | RET rdum = _dummy_sln(a1, a2); 798 | LOG("Dummy test passed."); 799 | RET rsln = _sln(a1, a2); 800 | if (rsln != rdum) { 801 | LOG("Manual test failed: Dummy: " << rdum << " != " << rsln << " :solution"); 802 | log_array(a1); 803 | log_array(a2); 804 | return false; 805 | } 806 | LOG("Manual test passed."); 807 | return true; 808 | } 809 | 810 | bool Test(vector a1, vector a2, const RET result) { 811 | RET rdum = _dummy_sln(a1, a2); 812 | if (rdum != result) { 813 | LOG("Dummy test failed: Dummy: " << rdum << " != " << result << " :answer"); 814 | log_array(a1); 815 | log_array(a2); 816 | return false; 817 | } 818 | else { 819 | LOG("Dummy test passed."); 820 | RET rsln = _sln(a1, a2); 821 | if (rsln != rdum) { 822 | LOG("Manual test failed: Dummy: " << rdum << " != " << rsln << " :solution"); 823 | log_array(a1); 824 | log_array(a2); 825 | return false; 826 | } 827 | LOG("Manual test passed."); 828 | return true; 829 | } 830 | } 831 | 832 | bool AutoTest(size_t test_count, size_t minN, size_t maxN) { 833 | #ifdef debug 834 | size_t test_number = 100000; 835 | const size_t test_groups = 3; 836 | // check low boundry 837 | for (size_t test = 0; test <= 5; test++) { 838 | vector a1 = _arr_info1.Make(minN + test); 839 | vector a2 = _arr_info2.Make(minN + test); 840 | if (!caller(a1, a2, test_number)) 841 | return false; 842 | test_number++; 843 | } 844 | 845 | test_number = 200000; 846 | for (size_t test = 1; test <= test_count / test_groups; test++) { 847 | size_t n = rand() % maxN + minN; 848 | vector a1 = _arr_info1.Make(n); 849 | vector a2 = _arr_info2.Make(n); 850 | if (!caller(a1, a2, test_number)) 851 | return false; 852 | test_number++; 853 | } 854 | // All Max 855 | test_number = 300000; 856 | for (size_t test = 1; test <= test_count / test_groups; test++) { 857 | size_t n = rand() % maxN + minN; 858 | vector a1 = _arr_info1.Make(n, _arr_info1.Max() - n, _arr_info1.Max()); 859 | vector a2 = _arr_info2.Make(n, _arr_info2.Max() - n, _arr_info2.Max()); 860 | if (!caller(a1, a2, test_number)) 861 | return false; 862 | test_number++; 863 | } 864 | 865 | // All Min 866 | test_number = 400000; 867 | for (size_t test = 1; test <= test_count / test_groups; test++) { 868 | size_t n = rand() % maxN + minN; 869 | vector a1 = _arr_info1.Make(n, _arr_info1.Min(), _arr_info1.Min() + n); 870 | vector a2 = _arr_info2.Make(n, _arr_info2.Min(), _arr_info2.Min() + n); 871 | if (!caller(a1, a2, test_number)) 872 | return false; 873 | test_number++; 874 | } 875 | LOG("All Tests Passed :-)"); 876 | #endif 877 | return true; 878 | } 879 | 880 | private: 881 | bool caller(vector& a1, vector& a2, size_t test_number) { 882 | if (_beforeRunningEachTest) 883 | _beforeRunningEachTest(a1, _arr_info1, a2, _arr_info2); 884 | 885 | RET ret_sln = _sln(a1, a2); 886 | RET ret_dummy = _dummy_sln(a1, a2); 887 | if (!this->IsEqual(ret_sln, ret_dummy)) { 888 | LOG("[x] Test(" << test_number << ") FAILED."); 889 | LOG("solution = (" << ret_sln << ") != (" << ret_dummy << ") dummy_solution"); 890 | log_array(a1); 891 | log_array(a2); 892 | return false; 893 | } 894 | else { 895 | LOG("[+] Test(" << test_number << ") Passed."); 896 | } 897 | return true; 898 | } 899 | 900 | ArrayInfo _arr_info1; 901 | ArrayInfo _arr_info2; 902 | Sln _dummy_sln; 903 | Sln _sln; 904 | BeforeRunningEachTest _beforeRunningEachTest = nullptr; 905 | }; 906 | 907 | template 908 | class Test_2a_1v : public TestBase { 909 | public: 910 | using Sln = function&, vector&, V1&)>; 911 | using BeforeRunningEachTest = function&, const ArrayInfo&, vector&, const ArrayInfo&, V1&, const VarInfo&)>; 912 | 913 | Test_2a_1v(const Sln& dummy_sln, const Sln& sln, const ArrayInfo& arr_info1, const ArrayInfo& arr_info2, const VarInfo& var_info) : 914 | _dummy_sln(dummy_sln), 915 | _sln(sln), 916 | _arr_info1(arr_info1), 917 | _arr_info2(arr_info2), 918 | _var_info(var_info) 919 | {} 920 | 921 | void SetBeforeRunningEachTestCallback(const BeforeRunningEachTest beforeRunningEachTest) { 922 | _beforeRunningEachTest = beforeRunningEachTest; 923 | } 924 | 925 | bool Test(vector a1, vector a2, V1 v1) { 926 | RET rdum = _dummy_sln(a1, a2, v1); 927 | LOG("Dummy test passed."); 928 | RET rsln = _sln(a1, a2, v1); 929 | if (rsln != rdum) { 930 | LOG("Manual test failed: Dummy: " << rdum << " != " << rsln << " :solution"); 931 | log_array(a1); 932 | log_array(a2); 933 | return false; 934 | } 935 | LOG("Manual test passed."); 936 | return true; 937 | } 938 | 939 | 940 | bool Test(vector a1, vector a2, V1 v1, RET result) { 941 | RET rdum = _dummy_sln(a1, a2, v1); 942 | if (rdum != result) { 943 | LOG("Dummy test failed: Dummy: " << rdum << " != " << result << " :answer"); 944 | log_array(a1); 945 | log_array(a2); 946 | return false; 947 | } 948 | else { 949 | LOG("Dummy test passed."); 950 | RET rsln = _sln(a1, a2, v1); 951 | if (rsln != rdum) { 952 | LOG("Manual test failed: Dummy: " << rdum << " != " << rsln << " :solution"); 953 | log_array(a1); 954 | log_array(a2); 955 | return false; 956 | } 957 | LOG("Manual test passed."); 958 | return true; 959 | } 960 | } 961 | 962 | bool AutoTest(size_t test_count, size_t minN, size_t maxN) { 963 | #ifdef debug 964 | size_t test_number = 100000; 965 | const size_t test_groups = 3; 966 | // check low boundry 967 | for (size_t test = 0; test <= 5; test++) { 968 | vector a1 = _arr_info1.Make(minN + test); 969 | vector a2 = _arr_info2.Make(minN + test); 970 | V1 v1 = _var_info.Make(); 971 | if (!caller(a1, a2, v1, test_number)) 972 | return false; 973 | test_number++; 974 | } 975 | 976 | test_number = 200000; 977 | for (size_t test = 1; test <= test_count / test_groups; test++) { 978 | size_t n = rand() % maxN + minN; 979 | vector a1 = _arr_info1.Make(n); 980 | vector a2 = _arr_info2.Make(n); 981 | V1 v1 = _var_info.Make(); 982 | if (!caller(a1, a2, v1, test_number)) 983 | return false; 984 | test_number++; 985 | } 986 | // All Max 987 | test_number = 300000; 988 | for (size_t test = 1; test <= test_count / test_groups; test++) { 989 | size_t n = rand() % maxN + minN; 990 | vector a1 = _arr_info1.Make(n, _arr_info1.Max() - n, _arr_info1.Max()); 991 | vector a2 = _arr_info2.Make(n, _arr_info2.Max() - n, _arr_info2.Max()); 992 | V1 v1 = _var_info.Make(_var_info.Max() - n, _var_info.Max()); 993 | if (!caller(a1, a2, v1, test_number)) 994 | return false; 995 | test_number++; 996 | } 997 | 998 | // All Min 999 | test_number = 400000; 1000 | for (size_t test = 1; test <= test_count / test_groups; test++) { 1001 | size_t n = rand() % maxN + minN; 1002 | vector a1 = _arr_info1.Make(n, _arr_info1.Min(), _arr_info1.Min() + n); 1003 | vector a2 = _arr_info2.Make(n, _arr_info2.Min(), _arr_info2.Min() + n); 1004 | V1 v1 = _var_info.Make(_var_info.Min(), _var_info.Min() + n); 1005 | if (!caller(a1, a2, v1, test_number)) 1006 | return false; 1007 | test_number++; 1008 | } 1009 | LOG("All Tests Passed :-)"); 1010 | #endif 1011 | return true; 1012 | } 1013 | 1014 | private: 1015 | bool caller(vector& a1, vector& a2, V1& v1, size_t test_number) { 1016 | if (_beforeRunningEachTest) 1017 | _beforeRunningEachTest(a1, _arr_info1, a2, _arr_info2, v1, _var_info); 1018 | 1019 | RET ret_sln = _sln(a1, a2, v1); 1020 | RET ret_dummy = _dummy_sln(a1, a2, v1); 1021 | if (!this->IsEqual(ret_sln, ret_dummy)) { 1022 | LOG("[x] Test(" << test_number << ") FAILED."); 1023 | LOG("solution = (" << ret_sln << ") != (" << ret_dummy << ") dummy_solution"); 1024 | LOG("failed on: variable=" << v1 << " and the array:"); 1025 | log_array(a1); 1026 | log_array(a2); 1027 | return false; 1028 | } 1029 | else { 1030 | LOG("[+] Test(" << test_number << ") Passed."); 1031 | } 1032 | return true; 1033 | } 1034 | 1035 | ArrayInfo _arr_info1; 1036 | ArrayInfo _arr_info2; 1037 | VarInfo _var_info; 1038 | Sln _dummy_sln; 1039 | Sln _sln; 1040 | BeforeRunningEachTest _beforeRunningEachTest = nullptr; 1041 | }; 1042 | 1043 | template 1044 | class Test_3a : public TestBase { 1045 | public: 1046 | using Sln = function&, vector&, vector&)>; 1047 | using BeforeRunningEachTest = function&, const ArrayInfo&, vector&, const ArrayInfo&, vector&, const ArrayInfo&)>; 1048 | 1049 | Test_3a(const Sln& dummy_sln, const Sln& sln, const ArrayInfo& arr_info1, const ArrayInfo& arr_info2, const ArrayInfo& arr_info3) : 1050 | _dummy_sln(dummy_sln), 1051 | _sln(sln), 1052 | _arr_info1(arr_info1), 1053 | _arr_info2(arr_info2), 1054 | _arr_info3(arr_info3) 1055 | {} 1056 | 1057 | void SetBeforeRunningEachTestCallback(const BeforeRunningEachTest beforeRunningEachTest) { 1058 | _beforeRunningEachTest = beforeRunningEachTest; 1059 | } 1060 | 1061 | bool Test(vector a1, vector a2, vector a3) { 1062 | RET rdum = _dummy_sln(a1, a2, a3); 1063 | LOG("Dummy test passed."); 1064 | RET rsln = _sln(a1, a2, a3); 1065 | if (rsln != rdum) { 1066 | LOG("Manual test failed: Dummy: " << rdum << " != " << rsln << " :solution"); 1067 | log_array(a1); 1068 | log_array(a2); 1069 | log_array(a3); 1070 | return false; 1071 | } 1072 | LOG("Manual test passed."); 1073 | return true; 1074 | } 1075 | 1076 | bool Test(vector a1, vector a2, vector a3, const RET result) { 1077 | RET rdum = _dummy_sln(a1, a2, a3); 1078 | if (rdum != result) { 1079 | LOG("Dummy test failed: Dummy: " << rdum << " != " << result << " :answer"); 1080 | log_array(a1); 1081 | log_array(a2); 1082 | log_array(a3); 1083 | return false; 1084 | } 1085 | else { 1086 | LOG("Dummy test passed."); 1087 | RET rsln = _sln(a1, a2, a3); 1088 | if (rsln != rdum) { 1089 | LOG("Manual test failed: Dummy: " << rdum << " != " << rsln << " :solution"); 1090 | log_array(a1); 1091 | log_array(a2); 1092 | log_array(a3); 1093 | return false; 1094 | } 1095 | LOG("Manual test passed."); 1096 | return true; 1097 | } 1098 | } 1099 | 1100 | bool AutoTest(size_t test_count, size_t minN, size_t maxN) { 1101 | #ifdef debug 1102 | size_t test_number = 100000; 1103 | const size_t test_groups = 3; 1104 | // check low boundry 1105 | for (size_t test = 0; test <= 5; test++) { 1106 | vector a1 = _arr_info1.Make(minN + test); 1107 | vector a2 = _arr_info2.Make(minN + test); 1108 | vector a3 = _arr_info3.Make(minN + test); 1109 | if (!caller(a1, a2, a3, test_number)) 1110 | return false; 1111 | test_number++; 1112 | } 1113 | 1114 | test_number = 200000; 1115 | for (size_t test = 1; test <= test_count / test_groups; test++) { 1116 | size_t n = rand() % maxN + minN; 1117 | vector a1 = _arr_info1.Make(n); 1118 | vector a2 = _arr_info2.Make(n); 1119 | vector a3 = _arr_info3.Make(minN + test); 1120 | if (!caller(a1, a2, a3, test_number)) 1121 | return false; 1122 | test_number++; 1123 | } 1124 | // All Max 1125 | test_number = 300000; 1126 | for (size_t test = 1; test <= test_count / test_groups; test++) { 1127 | size_t n = rand() % maxN + minN; 1128 | vector a1 = _arr_info1.Make(n, _arr_info1.Max() - n, _arr_info1.Max()); 1129 | vector a2 = _arr_info2.Make(n, _arr_info2.Max() - n, _arr_info2.Max()); 1130 | vector a3 = _arr_info3.Make(n, _arr_info3.Max() - n, _arr_info3.Max()); 1131 | if (!caller(a1, a2, a3, test_number)) 1132 | return false; 1133 | test_number++; 1134 | } 1135 | 1136 | // All Min 1137 | test_number = 400000; 1138 | for (size_t test = 1; test <= test_count / test_groups; test++) { 1139 | size_t n = rand() % maxN + minN; 1140 | vector a1 = _arr_info1.Make(n, _arr_info1.Min(), _arr_info1.Min() + n); 1141 | vector a2 = _arr_info2.Make(n, _arr_info2.Min(), _arr_info2.Min() + n); 1142 | vector a3 = _arr_info3.Make(n, _arr_info3.Min(), _arr_info3.Min() + n); 1143 | if (!caller(a1, a2, a3, test_number)) 1144 | return false; 1145 | test_number++; 1146 | } 1147 | LOG("All Tests Passed :-)"); 1148 | #endif 1149 | return true; 1150 | } 1151 | 1152 | private: 1153 | bool caller(vector& a1, vector& a2, vector& a3, size_t test_number) { 1154 | if (_beforeRunningEachTest) 1155 | _beforeRunningEachTest(a1, _arr_info1, a2, _arr_info2, a3, _arr_info3); 1156 | 1157 | RET ret_sln = _sln(a1, a2, a3); 1158 | RET ret_dummy = _dummy_sln(a1, a2, a3); 1159 | if (!this->IsEqual(ret_sln, ret_dummy)) { 1160 | LOG("[x] Test(" << test_number << ") FAILED."); 1161 | LOG("solution = (" << ret_sln << ") != (" << ret_dummy << ") dummy_solution"); 1162 | log_array(a1); 1163 | log_array(a2); 1164 | log_array(a3); 1165 | return false; 1166 | } 1167 | else { 1168 | LOG("[+] Test(" << test_number << ") Passed."); 1169 | } 1170 | return true; 1171 | } 1172 | 1173 | ArrayInfo _arr_info1; 1174 | ArrayInfo _arr_info2; 1175 | ArrayInfo _arr_info3; 1176 | Sln _dummy_sln; 1177 | Sln _sln; 1178 | BeforeRunningEachTest _beforeRunningEachTest = nullptr; 1179 | }; -------------------------------------------------------------------------------- /Todo.md: -------------------------------------------------------------------------------- 1 | [ ] NumberOfDiscIntersections 2 | [ ] 10/Peaks 3 | 4 | --------------------------------------------------------------------------------