├── .gitignore
├── .idea
├── Algorithmic Toolbox.iml
├── misc.xml
├── modules.xml
├── vcs.xml
└── workspace.xml
├── README.md
└── algorithmic_toolbox
├── week_1
└── maximum_pairwise_product
│ ├── max_pairwise_product.cpp
│ ├── max_pairwise_product.java
│ └── max_pairwise_product.py
├── week_2
├── 01_introduction_problems.pdf
└── 01_introduction_starter_files
│ ├── fibonacci
│ ├── Fibonacci.java
│ ├── fibonacci.cpp
│ └── fibonacci.py
│ ├── fibonacci_huge
│ ├── FibonacciHuge.java
│ ├── fibonacci_huge.cpp
│ └── fibonacci_huge.py
│ ├── fibonacci_last_digit
│ ├── FibonacciLastDigit.java
│ ├── fibonacci_last_digit.cpp
│ └── fibonacci_last_digit.py
│ ├── fibonacci_partial_sum
│ ├── FibonacciPartialSum.java
│ ├── fibonacci_partial_sum.cpp
│ └── fibonacci_partial_sum.py
│ ├── fibonacci_sum_last_digit
│ ├── FibonacciSumLastDigit.java
│ ├── fibonacci_sum_last_digit.cpp
│ └── fibonacci_sum_last_digit.py
│ ├── gcd
│ ├── GCD.java
│ ├── gcd.cpp
│ └── gcd.py
│ └── lcm
│ ├── LCM.java
│ ├── lcm.cpp
│ └── lcm.py
├── week_3
├── 02_greedy_algorithms_problems.pdf
└── 02_greedy_algorithms_starter_files
│ ├── change
│ ├── Change.java
│ ├── change.cpp
│ └── change.py
│ ├── covering_segments
│ ├── CoveringSegments.java
│ ├── covering_segments.cpp
│ └── covering_segments.py
│ ├── different_summands
│ ├── DifferentSummands.java
│ ├── different_summands.cpp
│ └── different_summands.py
│ ├── dot_product
│ ├── DotProduct.java
│ ├── dot_product.cpp
│ └── dot_product.py
│ ├── fractional_knapsack
│ ├── FractionalKnapsack.java
│ ├── fractional_knapsack.cpp
│ └── fractional_knapsack.py
│ └── largest_number
│ ├── LargestNumber.java
│ ├── by_learners
│ └── largest_number.rb
│ ├── largest_number.cpp
│ ├── largest_number.hs
│ └── largest_number.py
├── week_4
├── 03_divide_and_conquer_problems.pdf
└── 03_divide_and_conquer_starter_files_20160804
│ ├── binary_search
│ ├── BinarySearch.java
│ ├── binary_search.cpp
│ └── binary_search.py
│ ├── closest
│ ├── Closest.java
│ ├── closest.cpp
│ └── closest.py
│ ├── inversions
│ ├── Inversions.java
│ ├── inversions.cpp
│ └── inversions.py
│ ├── majority_element
│ ├── MajorityElement.java
│ ├── majority_element.cpp
│ └── majority_element.py
│ ├── points_and_segments
│ ├── PointsAndSegments.java
│ ├── points_and_segments.cpp
│ └── points_and_segments.py
│ └── sorting
│ ├── Sorting.java
│ ├── sorting.cpp
│ └── sorting.py
└── week_5
├── 04_dynamic_programming_problems.pdf
└── 04_dynamic_programming_starter_files
├── edit_distance
├── EditDistance.java
├── edit_distance.cpp
└── edit_distance.py
├── knapsack
├── Knapsack.java
├── knapsack.cpp
└── knapsack.py
├── lcs3
├── LCS3.java
├── lcs3.cpp
└── lcs3.py
├── placing_parentheses
├── PlacingParentheses.java
├── placing_parentheses.cpp
└── placing_parentheses.py
└── primitive_calculator
├── PrimitiveCalculator.java
├── primitive_calculator.cpp
├── primitive_calculator.py
├── primitive_calculator2.cpp
└── primitive_calculator3.cpp
/.gitignore:
--------------------------------------------------------------------------------
1 | /.buildpath
2 | /build/
3 | */archive/
4 |
5 | __MACOSX
6 | .DS_Store
7 |
8 | .project
9 | .settings
10 | .classpath
11 | .sass-cache/
12 | .hs
13 |
14 | # OS generated files #
15 | ######################
16 | */.DS_Store
17 | .DS_Store
18 | .DS_Store?
19 | ._*
20 | .Spotlight-V100
21 | .Trashes
22 | Icon?
23 | ehthumbs.db
24 | Thumbs.db
25 |
26 | # Packages #
27 | ############
28 | # it's better to unpack these files and commit the raw source
29 | # git has its own built in compression methods
30 | *.7z
31 | *.dmg
32 | *.gz
33 | *.iso
34 | *.jar
35 | *.rar
36 | *.tar
37 | *.zip
--------------------------------------------------------------------------------
/.idea/Algorithmic Toolbox.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 | 1484392836471
143 |
144 |
145 | 1484392836471
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Data Structures and Algorithms
2 |
3 | This repository will contain my work from the [Master Algorithmic Programming Techniques Specialization](https://www.coursera.org/specializations/data-structures-algorithms) that was created by UC San Diego and delivered through Coursera. I will be implementing solutions in Python3, Java, and C++.
4 |
5 | ## About This Specialization
6 |
7 | The Specialization covers algorithmic techniques for solving problems arising in computer science applications. It is a mix of theory and practice: you will not only design algorithms and estimate their complexity, but you will get a deeper understanding of algorithms by implementing them in the programming language of your choice (C, C++, C#, Haskell, Java, JavaScript, Python2, Python3, Ruby, and Scala).
8 |
9 | This Specialization is unique, because it offers two real-world projects. Advanced Shortest Paths project is offered in the end of the Algorithms on Graphs course. In this project, you'll deal with road network analysis and social network analysis. You'll learn how to compute the fastest route between New York and Mountain View thousands of times faster than classic algorithms and close to those used in Google Maps. Through Genome Assembly culminating project at the end of the Specialization, you'll learn how to assemble genomes from millions of short pieces and how algorithms fuel recent developments in personalized medicine.
10 |
11 | # Algorithmic Toolbox
12 | Assignments for Algorithmic Toolbox on Coursera with time and memory results from grader
13 |
14 | ## Week 1
15 | ### Solving a Simple Code Problem
16 | Problem: [Maximum Pairwise Product](https://github.com/mablatnik/Data-Structures-And-Algorithms/tree/master/algorithmic_toolbox/week_1/maximum_pairwise_product)
17 |
18 | * Python: Max time used: 0.14/5.00, max memory used: 26456064/536870912
19 | * Java: Max time used: 0.07/1.00, max memory used: 21037056/536870912
20 | * C++: Max time used: 0.12/1.00, max memory used: 21045248/536870912
21 |
22 | ## Week 2
23 | ### Prgramming Assignment: [Introduction](https://github.com/mablatnik/Data-Structures-And-Algorithms/blob/master/algorithmic_toolbox/week_2/01_introduction_problems.pdf)
24 | Problem: [Small Fibonacci Number](https://github.com/mablatnik/Data-Structures-And-Algorithms/tree/master/algorithmic_toolbox/week_2/01_introduction_starter_files/fibonacci)
25 |
26 | * Python: Max time used: 0.02/5.00, max memory used: 8740864/536870912
27 | * Java: Max time used: 0.21/1.50, max memory used: 24145920/536870912
28 | * C++: Max time used: 0.00/1.00, max memory used: 8744960/536870912
29 |
30 | Problem: [The Last Digit of a Large Fibonacci Number](https://github.com/mablatnik/Data-Structures-And-Algorithms/tree/master/algorithmic_toolbox/week_2/01_introduction_starter_files/fibonacci_last_digit)
31 |
32 | * Python: Max time used: 0.17/5.00, max memory used: 8699904/536870912
33 | * Java: Max time used: 0.19/1.50, max memory used: 28651520/536870912
34 | * C++: Max time used: 0.00/1.00, max memory used: 8699904/536870912
35 |
36 | Problem: [Greatest Common Divisor](https://github.com/mablatnik/Data-Structures-And-Algorithms/tree/master/algorithmic_toolbox/week_2/01_introduction_starter_files/gcd)
37 |
38 | * Python: Max time used: 0.05/5.00, max memory used: 9568256/536870912
39 | * Java: Max time used: 0.21/1.50, max memory used: 24121344/536870912
40 | * C++: Max time used: 0.00/1.00, max memory used: 9560064/536870912
41 |
42 | Problem: [Least Common Multiple](https://github.com/mablatnik/Data-Structures-And-Algorithms/tree/master/algorithmic_toolbox/week_2/01_introduction_starter_files/lcm)
43 |
44 | * Python: Max time used: 0.09/5.00, max memory used: 9601024/536870912
45 | * Java: Max time used: 0.17/1.50, max memory used: 24133632/536870912
46 | * C++: Max time used: 0.00/1.00, max memory used: 9580544/536870912
47 |
48 | Advanced Problem: [Huge Fibonacci Number modulo m](https://github.com/mablatnik/Data-Structures-And-Algorithms/tree/master/algorithmic_toolbox/week_2/01_introduction_starter_files/fibonacci_huge)
49 |
50 | * Python: Max time used: 0.21/5.00, max memory used: 30359552/536870912
51 | * Java: Max time used: 0.17/1.50, max memory used: 30363648/536870912
52 | * C++: Max time used: 0.00/1.00, max memory used: 30363648/536870912
53 |
54 | Advanced Problem: [Last Digit of a Sum of Fibonacci Numbers](https://github.com/mablatnik/Data-Structures-And-Algorithms/tree/master/algorithmic_toolbox/week_2/01_introduction_starter_files/fibonacci_sum_last_digit)
55 |
56 | * Python: Max time used: 0.06/5.00, max memory used: 9564160/536870912
57 | * Java: Max time used: 0.21/1.50, max memory used: 24285184/536870912
58 | * C++: Max time used: 0.00/1.00, max memory used: 8720384/536870912
59 |
60 | Advanced Problem: [Last Digit of a Partial Sum of Fibonacci Numbers](https://github.com/mablatnik/Data-Structures-And-Algorithms/tree/master/algorithmic_toolbox/week_2/01_introduction_starter_files/fibonacci_partial_sum)
61 |
62 | * Python: Max time used: 0.05/5.00, max memory used: 8720384/536870912
63 |
64 | ## Week 3
65 | ### Programming Assignment: [Greedy Algorithms](https://github.com/mablatnik/Data-Structures-And-Algorithms/blob/master/algorithmic_toolbox/week_3/02_greedy_algorithms_problems.pdf)
66 | Problem: [Changing Money](https://github.com/mablatnik/Data-Structures-And-Algorithms/tree/master/algorithmic_toolbox/week_3/02_greedy_algorithms_starter_files/change)
67 |
68 | * Python: Max time used: 0.05/5.00, max memory used: 8716288/536870912
69 | * Java: Max time used: 0.17/1.50, max memory used: 24166400/536870912
70 | * C++: Max time used: 0.00/1.00, max memory used: 8716288/536870912
71 |
72 | Problem: [Fractional Knapsack](https://github.com/mablatnik/Data-Structures-And-Algorithms/tree/master/algorithmic_toolbox/week_3/02_greedy_algorithms_starter_files/fractional_knapsack)
73 |
74 | * Python: Max time used: 0.05/5.00, max memory used: 8761344/671088640
75 | * Java: Max time used: 0.36/1.50, max memory used: 33243136/671088640
76 | * C++: Max time used: 0.00/1.00, max memory used: 8769536/671088640
77 |
78 | Problem: [Minimum Dot Product](https://github.com/mablatnik/Data-Structures-And-Algorithms/tree/master/algorithmic_toolbox/week_3/02_greedy_algorithms_starter_files/dot_product)
79 |
80 | * Python: Max time used: 0.02/5.00, max memory used: 8945664/536870912
81 | * Java: Max time used: 0.31/1.50, max memory used: 32632832/536870912
82 | * C++: Max time used: 0.00/1.00, max memory used: 8957952/536870912
83 |
84 | Problem: [Covering Segments by Points](https://github.com/mablatnik/Data-Structures-And-Algorithms/tree/master/algorithmic_toolbox/week_3/02_greedy_algorithms_starter_files/covering_segments)
85 |
86 | * Python: Max time used: 0.03/5.00, max memory used: 9023488/536870912
87 | * Java: Max time used: 0.20/1.50, max memory used: 24457216/536870912
88 | * C++: Max time used: 0.00/1.00, max memory used: 9019392/536870912
89 |
90 | Problem: [Pairwise Distinct Summands](https://github.com/mablatnik/Data-Structures-And-Algorithms/tree/master/algorithmic_toolbox/week_3/02_greedy_algorithms_starter_files/different_summands)
91 |
92 | * Python: Max time used: 0.07/5.00, max memory used: 9617408/536870912
93 | * Java: Max time used: 0.69/1.50, max memory used: 47325184/536870912
94 | * C++: Max time used: 0.00/1.00, max memory used: 9613312/536870912
95 |
96 | ## Week 4
97 | ### Programming Assignment: [Divide and Conquer](https://github.com/mablatnik/Data-Structures-And-Algorithms/blob/master/algorithmic_toolbox/week_4/03_divide_and_conquer_problems.pdf)
98 | Problem: [Binary Search](https://github.com/mablatnik/Data-Structures-And-Algorithms/tree/master/algorithmic_toolbox/week_4/03_divide_and_conquer_starter_files_20160804/binary_search)
99 |
100 | * Python: Max time used: 0.82/10.00, max memory used: 37974016/536870912
101 | * Java: Max time used: 1.13/3.00, max memory used: 74174464/536870912
102 | * C++: Max time used: 0.10/2.00, max memory used: 37974016/536870912
103 |
104 | Problem: [Majority Element](https://github.com/mablatnik/Data-Structures-And-Algorithms/tree/master/algorithmic_toolbox/week_4/03_divide_and_conquer_starter_files_20160804/majority_element)
105 |
106 | * Python: Max time used: 0.66/5.00, max memory used: 21393408/536870912
107 | * Java: Max time used: 0.36/1.50, max memory used: 42090496/536870912
108 | * C++: Max time used: 0.05/1.00, max memory used: 21393408/536870912
109 |
110 | Problem: [3-Way Partition](https://github.com/mablatnik/Data-Structures-And-Algorithms/tree/master/algorithmic_toolbox/week_4/03_divide_and_conquer_starter_files_20160804/sorting)
111 |
112 | * Python: Max time used: 1.02/11.00, max memory used: 28880896/536870912
113 | * Java: Max time used: 1.16/5.50, max memory used: 70074368/536870912
114 | * C++: Max time used: 0.08/2.20, max memory used: 29736960/536870912
115 |
116 | Advanced Problem: [Number of Inversions](https://github.com/mablatnik/Data-Structures-And-Algorithms/tree/master/algorithmic_toolbox/week_4/03_divide_and_conquer_starter_files_20160804/inversions)
117 |
118 | * Python: Max time used: 0.77/15.00, max memory used: 21364736/536870912
119 | * Java: Max time used: 0.87/4.50, max memory used: 112693248/536870912
120 | * C++: Max time used: 0.05/3.00, max memory used: 21360640/536870912
121 |
122 | Advanced Problem: [Points and Segments](https://github.com/mablatnik/Data-Structures-And-Algorithms/tree/master/algorithmic_toolbox/week_4/03_divide_and_conquer_starter_files_20160804/points_and_segments)
123 |
124 | * Python: Max time used: 0.41/20.00, max memory used: 44896256/536870912
125 |
126 | ## Week 5
127 | ### Programming Assignment: [Dynamic Programming](https://github.com/mablatnik/Data-Structures-And-Algorithms/blob/master/algorithmic_toolbox/week_5/04_dynamic_programming_problems.pdf)
128 | Problem: [Primitive Calculator](https://github.com/mablatnik/Data-Structures-And-Algorithms/tree/master/algorithmic_toolbox/week_5/04_dynamic_programming_starter_files/primitive_calculator)
129 |
130 | * Python: Max time used: 1.08/7.50, max memory used: 13688832/536870912
131 | * Java: Max time used: 0.19/2.25, max memory used: 32600064/536870912
132 | * C++: Max time used: 0.01/1.50, max memory used: 9396224/536870912
133 |
134 | Problem: [Take as Much Gold as Possible](https://github.com/mablatnik/Data-Structures-And-Algorithms/tree/master/algorithmic_toolbox/week_5/04_dynamic_programming_starter_files/knapsack)
135 |
136 | * Python: Max time used: 0.61/10.00, max memory used: 20611072/536870912
137 | * Java:
138 | * C++:
139 |
140 | Problem: [Compute the Edit Distance Between Two Strings](https://github.com/mablatnik/Data-Structures-And-Algorithms/tree/master/algorithmic_toolbox/week_5/04_dynamic_programming_starter_files/edit_distance)
141 |
142 | * Python:
143 | * Java:
144 | * C++:
145 |
146 | Problem: [Maximize the Value of an Arithmetic Expression]()
147 |
148 | * Python:
149 | * Java:
150 | * C++:
151 |
152 | Advanced Problem: [Longest Common Subsequence of Three Sequences]()
153 |
154 | * Python:
155 | * Java:
156 | * C++:
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_1/maximum_pairwise_product/max_pairwise_product.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | using std::vector;
6 | using std::cin;
7 | using std::cout;
8 |
9 | long long MaxPairwiseProduct(const vector &numbers) {
10 | long long result = 0;
11 | int n = numbers.size();
12 | for (int i = 0; i < n; ++i) {
13 | for (int j = i + 1; j < n; ++j) {
14 | if (((long long) (numbers[i])) * numbers[j] > result) {
15 | result = ((long long) (numbers[i])) * numbers[j];
16 | }
17 | }
18 | }
19 | return result;
20 | }
21 |
22 | long long MaxPairwiseProductFast(const vector &numbers) {
23 | int n = numbers.size();
24 |
25 | int max_index1 = -1;
26 | for (int i = 0; i < n; ++i)
27 | if ((max_index1 == -1) || (numbers[i] > numbers[max_index1]))
28 | max_index1 = i;
29 |
30 | int max_index2 = -1;
31 | for (int j = 0; j < n; ++j)
32 | if ((j != max_index1) && ((max_index2 == -1) || (numbers[j] > numbers[max_index2])))
33 | max_index2 = j;
34 |
35 | //cout << max_index1 << ' ' << max_index2 << "\n";
36 |
37 | return ((long long) (numbers[max_index1])) * numbers[max_index2];
38 | }
39 |
40 | int main() {
41 | // while (true) {
42 | // int n = rand() % 1000 + 2;
43 | // cout << n << "\n";
44 | // vector a;
45 | // for (int i = 0; i < n; ++i) {
46 | // a.push_back(rand() % 100000);
47 | // }
48 | // for (int i = 0; i < n; ++i) {
49 | // cout << a[i] << ' ';
50 | // }
51 | // cout << "\n";
52 | // long long res1 = MaxPairwiseProduct(a);
53 | // long long res2 = MaxPairwiseProductFast(a);
54 | // if (res1 != res2) {
55 | // cout << "Wrong answer: " << res1 << ' ' << res2 << "\n";
56 | // break;
57 | // }
58 | // else {
59 | // cout << "OK\n";
60 | // }
61 | // }
62 | int n;
63 | cin >> n;
64 | vector numbers(n);
65 | for (int i = 0; i < n; ++i) {
66 | cin >> numbers[i];
67 | }
68 |
69 | long long result = MaxPairwiseProductFast(numbers);
70 | cout << result << "\n";
71 | return 0;
72 | }
73 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_1/maximum_pairwise_product/max_pairwise_product.java:
--------------------------------------------------------------------------------
1 |
2 | import java.util.*;
3 | import java.io.*;
4 |
5 | public class MaxPairwiseProduct {
6 |
7 | // slower methon O(n^2)
8 | static long getMaxPairwiseProduct(int[] numbers) {
9 | long result = 0;
10 | int n = numbers.length;
11 | for (int i = 0; i < n; ++i) {
12 | for (int j = i + 1; j < n; ++j) {
13 | if ((long)numbers[i] * numbers[j] > result) {
14 | result = (long)numbers[i] * numbers[j];
15 | }
16 | }
17 | }
18 | return result;
19 | }
20 |
21 | // faster method
22 | static long getMaxPairwiseProductFast(int[] numbers) {
23 | int nSize = numbers.length;
24 |
25 | int max_index1 = -1;
26 | for (int i = 0; i < nSize; i++) {
27 | if ((max_index1 == -1) || (numbers[i] > numbers[max_index1]))
28 | max_index1 = i;
29 | }
30 |
31 | int max_index2 = -1;
32 | for (int j = 0; j < nSize; j++) {
33 | if ((j != max_index1) && ((max_index2 == -1) || (numbers[j] > numbers[max_index2])))
34 | max_index2 = j;
35 | }
36 |
37 | return (long)numbers[max_index1] * numbers[max_index2];
38 | }
39 |
40 | // main method
41 | public static void main(String[] args) {
42 |
43 | FastScanner scanner = new FastScanner(System.in);
44 | int n = scanner.nextInt();
45 | int[] numbers = new int[n];
46 | for (int i = 0; i < n; i++) {
47 | numbers[i] = scanner.nextInt();
48 | }
49 |
50 | System.out.println(getMaxPairwiseProductFast(numbers));
51 |
52 |
53 | /*
54 | // stress test
55 | while (true) {
56 |
57 | Random ran = new Random();
58 | int max = 5;
59 | int min = 2;
60 | int randomNum = ran.nextInt((max - min) + 1) + min;
61 |
62 | System.out.println("Random number: " + randomNum);
63 |
64 | int[] list = new int[randomNum];
65 |
66 | for (int i = 0; i < randomNum; i++) {
67 | list[i] = ran.nextInt((10) + 1);
68 | System.out.println(list[i]);
69 | }
70 | System.out.println("");
71 |
72 | double result1 = getMaxPairwiseProduct(list);
73 | double result2 = getMaxPairwiseProductFast(list);
74 |
75 | if (result1 != result2) {
76 | System.out.println("Error! slow: " + result1 + " fast: " + result2);
77 | break;
78 | } else {
79 | System.out.println("OK");
80 | }
81 | }
82 | */
83 | }
84 | // scanning code
85 | static class FastScanner {
86 | BufferedReader br;
87 | StringTokenizer st;
88 |
89 | FastScanner(InputStream stream) {
90 | try {
91 | br = new BufferedReader(new InputStreamReader(stream));
92 | } catch (Exception e) {
93 | e.printStackTrace();
94 | }
95 | }
96 |
97 | String next() {
98 | while (st == null || !st.hasMoreTokens()) {
99 | try {
100 | st = new StringTokenizer(br.readLine());
101 | } catch (IOException e) {
102 | e.printStackTrace();
103 | }
104 | }
105 | return st.nextToken();
106 | }
107 |
108 | int nextInt() {
109 | return Integer.parseInt(next());
110 | }
111 | }
112 |
113 | }
114 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_1/maximum_pairwise_product/max_pairwise_product.py:
--------------------------------------------------------------------------------
1 | # Uses python3
2 | result = 0
3 |
4 |
5 | def max_pairwise_product(n, a):
6 | for i in range(0, n):
7 | for j in range(i + 1, n):
8 | if a[i] * a[j] > result:
9 | result = a[i] * a[j]
10 | return result
11 |
12 |
13 | def max_pairwise_product_fast(n, numbers):
14 | max_index1 = -1
15 | for i in range(n):
16 | if max_index1 == -1 or numbers[i] > numbers[max_index1]:
17 | max_index1 = i
18 |
19 | max_index2 = -1
20 | for i in range(n):
21 | if i != max_index1 and (max_index2 == -1 or numbers[i] > numbers[max_index2]):
22 | max_index2 = i
23 |
24 | return numbers[max_index1] * numbers[max_index2]
25 |
26 |
27 | if __name__ == '__main__':
28 | n = int(input())
29 | a = [int(x) for x in input().split()]
30 | assert (len(a) == n)
31 |
32 | print(max_pairwise_product_fast(n, a))
33 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_2/01_introduction_problems.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mablatnik/Algorithmic-Toolbox/5d79938e2f2d97f2100f4555e2ac2f2b79f8f36f/algorithmic_toolbox/week_2/01_introduction_problems.pdf
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_2/01_introduction_starter_files/fibonacci/Fibonacci.java:
--------------------------------------------------------------------------------
1 | import java.util.Scanner;
2 |
3 | public class Fibonacci {
4 |
5 | private static long calc_fib(int n) {
6 | if (n <= 1)
7 | return n;
8 |
9 | int[] result = new int[n + 1];
10 | result[0] = 0;
11 | result[1] = 1;
12 | for (int i = 2; i < n + 1; i++) {
13 | result[i] = result[i - 1] + result[i - 2];
14 | }
15 | return result[n];
16 | }
17 |
18 | public static void main(String args[]) {
19 | Scanner in = new Scanner(System.in);
20 | int n = in.nextInt();
21 |
22 | System.out.println(calc_fib(n));
23 | }
24 | }
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_2/01_introduction_starter_files/fibonacci/fibonacci.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | // The following code calls a naive algorithm for computing a Fibonacci number.
5 | //
6 | // What to do:
7 | // 1. Compile the following code and run it on an input "40" to check that it is slow.
8 | // You may also want to submit it to the grader to ensure that it gets the "time limit exceeded" message.
9 | // 2. Implement the fibonacci_fast procedure.
10 | // 3. Remove the line that prints the result of the naive algorithm, comment the lines reading the input,
11 | // uncomment the line with a call to test_solution, compile the program, and run it.
12 | // This will ensure that your efficient algorithm returns the same as the naive one for small values of n.
13 | // 4. If test_solution() reveals a bug in your implementation, debug it, fix it, and repeat step 3.
14 | // 5. Remove the call to test_solution, uncomment the line with a call to fibonacci_fast (and the lines reading the input),
15 | // and submit it to the grader.
16 |
17 | int fibonacci_naive(int n) {
18 | if (n <= 1)
19 | return n;
20 |
21 | return fibonacci_naive(n - 1) + fibonacci_naive(n - 2);
22 | }
23 |
24 | int fibonacci_fast(int n) {
25 | if (n <= 1)
26 | return n;
27 |
28 | int F1, F2, F;
29 | F1 = 0;
30 | F2 = 1;
31 | for (int i = 2; i <= n; i++) {
32 | F = F1 + F2;
33 | F1 = F2;
34 | F2 = F;
35 | }
36 | return F;
37 | }
38 |
39 | void test_solution() {
40 | assert(fibonacci_fast(3) == 2);
41 | assert(fibonacci_fast(10) == 55);
42 | for (int n = 0; n < 20; ++n)
43 | assert(fibonacci_fast(n) == fibonacci_naive(n));
44 | }
45 |
46 | int main() {
47 | int n = 0;
48 | std::cin >> n;
49 |
50 | // test_solution();
51 | std::cout << fibonacci_fast(n) << '\n';
52 | return 0;
53 | }
54 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_2/01_introduction_starter_files/fibonacci/fibonacci.py:
--------------------------------------------------------------------------------
1 | # Uses python3
2 |
3 |
4 | def calc_fib(n):
5 | if n <= 1:
6 | return n
7 |
8 | previous = 0
9 | current = 1
10 |
11 | for _ in range(n - 1):
12 | previous, current = current, previous + current
13 |
14 | return current
15 |
16 |
17 | n = int(input())
18 | print(calc_fib(n))
19 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_2/01_introduction_starter_files/fibonacci_huge/FibonacciHuge.java:
--------------------------------------------------------------------------------
1 | import java.util.*;
2 |
3 | public class FibonacciHuge {
4 | private static long getFibonacciHugeNaive(long n, long m) {
5 | if (n <= 1)
6 | return n;
7 |
8 | long previous = 0;
9 | long current = 1;
10 |
11 | for (long i = 0; i < n - 1; ++i) {
12 | long tmp_previous = previous;
13 | previous = current;
14 | current = tmp_previous + current;
15 | }
16 |
17 | return current % m;
18 | }
19 |
20 | private static long pisanoPeriodLength(long m) {
21 | long F1 = 0, F2 = 1, F = F1 + F2, length = 0;
22 | for (int i = 0; i < m * m; i++) {
23 | F = (F1 + F2) % m;
24 | F1 = F2;
25 | F2 = F;
26 | if (F1 == 0 && F2 == 1) {
27 | length = i + 1;
28 | break;
29 | }
30 | }
31 | return length;
32 | }
33 |
34 | private static long getFibonacciHugeFast(long n, long m) {
35 | long remainder = n % pisanoPeriodLength(m);
36 |
37 | long F1 = 0, F2 = 1, F = remainder;
38 | for (int i = 1; i < remainder; i++) {
39 | F = (F1 + F2) % m;
40 | F1 = F2;
41 | F2 = F;
42 | }
43 | return F % m;
44 | }
45 |
46 | public static void main(String[] args) {
47 | Scanner scanner = new Scanner(System.in);
48 | long n = scanner.nextLong();
49 | long m = scanner.nextLong();
50 | System.out.println(getFibonacciHugeFast(n, m));
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_2/01_introduction_starter_files/fibonacci_huge/fibonacci_huge.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | using std::cin;
4 | using std::cout;
5 |
6 | long long get_fibonacci_huge_naive(long long n, long long m) {
7 | if (n <= 1)
8 | return n;
9 |
10 | long long previous = 0;
11 | long long current = 1;
12 |
13 | for (long long i = 0; i < n - 1; ++i) {
14 | long long tmp_previous = previous;
15 | previous = current;
16 | current = tmp_previous + current;
17 | }
18 |
19 | return current % m;
20 | }
21 |
22 | long long get_pisano_period_length(long long m) {
23 | long long F1 = 0, F2 = 1, F = F1 + F2;
24 | for (int i = 0; i < m * m; i++) {
25 | F = (F1 + F2) % m;
26 | F1 = F2;
27 | F2 = F;
28 | if (F1 == 0 && F2 == 1) return i + 1;
29 | }
30 | }
31 |
32 | long long get_fibonacci_huge_fast(long long n, long long m) {
33 | long long remainder = n % get_pisano_period_length(m);
34 |
35 | long long F1 = 0, F2 = 1, F = remainder;
36 | for (int i = 1; i < remainder; i++) {
37 | F = (F1 + F2) % m;
38 | F1 = F2;
39 | F2 = F;
40 | }
41 | return F % m;
42 | }
43 |
44 | int main() {
45 | long long n, m;
46 |
47 | std::cin >> n >> m;
48 | std::cout << get_fibonacci_huge_fast(n, m) << '\n';
49 | }
50 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_2/01_introduction_starter_files/fibonacci_huge/fibonacci_huge.py:
--------------------------------------------------------------------------------
1 | # Uses python3
2 | import sys
3 | import unittest
4 |
5 |
6 | def get_fibonacci_huge_naive(n, m):
7 | if n <= 1:
8 | return n
9 |
10 | previous = 0
11 | current = 1
12 |
13 | for _ in range(n - 1):
14 | previous, current = current, previous + current
15 |
16 | return current % m
17 |
18 |
19 | def get_fibonacci(n):
20 | if n <= 1:
21 | return n
22 |
23 | previous = 0
24 | current = 1
25 |
26 | for _ in range(n - 1):
27 | previous, current = current, previous + current
28 |
29 | return current
30 |
31 |
32 | def fib_period_length(m):
33 | previous = 0
34 | current = 1
35 | for i in range(m * m + 1):
36 | previous, current = current, (previous + current) % m
37 | if previous == 0 and current == 1:
38 | return i + 1
39 |
40 |
41 | def get_fibonacci_huge_fast(n, m):
42 | remainder = n % fib_period_length(m)
43 | return get_fibonacci(remainder) % m
44 |
45 |
46 | class MyTest(unittest.TestCase):
47 | def test_naive(self):
48 | self.assertEqual(get_fibonacci_huge_naive(1, 239), 1)
49 | self.assertEqual(get_fibonacci_huge_naive(239, 1000), 161)
50 |
51 | def test_fast(self):
52 | self.assertEqual(get_fibonacci_huge_fast(1, 239), 1)
53 | self.assertEqual(get_fibonacci_huge_fast(239, 1000), 161)
54 | self.assertEqual(get_fibonacci_huge_fast(2816213588, 30524), 10249)
55 |
56 |
57 | if __name__ == '__main__':
58 | # unittest.main()
59 |
60 | # while(True):
61 | # a = random.randint(1, 1000)
62 | # b = random.randint(2, 100)
63 |
64 | # res1 = get_fibonacci_huge_naive(a, b)
65 | # res2 = get_fibonacci_huge_fast(a, b)
66 | # if (res1 != res2):
67 | # print('Wrond answer: {} {}'.format(res1, res2))
68 | # break
69 | # else:
70 | # print('OK: {} {}'.format(res1, res2))
71 |
72 | input = sys.stdin.read()
73 | n, m = map(int, input.split())
74 | print(get_fibonacci_huge_fast(n, m))
75 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_2/01_introduction_starter_files/fibonacci_last_digit/FibonacciLastDigit.java:
--------------------------------------------------------------------------------
1 | import java.util.Scanner;
2 |
3 | public class FibonacciLastDigit {
4 | private static int getFibonacciLastDigitNaive(int n) {
5 | if (n <= 1)
6 | return n;
7 |
8 | int previous = 0;
9 | int current = 1;
10 |
11 | for (int i = 0; i < n - 1; ++i) {
12 | int tmp_previous = previous;
13 | previous = current;
14 | current = tmp_previous + current;
15 | }
16 |
17 | return current % 10;
18 | }
19 |
20 | public static int getFibonacciLastDigitFast(int n) {
21 | if (n <= 1)
22 | return n;
23 |
24 | int[] result = new int[n + 1];
25 | result[0] = 0;
26 | result[1] = 1;
27 | for (int i = 2; i < n + 1; i++) {
28 | result[i] = (result[i - 1] + result[i - 2]) % 10;
29 | }
30 | return result[n];
31 | }
32 |
33 | public static void main(String[] args) {
34 | Scanner scanner = new Scanner(System.in);
35 | int n = scanner.nextInt();
36 | int c = getFibonacciLastDigitFast(n);
37 | System.out.println(c);
38 | }
39 | }
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_2/01_introduction_starter_files/fibonacci_last_digit/fibonacci_last_digit.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | int get_fibonacci_last_digit_naive(long long n) {
5 | if (n <= 1)
6 | return n;
7 |
8 | int previous = 0;
9 | int current = 1;
10 |
11 | for (int i = 0; i < n - 1; ++i) {
12 | int tmp_previous = previous;
13 | previous = current;
14 | current = tmp_previous + current;
15 | }
16 |
17 | return current % 10;
18 | }
19 |
20 | int get_fibonacci_last_digit_fast(long long n) {
21 | if (n <= 1)
22 | return n;
23 |
24 | int previous = 0;
25 | int current = 1;
26 |
27 | for (int i = 0; i < n - 1; ++i) {
28 | int tmp_previous = previous % 10;
29 | previous = current % 10;
30 | current = tmp_previous + current % 10;
31 | }
32 | return current % 10;
33 | }
34 |
35 | // void test_solution() {
36 | // assert(get_fibonacci_last_digit_fast(3), 2);
37 | // assert(get_fibonacci_last_digit_fast(3), 2);
38 | // for (int n = 0; n < 20; ++n)
39 | // assert(get_fibonacci_last_digit_fast(n) == get_fibonacci_last_digit_naive(n));
40 | // }
41 |
42 | int main() {
43 | int n;
44 | std::cin >> n;
45 |
46 | // test_solution();
47 | int c = get_fibonacci_last_digit_fast(n);
48 | std::cout << c << '\n';
49 | }
50 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_2/01_introduction_starter_files/fibonacci_last_digit/fibonacci_last_digit.py:
--------------------------------------------------------------------------------
1 | # Uses python3
2 | import sys
3 | import unittest
4 |
5 |
6 | def get_fibonacci_last_digit_naive(n):
7 | if n <= 1:
8 | return n
9 |
10 | previous = 0
11 | current = 1
12 |
13 | for _ in range(n - 1):
14 | previous, current = current, previous + current
15 |
16 | return current % 10
17 |
18 |
19 | def get_fibonacci_last_digit_fast(n):
20 | if n <= 1:
21 | return n
22 |
23 | previous = 0
24 | current = 1
25 |
26 | for _ in range(n - 1):
27 | previous, current = current % 10, (previous + current) % 10
28 |
29 | return current
30 |
31 |
32 | class MyTest(unittest.TestCase):
33 | def test_naive(self):
34 | self.assertEqual(get_fibonacci_last_digit_naive(3), 2)
35 | self.assertEqual(get_fibonacci_last_digit_naive(331), 9)
36 | self.assertEqual(get_fibonacci_last_digit_naive(327305), 5)
37 |
38 | def test_fast(self):
39 | self.assertEqual(get_fibonacci_last_digit_fast(3), 2)
40 | self.assertEqual(get_fibonacci_last_digit_fast(331), 9)
41 | self.assertEqual(get_fibonacci_last_digit_fast(327305), 5)
42 |
43 |
44 | if __name__ == '__main__':
45 | # unittest.main()
46 | input = sys.stdin.read()
47 | n = int(input)
48 | print(get_fibonacci_last_digit_fast(n))
49 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_2/01_introduction_starter_files/fibonacci_partial_sum/FibonacciPartialSum.java:
--------------------------------------------------------------------------------
1 | import java.util.*;
2 |
3 | public class FibonacciPartialSum {
4 | private static long getFibonacciPartialSumNaive(long from, long to) {
5 | if (to <= 1)
6 | return to;
7 |
8 | long previous = 0;
9 | long current = 1;
10 |
11 | for (long i = 0; i < from - 1; ++i) {
12 | long tmp_previous = previous;
13 | previous = current;
14 | current = tmp_previous + current;
15 | }
16 |
17 | long sum = current;
18 |
19 | for (long i = 0; i < to - from; ++i) {
20 | long tmp_previous = previous;
21 | previous = current;
22 | current = tmp_previous + current;
23 | sum += current;
24 | }
25 |
26 | return sum % 10;
27 | }
28 |
29 | public static void main(String[] args) {
30 | Scanner scanner = new Scanner(System.in);
31 | long from = scanner.nextLong();
32 | long to = scanner.nextLong();
33 | System.out.println(getFibonacciPartialSumNaive(from, to));
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_2/01_introduction_starter_files/fibonacci_partial_sum/fibonacci_partial_sum.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | using std::vector;
5 |
6 | long long get_fibonacci_partial_sum_naive(long long from, long long to) {
7 | if (to <= 1)
8 | return to;
9 |
10 | long long previous = 0;
11 | long long current = 1;
12 |
13 | for (long long i = 0; i < from - 1; ++i) {
14 | long long tmp_previous = previous;
15 | previous = current;
16 | current = tmp_previous + current;
17 | }
18 |
19 | long long sum = current;
20 |
21 | for (long long i = 0; i < to - from; ++i) {
22 | long long tmp_previous = previous;
23 | previous = current;
24 | current = tmp_previous + current;
25 | sum += current;
26 | }
27 |
28 | return sum % 10;
29 | }
30 |
31 | long long fibonacci_fast(long long n) {
32 | if (n <= 1)
33 | return n;
34 |
35 | long long F1, F2, F;
36 | F1 = 0;
37 | F2 = 1;
38 | for (int i = 2; i <= n; i++) {
39 | F = F1 + F2;
40 | F1 = F2;
41 | F2 = F;
42 | }
43 | return F;
44 | }
45 |
46 | int get_pisano_period_length(long long m) {
47 | long long F1 = 0, F2 = 1, F = F1 + F2;
48 | for (int i = 0; i < m * m; i++) {
49 | F = (F1 + F2) % m;
50 | F1 = F2;
51 | F2 = F;
52 | if (F1 == 0 && F2 == 1) return i + 1;
53 | }
54 | }
55 |
56 | int get_fibonacci_huge_fast(long long n, long long m) {
57 | long long remainder = n % get_pisano_period_length(m);
58 |
59 | return fibonacci_fast(remainder) % m;
60 | }
61 |
62 | int get_fibonacci_last_digit_fast(long long n) {
63 | if (n <= 1)
64 | return n;
65 |
66 | int previous = 0;
67 | int current = 1;
68 |
69 | for (int i = 0; i < n - 1; ++i) {
70 | int tmp_previous = previous % 10;
71 | previous = current % 10;
72 | current = tmp_previous + current % 10;
73 | }
74 | return current % 10;
75 | }
76 |
77 | long long fibonacci_partial_sum_fast(long long from_, long long to) {
78 | long long from_last, to_last;
79 | if (from_ == to) {
80 | return get_fibonacci_last_digit_fast(from_ % 60);
81 | } else {
82 | from_ = from_ % 60;
83 | to = to % 60;
84 |
85 | from_last = get_fibonacci_huge_fast(from_ + 1, 10) - 1;
86 | to_last = get_fibonacci_huge_fast(to + 2, 10) - 1;
87 | }
88 | return (to_last - from_last) % 10;
89 | }
90 |
91 | int main() {
92 | long long from, to;
93 | std::cin >> from >> to;
94 | std::cout << fibonacci_partial_sum_fast(from, to) << '\n';
95 | }
96 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_2/01_introduction_starter_files/fibonacci_partial_sum/fibonacci_partial_sum.py:
--------------------------------------------------------------------------------
1 | # Uses python3
2 | import sys
3 | import unittest
4 |
5 |
6 | def fibonacci_partial_sum_naive(from_, to):
7 | if to <= 1:
8 | return to
9 |
10 | previous = 0
11 | current = 1
12 |
13 | for _ in range(from_ - 1):
14 | previous, current = current, previous + current
15 |
16 | sum = current
17 |
18 | for _ in range(to - from_):
19 | previous, current = current, previous + current
20 | sum += current
21 |
22 | return sum % 10
23 |
24 |
25 | def get_fibonacci(n):
26 | if n <= 1:
27 | return n
28 |
29 | previous = 0
30 | current = 1
31 |
32 | for _ in range(n - 1):
33 | previous, current = current, previous + current
34 |
35 | return current
36 |
37 |
38 | def fib_period_length(m):
39 | previous = 0
40 | current = 1
41 | for i in range(m * m + 1):
42 | previous, current = current, (previous + current) % m
43 | if previous == 0 and current == 1:
44 | return i + 1
45 |
46 |
47 | def get_fibonacci_huge_fast(n, m):
48 | remainder = n % fib_period_length(m)
49 | return get_fibonacci(remainder) % m
50 |
51 |
52 | def get_fibonacci_last_digit_fast(n):
53 | if n <= 1:
54 | return n
55 |
56 | previous = 0
57 | current = 1
58 |
59 | for _ in range(n - 1):
60 | previous, current = current % 10, (previous + current) % 10
61 |
62 | return current
63 |
64 |
65 | def fibonacci_partial_sum_fast(from_, to):
66 | if from_ == to:
67 | return get_fibonacci_last_digit_fast(from_ % 60)
68 | else:
69 | from_ %= 60
70 | to %= 60
71 |
72 | from_last = get_fibonacci_huge_fast(from_ + 1, 10) - 1
73 | to_last = get_fibonacci_huge_fast(to + 2, 10) - 1
74 |
75 | return (to_last - from_last) % 10
76 |
77 |
78 | class MyTest(unittest.TestCase):
79 | def test_naive(self):
80 | self.assertEqual(fibonacci_partial_sum_naive(3, 7), 1)
81 | self.assertEqual(fibonacci_partial_sum_naive(10, 10), 5)
82 |
83 | def test_fast(self):
84 | self.assertEqual(fibonacci_partial_sum_fast(3, 7), 1)
85 | self.assertEqual(fibonacci_partial_sum_fast(10, 10), 5)
86 | self.assertEqual(fibonacci_partial_sum_fast(10, 200), 2)
87 |
88 |
89 | if __name__ == '__main__':
90 | # unittest.main()
91 |
92 | input = sys.stdin.read()
93 | from_, to = map(int, input.split())
94 | print(fibonacci_partial_sum_fast(from_, to))
95 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_2/01_introduction_starter_files/fibonacci_sum_last_digit/FibonacciSumLastDigit.java:
--------------------------------------------------------------------------------
1 | import java.util.*;
2 |
3 | public class FibonacciSumLastDigit {
4 | private static long getFibonacciSumNaive(long n) {
5 | if (n <= 1)
6 | return n;
7 |
8 | long previous = 0;
9 | long current = 1;
10 | long sum = 1;
11 |
12 | for (long i = 0; i < n - 1; ++i) {
13 | long tmp_previous = previous;
14 | previous = current;
15 | current = tmp_previous + current;
16 | sum += current;
17 | }
18 |
19 | return sum % 10;
20 | }
21 |
22 | public static int getFibonacciLastDigitFast(int n) {
23 | if (n <= 1)
24 | return n;
25 |
26 | int[] result = new int[n + 1];
27 | result[0] = 0;
28 | result[1] = 1;
29 | for (int i = 2; i < n + 1; i++) {
30 | result[i] = (result[i - 1] + result[i - 2]) % 10;
31 | }
32 | return result[n];
33 | }
34 |
35 | public static int getFibonacciSumFast(long n) {
36 | int new_n = (int) ((n + 2) % 60);
37 | int new_last = getFibonacciLastDigitFast(new_n);
38 | if (new_last == 0) {
39 | return 9;
40 | } else {
41 | return new_last - 1;
42 | }
43 |
44 | }
45 |
46 | public static void main(String[] args) {
47 | Scanner scanner = new Scanner(System.in);
48 | long n = scanner.nextLong();
49 | long s = getFibonacciSumFast(n);
50 | System.out.println(s);
51 | }
52 | }
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_2/01_introduction_starter_files/fibonacci_sum_last_digit/fibonacci_sum_last_digit.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int fibonacci_sum_naive(long long n) {
4 | if (n <= 1)
5 | return n;
6 |
7 | long long previous = 0;
8 | long long current = 1;
9 | long long sum = 1;
10 |
11 | for (long long i = 0; i < n - 1; ++i) {
12 | long long tmp_previous = previous;
13 | previous = current;
14 | current = tmp_previous + current;
15 | sum += current;
16 | }
17 |
18 | return sum % 10;
19 | }
20 |
21 | int get_fibonacci_last_digit_fast(long long n) {
22 | if (n <= 1)
23 | return n;
24 |
25 | int previous = 0;
26 | int current = 1;
27 |
28 | for (int i = 0; i < n - 1; ++i) {
29 | int tmp_previous = previous % 10;
30 | previous = current % 10;
31 | current = tmp_previous + current % 10;
32 | }
33 | return current % 10;
34 | }
35 |
36 | int fibonacci_sum_fast(long long n) {
37 | int new_n = (n + 2) % 60;
38 | int new_last = get_fibonacci_last_digit_fast(new_n);
39 | if (new_last == 0) {
40 | return 9;
41 | } else {
42 | return new_last - 1;
43 | }
44 | }
45 |
46 | int main() {
47 | long long n = 0;
48 | std::cin >> n;
49 | std::cout << fibonacci_sum_fast(n);
50 | }
51 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_2/01_introduction_starter_files/fibonacci_sum_last_digit/fibonacci_sum_last_digit.py:
--------------------------------------------------------------------------------
1 | # Uses python3
2 | import sys
3 | import unittest
4 |
5 |
6 | def fibonacci_sum_naive(n):
7 | if n <= 1:
8 | return n
9 |
10 | previous = 0
11 | current = 1
12 | sum = 1
13 |
14 | for _ in range(n - 1):
15 | previous, current = current, previous + current
16 | sum += current
17 |
18 | return sum % 10
19 |
20 |
21 | def get_fibonacci_last_digit_fast(n):
22 | if n <= 1:
23 | return n
24 |
25 | previous = 0
26 | current = 1
27 |
28 | for _ in range(n - 1):
29 | previous, current = current % 10, (previous + current) % 10
30 |
31 | return current
32 |
33 |
34 | def fibonacci_sum_fast(n):
35 | new_n = (n + 2) % 60
36 | new_last = get_fibonacci_last_digit_fast(new_n)
37 | if new_last == 0:
38 | return 9
39 | else:
40 | return new_last - 1
41 |
42 |
43 | class MyTest(unittest.TestCase):
44 | def test_naive(self):
45 | self.assertEqual(fibonacci_sum_naive(3), 4)
46 | self.assertEqual(fibonacci_sum_naive(100), 5)
47 |
48 | def test_fast(self):
49 | self.assertEqual(fibonacci_sum_fast(3), 4)
50 | self.assertEqual(fibonacci_sum_fast(100), 5)
51 |
52 |
53 | if __name__ == '__main__':
54 | # unittest.main()
55 |
56 | # while(True):
57 | # a = random.randint(1, 100)
58 |
59 | # res1 = fibonacci_sum_naive(a)
60 | # res2 = fibonacci_sum_fast(a)
61 | # if (res1 != res2):
62 | # print('Generated: {}'.format(a))
63 | # print('Wrond answer: {} {}'.format(res1, res2))
64 | # break
65 | # else:
66 | # print('OK: {} {}'.format(res1, res2))
67 |
68 | input = sys.stdin.read()
69 | n = int(input)
70 | print(fibonacci_sum_fast(n))
71 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_2/01_introduction_starter_files/gcd/GCD.java:
--------------------------------------------------------------------------------
1 | import java.util.*;
2 |
3 | public class GCD {
4 | private static int gcd_naive(int a, int b) {
5 | int current_gcd = 1;
6 | for (int d = 2; d <= a && d <= b; ++d) {
7 | if (a % d == 0 && b % d == 0) {
8 | if (d > current_gcd) {
9 | current_gcd = d;
10 | }
11 | }
12 | }
13 |
14 | return current_gcd;
15 | }
16 |
17 | private static int euclid_gcd(int a, int b) {
18 | int divisor = a >= b ? a : b;
19 | int dividend = a <= b ? a : b;
20 | while (divisor != 0) {
21 | int remainder = dividend % divisor;
22 | dividend = divisor;
23 | divisor = remainder;
24 | }
25 | return dividend;
26 | }
27 |
28 | public static void main(String args[]) {
29 | Scanner scanner = new Scanner(System.in);
30 | int a = scanner.nextInt();
31 | int b = scanner.nextInt();
32 |
33 | System.out.println(euclid_gcd(a, b));
34 | }
35 | }
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_2/01_introduction_starter_files/gcd/gcd.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | using std::cin;
4 | using std::cout;
5 |
6 | int gcd_naive(int a, int b) {
7 | int current_gcd = 1;
8 | for (int d = 2; d <= a && d <= b; d++) {
9 | if (a % d == 0 && b % d == 0) {
10 | if (d > current_gcd) {
11 | current_gcd = d;
12 | }
13 | }
14 | }
15 | return current_gcd;
16 | }
17 |
18 | int euclid_gcd(int a, int b) {
19 | int divisor = a >= b ? a : b;
20 | int dividend = a <= b ? a : b;
21 | while (divisor != 0) {
22 | int remainder = dividend % divisor;
23 | dividend = divisor;
24 | divisor = remainder;
25 | }
26 | return dividend;
27 | }
28 |
29 | int main() {
30 | int a, b;
31 | // while (true) {
32 | // a = rand() % 1000 + 2;
33 | // b = rand() % 1000 + 2;
34 | // cout << "Numbers: " << a << ' ' << b << "\n";
35 |
36 | // long res1 = gcd_naive(a, b);
37 | // long res2 = euclid_gcd(a, b);
38 | // if (res1 != res2) {
39 | // cout << "Wrong answer: " << res1 << ' ' << res2 << "\n";
40 | // break;
41 | // }
42 | // else {
43 | // cout << "OK\n";
44 | // }
45 | // }
46 | std::cin >> a >> b;
47 | std::cout << euclid_gcd(a, b) << std::endl;
48 | return 0;
49 | }
50 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_2/01_introduction_starter_files/gcd/gcd.py:
--------------------------------------------------------------------------------
1 | # Uses python3
2 | import sys
3 | import unittest
4 |
5 |
6 | def gcd_naive(a, b):
7 | current_gcd = 1
8 | for d in range(2, min(a, b) + 1):
9 | if a % d == 0 and b % d == 0:
10 | if d > current_gcd:
11 | current_gcd = d
12 |
13 | return current_gcd
14 |
15 |
16 | def gcd_euclid(a, b):
17 | dividend = a if (a >= b) else b
18 | divisor = a if (a <= b) else b
19 |
20 | while divisor != 0:
21 | remainder = dividend % divisor
22 | dividend = divisor
23 | divisor = remainder
24 |
25 | return dividend
26 |
27 |
28 | class MyTest(unittest.TestCase):
29 | def test_naive(self):
30 | self.assertEqual(gcd_naive(18, 35), 1)
31 | self.assertEqual(gcd_naive(28851538, 1183019), 17657)
32 |
33 | def test_fast(self):
34 | self.assertEqual(gcd_euclid(18, 35), 1)
35 | self.assertEqual(gcd_euclid(28851538, 1183019), 17657)
36 |
37 |
38 | if __name__ == '__main__':
39 | # unittest.main()
40 |
41 | # while(True):
42 | # a = random.randint(1, 10000)
43 | # b = random.randint(2, 10000)
44 |
45 | # res1 = gcd_naive(a, b)
46 | # res2 = gcd_euclid(a, b)
47 | # if (res1 != res2):
48 | # print('Wrond answer: {} {}'.format(res1, res2))
49 | # break
50 | # else:
51 | # print('OK: {} {}'.format(res1, res2))
52 |
53 | input = sys.stdin.read()
54 | a, b = map(int, input.split())
55 | print(gcd_euclid(a, b))
56 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_2/01_introduction_starter_files/lcm/LCM.java:
--------------------------------------------------------------------------------
1 | import java.util.*;
2 |
3 | public class LCM {
4 | private static long lcm_naive(int a, int b) {
5 | for (long l = 1; l <= (long) a * b; ++l)
6 | if (l % a == 0 && l % b == 0)
7 | return l;
8 |
9 | return (long) a * b;
10 | }
11 |
12 | private static long euclid_gcd(long a, long b) {
13 | long divisor = a >= b ? a : b;
14 | long dividend = a <= b ? a : b;
15 | while (divisor != 0) {
16 | long remainder = dividend % divisor;
17 | dividend = divisor;
18 | divisor = remainder;
19 | }
20 | return dividend;
21 | }
22 |
23 | private static long lmc_fast(long a, long b) {
24 | return (a * b) / euclid_gcd(a, b);
25 | }
26 |
27 | public static void main(String args[]) {
28 | Scanner scanner = new Scanner(System.in);
29 | int a = scanner.nextInt();
30 | int b = scanner.nextInt();
31 |
32 | System.out.println(lmc_fast(a, b));
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_2/01_introduction_starter_files/lcm/lcm.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | long long lcm_naive(int a, int b) {
4 | for (long l = 1; l <= (long long) a * b; ++l)
5 | if (l % a == 0 && l % b == 0)
6 | return l;
7 |
8 | return (long long) a * b;
9 | }
10 |
11 | int euclid_gcd(long a, long b) {
12 | int divisor = a >= b ? a : b;
13 | int dividend = a <= b ? a : b;
14 | while (divisor != 0) {
15 | int remainder = dividend % divisor;
16 | dividend = divisor;
17 | divisor = remainder;
18 | }
19 | return dividend;
20 | }
21 |
22 | long long lcm_fast(long long a, long long b) {
23 | return (a * b) / euclid_gcd(a, b);
24 | }
25 |
26 | int main() {
27 | long long a, b;
28 | std::cin >> a >> b;
29 | std::cout << lcm_fast(a, b) << std::endl;
30 | return 0;
31 | }
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_2/01_introduction_starter_files/lcm/lcm.py:
--------------------------------------------------------------------------------
1 | # Uses python3
2 | import sys
3 | import unittest
4 |
5 |
6 | def lcm_naive(a, b):
7 | for l in range(1, a * b + 1):
8 | if l % a == 0 and l % b == 0:
9 | return l
10 |
11 | return a * b
12 |
13 |
14 | def gcd_euclid(a, b):
15 | dividend = a if (a >= b) else b
16 | divisor = a if (a <= b) else b
17 |
18 | while divisor != 0:
19 | remainder = dividend % divisor
20 | dividend = divisor
21 | divisor = remainder
22 |
23 | return dividend
24 |
25 |
26 | def lcm_fast(a, b):
27 | return (a * b) // gcd_euclid(a, b)
28 |
29 |
30 | class MyTest(unittest.TestCase):
31 | def test_naive(self):
32 | self.assertEqual(lcm_naive(6, 8), 24)
33 |
34 | # self.assertEqual( lcm_naive(28851538, 1183019), 1933053046)
35 |
36 | def test_fast(self):
37 | self.assertEqual(lcm_fast(6, 8), 24)
38 | self.assertEqual(lcm_fast(28851538, 1183019), 1933053046)
39 |
40 |
41 | if __name__ == '__main__':
42 | # unittest.main()
43 |
44 | # while(True):
45 | # a = random.randint(1, 1000)
46 | # b = random.randint(2, 1000)
47 |
48 | # res1 = lcm_naive(a, b)
49 | # res2 = lcm_fast(a, b)
50 | # if (res1 != res2):
51 | # print('Wrond answer: {} {}'.format(res1, res2))
52 | # break
53 | # else:
54 | # print('OK: {} {}'.format(res1, res2))
55 |
56 | input = sys.stdin.read()
57 | a, b = map(int, input.split())
58 | print(lcm_fast(a, b))
59 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_3/02_greedy_algorithms_problems.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mablatnik/Algorithmic-Toolbox/5d79938e2f2d97f2100f4555e2ac2f2b79f8f36f/algorithmic_toolbox/week_3/02_greedy_algorithms_problems.pdf
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_3/02_greedy_algorithms_starter_files/change/Change.java:
--------------------------------------------------------------------------------
1 | import java.util.Scanner;
2 |
3 | public class Change {
4 | private static int getChange(int m) {
5 | int[] coins = { 10, 5, 1 };
6 | int count = 0;
7 |
8 | for (int i = 0; m > 0; i++) {
9 | count += m / coins[i];
10 | m %= coins[i];
11 | }
12 | return count;
13 | }
14 |
15 | public static void main(String[] args) {
16 | Scanner scanner = new Scanner(System.in);
17 | int m = scanner.nextInt();
18 | System.out.println(getChange(m));
19 |
20 | }
21 | }
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_3/02_greedy_algorithms_starter_files/change/change.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int get_change(int m) {
4 | int coins[] = {10, 5, 1};
5 | int count = 0;
6 | for (int i = 0; m > 0; i++) {
7 | count += m / coins[i];
8 | m %= coins[i];
9 | }
10 | return count;
11 | }
12 |
13 | int main() {
14 | int m;
15 | std::cin >> m;
16 | std::cout << get_change(m) << '\n';
17 | }
18 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_3/02_greedy_algorithms_starter_files/change/change.py:
--------------------------------------------------------------------------------
1 | # Uses python3
2 | import sys
3 | import unittest
4 |
5 |
6 | def get_change_specific(value):
7 | p, n, d = 1, 5, 10
8 | count = 0
9 | while value > 0:
10 | if value >= d:
11 | count += value // d
12 | value %= d
13 | elif value >= n:
14 | count += value // n
15 | value %= n
16 | else:
17 | count += value // p
18 | break
19 | return count
20 |
21 |
22 | def get_change_abstract(value, *coins):
23 | count = 0
24 | i = 0
25 | while value > 0:
26 | count += value // coins[i]
27 | value %= coins[i]
28 | i += 1
29 | return count
30 |
31 |
32 | class MyTest(unittest.TestCase):
33 | def test_naive(self):
34 | self.assertEqual(get_change_specific(2), 2)
35 | self.assertEqual(get_change_specific(28), 6)
36 |
37 | def test_naive(self):
38 | self.assertEqual(get_change_abstract(2, 10, 5, 1), 2)
39 | self.assertEqual(get_change_abstract(28, 10, 5, 1), 6)
40 |
41 |
42 | if __name__ == '__main__':
43 | # unittest.main()
44 |
45 | value = int(sys.stdin.read())
46 | print(get_change_specific(value))
47 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_3/02_greedy_algorithms_starter_files/covering_segments/CoveringSegments.java:
--------------------------------------------------------------------------------
1 | import java.util.*;
2 |
3 | public class CoveringSegments {
4 |
5 | private static int[] optimalPoints(Segment[] segments) {
6 | int[] points = new int[2 * segments.length];
7 |
8 | Arrays.sort(segments, new Comparator() {
9 | public int compare(Segment s1, Segment s2) {
10 | return Integer.compare(s1.end, s2.end);
11 | }
12 | });
13 | int point = segments[0].end;
14 | points[0] = point;
15 |
16 | int j = 1;
17 | for (int i = 1; i < segments.length; i++) {
18 | if (point < segments[i].start || point > segments[i].end) {
19 | point = segments[i].end;
20 | points[j] = point;
21 | j++;
22 | }
23 | }
24 | int[] pointsFinal = new int[j];
25 | for (int i = 0; i < j; i++) {
26 | pointsFinal[i] = points[i];
27 | }
28 | return pointsFinal;
29 | }
30 |
31 | private static class Segment {
32 | int start, end;
33 |
34 | Segment(int start, int end) {
35 | this.start = start;
36 | this.end = end;
37 | }
38 | }
39 |
40 | public static void main(String[] args) {
41 | Scanner scanner = new Scanner(System.in);
42 | int n = scanner.nextInt();
43 | Segment[] segments = new Segment[n];
44 | for (int i = 0; i < n; i++) {
45 | int start, end;
46 | start = scanner.nextInt();
47 | end = scanner.nextInt();
48 | segments[i] = new Segment(start, end);
49 | }
50 | int[] points = optimalPoints(segments);
51 | System.out.println(points.length);
52 | for (int point : points) {
53 | System.out.print(point + " ");
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_3/02_greedy_algorithms_starter_files/covering_segments/covering_segments.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | using std::vector;
7 |
8 | struct Segment {
9 | int start, end;
10 | };
11 |
12 | bool sortFunction(Segment i, Segment j) { return (i.end < j.end); }
13 |
14 | vector optimal_points(vector &segments) {
15 |
16 | std::sort(segments.begin(), segments.end(), sortFunction);
17 |
18 | vector points;
19 | int point = segments[0].end;
20 | points.push_back(point);
21 |
22 | for (size_t i = 1; i < segments.size(); ++i) {
23 | if (point < segments[i].start || point > segments[i].end) {
24 | point = segments[i].end;
25 | points.push_back(point);
26 | }
27 | }
28 | return points;
29 | }
30 |
31 | int main() {
32 | int n;
33 | std::cin >> n;
34 | vector segments(n);
35 | for (size_t i = 0; i < segments.size(); ++i) {
36 | std::cin >> segments[i].start >> segments[i].end;
37 | }
38 | vector points = optimal_points(segments);
39 | std::cout << points.size() << "\n";
40 | for (size_t i = 0; i < points.size(); ++i) {
41 | std::cout << points[i] << " ";
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_3/02_greedy_algorithms_starter_files/covering_segments/covering_segments.py:
--------------------------------------------------------------------------------
1 | # Uses python3
2 | import sys
3 | from operator import attrgetter
4 | from collections import namedtuple
5 |
6 | Segment = namedtuple('Segment', 'start end')
7 |
8 |
9 | def optimal_points(segments):
10 | points = []
11 | segments = sorted(segments, key=attrgetter('end'))
12 | max_right = segments[0].end
13 | points.append(max_right)
14 | i = 1
15 | while i < len(segments):
16 | if max_right < segments[i].start:
17 | max_right = segments[i].end
18 | points.append(max_right)
19 | i += 1
20 |
21 | return points
22 |
23 |
24 | if __name__ == '__main__':
25 | input = sys.stdin.read()
26 | n, *data = map(int, input.split())
27 | segments = list(map(lambda x: Segment(x[0], x[1]), zip(data[::2], data[1::2])))
28 | points = optimal_points(segments)
29 | print(len(points))
30 | for p in points:
31 | print(p, end=' ')
32 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_3/02_greedy_algorithms_starter_files/different_summands/DifferentSummands.java:
--------------------------------------------------------------------------------
1 | import java.util.*;
2 |
3 | public class DifferentSummands {
4 | private static List optimalSummands(int n) {
5 | List summands = new ArrayList();
6 | for (int i = 1; i <= n; i++) {
7 | n -= i;
8 | if (n <= i) {
9 | summands.add(n + i);
10 | } else if (n == 0) {
11 | summands.add(i);
12 | break;
13 | } else {
14 | summands.add(i);
15 | }
16 | }
17 | return summands;
18 | }
19 |
20 | public static void main(String[] args) {
21 | Scanner scanner = new Scanner(System.in);
22 | int n = scanner.nextInt();
23 | List summands = optimalSummands(n);
24 | System.out.println(summands.size());
25 | for (Integer summand : summands) {
26 | System.out.print(summand + " ");
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_3/02_greedy_algorithms_starter_files/different_summands/different_summands.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | using std::vector;
5 |
6 | vector optimal_summands(int n) {
7 | vector summands;
8 | for (int i = 1; i <= n; i++) {
9 | n -= i;
10 | if (n <= i) {
11 | summands.push_back(n + i);
12 | } else if (n == 0) {
13 | summands.push_back(i);
14 | break;
15 | } else {
16 | summands.push_back(i);
17 | }
18 | }
19 | return summands;
20 | }
21 |
22 | int main() {
23 | int n;
24 | std::cin >> n;
25 | vector summands = optimal_summands(n);
26 | std::cout << summands.size() << '\n';
27 | for (size_t i = 0; i < summands.size(); ++i) {
28 | std::cout << summands[i] << ' ';
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_3/02_greedy_algorithms_starter_files/different_summands/different_summands.py:
--------------------------------------------------------------------------------
1 | # Uses python3
2 | import sys
3 |
4 |
5 | def optimal_summands(n):
6 | summands = []
7 | for i in range(1, n + 1):
8 | n -= i
9 | if n <= i:
10 | summands.append(n + i)
11 | break
12 | elif n == 0:
13 | summands.append(i)
14 | break
15 | else:
16 | summands.append(i)
17 | return summands
18 |
19 |
20 | if __name__ == '__main__':
21 | input = sys.stdin.read()
22 | n = int(input)
23 | summands = optimal_summands(n)
24 | print(len(summands))
25 | for x in summands:
26 | print(x, end=' ')
27 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_3/02_greedy_algorithms_starter_files/dot_product/DotProduct.java:
--------------------------------------------------------------------------------
1 | import java.util.*;
2 |
3 | public class DotProduct {
4 | private static long maxDotProduct(int[] a, int[] b) {
5 | Arrays.sort(a);
6 | Arrays.sort(b);
7 | long result = 0;
8 | for (int i = 0; i < a.length; i++) {
9 | result += (long) a[i] * b[i];
10 | }
11 | return result;
12 | }
13 |
14 | public static void main(String[] args) {
15 | Scanner scanner = new Scanner(System.in);
16 | int n = scanner.nextInt();
17 | int[] a = new int[n];
18 | for (int i = 0; i < n; i++) {
19 | a[i] = scanner.nextInt();
20 | }
21 | int[] b = new int[n];
22 | for (int i = 0; i < n; i++) {
23 | b[i] = scanner.nextInt();
24 | }
25 | System.out.println(maxDotProduct(a, b));
26 | }
27 | }
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_3/02_greedy_algorithms_starter_files/dot_product/dot_product.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | using std::vector;
6 |
7 | long long max_dot_product(vector a, vector b) {
8 | std::sort(begin(a), end(a));
9 | std::sort(begin(b), end(b));
10 | long long result = 0;
11 | for (int i = 0; i < a.size(); i++) {
12 | result += (long long) a[i] * b[i];
13 | }
14 | return result;
15 | }
16 |
17 | int main() {
18 | size_t n;
19 | std::cin >> n;
20 | vector a(n), b(n);
21 | for (size_t i = 0; i < n; i++) {
22 | std::cin >> a[i];
23 | }
24 | for (size_t i = 0; i < n; i++) {
25 | std::cin >> b[i];
26 | }
27 | std::cout << max_dot_product(a, b) << std::endl;
28 | }
29 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_3/02_greedy_algorithms_starter_files/dot_product/dot_product.py:
--------------------------------------------------------------------------------
1 | # Uses python3
2 |
3 | import sys
4 |
5 |
6 | def max_dot_product(a, b):
7 | a.sort()
8 | b.sort()
9 |
10 | res = 0
11 | for i in range(len(a)):
12 | res += a[i] * b[i]
13 | return res
14 |
15 |
16 | if __name__ == '__main__':
17 | input = sys.stdin.read()
18 | data = list(map(int, input.split()))
19 | n = data[0]
20 | a = data[1:(n + 1)]
21 | b = data[(n + 1):]
22 | print(max_dot_product(a, b))
23 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_3/02_greedy_algorithms_starter_files/fractional_knapsack/FractionalKnapsack.java:
--------------------------------------------------------------------------------
1 | import java.util.Scanner;
2 |
3 | public class FractionalKnapsack {
4 |
5 | private static int getMaxIndex(int[] weights, int[] values) {
6 | int max_i = 0;
7 | double max = 0;
8 |
9 | for (int i = 0; i < weights.length; i++) {
10 | if (weights[i] != 0 && (double) values[i] / weights[i] > max) {
11 | max = (double) values[i] / weights[i];
12 | max_i = i;
13 | }
14 | }
15 | return max_i;
16 | }
17 |
18 | private static double getOptimalValue(int capacity, int[] values, int[] weights) {
19 | double value = 0.0;
20 |
21 | for (int i = 0; i < weights.length; i++) {
22 | if (capacity == 0)
23 | return value;
24 | int index = getMaxIndex(weights, values);
25 | int a = Math.min(capacity, weights[index]);
26 | value += a * (double) values[index] / weights[index];
27 | weights[index] -= a;
28 | capacity -= a;
29 | }
30 | return value;
31 | }
32 |
33 | public static void main(String args[]) {
34 | Scanner scanner = new Scanner(System.in);
35 | int n = scanner.nextInt();
36 | int capacity = scanner.nextInt();
37 | int[] values = new int[n];
38 | int[] weights = new int[n];
39 | for (int i = 0; i < n; i++) {
40 | values[i] = scanner.nextInt();
41 | weights[i] = scanner.nextInt();
42 | }
43 | System.out.println(getOptimalValue(capacity, values, weights));
44 | }
45 | }
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_3/02_greedy_algorithms_starter_files/fractional_knapsack/fractional_knapsack.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | using std::vector;
5 |
6 | int get_max_index(vector weights, vector values) {
7 | int max_i = 0;
8 | double max = 0;
9 |
10 | for (int i = 0; i < weights.size(); i++) {
11 | if (weights[i] != 0 && (double) values[i] / weights[i] > max) {
12 | max = (double) values[i] / weights[i];
13 | max_i = i;
14 | }
15 | }
16 | return max_i;
17 | }
18 |
19 | double get_optimal_value(int capacity, vector weights, vector values) {
20 | double value = 0.0;
21 |
22 | for (int i = 0; i < weights.size(); i++) {
23 | if (capacity == 0) return value;
24 | int index = get_max_index(weights, values);
25 | int a = std::min(capacity, weights[index]);
26 | value += a * (double) values[index] / weights[index];
27 | weights[index] -= a;
28 | capacity -= a;
29 | }
30 |
31 | return value;
32 | }
33 |
34 | int main() {
35 | int n;
36 | int capacity;
37 | std::cin >> n >> capacity;
38 | vector values(n);
39 | vector weights(n);
40 | for (int i = 0; i < n; i++) {
41 | std::cin >> values[i] >> weights[i];
42 | }
43 |
44 | double optimal_value = get_optimal_value(capacity, weights, values);
45 |
46 | std::cout.precision(10);
47 | std::cout << optimal_value << std::endl;
48 | return 0;
49 | }
50 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_3/02_greedy_algorithms_starter_files/fractional_knapsack/fractional_knapsack.py:
--------------------------------------------------------------------------------
1 | # Uses python3
2 | import sys
3 | import unittest
4 |
5 |
6 | def get_optimal_value(capacity, weights, values):
7 | value = 0.
8 | proportion = [float(v) / float(w) for v, w in zip(values, weights)]
9 | for _ in range(len(weights) + 1):
10 | if capacity == 0:
11 | return value
12 | break
13 | max_weight = max(proportion)
14 | index = proportion.index(max_weight)
15 | proportion[index] = -1
16 | add_capacity = min(capacity, weights[index])
17 | value += add_capacity * max_weight
18 | weights[index] -= add_capacity
19 | capacity -= add_capacity
20 | return value
21 |
22 |
23 | if __name__ == "__main__":
24 | data = list(map(int, sys.stdin.read().split()))
25 | n, capacity = data[0:2]
26 | values = data[2:(2 * n + 2):2]
27 | weights = data[3:(2 * n + 2):2]
28 | opt_value = get_optimal_value(capacity, weights, values)
29 | print("{:.10f}".format(opt_value))
30 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_3/02_greedy_algorithms_starter_files/largest_number/LargestNumber.java:
--------------------------------------------------------------------------------
1 | import java.util.*;
2 |
3 | public class LargestNumber {
4 | private static String largestNumber(String[] a) {
5 | // write your code here
6 | String result = "";
7 | for (int i = 0; i < a.length; i++) {
8 | result += a[i];
9 | }
10 | return result;
11 | }
12 |
13 | public static void main(String[] args) {
14 | Scanner scanner = new Scanner(System.in);
15 | int n = scanner.nextInt();
16 | String[] a = new String[n];
17 | for (int i = 0; i < n; i++) {
18 | a[i] = scanner.next();
19 | }
20 | System.out.println(largestNumber(a));
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_3/02_greedy_algorithms_starter_files/largest_number/by_learners/largest_number.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # by Andronik Ordian
3 |
4 | def largest_number(a)
5 | # write your code here
6 | a.join('')
7 | end
8 |
9 | if __FILE__ == $0
10 | a = STDIN.read.split().drop(1)
11 | puts largest_number(a)
12 | end
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_3/02_greedy_algorithms_starter_files/largest_number/largest_number.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | using std::vector;
8 | using std::string;
9 |
10 | string largest_number(vector a) {
11 | //write your code here
12 | std::stringstream ret;
13 | for (size_t i = 0; i < a.size(); i++) {
14 | ret << a[i];
15 | }
16 | string result;
17 | ret >> result;
18 | return result;
19 | }
20 |
21 | int main() {
22 | int n;
23 | std::cin >> n;
24 | vector a(n);
25 | for (size_t i = 0; i < a.size(); i++) {
26 | std::cin >> a[i];
27 | }
28 | std::cout << largest_number(a);
29 | }
30 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_3/02_greedy_algorithms_starter_files/largest_number/largest_number.hs:
--------------------------------------------------------------------------------
1 | -- by Kirill Elagin
2 |
3 | largest_number :: [Int] -> String
4 | largest_number as = concat (map show as) -- write your code here
5 |
6 | main :: IO ()
7 | main = do
8 | _ <- getLine
9 | as <- fmap (map read . words) getLine
10 | putStrLn $ largest_number as
11 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_3/02_greedy_algorithms_starter_files/largest_number/largest_number.py:
--------------------------------------------------------------------------------
1 | # Uses python3
2 |
3 | import sys
4 |
5 |
6 | def largest_number(a):
7 | nums = map(str, a)
8 | nums.sort()
9 |
10 | return res
11 |
12 |
13 | if __name__ == '__main__':
14 | input = sys.stdin.read()
15 | data = input.split()
16 | a = data[1:]
17 | print(largest_number(a))
18 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_4/03_divide_and_conquer_problems.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mablatnik/Algorithmic-Toolbox/5d79938e2f2d97f2100f4555e2ac2f2b79f8f36f/algorithmic_toolbox/week_4/03_divide_and_conquer_problems.pdf
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_4/03_divide_and_conquer_starter_files_20160804/binary_search/BinarySearch.java:
--------------------------------------------------------------------------------
1 | import java.io.*;
2 | import java.util.*;
3 |
4 | public class BinarySearch {
5 |
6 | static int binarySearch(int[] a, int x) {
7 | int left = 0, right = a.length - 1;
8 | while (left <= right) {
9 | int mid = left + (right - left) / 2;
10 | if (x == a[mid]) {
11 | return mid;
12 | } else if (x < a[mid]) {
13 | right = mid - 1;
14 | } else {
15 | left = mid + 1;
16 | }
17 | }
18 | return -1;
19 | }
20 |
21 | static int linearSearch(int[] a, int x) {
22 | for (int i = 0; i < a.length; i++) {
23 | if (a[i] == x)
24 | return i;
25 | }
26 | return -1;
27 | }
28 |
29 | public static void main(String[] args) {
30 | FastScanner scanner = new FastScanner(System.in);
31 | int n = scanner.nextInt();
32 | int[] a = new int[n];
33 | for (int i = 0; i < n; i++) {
34 | a[i] = scanner.nextInt();
35 | }
36 | int m = scanner.nextInt();
37 | int[] b = new int[m];
38 | for (int i = 0; i < m; i++) {
39 | b[i] = scanner.nextInt();
40 | }
41 | for (int i = 0; i < m; i++) {
42 | // replace with the call to binarySearch when implemented
43 | System.out.print(binarySearch(a, b[i]) + " ");
44 | }
45 | }
46 |
47 | static class FastScanner {
48 | BufferedReader br;
49 | StringTokenizer st;
50 |
51 | FastScanner(InputStream stream) {
52 | try {
53 | br = new BufferedReader(new InputStreamReader(stream));
54 | } catch (Exception e) {
55 | e.printStackTrace();
56 | }
57 | }
58 |
59 | String next() {
60 | while (st == null || !st.hasMoreTokens()) {
61 | try {
62 | st = new StringTokenizer(br.readLine());
63 | } catch (IOException e) {
64 | e.printStackTrace();
65 | }
66 | }
67 | return st.nextToken();
68 | }
69 |
70 | int nextInt() {
71 | return Integer.parseInt(next());
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_4/03_divide_and_conquer_starter_files_20160804/binary_search/binary_search.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | using std::vector;
6 |
7 | int binary_search_iterative(const vector &a, int x) {
8 | int left = 0, right = (int) a.size();
9 | while (left <= right) {
10 | int mid = left + (right - left) / 2;
11 | if (x == a[mid]) return mid;
12 | else if (x < a[mid]) right = mid - 1;
13 | else left = mid + 1;
14 | }
15 | return -1;
16 | }
17 |
18 | int linear_search(const vector &a, int x) {
19 | for (size_t i = 0; i < a.size(); ++i) {
20 | if (a[i] == x) return i;
21 | }
22 | return -1;
23 | }
24 |
25 | int main() {
26 | int n;
27 | std::cin >> n;
28 | vector a(n);
29 | for (size_t i = 0; i < a.size(); i++) {
30 | std::cin >> a[i];
31 | }
32 | int m;
33 | std::cin >> m;
34 | vector b(m);
35 | for (int i = 0; i < m; ++i) {
36 | std::cin >> b[i];
37 | }
38 | for (int i = 0; i < m; ++i) {
39 | //replace with the call to binary_search when implemented
40 | std::cout << binary_search_iterative(a, b[i]) << ' ';
41 | }
42 | }
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_4/03_divide_and_conquer_starter_files_20160804/binary_search/binary_search.py:
--------------------------------------------------------------------------------
1 | # Uses python3
2 | import sys
3 |
4 |
5 | def binary_search_iterative(a, x):
6 | left, right = 0, len(a) - 1
7 |
8 | while left <= right:
9 | mid = left + (right - left) // 2
10 | if a[mid] == x:
11 | return mid
12 | elif x < a[mid]:
13 | right = mid - 1
14 | else:
15 | left = mid + 1
16 | return -1
17 |
18 |
19 | def linear_search(a, x):
20 | for i in range(len(a)):
21 | if a[i] == x:
22 | return i
23 | return -1
24 |
25 |
26 | if __name__ == '__main__':
27 | input = sys.stdin.read()
28 | data = list(map(int, input.split()))
29 | n = data[0]
30 | m = data[n + 1]
31 | a = data[1: n + 1]
32 | for x in data[n + 2:]:
33 | # replace with the call to binary_search when implemented
34 | print(binary_search_iterative(a, x), end=' ')
35 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_4/03_divide_and_conquer_starter_files_20160804/closest/Closest.java:
--------------------------------------------------------------------------------
1 | import java.io.*;
2 | import java.util.*;
3 |
4 | import static java.lang.Math.*;
5 |
6 | public class Closest {
7 |
8 | static class Point implements Comparable {
9 | long x, y;
10 |
11 | public Point(long x, long y) {
12 | this.x = x;
13 | this.y = y;
14 | }
15 |
16 | @Override
17 | public int compareTo(Point o) {
18 | return o.y == y ? Long.signum(x - o.x) : Long.signum(y - o.y);
19 | }
20 | }
21 |
22 | static double minimalDistance(int[] x, int y[]) {
23 | double ans = Double.POSITIVE_INFINITY;
24 | // write your code here
25 | return ans;
26 | }
27 |
28 | public static void main(String[] args) throws Exception {
29 | reader = new BufferedReader(new InputStreamReader(System.in));
30 | writer = new PrintWriter(System.out);
31 | int n = nextInt();
32 | int[] x = new int[n];
33 | int[] y = new int[n];
34 | for (int i = 0; i < n; i++) {
35 | x[i] = nextInt();
36 | y[i] = nextInt();
37 | }
38 | System.out.println(minimalDistance(x, y));
39 | writer.close();
40 | }
41 |
42 | static BufferedReader reader;
43 | static PrintWriter writer;
44 | static StringTokenizer tok = new StringTokenizer("");
45 |
46 | static String next() {
47 | while (!tok.hasMoreTokens()) {
48 | String w = null;
49 | try {
50 | w = reader.readLine();
51 | } catch (Exception e) {
52 | e.printStackTrace();
53 | }
54 | if (w == null)
55 | return null;
56 | tok = new StringTokenizer(w);
57 | }
58 | return tok.nextToken();
59 | }
60 |
61 | static int nextInt() {
62 | return Integer.parseInt(next());
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_4/03_divide_and_conquer_starter_files_20160804/closest/closest.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | using std::vector;
10 | using std::string;
11 | using std::pair;
12 | using std::min;
13 |
14 |
15 | double minimal_distance(vector x, vector y) {
16 | //write your code here
17 | return 0.;
18 | }
19 |
20 | int main() {
21 | size_t n;
22 | std::cin >> n;
23 | vector x(n);
24 | vector y(n);
25 | for (size_t i = 0; i < n; i++) {
26 | std::cin >> x[i] >> y[i];
27 | }
28 | std::cout << std::fixed;
29 | std::cout << std::setprecision(9) << minimal_distance(x, y) << "\n";
30 | }
31 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_4/03_divide_and_conquer_starter_files_20160804/closest/closest.py:
--------------------------------------------------------------------------------
1 | # Uses python3
2 | import sys
3 | import math
4 |
5 |
6 | def minimum_distance(x, y):
7 | # write your code here
8 | return 10 ** 18
9 |
10 |
11 | if __name__ == '__main__':
12 | input = sys.stdin.read()
13 | data = list(map(int, input.split()))
14 | n = data[0]
15 | x = data[1::2]
16 | y = data[2::2]
17 | print("{0:.9f}".format(minimum_distance(x, y)))
18 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_4/03_divide_and_conquer_starter_files_20160804/inversions/Inversions.java:
--------------------------------------------------------------------------------
1 | import java.util.*;
2 |
3 | public class Inversions {
4 | private static long merge(int[] a, int[] b, int left, int ave, int right) {
5 | int i = left, j = ave, k = left;
6 | long inv_count = 0;
7 | while (i <= ave - 1 && j <= right) {
8 | if (a[i] <= a[j]) {
9 | b[k] = a[i];
10 | i++;
11 | } else {
12 | b[k] = a[j];
13 | inv_count += ave - i;
14 | j++;
15 | }
16 | k++;
17 | }
18 | while (i <= ave - 1) {
19 | b[k] = a[i];
20 | i++;
21 | k++;
22 | }
23 | while (j <= right) {
24 | b[k] = a[j];
25 | j++;
26 | k++;
27 | }
28 | for (i = left; i <= right; i++) {
29 | a[i] = b[i];
30 | }
31 | return inv_count;
32 | }
33 |
34 | private static long getNumberOfInversions(int[] a, int[] b, int left, int right) {
35 | long inv_count = 0;
36 | if (right <= left) {
37 | return inv_count;
38 | }
39 | int ave = left + (right - left) / 2;
40 | inv_count += getNumberOfInversions(a, b, left, ave);
41 | inv_count += getNumberOfInversions(a, b, ave + 1, right);
42 | inv_count += merge(a, b, left, ave + 1, right);
43 | return inv_count;
44 | }
45 |
46 | public static void main(String[] args) {
47 | Scanner scanner = new Scanner(System.in);
48 | int n = scanner.nextInt();
49 | int[] a = new int[n];
50 | for (int i = 0; i < n; i++) {
51 | a[i] = scanner.nextInt();
52 | }
53 | int[] b = new int[n];
54 | System.out.println(getNumberOfInversions(a, b, 0, a.length - 1));
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_4/03_divide_and_conquer_starter_files_20160804/inversions/inversions.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | using std::vector;
5 |
6 | long long get_inversions(vector &a, vector &b, size_t left, int ave, size_t right) {
7 | size_t i = left, j = ave, k = left;
8 | long long inv_count = 0;
9 | while (i <= ave - 1 && j <= right) {
10 | if (a[i] <= a[j]) {
11 | b[k] = a[i];
12 | i++;
13 | } else {
14 | b[k] = a[j];
15 | inv_count += ave - i;
16 | j++;
17 | }
18 | k++;
19 | }
20 | while (i <= ave - 1) {
21 | b[k] = a[i];
22 | i++;
23 | k++;
24 | }
25 | while (j <= right) {
26 | b[k] = a[j];
27 | j++;
28 | k++;
29 | }
30 | for (i = left; i <= right; i++) {
31 | a[i] = b[i];
32 | }
33 | return inv_count;
34 | }
35 |
36 | long long merge_sort(vector &a, vector &b, size_t left, size_t right) {
37 | long long inv_count = 0;
38 | if (right <= left) return inv_count;
39 | size_t ave = left + (right - left) / 2;
40 | inv_count += merge_sort(a, b, left, ave);
41 | inv_count += merge_sort(a, b, ave + 1, right);
42 | inv_count += get_inversions(a, b, left, ave + 1, right);
43 | return inv_count;
44 | }
45 |
46 | int main() {
47 | int n;
48 | std::cin >> n;
49 | vector a(n);
50 | for (size_t i = 0; i < a.size(); i++) {
51 | std::cin >> a[i];
52 | }
53 | vector b(a.size());
54 | std::cout << merge_sort(a, b, 0, a.size() - 1) << '\n';
55 | }
56 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_4/03_divide_and_conquer_starter_files_20160804/inversions/inversions.py:
--------------------------------------------------------------------------------
1 | # Uses python3
2 | import sys
3 |
4 |
5 | def merge(a, b, left, ave, right):
6 | inv_count = 0
7 | i, j, k = left, ave, left
8 | while i <= ave - 1 and j <= right:
9 | if a[i] <= a[j]:
10 | b[k] = a[i]
11 | i += 1
12 | else:
13 | b[k] = a[j]
14 | j += 1
15 | inv_count += ave - i
16 | k += 1
17 | while i <= ave - 1:
18 | b[k] = a[i]
19 | i += 1
20 | k += 1
21 | while j <= right:
22 | b[k] = a[j]
23 | j += 1
24 | k += 1
25 | for i in range(left, right + 1):
26 | a[i] = b[i]
27 | return inv_count
28 |
29 |
30 | def merge_sort(a, b, left, right):
31 | inv_count = 0
32 | if right > left:
33 | ave = (left + right) // 2
34 | inv_count += merge_sort(a, b, left, ave)
35 | inv_count += merge_sort(a, b, ave + 1, right)
36 |
37 | inv_count += merge(a, b, left, ave + 1, right)
38 |
39 | return inv_count
40 |
41 |
42 | if __name__ == '__main__':
43 | input = sys.stdin.read()
44 | n, *a = list(map(int, input.split()))
45 | b = n * [0]
46 | print(merge_sort(a, b, 0, len(a) - 1))
47 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_4/03_divide_and_conquer_starter_files_20160804/majority_element/MajorityElement.java:
--------------------------------------------------------------------------------
1 | import java.util.*;
2 | import java.io.*;
3 |
4 | public class MajorityElement {
5 | private static int getMajorityElement(int[] a, int left, int right) {
6 | if (left == right) {
7 | return -1;
8 | }
9 | if (left + 1 == right) {
10 | return a[left];
11 | }
12 | int left_elem = getMajorityElement(a, left, (left + right - 1) / 2 + 1);
13 | int right_elem = getMajorityElement(a, (left + right - 1) / 2 + 1, right);
14 |
15 | int lcount = 0;
16 | for (int i = left; i < right; i++) {
17 | if (a[i] == left_elem)
18 | lcount += 1;
19 | }
20 | if (lcount > (right - left) / 2)
21 | return left_elem;
22 |
23 | int rcount = 0;
24 | for (int i = left; i < right; i++) {
25 | if (a[i] == right_elem)
26 | rcount += 1;
27 | }
28 | if (rcount > (right - left) / 2)
29 | return right_elem;
30 | return -1;
31 | }
32 |
33 | public static void main(String[] args) {
34 | FastScanner scanner = new FastScanner(System.in);
35 | int n = scanner.nextInt();
36 | int[] a = new int[n];
37 | for (int i = 0; i < n; i++) {
38 | a[i] = scanner.nextInt();
39 | }
40 | if (getMajorityElement(a, 0, a.length) != -1) {
41 | System.out.println(1);
42 | } else {
43 | System.out.println(0);
44 | }
45 | }
46 |
47 | static class FastScanner {
48 | BufferedReader br;
49 | StringTokenizer st;
50 |
51 | FastScanner(InputStream stream) {
52 | try {
53 | br = new BufferedReader(new InputStreamReader(stream));
54 | } catch (Exception e) {
55 | e.printStackTrace();
56 | }
57 | }
58 |
59 | String next() {
60 | while (st == null || !st.hasMoreTokens()) {
61 | try {
62 | st = new StringTokenizer(br.readLine());
63 | } catch (IOException e) {
64 | e.printStackTrace();
65 | }
66 | }
67 | return st.nextToken();
68 | }
69 |
70 | int nextInt() {
71 | return Integer.parseInt(next());
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_4/03_divide_and_conquer_starter_files_20160804/majority_element/majority_element.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | using std::vector;
6 |
7 | int get_majority_element(vector &a, int left, int right) {
8 | if (left == right) return -1;
9 | if (left + 1 == right) return a[left];
10 |
11 | int left_elem = get_majority_element(a, left, (left + right - 1) / 2 + 1);
12 | int right_elem = get_majority_element(a, (left + right - 1) / 2 + 1, right);
13 |
14 | int lcount = 0;
15 | for (int i = left; i < right; i++) {
16 | if (a[i] == left_elem) lcount += 1;
17 | }
18 | if (lcount > (right - left) / 2) return left_elem;
19 |
20 | int rcount = 0;
21 | for (int i = left; i < right; i++) {
22 | if (a[i] == right_elem) rcount += 1;
23 | }
24 | if (rcount > (right - left) / 2) return right_elem;
25 |
26 | return -1;
27 | }
28 |
29 | int main() {
30 | int n;
31 | std::cin >> n;
32 | vector a(n);
33 | for (size_t i = 0; i < a.size(); ++i) {
34 | std::cin >> a[i];
35 | }
36 | std::cout << (get_majority_element(a, 0, a.size()) != -1) << '\n';
37 | }
38 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_4/03_divide_and_conquer_starter_files_20160804/majority_element/majority_element.py:
--------------------------------------------------------------------------------
1 | # Uses python3
2 | import sys
3 |
4 |
5 | def get_majority_element(a, left, right):
6 | if left == right:
7 | return -1
8 | if left + 1 == right:
9 | return a[left]
10 |
11 | left_elem = get_majority_element(a, left, (left + right - 1) // 2 + 1)
12 | right_elem = get_majority_element(a, (left + right - 1) // 2 + 1, right)
13 |
14 | lcount = 0
15 | for i in range(left, right):
16 | if a[i] == left_elem:
17 | lcount += 1
18 | if lcount > (right - left) // 2:
19 | return left_elem
20 |
21 | rcount = 0
22 | for i in range(left, right):
23 | if a[i] == right_elem:
24 | rcount += 1
25 | if rcount > (right - left) // 2:
26 | return right_elem
27 |
28 | return -1
29 |
30 |
31 | if __name__ == '__main__':
32 | input = sys.stdin.read()
33 | n, *a = list(map(int, input.split()))
34 | if get_majority_element(a, 0, n) != -1:
35 | print(1)
36 | else:
37 | print(0)
38 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_4/03_divide_and_conquer_starter_files_20160804/points_and_segments/PointsAndSegments.java:
--------------------------------------------------------------------------------
1 | import java.util.Scanner;
2 |
3 | public class PointsAndSegments {
4 |
5 | private static int[] fastCountSegments(int[] starts, int[] ends, int[] points) {
6 | int[] cnt = new int[points.length];
7 | // write your code here
8 | return cnt;
9 | }
10 |
11 | private static int[] naiveCountSegments(int[] starts, int[] ends, int[] points) {
12 | int[] cnt = new int[points.length];
13 | for (int i = 0; i < points.length; i++) {
14 | for (int j = 0; j < starts.length; j++) {
15 | if (starts[j] <= points[i] && points[i] <= ends[j]) {
16 | cnt[i]++;
17 | }
18 | }
19 | }
20 | return cnt;
21 | }
22 |
23 | public static void main(String[] args) {
24 | Scanner scanner = new Scanner(System.in);
25 | int n, m;
26 | n = scanner.nextInt();
27 | m = scanner.nextInt();
28 | int[] starts = new int[n];
29 | int[] ends = new int[n];
30 | int[] points = new int[m];
31 | for (int i = 0; i < n; i++) {
32 | starts[i] = scanner.nextInt();
33 | ends[i] = scanner.nextInt();
34 | }
35 | for (int i = 0; i < m; i++) {
36 | points[i] = scanner.nextInt();
37 | }
38 | // use fastCountSegments
39 | int[] cnt = naiveCountSegments(starts, ends, points);
40 | for (int x : cnt) {
41 | System.out.print(x + " ");
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_4/03_divide_and_conquer_starter_files_20160804/points_and_segments/points_and_segments.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | using std::vector;
5 |
6 | vector fast_count_segments(vector starts, vector ends, vector points) {
7 | vector cnt(points.size());
8 | //write your code here
9 | return cnt;
10 | }
11 |
12 | vector naive_count_segments(vector starts, vector ends, vector points) {
13 | vector cnt(points.size());
14 | for (size_t i = 0; i < points.size(); i++) {
15 | for (size_t j = 0; j < starts.size(); j++) {
16 | cnt[i] += starts[j] <= points[i] && points[i] <= ends[j];
17 | }
18 | }
19 | return cnt;
20 | }
21 |
22 | int main() {
23 | int n, m;
24 | std::cin >> n >> m;
25 | vector starts(n), ends(n);
26 | for (size_t i = 0; i < starts.size(); i++) {
27 | std::cin >> starts[i] >> ends[i];
28 | }
29 | vector points(m);
30 | for (size_t i = 0; i < points.size(); i++) {
31 | std::cin >> points[i];
32 | }
33 | //use fast_count_segments
34 | vector cnt = naive_count_segments(starts, ends, points);
35 | for (size_t i = 0; i < cnt.size(); i++) {
36 | std::cout << cnt[i] << ' ';
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_4/03_divide_and_conquer_starter_files_20160804/points_and_segments/points_and_segments.py:
--------------------------------------------------------------------------------
1 | # Uses python3
2 | import sys
3 | from itertools import chain
4 |
5 |
6 | def fast_count_segments(starts, ends, points):
7 | cnt = [0] * len(points)
8 | start_points = zip(starts, ['l'] * len(starts), range(len(starts)))
9 | end_points = zip(ends, ['r'] * len(ends), range(len(ends)))
10 | point_points = zip(points, ['p'] * len(points), range(len(points)))
11 |
12 | sort_list = chain(start_points, end_points, point_points)
13 | sort_list = sorted(sort_list, key=lambda a: (a[0], a[1]))
14 | segment = 0
15 | i = 0
16 | for num, letter, index in sort_list:
17 | if letter == 'l':
18 | segment += 1
19 | elif letter == 'r':
20 | segment -= 1
21 | else:
22 | cnt[index] = segment
23 | i += 1
24 | return cnt
25 |
26 |
27 | def naive_count_segments(starts, ends, points):
28 | cnt = [0] * len(points)
29 | for i in range(len(points)):
30 | for j in range(len(starts)):
31 | if starts[j] <= points[i] <= ends[j]:
32 | cnt[i] += 1
33 | return cnt
34 |
35 |
36 | if __name__ == '__main__':
37 | input = sys.stdin.read()
38 | data = list(map(int, input.split()))
39 | n = data[0]
40 | m = data[1]
41 | starts = data[2:2 * n + 2:2]
42 | ends = data[3:2 * n + 2:2]
43 | points = data[2 * n + 2:]
44 | # use fast_count_segments
45 | cnt = fast_count_segments(starts, ends, points)
46 | for x in cnt:
47 | print(x, end=' ')
48 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_4/03_divide_and_conquer_starter_files_20160804/sorting/Sorting.java:
--------------------------------------------------------------------------------
1 | import java.io.*;
2 | import java.util.*;
3 |
4 | public class Sorting {
5 | private static Random random = new Random();
6 |
7 | private static int[] partition3(int[] a, int l, int r) {
8 | int m1 = l;
9 | int m2 = r;
10 | int i = l;
11 | int x = a[l];
12 | int[] m = { m1, m2 };
13 |
14 | while (i <= m2) {
15 | if (a[i] < x) {
16 | int temp = a[m1];
17 | a[m1] = a[i];
18 | a[i] = temp;
19 | m1++;
20 | i++;
21 | } else if (a[i] == x) {
22 | i++;
23 | } else {
24 | int temp = a[m2];
25 | a[m2] = a[i];
26 | a[i] = temp;
27 | m2--;
28 | }
29 | m[0] = m1;
30 | m[1] = m2;
31 | }
32 |
33 | return m;
34 | }
35 |
36 | private static int partition2(int[] a, int l, int r) {
37 | int x = a[l];
38 | int j = l;
39 | for (int i = l + 1; i <= r; i++) {
40 | if (a[i] <= x) {
41 | j++;
42 | int t = a[i];
43 | a[i] = a[j];
44 | a[j] = t;
45 | }
46 | }
47 | int t = a[l];
48 | a[l] = a[j];
49 | a[j] = t;
50 | return j;
51 | }
52 |
53 | private static void randomizedQuickSort(int[] a, int l, int r) {
54 | if (l >= r) {
55 | return;
56 | }
57 | int k = random.nextInt(r - l + 1) + l;
58 | int t = a[l];
59 | a[l] = a[k];
60 | a[k] = t;
61 | int[] m = partition3(a, l, r);
62 | randomizedQuickSort(a, l, m[0] - 1);
63 | randomizedQuickSort(a, m[1] + 1, r);
64 | }
65 |
66 | public static void main(String[] args) {
67 | FastScanner scanner = new FastScanner(System.in);
68 | int n = scanner.nextInt();
69 | int[] a = new int[n];
70 | for (int i = 0; i < n; i++) {
71 | a[i] = scanner.nextInt();
72 | }
73 | randomizedQuickSort(a, 0, n - 1);
74 | for (int i = 0; i < n; i++) {
75 | System.out.print(a[i] + " ");
76 | }
77 | }
78 |
79 | static class FastScanner {
80 | BufferedReader br;
81 | StringTokenizer st;
82 |
83 | FastScanner(InputStream stream) {
84 | try {
85 | br = new BufferedReader(new InputStreamReader(stream));
86 | } catch (Exception e) {
87 | e.printStackTrace();
88 | }
89 | }
90 |
91 | String next() {
92 | while (st == null || !st.hasMoreTokens()) {
93 | try {
94 | st = new StringTokenizer(br.readLine());
95 | } catch (IOException e) {
96 | e.printStackTrace();
97 | }
98 | }
99 | return st.nextToken();
100 | }
101 |
102 | int nextInt() {
103 | return Integer.parseInt(next());
104 | }
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_4/03_divide_and_conquer_starter_files_20160804/sorting/sorting.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | using std::vector;
6 | using std::swap;
7 |
8 | vector quick_sort_partition3(vector &a, int l, int r) {
9 | int x = a[l];
10 | int p_l = l;
11 | int i = l;
12 | int p_e = r;
13 | vector m(2);
14 | while (i <= p_e) {
15 | if (a[i] < x) {
16 | swap(a[p_l], a[i]);
17 | p_l++;
18 | i++;
19 | } else if (a[i] == x) {
20 | i++;
21 | } else {
22 | swap(a[i], a[p_e]);
23 | p_e -= 1;
24 | }
25 | m[0] = p_l;
26 | m[1] = p_e;
27 | }
28 | return m;
29 | }
30 |
31 | int partition2(vector &a, int l, int r) {
32 | int x = a[l];
33 | int j = l;
34 | for (int i = l + 1; i <= r; i++) {
35 | if (a[i] <= x) {
36 | j++;
37 | swap(a[i], a[j]);
38 | }
39 | }
40 | swap(a[l], a[j]);
41 | return j;
42 | }
43 |
44 | void randomized_quick_sort(vector &a, int l, int r) {
45 | if (l >= r) {
46 | return;
47 | }
48 |
49 | int k = l + rand() % (r - l + 1);
50 | swap(a[l], a[k]);
51 | vector m = quick_sort_partition3(a, l, r);
52 |
53 | randomized_quick_sort(a, l, m[0] - 1);
54 | randomized_quick_sort(a, m[1] + 1, r);
55 | }
56 |
57 | int main() {
58 | int n;
59 | std::cin >> n;
60 | vector a(n);
61 | for (size_t i = 0; i < a.size(); ++i) {
62 | std::cin >> a[i];
63 | }
64 | randomized_quick_sort(a, 0, a.size() - 1);
65 | for (size_t i = 0; i < a.size(); ++i) {
66 | std::cout << a[i] << ' ';
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_4/03_divide_and_conquer_starter_files_20160804/sorting/sorting.py:
--------------------------------------------------------------------------------
1 | # Uses python3
2 | import sys
3 | import random
4 |
5 |
6 | def partition3(a, left, right):
7 | pivot_value = a[left]
8 | p_l = i = left
9 | p_e = right
10 | while i <= p_e:
11 | if a[i] < pivot_value:
12 | a[i], a[p_l] = a[p_l], a[i]
13 | p_l += 1
14 | i += 1
15 | elif a[i] == pivot_value:
16 | i += 1
17 | else:
18 | a[i], a[p_e] = a[p_e], a[i]
19 | p_e -= 1
20 | pIndexes = [p_l, p_e]
21 | return pIndexes
22 |
23 |
24 | def partition2(a, left, right):
25 | pivot = random.randint(left, right)
26 | a[right], a[pivot] = a[pivot], a[right]
27 | pivot_value = a[right]
28 | pIndex = left
29 | for i in range(left, right):
30 | if a[i] <= pivot_value:
31 | a[i], a[pIndex] = a[pIndex], a[i]
32 | pIndex += 1
33 | a[right], a[pIndex] = a[pIndex], a[right]
34 | return pIndex
35 |
36 |
37 | def randomized_quick_sort(a, left, right):
38 | if left >= right:
39 | return
40 |
41 | pivot = random.randint(left, right)
42 | a[left], a[pivot] = a[pivot], a[left]
43 | pIndex = partition3(a, left, right)
44 | randomized_quick_sort(a, left, pIndex[0] - 1)
45 | randomized_quick_sort(a, pIndex[1] + 1, right)
46 |
47 |
48 | if __name__ == '__main__':
49 | input = sys.stdin.read()
50 | n, *a = list(map(int, input.split()))
51 | randomized_quick_sort(a, 0, n - 1)
52 | for x in a:
53 | print(x, end=' ')
54 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_5/04_dynamic_programming_problems.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mablatnik/Algorithmic-Toolbox/5d79938e2f2d97f2100f4555e2ac2f2b79f8f36f/algorithmic_toolbox/week_5/04_dynamic_programming_problems.pdf
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_5/04_dynamic_programming_starter_files/edit_distance/EditDistance.java:
--------------------------------------------------------------------------------
1 | import java.util.*;
2 |
3 | class EditDistance {
4 | public static int EditDistance(String s, String t) {
5 | //write your code here
6 | return 0;
7 | }
8 | public static void main(String args[]) {
9 | Scanner scan = new Scanner(System.in);
10 |
11 | String s = scan.next();
12 | String t = scan.next();
13 |
14 | System.out.println(EditDistance(s, t));
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_5/04_dynamic_programming_starter_files/edit_distance/edit_distance.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | using std::string;
5 |
6 | int edit_distance(const string &str1, const string &str2) {
7 | //write your code here
8 | return 0;
9 | }
10 |
11 | int main() {
12 | string str1;
13 | string str2;
14 | std::cin >> str1 >> str2;
15 | std::cout << edit_distance(str1, str2) << std::endl;
16 | return 0;
17 | }
18 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_5/04_dynamic_programming_starter_files/edit_distance/edit_distance.py:
--------------------------------------------------------------------------------
1 | # Uses python3
2 | def edit_distance(s, t):
3 | #write your code here
4 | return 0
5 |
6 | if __name__ == "__main__":
7 | print(edit_distance(input(), input()))
8 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_5/04_dynamic_programming_starter_files/knapsack/Knapsack.java:
--------------------------------------------------------------------------------
1 | import java.util.*;
2 |
3 | public class Knapsack {
4 | static int optimalWeight(int W, int[] w) {
5 | int num_items = 0;
6 | for (int item : w) {
7 | if (item <= W)
8 | num_items++;
9 | }
10 | int[] items = new int[num_items];
11 | int index = 0;
12 | for (int i = 0; i < w.length - 1; i++) {
13 | if (w[i] <= W) {
14 | items[index] = w[i];
15 | index++;
16 | }
17 | }
18 |
19 | int capacity = W + 1;
20 |
21 | int K[][] = new int[items.length + 1][capacity];
22 |
23 | for (int col = 0; col <= W; col++) {
24 | K[0][col] = 0;
25 | }
26 |
27 | for (int row = 0; row <= items.length; row++) {
28 | K[row][0] = 0;
29 | }
30 |
31 | for (int item = 1; item <= items.length; item++) {
32 | for (int weight = 1; weight <= W; weight++) {
33 | if (items[item - 1] <= weight) {
34 | K[item][weight] = Math.max(items[item - 1] + K[item - 1][weight - items[item - 1]],
35 | K[item - 1][weight]);
36 | } else {
37 | K[item][weight] = K[item - 1][weight];
38 | }
39 | }
40 | }
41 | return K[items.length + 1][capacity];
42 | }
43 |
44 | public static void main(String[] args) {
45 | Scanner scanner = new Scanner(System.in);
46 | int W, n;
47 | W = scanner.nextInt();
48 | n = scanner.nextInt();
49 | int[] w = new int[n];
50 | for (int i = 0; i < n; i++) {
51 | w[i] = scanner.nextInt();
52 | }
53 | System.out.println(optimalWeight(W, w));
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_5/04_dynamic_programming_starter_files/knapsack/knapsack.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | using std::vector;
5 |
6 | int optimal_weight(int W, const vector &w) {
7 | //write your code here
8 | int current_weight = 0;
9 | for (size_t i = 0; i < w.size(); ++i) {
10 | if (current_weight + w[i] <= W) {
11 | current_weight += w[i];
12 | }
13 | }
14 | return current_weight;
15 | }
16 |
17 | int main() {
18 | int n, W;
19 | std::cin >> W >> n;
20 | vector w(n);
21 | for (int i = 0; i < n; i++) {
22 | std::cin >> w[i];
23 | }
24 | std::cout << optimal_weight(W, w) << '\n';
25 | }
26 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_5/04_dynamic_programming_starter_files/knapsack/knapsack.py:
--------------------------------------------------------------------------------
1 | # Uses python3
2 | import sys
3 |
4 |
5 | def optimal_weight(W, w):
6 | items = [0]
7 | for item in w:
8 | if item <= W:
9 | items.append(item)
10 |
11 | item_length = len(items)
12 | capacity = W + 1
13 |
14 | weights = [[0 for _ in range(item_length)] for _ in range(capacity)]
15 |
16 | for j in range(1, item_length):
17 | for i in range(1, capacity):
18 | previous = weights[i][j - 1]
19 | current = items[j] + weights[i - items[j]][j - 1]
20 | if current > i:
21 | weights[i][j] = previous
22 | else:
23 | weights[i][j] = max(previous, current)
24 |
25 | return weights[-1][-1]
26 |
27 |
28 | if __name__ == '__main__':
29 | input = sys.stdin.read()
30 | W, n, *w = list(map(int, input.split()))
31 | print(optimal_weight(W, w))
32 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_5/04_dynamic_programming_starter_files/lcs3/LCS3.java:
--------------------------------------------------------------------------------
1 | import java.util.*;
2 |
3 | public class LCS3 {
4 |
5 | private static int lcs3(int[] a, int[] b, int[] c) {
6 | //Write your code here
7 | return Math.min(Math.min(a.length, b.length), c.length);
8 | }
9 |
10 | public static void main(String[] args) {
11 | Scanner scanner = new Scanner(System.in);
12 | int an = scanner.nextInt();
13 | int[] a = new int[an];
14 | for (int i = 0; i < an; i++) {
15 | a[i] = scanner.nextInt();
16 | }
17 | int bn = scanner.nextInt();
18 | int[] b = new int[bn];
19 | for (int i = 0; i < bn; i++) {
20 | b[i] = scanner.nextInt();
21 | }
22 | int cn = scanner.nextInt();
23 | int[] c = new int[cn];
24 | for (int i = 0; i < cn; i++) {
25 | c[i] = scanner.nextInt();
26 | }
27 | System.out.println(lcs3(a, b, c));
28 | }
29 | }
30 |
31 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_5/04_dynamic_programming_starter_files/lcs3/lcs3.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | using std::vector;
5 |
6 | int lcs3(vector &a, vector &b, vector &c) {
7 | //write your code here
8 | return std::min(std::min(a.size(), b.size()), c.size());
9 | }
10 |
11 | int main() {
12 | size_t an;
13 | std::cin >> an;
14 | vector a(an);
15 | for (size_t i = 0; i < an; i++) {
16 | std::cin >> a[i];
17 | }
18 | size_t bn;
19 | std::cin >> bn;
20 | vector b(bn);
21 | for (size_t i = 0; i < bn; i++) {
22 | std::cin >> b[i];
23 | }
24 | size_t cn;
25 | std::cin >> cn;
26 | vector c(cn);
27 | for (size_t i = 0; i < cn; i++) {
28 | std::cin >> c[i];
29 | }
30 | std::cout << lcs3(a, b, c) << std::endl;
31 | }
32 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_5/04_dynamic_programming_starter_files/lcs3/lcs3.py:
--------------------------------------------------------------------------------
1 | #Uses python3
2 |
3 | import sys
4 |
5 | def lcs3(a, b, c):
6 | #write your code here
7 | return min(len(a), len(b), len(c))
8 |
9 | if __name__ == '__main__':
10 | input = sys.stdin.read()
11 | data = list(map(int, input.split()))
12 | an = data[0]
13 | data = data[1:]
14 | a = data[:an]
15 | data = data[an:]
16 | bn = data[0]
17 | data = data[1:]
18 | b = data[:bn]
19 | data = data[bn:]
20 | cn = data[0]
21 | data = data[1:]
22 | c = data[:cn]
23 | print(lcs3(a, b, c))
24 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_5/04_dynamic_programming_starter_files/placing_parentheses/PlacingParentheses.java:
--------------------------------------------------------------------------------
1 | import java.util.Scanner;
2 |
3 | public class PlacingParentheses {
4 | private static long getMaximValue(String exp) {
5 | //write your code here
6 | return 0;
7 | }
8 |
9 | private static long eval(long a, long b, char op) {
10 | if (op == '+') {
11 | return a + b;
12 | } else if (op == '-') {
13 | return a - b;
14 | } else if (op == '*') {
15 | return a * b;
16 | } else {
17 | assert false;
18 | return 0;
19 | }
20 | }
21 |
22 | public static void main(String[] args) {
23 | Scanner scanner = new Scanner(System.in);
24 | String exp = scanner.next();
25 | System.out.println(getMaximValue(exp));
26 | }
27 | }
28 |
29 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_5/04_dynamic_programming_starter_files/placing_parentheses/placing_parentheses.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | using std::vector;
7 | using std::string;
8 | using std::max;
9 | using std::min;
10 |
11 | long long eval(long long a, long long b, char op) {
12 | if (op == '*') {
13 | return a * b;
14 | } else if (op == '+') {
15 | return a + b;
16 | } else if (op == '-') {
17 | return a - b;
18 | } else {
19 | assert(0);
20 | }
21 | }
22 |
23 | long long get_maximum_value(const string &exp) {
24 | //write your code here
25 | return 0;
26 | }
27 |
28 | int main() {
29 | string s;
30 | std::cin >> s;
31 | std::cout << get_maximum_value(s) << '\n';
32 | }
33 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_5/04_dynamic_programming_starter_files/placing_parentheses/placing_parentheses.py:
--------------------------------------------------------------------------------
1 | # Uses python3
2 | def evalt(a, b, op):
3 | if op == '+':
4 | return a + b
5 | elif op == '-':
6 | return a - b
7 | elif op == '*':
8 | return a * b
9 | else:
10 | assert False
11 |
12 | def get_maximum_value(dataset):
13 | #write your code here
14 | return 0
15 |
16 |
17 | if __name__ == "__main__":
18 | print(get_maximum_value(input()))
19 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_5/04_dynamic_programming_starter_files/primitive_calculator/PrimitiveCalculator.java:
--------------------------------------------------------------------------------
1 | import java.util.*;
2 |
3 | public class PrimitiveCalculator {
4 | private static List optimal_sequence(int n) {
5 | List sequence = new ArrayList();
6 | while (n >= 1) {
7 | sequence.add(n);
8 | if (n % 3 == 0) {
9 | n /= 3;
10 | } else if (n % 2 == 0) {
11 | n /= 2;
12 | } else {
13 | n -= 1;
14 | }
15 | }
16 | Collections.reverse(sequence);
17 | return sequence;
18 | }
19 |
20 | private static List dynamic_sequence(int n) {
21 | int[] a = new int[n + 1];
22 | int[] predecessor = new int[n + 1];
23 |
24 | for (int i = 2; i <= n; i++) {
25 | a[i] = a[i - 1] + 1;
26 | predecessor[i] = i - 1;
27 | if (i % 3 == 0) {
28 | if (a[i / 3] < a[i]) {
29 | a[i] = a[i / 3] + 1;
30 | predecessor[i] = i / 3;
31 | }
32 | }
33 | if (i % 2 == 0) {
34 | if (a[i / 2] < a[i]) {
35 | a[i] = a[i / 2] + 1;
36 | predecessor[i] = i / 2;
37 | }
38 | }
39 | }
40 |
41 | ArrayList sequence = new ArrayList();
42 |
43 | for (int i = n; i != 0; i = predecessor[i]) {
44 | sequence.add(i);
45 | }
46 |
47 | Collections.reverse(sequence);
48 | return sequence;
49 | }
50 |
51 | public static void main(String[] args) {
52 | Scanner scanner = new Scanner(System.in);
53 | int n = scanner.nextInt();
54 | List sequence = dynamic_sequence(n);
55 | System.out.println(sequence.size() - 1);
56 | for (Integer x : sequence) {
57 | System.out.print(x + " ");
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_5/04_dynamic_programming_starter_files/primitive_calculator/primitive_calculator.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | using std::vector;
7 | using std::min;
8 |
9 | vector optimal_sequence(int n) {
10 | std::vector sequence;
11 | while (n >= 1) {
12 | sequence.push_back(n);
13 | if (n % 3 == 0) {
14 | n /= 3;
15 | } else if (n % 2 == 0) {
16 | n /= 2;
17 | } else {
18 | n = n - 1;
19 | }
20 | }
21 | reverse(sequence.begin(), sequence.end());
22 | return sequence;
23 | }
24 |
25 | vector dynamic_sequence(int n) {
26 | vector a(n+1);
27 | vector count_index;
28 | vector sequence;
29 | vector option_list;
30 |
31 | a[1] = 1;
32 | for(int i=2; i> n;
70 | vector sequence = dynamic_sequence(n);
71 | std::cout << sequence.size() - 1 << std::endl;
72 | for (size_t i = 0; i < sequence.size(); ++i) {
73 | std::cout << sequence[i] << " ";
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_5/04_dynamic_programming_starter_files/primitive_calculator/primitive_calculator.py:
--------------------------------------------------------------------------------
1 | # Uses python3
2 | import sys
3 |
4 |
5 | def optimal_sequence(n):
6 | sequence = []
7 | while n >= 1:
8 | sequence.append(n)
9 | if n % 3 == 0:
10 | n //= 3
11 | elif n % 2 == 0:
12 | n //= 2
13 | else:
14 | n = n - 1
15 | return reversed(sequence)
16 |
17 |
18 | def dynamic_sequence(n):
19 | operations_count = [0] * (n + 1)
20 |
21 | operations_count[1] = 1
22 | for i in range(2, n + 1):
23 | count_index = [i - 1]
24 | if i % 2 == 0:
25 | count_index.append(i // 2)
26 | if i % 3 == 0:
27 | count_index.append(i // 3)
28 |
29 | min_count = min([operations_count[x] for x in count_index])
30 | operations_count[i] = min_count + 1
31 |
32 | current_value = n
33 | value_trail = [current_value]
34 | while current_value != 1:
35 | option_list = [current_value - 1]
36 | if current_value % 2 == 0:
37 | option_list.append(current_value // 2)
38 | if current_value % 3 == 0:
39 | option_list.append(current_value // 3)
40 |
41 | current_value = min(
42 | [(c, operations_count[c]) for c in option_list],
43 | key=lambda x: x[1]
44 | )[0]
45 | value_trail.append(current_value)
46 | return reversed(value_trail)
47 |
48 |
49 | input = sys.stdin.read()
50 | n = int(input)
51 | sequence = list(dynamic_sequence(n))
52 | print(len(sequence) - 1)
53 | for x in sequence:
54 | print(x, end=' ')
55 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_5/04_dynamic_programming_starter_files/primitive_calculator/primitive_calculator2.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | using std::vector;
6 | using std::min;
7 |
8 | vector optimal_sequence(int n) {
9 | std::vector sequence;
10 | while (n >= 1) {
11 | sequence.push_back(n);
12 | if (n % 3 == 0) {
13 | n /= 3;
14 | } else if (n % 2 == 0) {
15 | n /= 2;
16 | } else {
17 | n = n - 1;
18 | }
19 | }
20 | reverse(sequence.begin(), sequence.end());
21 | return sequence;
22 | }
23 |
24 | vector dynamic_sequence(int n) {
25 | vector sequence;
26 | vector a(n+1);
27 |
28 | a[0] = 0;
29 | for(int i=1; i 1) {
38 | sequence.push_back(i);
39 | if (a[i-1] == a[i] -1)
40 | i = i-1;
41 | else if (i%2 && (a[i/2] == a[i] -1))
42 | i = i/2;
43 | else if (i%3 && (a[i/3] == a[i] -1))
44 | i = i/3;
45 | }
46 | sequence.push_back(1);
47 | reverse(sequence.begin(), sequence.end());
48 | return sequence;
49 | }
50 |
51 | int main() {
52 | int n;
53 | std::cin >> n;
54 | vector sequence = dynamic_sequence(n);
55 | std::cout << sequence.size() - 1 << std::endl;
56 | for (size_t i = 0; i < sequence.size(); ++i) {
57 | std::cout << sequence[i] << " ";
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/algorithmic_toolbox/week_5/04_dynamic_programming_starter_files/primitive_calculator/primitive_calculator3.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | using std::vector;
6 | using std::min;
7 |
8 | vector optimal_sequence(int n) {
9 | std::vector sequence;
10 | while (n >= 1) {
11 | sequence.push_back(n);
12 | if (n % 3 == 0) {
13 | n /= 3;
14 | } else if (n % 2 == 0) {
15 | n /= 2;
16 | } else {
17 | n = n - 1;
18 | }
19 | }
20 | reverse(sequence.begin(), sequence.end());
21 | return sequence;
22 | }
23 |
24 | vector dynamic_sequence(int n) {
25 | vector a(n+1);
26 | vector predecessor(n+1);
27 |
28 | for (int i = 2; i <= n; i++) {
29 | a[i] = a[i-1] + 1;
30 | predecessor[i] = i - 1;
31 | if (i % 3 == 0) {
32 | if (a[i/3] < a[i]) {
33 | a[i] = a[i/3] + 1;
34 | predecessor[i] = i/3;
35 | }
36 | }
37 | if (i % 2 == 0) {
38 | if (a[i/2] < a[i]) {
39 | a[i] = a[i/2] + 1;
40 | predecessor[i] = i/2;
41 | }
42 | }
43 | }
44 |
45 | vector sequence;
46 |
47 | for (int i = n; i !=0; i = predecessor[i]) {
48 | sequence.push_back(i);
49 | }
50 | reverse(sequence.begin(), sequence.end());
51 | return sequence;
52 | }
53 |
54 | int main() {
55 | int n;
56 | std::cin >> n;
57 | vector sequence = dynamic_sequence(n);
58 | std::cout << sequence.size() - 1 << std::endl;
59 | for (size_t i = 0; i < sequence.size(); ++i) {
60 | std::cout << sequence[i] << " ";
61 | }
62 | }
63 |
--------------------------------------------------------------------------------