├── .gitignore ├── Readme.md ├── competitive-programming ├── 1-implementation │ ├── advanced-programming-spring-week1.pdf │ └── minesweeper │ │ ├── solution │ │ ├── Main.java │ │ ├── Minesweeper.in │ │ └── gen.py │ │ └── template │ │ ├── Main.java │ │ └── Minesweeper.in ├── 2-complete-search │ ├── advanced-programming-spring-week2.pdf │ ├── simple-eqs │ │ ├── solution │ │ │ ├── Main.java │ │ │ ├── main.cpp │ │ │ ├── test.in │ │ │ └── test.out │ │ └── template │ │ │ ├── Main.java │ │ │ ├── test.in │ │ │ └── test.out │ └── sum-it-up │ │ ├── solution │ │ ├── Main.java │ │ ├── test.in │ │ └── test.out │ │ └── templates │ │ ├── Main.java │ │ ├── test.in │ │ └── test.out ├── 3-divide-and-conquer │ ├── advanced-programming-spring-week3.pdf │ ├── exact-sum │ │ ├── solution │ │ │ ├── Main.java │ │ │ └── test.in │ │ └── template │ │ │ ├── Main.java │ │ │ └── test.in │ ├── merge-sort │ │ ├── solution │ │ │ ├── Main.java │ │ │ └── sort.in │ │ └── template │ │ │ ├── Main.java │ │ │ └── sort.in │ └── solve-it │ │ ├── solution │ │ ├── Main.java │ │ └── test.in │ │ ├── template │ │ ├── Main.java │ │ └── test.in │ │ └── test.in ├── 4-greedy-dynamic-programming │ ├── advanced-programming-spring-week4.pdf │ ├── bridge │ │ ├── Main.java │ │ └── bridge.in │ ├── discrete-knapsack │ │ ├── solution │ │ │ ├── Main.java │ │ │ └── test.in │ │ └── template │ │ │ ├── Main.java │ │ │ └── test.in │ ├── fractional-knapsack │ │ ├── solution │ │ │ ├── Main.java │ │ │ └── test.in │ │ └── template │ │ │ ├── Main.java │ │ │ └── test.in │ ├── max-sum-2D │ │ ├── Main.java │ │ └── test.in │ ├── scarecrow │ │ ├── Main.java │ │ └── test.in │ └── shoemaker │ │ ├── Main.java │ │ └── test.in ├── 5-graphs │ ├── advanced-programming-spring-week-56.pdf │ ├── solutions │ │ ├── Dijkstra.java │ │ ├── GraphLib.java │ │ ├── Mst.java │ │ ├── Topo.java │ │ ├── Traversals.java │ │ ├── din.dot │ │ ├── in.dot │ │ └── uin.dot │ └── templates │ │ ├── Dijkstra.java │ │ ├── GraphLib.java │ │ ├── Mst.java │ │ ├── Topo.java │ │ ├── Traversals.java │ │ ├── din.dot │ │ ├── in.dot │ │ └── uin.dot ├── 6-geometry │ ├── advanced-programming-spring-week7.pdf │ ├── area │ │ ├── solution │ │ │ ├── Main.java │ │ │ └── test.in │ │ └── template │ │ │ ├── Main.java │ │ │ └── test.in │ └── convex-hull │ │ ├── solution │ │ ├── Main.java │ │ └── hull.in │ │ └── template │ │ ├── Main.java │ │ └── hull.in ├── 7-maths │ ├── advanced-programming-spring-week8.pdf │ ├── solutions │ │ ├── Fib.java │ │ ├── Gauss.java │ │ └── Sieve.java │ └── templates │ │ ├── Fib.java │ │ ├── Gauss.java │ │ ├── Sieve.java │ │ └── gauss.in └── readme.md └── performance-aware-programming ├── Readme.md ├── img ├── algorithms.jpg ├── cache1.png ├── cache2.png ├── cache3.png ├── cache4.png ├── cache5.png ├── cache6.png ├── java.png ├── loop-interchange.png ├── matrix-multiply.png ├── matrix_mult.png ├── no-idea.jpg ├── no-questions.jpg ├── overlapping.png ├── right.jpg ├── skiena.jpg ├── slow.jpg └── vectorization.png ├── lecture1.md ├── lecture2.md ├── lecture3.md ├── lecture4.md └── src ├── lecture1 ├── Measuring.java ├── Readme.md ├── matrix_mult.sh └── plot.gnuplot ├── lecture2 ├── Main.java ├── Readme.md ├── run.exp ├── run.sh └── test.in ├── lecture3 └── Measuring.java └── lecture4 ├── Main.java ├── PiEstimator.java ├── Point.java ├── Readme.md └── Threads.java /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | a.out 3 | tmp.out 4 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | This is a collection of short (4 - 8 hours) courses I taught/teach at 2 | Imperial as part of the optional, first year Advanced Programming 3 | Lectures. 4 | 5 | `competitive-programming` is a gentle introduction to competitive 6 | programming, covering a few of the most basic algorithms and 7 | implementations tips. This can serve as a first stage of preparation 8 | for some coding interviews. 9 | 10 | `performance-aware-programming` is a short teaser course highlighting 11 | some of the concepts we need to be aware of when optimising the 12 | performance of our programs. 13 | 14 | Both courses come with Java based examples and with a bit of 15 | python/bash/gnuplot scripting (where needed). 16 | -------------------------------------------------------------------------------- /competitive-programming/1-implementation/advanced-programming-spring-week1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paul-g/brabble/a6b88e528d2e7222e41924a136797e9c55903598/competitive-programming/1-implementation/advanced-programming-spring-week1.pdf -------------------------------------------------------------------------------- /competitive-programming/1-implementation/minesweeper/solution/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | 4 | public class Main { 5 | 6 | static Scanner sc = new Scanner(System.in); 7 | 8 | public static void main(String[] args) { 9 | for (int field = 1;;field++) { 10 | int n = sc.nextInt(); 11 | int m = sc.nextInt(); 12 | if ( n == 0 && m == 0 ) break; 13 | sc.nextLine(); 14 | 15 | if (field != 1) 16 | System.out.println(); 17 | System.out.println("Field #" + field +":"); 18 | solve(n, m); 19 | } 20 | sc.close(); 21 | } 22 | 23 | public static void solve(int n, int m) { 24 | int count[][] = new int[n][m]; 25 | for (int i = 0; i < n; i++) { 26 | char[] line = sc.nextLine().toCharArray(); 27 | for (int j = 0; j < m; j++) { 28 | if ( line[j] != '*' ) 29 | continue; 30 | for (int l = i - 1; l <= i + 1 && l < n; l++) 31 | for (int c = j - 1; c <= j + 1 && c < m; c++) 32 | if (l >= 0 && c >= 0 && count[l][c] != -1) 33 | count[l][c]++; 34 | count[i][j] = -1; 35 | } 36 | } 37 | 38 | for (int i = 0; i < n; i++) { 39 | for (int j = 0; j < m; j++) 40 | System.out.print(count[i][j] == -1 ? "*" : count[i][j]); 41 | System.out.println(); 42 | } 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /competitive-programming/1-implementation/minesweeper/solution/Minesweeper.in: -------------------------------------------------------------------------------- 1 | 4 4 2 | *... 3 | .... 4 | .*.. 5 | .... 6 | 3 5 7 | **... 8 | ..... 9 | .*... 10 | 0 0 -------------------------------------------------------------------------------- /competitive-programming/1-implementation/minesweeper/solution/gen.py: -------------------------------------------------------------------------------- 1 | import sys, random 2 | 3 | MAX_N = 10 4 | 5 | print '{} {}'.format(MAX_N, MAX_N) 6 | 7 | for i in range(MAX_N): 8 | for j in range(MAX_N): 9 | sys.stdout.write('.' if random.randint(0, 1) == 1 else '*') 10 | print '' 11 | 12 | print '0 0' 13 | -------------------------------------------------------------------------------- /competitive-programming/1-implementation/minesweeper/template/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | 4 | public class Main { 5 | 6 | public static void main(String[] args) { 7 | } 8 | 9 | public static void solve(int n, int m) { 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /competitive-programming/1-implementation/minesweeper/template/Minesweeper.in: -------------------------------------------------------------------------------- 1 | 4 4 2 | *... 3 | .... 4 | .*.. 5 | .... 6 | 3 5 7 | **... 8 | ..... 9 | .*... 10 | 0 0 -------------------------------------------------------------------------------- /competitive-programming/2-complete-search/advanced-programming-spring-week2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paul-g/brabble/a6b88e528d2e7222e41924a136797e9c55903598/competitive-programming/2-complete-search/advanced-programming-spring-week2.pdf -------------------------------------------------------------------------------- /competitive-programming/2-complete-search/simple-eqs/solution/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | 4 | import static java.lang.Math.*; 5 | import static java.lang.System.out; 6 | 7 | public class Main { 8 | 9 | static int a, b, c; 10 | 11 | public static void main (String [] args) throws Exception { 12 | Scanner sc = new Scanner(System.in); 13 | sc.nextInt(); // skip number of tests 14 | while ( sc.hasNext() ) { 15 | a = sc.nextInt(); 16 | b = sc.nextInt(); 17 | c = sc.nextInt(); 18 | solve(); 19 | } 20 | } 21 | 22 | public static void solve() { 23 | int bound = 34; 24 | for (int x = -bound; x <= bound; x++) { 25 | for (int y = x + 1; y <= bound; y++) { 26 | int z = a - x - y; 27 | if ( y != z && z != x && 28 | x * y * z == b && 29 | x * x + y * y + z * z == c) { 30 | int min = min(x, min(y, z)); 31 | int max = max(x, max(y, z)); 32 | int mid = a - min - max; 33 | out.printf("%d %d %d\n", min, mid, max); 34 | return; 35 | } 36 | } 37 | } 38 | out.println("No solution."); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /competitive-programming/2-complete-search/simple-eqs/solution/main.cpp: -------------------------------------------------------------------------------- 1 | /** This is solution is just for reference. Notice how much faster it 2 | is than the Java version (0.004s vs 0.131s). This is due to JVM 3 | startup time: 4 | http://en.wikipedia.org/wiki/Java_performance#Startup_time */ 5 | 6 | #include 7 | 8 | using namespace std; 9 | 10 | int main() { 11 | 12 | bool found; 13 | int nt, a, b, c; 14 | cin >> nt; 15 | 16 | for (int t = 0; t < nt; t++) { 17 | int bound = 34; 18 | cin >> a >> b >> c; 19 | found = false; 20 | for (int x = -bound; x <= bound && !found; x++) { 21 | for (int y = x + 1; y <= bound && !found; y++) { 22 | int z = a - x - y; 23 | if ( y != z && z != x && 24 | x * y * z == b && 25 | x * x + y * y + z * z == c) { 26 | cout << x << " " << y << " " << z << endl; 27 | found = true; 28 | } 29 | } 30 | } 31 | 32 | if (!found) 33 | cout << "No solution." << endl; 34 | } 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /competitive-programming/2-complete-search/simple-eqs/solution/test.in: -------------------------------------------------------------------------------- 1 | 12 2 | 3 1 3 3 | 1 2 3 4 | 6 6 14 5 | 3 1 3 6 | 4 1 5 7 | 1000 222 333 8 | 191 19 13 9 | 1 1 1 10 | 2 2 2 11 | 10000 10000 10000 12 | 10000 10000 10000 13 | 13 60 65 14 | -------------------------------------------------------------------------------- /competitive-programming/2-complete-search/simple-eqs/solution/test.out: -------------------------------------------------------------------------------- 1 | No solution. 2 | No solution. 3 | 1 2 3 4 | No solution. 5 | No solution. 6 | No solution. 7 | No solution. 8 | No solution. 9 | No solution. 10 | No solution. 11 | No solution. 12 | 2 5 6 13 | -------------------------------------------------------------------------------- /competitive-programming/2-complete-search/simple-eqs/template/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | 4 | import static java.lang.Math.*; 5 | import static java.lang.System.out; 6 | 7 | public class Main { 8 | 9 | static int a, b, c; 10 | 11 | public static void main (String [] args) throws Exception { 12 | Scanner sc = new Scanner(System.in); 13 | sc.nextInt(); // skip number of tests 14 | while ( sc.hasNext() ) { 15 | a = sc.nextInt(); 16 | b = sc.nextInt(); 17 | c = sc.nextInt(); 18 | solve(); 19 | } 20 | } 21 | 22 | public static void solve() { 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /competitive-programming/2-complete-search/simple-eqs/template/test.in: -------------------------------------------------------------------------------- 1 | 12 2 | 3 1 3 3 | 1 2 3 4 | 6 6 14 5 | 3 1 3 6 | 4 1 5 7 | 1000 222 333 8 | 191 19 13 9 | 1 1 1 10 | 2 2 2 11 | 10000 10000 10000 12 | 10000 10000 10000 13 | 13 60 65 14 | -------------------------------------------------------------------------------- /competitive-programming/2-complete-search/simple-eqs/template/test.out: -------------------------------------------------------------------------------- 1 | No solution. 2 | No solution. 3 | 1 2 3 4 | No solution. 5 | No solution. 6 | No solution. 7 | No solution. 8 | No solution. 9 | No solution. 10 | No solution. 11 | No solution. 12 | 2 5 6 13 | -------------------------------------------------------------------------------- /competitive-programming/2-complete-search/sum-it-up/solution/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | import static java.lang.System.out; 4 | 5 | public class Main { 6 | 7 | static int values[], sol[]; 8 | static int pos; 9 | static boolean found; 10 | 11 | public static void main (String [] args) { 12 | Scanner sc = new Scanner(System.in); 13 | while (sc.hasNext()) { 14 | int t = sc.nextInt(); 15 | int n = sc.nextInt(); 16 | if (t == 0 && n == 0) 17 | break; 18 | 19 | values = new int[n]; 20 | sol = new int[n]; 21 | pos = 0; 22 | 23 | for (int i = 0; i < n; i++) 24 | values[i] = sc.nextInt(); 25 | 26 | out.format("Sums of %d:\n", t); 27 | found = false; 28 | 29 | solveRec(0, 0, t); 30 | 31 | if (!found) 32 | out.println("NONE"); 33 | } 34 | 35 | sc.close(); 36 | } 37 | 38 | public static void solveRec(int size, int start, int sum) { 39 | if (sum == 0) { 40 | found = true; 41 | boolean first = true; 42 | for (int i = 0; i < pos; i++, first=false) 43 | out.print(first ? sol[i] : "+" + sol[i]); 44 | out.println(); 45 | } 46 | 47 | if (size == values.length) 48 | return; 49 | 50 | for (int i = start; i < values.length; i++) { 51 | int s = sum - values[i]; 52 | if (s >= 0) { 53 | sol[pos++] = values[i]; 54 | solveRec(size + 1, i + 1, s); 55 | pos--; 56 | int valueUsed = values[i]; 57 | while(i + 1 < values.length && values[i + 1] == valueUsed) i++; 58 | } 59 | } 60 | } 61 | 62 | } 63 | 64 | -------------------------------------------------------------------------------- /competitive-programming/2-complete-search/sum-it-up/solution/test.in: -------------------------------------------------------------------------------- 1 | 4 6 4 3 2 2 1 1 2 | 5 3 2 1 1 3 | 400 12 50 50 50 50 50 50 25 25 25 25 25 25 4 | 1000 25 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 5 | 200 25 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 6 | 0 0 -------------------------------------------------------------------------------- /competitive-programming/2-complete-search/sum-it-up/solution/test.out: -------------------------------------------------------------------------------- 1 | Sums of 4: 2 | 4 3 | 3+1 4 | 2+2 5 | 2+1+1 6 | Sums of 5: 7 | NONE 8 | Sums of 400: 9 | 50+50+50+50+50+50+25+25+25+25 10 | 50+50+50+50+50+25+25+25+25+25+25 11 | Sums of 1000: 12 | NONE 13 | Sums of 200: 14 | 41+42+52+65 15 | 41+42+53+64 16 | 41+42+54+63 17 | 41+42+55+62 18 | 41+42+56+61 19 | 41+42+57+60 20 | 41+42+58+59 21 | 41+43+51+65 22 | 41+43+52+64 23 | 41+43+53+63 24 | 41+43+54+62 25 | 41+43+55+61 26 | 41+43+56+60 27 | 41+43+57+59 28 | 41+44+50+65 29 | 41+44+51+64 30 | 41+44+52+63 31 | 41+44+53+62 32 | 41+44+54+61 33 | 41+44+55+60 34 | 41+44+56+59 35 | 41+44+57+58 36 | 41+45+49+65 37 | 41+45+50+64 38 | 41+45+51+63 39 | 41+45+52+62 40 | 41+45+53+61 41 | 41+45+54+60 42 | 41+45+55+59 43 | 41+45+56+58 44 | 41+46+48+65 45 | 41+46+49+64 46 | 41+46+50+63 47 | 41+46+51+62 48 | 41+46+52+61 49 | 41+46+53+60 50 | 41+46+54+59 51 | 41+46+55+58 52 | 41+46+56+57 53 | 41+47+48+64 54 | 41+47+49+63 55 | 41+47+50+62 56 | 41+47+51+61 57 | 41+47+52+60 58 | 41+47+53+59 59 | 41+47+54+58 60 | 41+47+55+57 61 | 41+48+49+62 62 | 41+48+50+61 63 | 41+48+51+60 64 | 41+48+52+59 65 | 41+48+53+58 66 | 41+48+54+57 67 | 41+48+55+56 68 | 41+49+50+60 69 | 41+49+51+59 70 | 41+49+52+58 71 | 41+49+53+57 72 | 41+49+54+56 73 | 41+50+51+58 74 | 41+50+52+57 75 | 41+50+53+56 76 | 41+50+54+55 77 | 41+51+52+56 78 | 41+51+53+55 79 | 41+52+53+54 80 | 42+43+50+65 81 | 42+43+51+64 82 | 42+43+52+63 83 | 42+43+53+62 84 | 42+43+54+61 85 | 42+43+55+60 86 | 42+43+56+59 87 | 42+43+57+58 88 | 42+44+49+65 89 | 42+44+50+64 90 | 42+44+51+63 91 | 42+44+52+62 92 | 42+44+53+61 93 | 42+44+54+60 94 | 42+44+55+59 95 | 42+44+56+58 96 | 42+45+48+65 97 | 42+45+49+64 98 | 42+45+50+63 99 | 42+45+51+62 100 | 42+45+52+61 101 | 42+45+53+60 102 | 42+45+54+59 103 | 42+45+55+58 104 | 42+45+56+57 105 | 42+46+47+65 106 | 42+46+48+64 107 | 42+46+49+63 108 | 42+46+50+62 109 | 42+46+51+61 110 | 42+46+52+60 111 | 42+46+53+59 112 | 42+46+54+58 113 | 42+46+55+57 114 | 42+47+48+63 115 | 42+47+49+62 116 | 42+47+50+61 117 | 42+47+51+60 118 | 42+47+52+59 119 | 42+47+53+58 120 | 42+47+54+57 121 | 42+47+55+56 122 | 42+48+49+61 123 | 42+48+50+60 124 | 42+48+51+59 125 | 42+48+52+58 126 | 42+48+53+57 127 | 42+48+54+56 128 | 42+49+50+59 129 | 42+49+51+58 130 | 42+49+52+57 131 | 42+49+53+56 132 | 42+49+54+55 133 | 42+50+51+57 134 | 42+50+52+56 135 | 42+50+53+55 136 | 42+51+52+55 137 | 42+51+53+54 138 | 43+44+48+65 139 | 43+44+49+64 140 | 43+44+50+63 141 | 43+44+51+62 142 | 43+44+52+61 143 | 43+44+53+60 144 | 43+44+54+59 145 | 43+44+55+58 146 | 43+44+56+57 147 | 43+45+47+65 148 | 43+45+48+64 149 | 43+45+49+63 150 | 43+45+50+62 151 | 43+45+51+61 152 | 43+45+52+60 153 | 43+45+53+59 154 | 43+45+54+58 155 | 43+45+55+57 156 | 43+46+47+64 157 | 43+46+48+63 158 | 43+46+49+62 159 | 43+46+50+61 160 | 43+46+51+60 161 | 43+46+52+59 162 | 43+46+53+58 163 | 43+46+54+57 164 | 43+46+55+56 165 | 43+47+48+62 166 | 43+47+49+61 167 | 43+47+50+60 168 | 43+47+51+59 169 | 43+47+52+58 170 | 43+47+53+57 171 | 43+47+54+56 172 | 43+48+49+60 173 | 43+48+50+59 174 | 43+48+51+58 175 | 43+48+52+57 176 | 43+48+53+56 177 | 43+48+54+55 178 | 43+49+50+58 179 | 43+49+51+57 180 | 43+49+52+56 181 | 43+49+53+55 182 | 43+50+51+56 183 | 43+50+52+55 184 | 43+50+53+54 185 | 43+51+52+54 186 | 44+45+46+65 187 | 44+45+47+64 188 | 44+45+48+63 189 | 44+45+49+62 190 | 44+45+50+61 191 | 44+45+51+60 192 | 44+45+52+59 193 | 44+45+53+58 194 | 44+45+54+57 195 | 44+45+55+56 196 | 44+46+47+63 197 | 44+46+48+62 198 | 44+46+49+61 199 | 44+46+50+60 200 | 44+46+51+59 201 | 44+46+52+58 202 | 44+46+53+57 203 | 44+46+54+56 204 | 44+47+48+61 205 | 44+47+49+60 206 | 44+47+50+59 207 | 44+47+51+58 208 | 44+47+52+57 209 | 44+47+53+56 210 | 44+47+54+55 211 | 44+48+49+59 212 | 44+48+50+58 213 | 44+48+51+57 214 | 44+48+52+56 215 | 44+48+53+55 216 | 44+49+50+57 217 | 44+49+51+56 218 | 44+49+52+55 219 | 44+49+53+54 220 | 44+50+51+55 221 | 44+50+52+54 222 | 44+51+52+53 223 | 45+46+47+62 224 | 45+46+48+61 225 | 45+46+49+60 226 | 45+46+50+59 227 | 45+46+51+58 228 | 45+46+52+57 229 | 45+46+53+56 230 | 45+46+54+55 231 | 45+47+48+60 232 | 45+47+49+59 233 | 45+47+50+58 234 | 45+47+51+57 235 | 45+47+52+56 236 | 45+47+53+55 237 | 45+48+49+58 238 | 45+48+50+57 239 | 45+48+51+56 240 | 45+48+52+55 241 | 45+48+53+54 242 | 45+49+50+56 243 | 45+49+51+55 244 | 45+49+52+54 245 | 45+50+51+54 246 | 45+50+52+53 247 | 46+47+48+59 248 | 46+47+49+58 249 | 46+47+50+57 250 | 46+47+51+56 251 | 46+47+52+55 252 | 46+47+53+54 253 | 46+48+49+57 254 | 46+48+50+56 255 | 46+48+51+55 256 | 46+48+52+54 257 | 46+49+50+55 258 | 46+49+51+54 259 | 46+49+52+53 260 | 46+50+51+53 261 | 47+48+49+56 262 | 47+48+50+55 263 | 47+48+51+54 264 | 47+48+52+53 265 | 47+49+50+54 266 | 47+49+51+53 267 | 47+50+51+52 268 | 48+49+50+53 269 | 48+49+51+52 270 | -------------------------------------------------------------------------------- /competitive-programming/2-complete-search/sum-it-up/templates/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | import static java.lang.System.out; 4 | 5 | public class Main { 6 | 7 | static int values[], sol[]; 8 | static int pos; 9 | static boolean found; 10 | 11 | public static void main (String [] args) { 12 | Scanner sc = new Scanner(System.in); 13 | while (sc.hasNext()) { 14 | int t = sc.nextInt(); 15 | int n = sc.nextInt(); 16 | if (t == 0 && n == 0) 17 | break; 18 | 19 | values = new int[n]; 20 | sol = new int[n]; 21 | pos = 0; 22 | 23 | for (int i = 0; i < n; i++) 24 | values[i] = sc.nextInt(); 25 | 26 | out.format("Sums of %d:\n", t); 27 | found = false; 28 | 29 | solveRec(0, 0, t); 30 | 31 | if (!found) 32 | out.println("NONE"); 33 | } 34 | 35 | sc.close(); 36 | } 37 | 38 | public static void solveRec(int size, int start, int sum) { 39 | } 40 | 41 | } 42 | 43 | -------------------------------------------------------------------------------- /competitive-programming/2-complete-search/sum-it-up/templates/test.in: -------------------------------------------------------------------------------- 1 | 4 6 4 3 2 2 1 1 2 | 5 3 2 1 1 3 | 400 12 50 50 50 50 50 50 25 25 25 25 25 25 4 | 1000 25 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 5 | 200 25 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 6 | 0 0 -------------------------------------------------------------------------------- /competitive-programming/2-complete-search/sum-it-up/templates/test.out: -------------------------------------------------------------------------------- 1 | Sums of 4: 2 | 4 3 | 3+1 4 | 2+2 5 | 2+1+1 6 | Sums of 5: 7 | NONE 8 | Sums of 400: 9 | 50+50+50+50+50+50+25+25+25+25 10 | 50+50+50+50+50+25+25+25+25+25+25 11 | Sums of 1000: 12 | NONE 13 | Sums of 200: 14 | 41+42+52+65 15 | 41+42+53+64 16 | 41+42+54+63 17 | 41+42+55+62 18 | 41+42+56+61 19 | 41+42+57+60 20 | 41+42+58+59 21 | 41+43+51+65 22 | 41+43+52+64 23 | 41+43+53+63 24 | 41+43+54+62 25 | 41+43+55+61 26 | 41+43+56+60 27 | 41+43+57+59 28 | 41+44+50+65 29 | 41+44+51+64 30 | 41+44+52+63 31 | 41+44+53+62 32 | 41+44+54+61 33 | 41+44+55+60 34 | 41+44+56+59 35 | 41+44+57+58 36 | 41+45+49+65 37 | 41+45+50+64 38 | 41+45+51+63 39 | 41+45+52+62 40 | 41+45+53+61 41 | 41+45+54+60 42 | 41+45+55+59 43 | 41+45+56+58 44 | 41+46+48+65 45 | 41+46+49+64 46 | 41+46+50+63 47 | 41+46+51+62 48 | 41+46+52+61 49 | 41+46+53+60 50 | 41+46+54+59 51 | 41+46+55+58 52 | 41+46+56+57 53 | 41+47+48+64 54 | 41+47+49+63 55 | 41+47+50+62 56 | 41+47+51+61 57 | 41+47+52+60 58 | 41+47+53+59 59 | 41+47+54+58 60 | 41+47+55+57 61 | 41+48+49+62 62 | 41+48+50+61 63 | 41+48+51+60 64 | 41+48+52+59 65 | 41+48+53+58 66 | 41+48+54+57 67 | 41+48+55+56 68 | 41+49+50+60 69 | 41+49+51+59 70 | 41+49+52+58 71 | 41+49+53+57 72 | 41+49+54+56 73 | 41+50+51+58 74 | 41+50+52+57 75 | 41+50+53+56 76 | 41+50+54+55 77 | 41+51+52+56 78 | 41+51+53+55 79 | 41+52+53+54 80 | 42+43+50+65 81 | 42+43+51+64 82 | 42+43+52+63 83 | 42+43+53+62 84 | 42+43+54+61 85 | 42+43+55+60 86 | 42+43+56+59 87 | 42+43+57+58 88 | 42+44+49+65 89 | 42+44+50+64 90 | 42+44+51+63 91 | 42+44+52+62 92 | 42+44+53+61 93 | 42+44+54+60 94 | 42+44+55+59 95 | 42+44+56+58 96 | 42+45+48+65 97 | 42+45+49+64 98 | 42+45+50+63 99 | 42+45+51+62 100 | 42+45+52+61 101 | 42+45+53+60 102 | 42+45+54+59 103 | 42+45+55+58 104 | 42+45+56+57 105 | 42+46+47+65 106 | 42+46+48+64 107 | 42+46+49+63 108 | 42+46+50+62 109 | 42+46+51+61 110 | 42+46+52+60 111 | 42+46+53+59 112 | 42+46+54+58 113 | 42+46+55+57 114 | 42+47+48+63 115 | 42+47+49+62 116 | 42+47+50+61 117 | 42+47+51+60 118 | 42+47+52+59 119 | 42+47+53+58 120 | 42+47+54+57 121 | 42+47+55+56 122 | 42+48+49+61 123 | 42+48+50+60 124 | 42+48+51+59 125 | 42+48+52+58 126 | 42+48+53+57 127 | 42+48+54+56 128 | 42+49+50+59 129 | 42+49+51+58 130 | 42+49+52+57 131 | 42+49+53+56 132 | 42+49+54+55 133 | 42+50+51+57 134 | 42+50+52+56 135 | 42+50+53+55 136 | 42+51+52+55 137 | 42+51+53+54 138 | 43+44+48+65 139 | 43+44+49+64 140 | 43+44+50+63 141 | 43+44+51+62 142 | 43+44+52+61 143 | 43+44+53+60 144 | 43+44+54+59 145 | 43+44+55+58 146 | 43+44+56+57 147 | 43+45+47+65 148 | 43+45+48+64 149 | 43+45+49+63 150 | 43+45+50+62 151 | 43+45+51+61 152 | 43+45+52+60 153 | 43+45+53+59 154 | 43+45+54+58 155 | 43+45+55+57 156 | 43+46+47+64 157 | 43+46+48+63 158 | 43+46+49+62 159 | 43+46+50+61 160 | 43+46+51+60 161 | 43+46+52+59 162 | 43+46+53+58 163 | 43+46+54+57 164 | 43+46+55+56 165 | 43+47+48+62 166 | 43+47+49+61 167 | 43+47+50+60 168 | 43+47+51+59 169 | 43+47+52+58 170 | 43+47+53+57 171 | 43+47+54+56 172 | 43+48+49+60 173 | 43+48+50+59 174 | 43+48+51+58 175 | 43+48+52+57 176 | 43+48+53+56 177 | 43+48+54+55 178 | 43+49+50+58 179 | 43+49+51+57 180 | 43+49+52+56 181 | 43+49+53+55 182 | 43+50+51+56 183 | 43+50+52+55 184 | 43+50+53+54 185 | 43+51+52+54 186 | 44+45+46+65 187 | 44+45+47+64 188 | 44+45+48+63 189 | 44+45+49+62 190 | 44+45+50+61 191 | 44+45+51+60 192 | 44+45+52+59 193 | 44+45+53+58 194 | 44+45+54+57 195 | 44+45+55+56 196 | 44+46+47+63 197 | 44+46+48+62 198 | 44+46+49+61 199 | 44+46+50+60 200 | 44+46+51+59 201 | 44+46+52+58 202 | 44+46+53+57 203 | 44+46+54+56 204 | 44+47+48+61 205 | 44+47+49+60 206 | 44+47+50+59 207 | 44+47+51+58 208 | 44+47+52+57 209 | 44+47+53+56 210 | 44+47+54+55 211 | 44+48+49+59 212 | 44+48+50+58 213 | 44+48+51+57 214 | 44+48+52+56 215 | 44+48+53+55 216 | 44+49+50+57 217 | 44+49+51+56 218 | 44+49+52+55 219 | 44+49+53+54 220 | 44+50+51+55 221 | 44+50+52+54 222 | 44+51+52+53 223 | 45+46+47+62 224 | 45+46+48+61 225 | 45+46+49+60 226 | 45+46+50+59 227 | 45+46+51+58 228 | 45+46+52+57 229 | 45+46+53+56 230 | 45+46+54+55 231 | 45+47+48+60 232 | 45+47+49+59 233 | 45+47+50+58 234 | 45+47+51+57 235 | 45+47+52+56 236 | 45+47+53+55 237 | 45+48+49+58 238 | 45+48+50+57 239 | 45+48+51+56 240 | 45+48+52+55 241 | 45+48+53+54 242 | 45+49+50+56 243 | 45+49+51+55 244 | 45+49+52+54 245 | 45+50+51+54 246 | 45+50+52+53 247 | 46+47+48+59 248 | 46+47+49+58 249 | 46+47+50+57 250 | 46+47+51+56 251 | 46+47+52+55 252 | 46+47+53+54 253 | 46+48+49+57 254 | 46+48+50+56 255 | 46+48+51+55 256 | 46+48+52+54 257 | 46+49+50+55 258 | 46+49+51+54 259 | 46+49+52+53 260 | 46+50+51+53 261 | 47+48+49+56 262 | 47+48+50+55 263 | 47+48+51+54 264 | 47+48+52+53 265 | 47+49+50+54 266 | 47+49+51+53 267 | 47+50+51+52 268 | 48+49+50+53 269 | 48+49+51+52 270 | -------------------------------------------------------------------------------- /competitive-programming/3-divide-and-conquer/advanced-programming-spring-week3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paul-g/brabble/a6b88e528d2e7222e41924a136797e9c55903598/competitive-programming/3-divide-and-conquer/advanced-programming-spring-week3.pdf -------------------------------------------------------------------------------- /competitive-programming/3-divide-and-conquer/exact-sum/solution/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.util.*; 3 | 4 | import static java.lang.Math.*; 5 | 6 | public class Main { 7 | 8 | public static void main (String [] args) throws Exception { 9 | 10 | Scanner sc = new Scanner(System.in); 11 | while (sc.hasNext()) { 12 | // read 13 | int n = sc.nextInt(); 14 | List l = new ArrayList(); 15 | for (int i = 0; i < n; i++) 16 | l.add(sc.nextInt()); 17 | int t = sc.nextInt(); 18 | 19 | // solve 20 | Pair sol = solve(l, t); 21 | 22 | // print 23 | System.out.format("Peter should buy books whose prices are %d and %d.\n\n", 24 | sol.x, sol.y); 25 | } 26 | 27 | } 28 | 29 | public static Pair solve(List l, int t) { 30 | Collections.sort(l); 31 | 32 | int smallestDiff = Integer.MAX_VALUE; 33 | int besta = 0, bestb = 0; 34 | 35 | for (int i = 0; i < l.size(); i++) { 36 | int a = l.get(i); 37 | int pos = Collections.binarySearch(l, t - a); 38 | 39 | // either not found, or found the element we are currently 40 | // at, both are no good 41 | if (pos < 0 || pos == i) 42 | continue; 43 | 44 | int b = l.get(pos); 45 | if (abs(a - b) < smallestDiff) { 46 | besta = min(a, b); 47 | bestb = max(a, b); 48 | smallestDiff = abs(besta - bestb); 49 | } 50 | } 51 | 52 | return new Pair(besta, bestb); 53 | } 54 | 55 | } 56 | 57 | class Pair { 58 | int x, y; 59 | Pair(int x, int y) { 60 | this.x = x; 61 | this.y = y; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /competitive-programming/3-divide-and-conquer/exact-sum/solution/test.in: -------------------------------------------------------------------------------- 1 | 2 2 | 40 40 3 | 80 4 | 5 | 5 6 | 10 2 6 8 4 7 | 10 8 | 9 | 4 10 | 10 30 30 50 11 | 60 12 | 13 | 2 14 | 10 30 15 | 40 16 | 17 | 3 18 | 10 20 30 19 | 30 20 | 21 | 3 22 | 1000000 1 1 23 | 2 24 | 25 | 4 26 | 4 6 2 8 27 | 10 28 | 29 | 2 30 | 40 40 31 | 80 32 | 33 | 5 34 | 10 2 6 8 4 35 | 10 36 | 37 | 4 38 | 4 6 2 8 39 | 10 40 | 41 | 3 42 | 1000000 100000 1 43 | 1100000 44 | 45 | 3 46 | 10 30 50 47 | 60 -------------------------------------------------------------------------------- /competitive-programming/3-divide-and-conquer/exact-sum/template/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.util.*; 3 | 4 | import static java.lang.Math.*; 5 | 6 | public class Main { 7 | 8 | public static void main (String [] args) throws Exception { 9 | 10 | Scanner sc = new Scanner(System.in); 11 | while (sc.hasNext()) { 12 | // read 13 | int n = sc.nextInt(); 14 | List l = new ArrayList(); 15 | for (int i = 0; i < n; i++) 16 | l.add(sc.nextInt()); 17 | int t = sc.nextInt(); 18 | 19 | // solve 20 | Pair sol = solve(l, t); 21 | 22 | // print 23 | System.out.format("Peter should buy books whose prices are %d and %d.\n\n", 24 | sol.x, sol.y); 25 | } 26 | 27 | } 28 | 29 | public static Pair solve(List l, int t) { 30 | // TODO solve me! 31 | } 32 | 33 | } 34 | 35 | class Pair { 36 | int x, y; 37 | Pair(int x, int y) { 38 | this.x = x; 39 | this.y = y; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /competitive-programming/3-divide-and-conquer/exact-sum/template/test.in: -------------------------------------------------------------------------------- 1 | 2 2 | 40 40 3 | 80 4 | 5 | 5 6 | 10 2 6 8 4 7 | 10 8 | 9 | 4 10 | 10 30 30 50 11 | 60 12 | 13 | 2 14 | 10 30 15 | 40 16 | 17 | 3 18 | 10 20 30 19 | 30 20 | 21 | 3 22 | 1000000 1 1 23 | 2 24 | 25 | 4 26 | 4 6 2 8 27 | 10 28 | 29 | 2 30 | 40 40 31 | 80 32 | 33 | 5 34 | 10 2 6 8 4 35 | 10 36 | 37 | 4 38 | 4 6 2 8 39 | 10 40 | 41 | 3 42 | 1000000 100000 1 43 | 1100000 44 | 45 | 3 46 | 10 30 50 47 | 60 -------------------------------------------------------------------------------- /competitive-programming/3-divide-and-conquer/merge-sort/solution/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | class Main { 4 | 5 | static int v[]; 6 | 7 | public static void main(String[] args) { 8 | 9 | Scanner sc = new Scanner(System.in); 10 | while (sc.hasNextInt()) { 11 | // read 12 | int n = sc.nextInt(); 13 | v = new int[n]; 14 | for (int i = 0; i < n; i++) 15 | v[i] = sc.nextInt(); 16 | 17 | // solve 18 | mergeSort(0, v.length - 1); 19 | 20 | // print 21 | System.out.println(Arrays.toString(v)); 22 | } 23 | } 24 | 25 | public static void mergeSort(int low, int high) { 26 | 27 | int size = high - low + 1; 28 | 29 | if (size <= 1) 30 | return; 31 | 32 | int mid = (low + high) / 2; 33 | 34 | mergeSort(low, mid); 35 | mergeSort(mid + 1, high); 36 | 37 | int p1 = low, p2 = mid + 1; 38 | 39 | int sol[] = new int[size]; 40 | int psol = 0; 41 | 42 | while (p1 <= mid && p2 <= high) 43 | sol[psol++] = v[p1] < v[p2] ? v[p1++] : v[p2++]; 44 | 45 | while (p1 <= mid) sol[psol++] = v[p1++]; 46 | 47 | while (p2 <= high) sol[psol++] = v[p2++]; 48 | 49 | System.arraycopy(sol, 0, v, low, size); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /competitive-programming/3-divide-and-conquer/merge-sort/solution/sort.in: -------------------------------------------------------------------------------- 1 | 3 2 | 1 2 3 3 | 3 4 | 3 2 1 5 | 4 6 | 9 8 7 6 7 | 1 8 | 1 9 | 2 10 | 3 1 11 | 2 12 | 1 3 -------------------------------------------------------------------------------- /competitive-programming/3-divide-and-conquer/merge-sort/template/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | class Main { 4 | 5 | static int v[]; 6 | 7 | public static void main(String[] args) { 8 | 9 | Scanner sc = new Scanner(System.in); 10 | while (sc.hasNextInt()) { 11 | // read 12 | int n = sc.nextInt(); 13 | v = new int[n]; 14 | for (int i = 0; i < n; i++) 15 | v[i] = sc.nextInt(); 16 | 17 | // solve 18 | mergeSort(0, v.length - 1); 19 | 20 | // print 21 | System.out.println(Arrays.toString(v)); 22 | } 23 | } 24 | 25 | public static void mergeSort(int low, int high) { 26 | // Solve MEEEE! 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /competitive-programming/3-divide-and-conquer/merge-sort/template/sort.in: -------------------------------------------------------------------------------- 1 | 3 2 | 1 2 3 3 | 3 4 | 3 2 1 5 | 4 6 | 9 8 7 6 7 | 1 8 | 1 9 | 2 10 | 3 1 11 | 2 12 | 1 3 -------------------------------------------------------------------------------- /competitive-programming/3-divide-and-conquer/solve-it/solution/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import static java.lang.Math.*; 3 | 4 | public class Main { 5 | 6 | static double p, q, r, s, t, u; 7 | static final double EPS = 0.000001; 8 | static final double NO_SOL_BOUND = 0.000000001; 9 | 10 | public static void main (String [] args) { 11 | Scanner sc = new Scanner(System.in); 12 | 13 | while(sc.hasNext()) { 14 | // read 15 | p = sc.nextDouble(); 16 | q = sc.nextDouble(); 17 | r = sc.nextDouble(); 18 | s = sc.nextDouble(); 19 | t = sc.nextDouble(); 20 | u = sc.nextDouble(); 21 | 22 | double high = 1; 23 | double low = 0; 24 | 25 | if (signum(eval(high)) == signum(eval(low))) 26 | System.out.println("No solution"); 27 | else 28 | System.out.format("%.4f\n", solve(high, low)); 29 | } 30 | } 31 | 32 | public static double solve(double high, double low) { 33 | double mid = (high + low) / 2; 34 | double res = eval(mid); 35 | 36 | if (abs(res) < EPS) 37 | // found solution 38 | return mid; 39 | if (eval(mid) > 0 && eval(low) > 0) 40 | // low and mid have same sign, go right 41 | return solve(high, mid); 42 | 43 | // else go left 44 | return solve(mid, low); 45 | } 46 | 47 | public static double eval(double x) { 48 | return p * pow(E, -x) + 49 | q*sin(x) + r*cos(x) + s*tan(x) + t * x * x + u; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /competitive-programming/3-divide-and-conquer/solve-it/solution/test.in: -------------------------------------------------------------------------------- 1 | 0 0 0 0 -2 1 2 | 1 0 0 0 -1 2 3 | 1 -1 1 -1 -1 1 4 | 0 0 0 0 0 0 5 | 1 -20 3 -20 -5 6 6 | 2 -20 3 -20 -5 6 7 | 3 -20 3 -20 -5 6 8 | 4 -20 3 -20 -5 6 9 | 5 -20 3 -20 -5 6 10 | 6 -20 3 -20 -5 6 11 | 3 -4 1 -3 -2 5 12 | 6 -11 8 -20 -3 1 13 | 4 -4 4 -4 -4 5 14 | 17 -6 2 -8 -1 3 15 | 16 -1 12 -2 -12 4 16 | 4 -9 10 -2 -4 8 17 | 4 -15 19 0 -5 6 -------------------------------------------------------------------------------- /competitive-programming/3-divide-and-conquer/solve-it/template/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import static java.lang.Math.*; 3 | 4 | public class Main { 5 | 6 | static double p, q, r, s, t, u; 7 | static final double EPS = 0.000001; 8 | static final double NO_SOL_BOUND = 0.000000001; 9 | 10 | public static void main (String [] args) { 11 | Scanner sc = new Scanner(System.in); 12 | 13 | while(sc.hasNext()) { 14 | // read 15 | p = sc.nextDouble(); 16 | q = sc.nextDouble(); 17 | r = sc.nextDouble(); 18 | s = sc.nextDouble(); 19 | t = sc.nextDouble(); 20 | u = sc.nextDouble(); 21 | 22 | double high = 1; 23 | double low = 0; 24 | 25 | System.out.format("%.4f\n", solve(high, low)); 26 | } 27 | } 28 | 29 | public static double solve(double high, double low) { 30 | return 0.0; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /competitive-programming/3-divide-and-conquer/solve-it/template/test.in: -------------------------------------------------------------------------------- 1 | 0 0 0 0 -2 1 2 | 1 0 0 0 -1 2 3 | 1 -1 1 -1 -1 1 4 | 0 0 0 0 0 0 5 | 1 -20 3 -20 -5 6 6 | 2 -20 3 -20 -5 6 7 | 3 -20 3 -20 -5 6 8 | 4 -20 3 -20 -5 6 9 | 5 -20 3 -20 -5 6 10 | 6 -20 3 -20 -5 6 11 | 3 -4 1 -3 -2 5 12 | 6 -11 8 -20 -3 1 13 | 4 -4 4 -4 -4 5 14 | 17 -6 2 -8 -1 3 15 | 16 -1 12 -2 -12 4 16 | 4 -9 10 -2 -4 8 17 | 4 -15 19 0 -5 6 -------------------------------------------------------------------------------- /competitive-programming/3-divide-and-conquer/solve-it/test.in: -------------------------------------------------------------------------------- 1 | 0 0 0 0 -2 1 2 | 1 0 0 0 -1 2 3 | 1 -1 1 -1 -1 1 4 | 0 0 0 0 0 0 5 | 1 -20 3 -20 -5 6 6 | 2 -20 3 -20 -5 6 7 | 3 -20 3 -20 -5 6 8 | 4 -20 3 -20 -5 6 9 | 5 -20 3 -20 -5 6 10 | 6 -20 3 -20 -5 6 11 | 3 -4 1 -3 -2 5 12 | 6 -11 8 -20 -3 1 13 | 4 -4 4 -4 -4 5 14 | 17 -6 2 -8 -1 3 15 | 16 -1 12 -2 -12 4 16 | 4 -9 10 -2 -4 8 17 | 4 -15 19 0 -5 6 -------------------------------------------------------------------------------- /competitive-programming/4-greedy-dynamic-programming/advanced-programming-spring-week4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paul-g/brabble/a6b88e528d2e7222e41924a136797e9c55903598/competitive-programming/4-greedy-dynamic-programming/advanced-programming-spring-week4.pdf -------------------------------------------------------------------------------- /competitive-programming/4-greedy-dynamic-programming/bridge/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | class Main { 4 | static final Scanner sc = new Scanner(System.in); 5 | 6 | public static void main(String[] args) { 7 | 8 | int nt = sc.nextInt(); 9 | for (int i = 0; i < nt; i++) { 10 | solve(); 11 | if (i < nt - 1) 12 | System.out.println(); 13 | } 14 | } 15 | 16 | static void solve() { 17 | int n = sc.nextInt(); 18 | int [] vals = new int[n]; 19 | for (int i = 0; i < n; i++) { 20 | vals[i] = sc.nextInt(); 21 | } 22 | 23 | if (n == 1) { 24 | System.out.println(vals[0] + "\n" + vals[0]); 25 | return; 26 | } 27 | 28 | Arrays.sort(vals); 29 | 30 | LinkedList ll = new LinkedList(); 31 | for (int i = 0; i < n; i++) { 32 | ll.add(vals[i]); 33 | } 34 | 35 | int sum = 0; 36 | StringBuilder sb = new StringBuilder(); 37 | while (true) { 38 | int fst = ll.get(0); 39 | int snd = ll.get(1); 40 | 41 | if (ll.size() == 2) { 42 | sb.append(fst + " " + snd + "\n"); 43 | sum += snd; 44 | break; 45 | } 46 | 47 | int lst = ll.pollLast(); 48 | 49 | if (ll.size() == 2) { 50 | sb.append(fst + " " + lst + "\n"); 51 | sb.append(fst + "\n"); 52 | sb.append(fst + " " + snd + "\n"); 53 | sum += fst + snd + lst; 54 | break; 55 | } 56 | 57 | // general case, ll.size() >= 4 58 | int secondLargest = ll.pollLast(); 59 | 60 | // (fst, lst), (fst), (fst, secondLargest), (fst) 61 | int firstOption = 2 * fst + lst + secondLargest; 62 | // (fst, snd), (fst), (secondLargset, largest), (snd) 63 | int secondOption = fst + 2 * snd + lst; 64 | 65 | if (secondOption < firstOption) { 66 | sb.append(String.format("%d %d\n%d\n%d %d\n%d\n", 67 | fst, snd, 68 | fst, 69 | secondLargest, lst, 70 | snd) 71 | ); 72 | sum += secondOption; 73 | continue; 74 | } 75 | 76 | sb.append(String.format("%d %d\n%d\n%d %d\n%d\n", 77 | fst, lst, 78 | fst, 79 | fst, secondLargest, 80 | fst) 81 | ); 82 | sum += firstOption; 83 | } 84 | 85 | System.out.println(sum); 86 | System.out.print(sb); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /competitive-programming/4-greedy-dynamic-programming/bridge/bridge.in: -------------------------------------------------------------------------------- 1 | 5 2 | 3 | 3 4 | 1 5 | 2 6 | 3 7 | 8 | 2 9 | 1 10 | 3 11 | 12 | 1 13 | 1 14 | 15 | 4 16 | 1 17 | 2 18 | 5 19 | 10 20 | 21 | 20 22 | 95 23 | 95 24 | 88 25 | 89 26 | 62 27 | 70 28 | 51 29 | 53 30 | 45 31 | 47 32 | 32 33 | 38 34 | 28 35 | 31 36 | 27 37 | 28 38 | 24 39 | 23 40 | 5 41 | 15 -------------------------------------------------------------------------------- /competitive-programming/4-greedy-dynamic-programming/discrete-knapsack/solution/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | import static java.lang.Math.*; 4 | 5 | class Main { 6 | 7 | static int w[], p[]; 8 | static double memo[][]; 9 | 10 | public static void main(String[] args) { 11 | Scanner sc = new Scanner(System.in); 12 | 13 | while (sc.hasNext()) { 14 | 15 | // read 16 | int n = sc.nextInt(); 17 | int maxWeight = sc.nextInt(); 18 | 19 | w = new int[n]; 20 | p = new int[n]; 21 | memo = new double[n][maxWeight + 1]; 22 | 23 | for (int i = 0; i < n; i++) 24 | for (int j = 0; j < maxWeight + 1; j++) 25 | memo[i][j] = -1; 26 | 27 | for (int i = 0; i < n; i++){ 28 | w[i] = sc.nextInt(); 29 | p[i] = sc.nextInt(); 30 | } 31 | 32 | // solve and print 33 | System.out.println(profit(n - 1, maxWeight)); 34 | System.out.println(profitMemo(n - 1, maxWeight)); 35 | System.out.println(bottomUp(n, maxWeight)); 36 | } 37 | } 38 | 39 | 40 | // the naive complete search approach 41 | public static double profit (int i, int weight) { 42 | // System.out.println(i + " " + weight); 43 | 44 | if (i == 0 || weight == 0) 45 | return 0; 46 | if (w[i] <= weight) 47 | return max(profit(i - 1, weight), 48 | profit(i - 1, weight - w[i]) + p[i]); 49 | return profit(i - 1, weight); 50 | } 51 | 52 | public static double memo(int i, int weight) { 53 | if (memo[i][weight] == -1) 54 | memo[i][weight] = profitMemo(i, weight); 55 | return memo[i][weight]; 56 | } 57 | 58 | // the recurrence is the same, but we cache the results in memo to 59 | // avoid unnecessary computation 60 | public static double profitMemo (int i, int weight) { 61 | // System.out.println(i + " " + weight); 62 | 63 | if (i == 0 || weight == 0) 64 | return 0; 65 | if (w[i] <= weight) 66 | return max(memo(i - 1, weight), 67 | memo(i - 1, weight - w[i]) + p[i]); 68 | return memo(i - 1, weight); 69 | } 70 | 71 | // the bottom up approach builds the smaller solutions first it 72 | // also avoids any need for recursion also since all required 73 | // subproblems for a step are from step-1, we only need to use a 74 | // single vector to store them 75 | public static double bottomUp(int n, int weight) { 76 | 77 | int [] best = new int[weight + 1]; 78 | 79 | for (int i = 0; i < n; i++) { 80 | for (int j = weight; j >= 1; j--) { 81 | best[j] = max(best[j], j - w[i] < 0 ? 0 : best[j - w[i]] + p[i]); 82 | } 83 | } 84 | 85 | return best[weight]; 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /competitive-programming/4-greedy-dynamic-programming/discrete-knapsack/solution/test.in: -------------------------------------------------------------------------------- 1 | 30 2 | 50 3 | 5 4 4 | 9 11 5 | 8 16 6 | 2 31 7 | 3 2 8 | 4 4 9 | 25 22 10 | 30 11 11 | 45 3 12 | 15 6 13 | 5 4 14 | 9 11 15 | 8 16 16 | 2 31 17 | 3 2 18 | 4 4 19 | 25 22 20 | 30 11 21 | 45 3 22 | 15 6 23 | 5 4 24 | 9 11 25 | 8 16 26 | 2 31 27 | 3 2 28 | 4 4 29 | 25 22 30 | 30 11 31 | 45 3 32 | 15 6 33 | -------------------------------------------------------------------------------- /competitive-programming/4-greedy-dynamic-programming/discrete-knapsack/template/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | import static java.lang.Math.*; 4 | 5 | class Main { 6 | 7 | static int w[], p[]; 8 | static double memo[][]; 9 | 10 | public static void main(String[] args) { 11 | Scanner sc = new Scanner(System.in); 12 | 13 | while (sc.hasNext()) { 14 | 15 | // read 16 | int n = sc.nextInt(); 17 | int maxWeight = sc.nextInt(); 18 | 19 | w = new int[n]; 20 | p = new int[n]; 21 | 22 | for (int i = 0; i < n; i++){ 23 | w[i] = sc.nextInt(); 24 | p[i] = sc.nextInt(); 25 | } 26 | 27 | // solve and print 28 | System.out.println(profit(n - 1, maxWeight)); 29 | // System.out.println(profitMemo(n - 1, maxWeight)); 30 | // System.out.println(bottomUp(n, maxWeight)); 31 | } 32 | } 33 | 34 | public static double profit (int i, int weight) { 35 | return 0; 36 | } 37 | 38 | public static double memo(int i, int weight) { 39 | return 0; 40 | } 41 | 42 | public static double profitMemo (int i, int weight) { 43 | return 0; 44 | } 45 | 46 | public static double bottomUp(int n, int weight) { 47 | return 0; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /competitive-programming/4-greedy-dynamic-programming/discrete-knapsack/template/test.in: -------------------------------------------------------------------------------- 1 | 30 2 | 50 3 | 5 4 4 | 9 11 5 | 8 16 6 | 2 31 7 | 3 2 8 | 4 4 9 | 25 22 10 | 30 11 11 | 45 3 12 | 15 6 13 | 5 4 14 | 9 11 15 | 8 16 16 | 2 31 17 | 3 2 18 | 4 4 19 | 25 22 20 | 30 11 21 | 45 3 22 | 15 6 23 | 5 4 24 | 9 11 25 | 8 16 26 | 2 31 27 | 3 2 28 | 4 4 29 | 25 22 30 | 30 11 31 | 45 3 32 | 15 6 33 | -------------------------------------------------------------------------------- /competitive-programming/4-greedy-dynamic-programming/fractional-knapsack/solution/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | class Main { 4 | 5 | public static void main(String[] args) { 6 | Scanner sc = new Scanner(System.in); 7 | 8 | while (sc.hasNext()) { 9 | 10 | // read 11 | int n = sc.nextInt(); 12 | int maxWeight = sc.nextInt(); 13 | List items = new ArrayList(); 14 | for (int i = 0; i < n; i++) 15 | items.add(new Item(sc.nextInt(), sc.nextInt())); 16 | 17 | // solve 18 | double profit = solve(items, maxWeight); 19 | 20 | // print 21 | System.out.println(profit); 22 | } 23 | } 24 | 25 | public static double solve(List items, int maxWeight) { 26 | 27 | Collections.sort(items, Collections.reverseOrder()); 28 | 29 | // Use a custom comparator if you want something different 30 | // than the natural ordering, or there is no natural ordering 31 | // Collections.sort(items, new Comparator () { 32 | // public int compare(Item it1, Item it2) { 33 | // return Double.compare(it1.ratio, it2.ratio); 34 | // }}); 35 | 36 | // In JDK 1.8 you can use lambdas: 37 | // Collections.sort(items, 38 | // (item1, item2) -> {return Double.compare(item2.ratio, item1.ratio);}); 39 | 40 | int weightUsed = 0; 41 | double profit = 0; 42 | List used = new ArrayList(); 43 | for (Item item : items) { 44 | int left = maxWeight - weightUsed; 45 | if (item.weight > left) { 46 | profit += item.useProportion(left); 47 | used.add(item); 48 | break; 49 | } else { 50 | profit += item.price; 51 | used.add(item); 52 | weightUsed += item.weight; 53 | } 54 | } 55 | 56 | System.out.println(used); 57 | return profit; 58 | } 59 | 60 | } 61 | 62 | // Implement comparable to provide a natural ordering for objects of 63 | // type Item; this is used for example in Collections.sort() 64 | class Item implements Comparable { 65 | double weight, price, ratio; 66 | double prop = 1.0; 67 | 68 | Item(int weight, int price) { 69 | this.weight = (double)weight; 70 | this.price = (double)price; 71 | this.ratio = this.price / this.weight; 72 | } 73 | 74 | double useProportion(double weight){ 75 | this.prop = weight / this.weight; 76 | return this.prop * this.price; 77 | } 78 | 79 | // Use annotations to let the compiler know you want to override a 80 | // base class method; if there is no such method, the compiler 81 | // will generate an error - very useful to catch silly bugs 82 | @Override 83 | public String toString() { 84 | return String.format("[w=%.3f, p=%.3f, r=%.3f, p=%.3f]\n", 85 | weight, price, ratio, prop); 86 | } 87 | 88 | @Override 89 | public int compareTo(Item item) { 90 | if (item == null) 91 | return 1; 92 | return Double.compare(ratio, item.ratio); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /competitive-programming/4-greedy-dynamic-programming/fractional-knapsack/solution/test.in: -------------------------------------------------------------------------------- 1 | 3 2 | 10 3 | 5 3 4 | 2 2 5 | 4 1 6 | 7 | 8 | 2 9 | 1 10 | 8 10 11 | 4 20 12 | 13 | 14 | 10 15 | 50 16 | 5 4 17 | 9 11 18 | 8 16 19 | 2 31 20 | 3 2 21 | 4 4 22 | 25 22 23 | 30 11 24 | 45 3 25 | 15 6 26 | -------------------------------------------------------------------------------- /competitive-programming/4-greedy-dynamic-programming/fractional-knapsack/template/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | class Main { 4 | 5 | public static void main(String[] args) { 6 | Scanner sc = new Scanner(System.in); 7 | 8 | while (sc.hasNext()) { 9 | 10 | // read 11 | int n = sc.nextInt(); 12 | int maxWeight = sc.nextInt(); 13 | List items = new ArrayList(); 14 | for (int i = 0; i < n; i++) 15 | items.add(new Item(sc.nextInt(), sc.nextInt())); 16 | 17 | // solve 18 | double profit = solve(items, maxWeight); 19 | 20 | // print 21 | System.out.println(profit); 22 | } 23 | } 24 | 25 | public static double solve(List items, int maxWeight) { 26 | // TODO Implement me! 27 | return 0; 28 | } 29 | 30 | } 31 | 32 | class Item { 33 | double weight, price, ratio; 34 | double prop = 1.0; 35 | 36 | Item(int weight, int price) { 37 | this.weight = (double)weight; 38 | this.price = (double)price; 39 | this.ratio = this.price / this.weight; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /competitive-programming/4-greedy-dynamic-programming/fractional-knapsack/template/test.in: -------------------------------------------------------------------------------- 1 | 3 2 | 10 3 | 5 3 4 | 2 2 5 | 4 1 6 | 7 | 8 | 2 9 | 1 10 | 8 10 11 | 4 20 12 | 13 | 14 | 10 15 | 50 16 | 5 4 17 | 9 11 18 | 8 16 19 | 2 31 20 | 3 2 21 | 4 4 22 | 25 22 23 | 30 11 24 | 45 3 25 | 15 6 26 | -------------------------------------------------------------------------------- /competitive-programming/4-greedy-dynamic-programming/max-sum-2D/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.util.*; 3 | 4 | public class Main { 5 | 6 | public static void main (String[] args) { 7 | Scanner sc = new Scanner(System.in); 8 | int n = sc.nextInt(); 9 | 10 | int [][] mat = new int[n][n]; 11 | int [][] sum = new int[n][n]; 12 | 13 | for (int i = 0; i < n; i++) 14 | for (int j = 0; j < n; j++) { 15 | mat[i][j] = sc.nextInt(); 16 | 17 | // precompute the sum matrix 18 | sum[i][j] += mat[i][j] + 19 | (i > 0 ? sum[i - 1][j] : 0) + 20 | (j > 0 ? sum[i][j - 1] : 0) - 21 | (i > 0 && j > 0 ? sum[i - 1][j - 1] : 0); 22 | } 23 | 24 | dp(mat, sum); 25 | 26 | sc.close(); 27 | } 28 | 29 | // Dynamic programming solution is O(n^4), which is fine for n up to 100. 30 | static void dp(int [][] mat, int[][] sum) { 31 | int bestSum = Integer.MIN_VALUE; 32 | int n = mat.length; 33 | for (int i = 0; i < n; i++) 34 | for (int j = 0; j < n; j++) 35 | for (int li = i; li < n; li++) 36 | for (int lj = j; lj < n; lj++) { 37 | // use the precomputed sum matrix to reconstruct the sum 38 | // of every subsquare in the original matrix 39 | int s = sum[li][lj] - 40 | (i > 0 ? sum[i - 1][lj] : 0) - 41 | (j > 0 ? sum[li][j - 1] : 0) + 42 | (i > 0 && j > 0 ? sum[i - 1][j - 1] : 0); 43 | bestSum = Math.max(bestSum, s); 44 | } 45 | 46 | System.out.println(bestSum); 47 | } 48 | 49 | // Complete search is too slow O(n^6), for n up to 100. 50 | static void completeSearch(int [][] mat) { 51 | int n = mat.length; 52 | int bestSum = Integer.MIN_VALUE; 53 | for (int i = 0; i < n; i++) 54 | for (int j = 0; j < n; j++) 55 | for (int di = i; di < n; di++) 56 | for (int dj = j; dj < n; dj++) { 57 | int sum = 0; 58 | for (int l = i; l <= di; l++) 59 | for (int c = j; c <= dj; c++) 60 | sum += mat[l][c]; 61 | bestSum = Math.max(sum, bestSum); 62 | } 63 | System.out.println(bestSum); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /competitive-programming/4-greedy-dynamic-programming/max-sum-2D/test.in: -------------------------------------------------------------------------------- 1 | 4 2 | 0 -2 -7 0 3 | 9 2 -6 2 4 | -4 1 -4 1 5 | -1 8 0 -2 -------------------------------------------------------------------------------- /competitive-programming/4-greedy-dynamic-programming/scarecrow/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.util.*; 3 | 4 | public class Main { 5 | 6 | static final Scanner sc = new Scanner(System.in); 7 | public static void main(String [] args) { 8 | int nt = sc.nextInt(); 9 | for (int t = 1; t <= nt; t++) { 10 | System.out.format("Case %d: ", t); 11 | solve(); 12 | } 13 | sc.close(); 14 | } 15 | 16 | static void solve() { 17 | int n = sc.nextInt(); 18 | String line = sc.next(); 19 | int covered = 0; 20 | int scarecrow = 0; 21 | for (char c : line.toCharArray()) { 22 | if (c == '.' && covered == 0) { 23 | scarecrow++; 24 | covered = 3; 25 | } 26 | if (covered > 0) 27 | covered--; 28 | } 29 | System.out.println(scarecrow); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /competitive-programming/4-greedy-dynamic-programming/scarecrow/test.in: -------------------------------------------------------------------------------- 1 | 3 2 | 3 3 | .#. 4 | 11 5 | ...##....## 6 | 2 7 | ## -------------------------------------------------------------------------------- /competitive-programming/4-greedy-dynamic-programming/shoemaker/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Main { 4 | 5 | static final Scanner sc = new Scanner(System.in); 6 | 7 | public static void main(String[] args) { 8 | int nt = sc.nextInt(); 9 | for (int t = 1; t <= nt; t++) { 10 | solve(); 11 | if (t < nt) 12 | System.out.println(); 13 | } 14 | sc.close(); 15 | } 16 | 17 | static void solve() { 18 | int n = sc.nextInt(); 19 | double r[] = new double[n]; 20 | 21 | for (int i = 0; i < n; i++) { 22 | double t = sc.nextDouble(); 23 | double v = sc.nextDouble(); 24 | r[i] = v / t; 25 | } 26 | 27 | for (int i = 0; i < n; i++) { 28 | int bestj = -1; 29 | for (int j = 0; j < n; j++) 30 | if (r[j] != -1 && (bestj == - 1 || r[j] > r[bestj])) 31 | bestj = j; 32 | System.out.print(bestj + 1 + (i == n - 1 ? "\n" : " ")); 33 | r[bestj] = -1; 34 | } 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /competitive-programming/4-greedy-dynamic-programming/shoemaker/test.in: -------------------------------------------------------------------------------- 1 | 2 2 | 3 | 4 4 | 3 4 5 | 1 1000 6 | 2 2 7 | 5 5 8 | 9 | 4 10 | 3 4 11 | 1 1000 12 | 2 2 13 | 5 5 -------------------------------------------------------------------------------- /competitive-programming/5-graphs/advanced-programming-spring-week-56.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paul-g/brabble/a6b88e528d2e7222e41924a136797e9c55903598/competitive-programming/5-graphs/advanced-programming-spring-week-56.pdf -------------------------------------------------------------------------------- /competitive-programming/5-graphs/solutions/Dijkstra.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | /** Pair is need to store vertex and distance from source in a 4 | priority queue. **/ 5 | class Pair implements Comparable { 6 | 7 | int vertex; 8 | double distanceFromSource; 9 | 10 | Pair(int vertex, double distanceFromSource) { 11 | this.vertex = vertex; 12 | this.distanceFromSource = distanceFromSource; 13 | } 14 | 15 | @Override 16 | public int compareTo(Pair other) { 17 | return Double.compare(distanceFromSource, other.distanceFromSource); 18 | } 19 | 20 | } 21 | 22 | class Dijkstra { 23 | 24 | public static void main(String[] args) throws Exception { 25 | 26 | List> graph = GraphLib.readDirectedGraphFromDotFile("din.dot"); 27 | 28 | PriorityQueue pq = new PriorityQueue(); 29 | 30 | int source = 0; 31 | 32 | int n = graph.size(); 33 | // holds distance from source to all other nodes 34 | double d[] = new double[n]; 35 | 36 | // keep track of nodes we've visited 37 | boolean seen[] = new boolean[n]; 38 | for (int i = 0; i < n; i++) { 39 | d[i] = Integer.MAX_VALUE; 40 | seen[i] = false; 41 | } 42 | 43 | pq.add(new Pair(source, 0)); 44 | d[source] = 0; 45 | 46 | while (!pq.isEmpty()) { 47 | 48 | int node = pq.poll().vertex; 49 | 50 | if (seen[node]) continue; 51 | 52 | seen[node] = true; 53 | for (Edge e : graph.get(node)) { 54 | double alt = d[node] + e.weight; 55 | int to = e.to; 56 | if (!seen[to] && d[to] > alt) { 57 | d[to] = alt; 58 | pq.add(new Pair(to, d[to])); 59 | } 60 | } 61 | } 62 | 63 | for (double val : d) { 64 | System.out.format("%.2f ", val); 65 | } 66 | 67 | System.out.println(); 68 | 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /competitive-programming/5-graphs/solutions/GraphLib.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | import java.util.regex.*; 4 | 5 | 6 | /** An edge in the graph. **/ 7 | class Edge implements Comparable { 8 | Integer from, to; 9 | double weight; 10 | 11 | Edge(int from, int to, double weight) { 12 | this.from = from; 13 | this.to = to; 14 | this.weight = weight; 15 | } 16 | 17 | @Override 18 | public String toString() { 19 | return String.format("(%s, %s, %f)", from, to, weight); 20 | } 21 | 22 | @Override 23 | public int compareTo(Edge other) { 24 | return Double.compare(weight, other.weight); 25 | } 26 | 27 | @Override 28 | public int hashCode() { 29 | return from.hashCode() ^ to.hashCode(); 30 | } 31 | 32 | @Override 33 | public boolean equals(Object obj) { 34 | if (obj == null) 35 | return false; 36 | if (!(obj instanceof Edge)) 37 | return false; 38 | Edge other = (Edge) obj; 39 | return (other.from == from && other.to == to) || 40 | (other.from == to && other.to == from); 41 | } 42 | 43 | 44 | } 45 | 46 | 47 | public class GraphLib { 48 | 49 | static int num = 0; 50 | 51 | /** Make sure list has at least size elements. **/ 52 | private static void ensureSize(List> list, int size) { 53 | while (list.size() <= size) { 54 | list.add(new ArrayList()); 55 | } 56 | } 57 | 58 | /** Read a graph from a dot file and return its adjacency list. **/ 59 | public static List> readGraphFromDotFile(String filename) throws Exception { 60 | BufferedReader br = new BufferedReader(new FileReader(filename)); 61 | 62 | br.readLine(); 63 | ArrayList> graph = new ArrayList<>(); 64 | 65 | int max = 0; 66 | 67 | String line; 68 | while ( (line = br.readLine()) != null && !"}".equals(line)) { 69 | String ls[] = line.split("->"); 70 | Integer from = Integer.parseInt(ls[0].trim()); 71 | Integer to = Integer.parseInt(ls[1].trim()); 72 | 73 | max = Math.max(max, from); 74 | max = Math.max(max, to); 75 | 76 | ensureSize(graph, from); 77 | 78 | List neighbours = graph.get(from); 79 | if (neighbours == null) 80 | neighbours = new ArrayList(); 81 | 82 | neighbours.add(to); 83 | } 84 | 85 | ensureSize(graph, max); 86 | 87 | br.close(); 88 | return graph; 89 | } 90 | 91 | /** Read a graph from a dot file and return its adjacency list. **/ 92 | public static List> readDirectedGraphFromDotFile(String filename) throws Exception { 93 | return readFromDotFile(filename, false); 94 | } 95 | 96 | /** Read undirected graph from a dot file and return its adjacency list. **/ 97 | public static List> readUndirectedGraphFromDotFile(String filename) throws Exception { 98 | return readFromDotFile(filename, true); 99 | } 100 | 101 | private static List> readFromDotFile(String filename, 102 | boolean undirected) throws Exception { 103 | Scanner sc = new Scanner(new File(filename)); 104 | 105 | String line = sc.nextLine(); 106 | 107 | ArrayList> graph = new ArrayList<>(); 108 | 109 | int max = 0; 110 | 111 | String pattern = undirected ? 112 | "(\\d*) -- (\\d*) \\[label=(\\d*\\.\\d*)\\]" : 113 | "(\\d*) -> (\\d*) \\[label=(\\d*\\.\\d*)\\]"; 114 | 115 | while (sc.hasNextLine()) { 116 | sc.findInLine(pattern); 117 | 118 | MatchResult result = sc.match(); 119 | sc.nextLine(); 120 | 121 | int from = Integer.parseInt(result.group(1)); 122 | int to = Integer.parseInt(result.group(2)); 123 | double weight = Double.parseDouble(result.group(3)); 124 | 125 | max = Math.max(max, from); 126 | max = Math.max(max, to); 127 | 128 | ensureSize(graph, from); 129 | List neighbours = graph.get(from); 130 | if (neighbours == null) 131 | neighbours = new ArrayList(); 132 | neighbours.add(new Edge(from, to, weight)); 133 | 134 | if (undirected) { 135 | ensureSize(graph, to); 136 | neighbours = graph.get(to); 137 | if (neighbours == null) 138 | neighbours = new ArrayList(); 139 | neighbours.add(new Edge(to, from, weight)); 140 | } 141 | } 142 | 143 | ensureSize(graph, max); 144 | return graph; 145 | } 146 | 147 | /** Pretty print a graph given as an adjacency list. **/ 148 | public static void prettyPrintGraph(List> nodes) { 149 | int pos = 0; 150 | for (List ns : nodes) { 151 | System.out.format(" %d --> ", pos++); 152 | System.out.println(ns); 153 | } 154 | } 155 | 156 | /** Returns a fully connected graph in adjacency list format. **/ 157 | public static List> fullyConnected(int n) { 158 | List> nodes = new LinkedList<>(); 159 | for (int i = 0; i < n; i++) { 160 | List ns = new LinkedList(); 161 | nodes.add(ns); 162 | for (int j = 0; j < n; j++) 163 | if (i != j) 164 | ns.add(j); 165 | } 166 | return nodes; 167 | } 168 | 169 | /** Writes graph.dot containing a dot representation of the given graph. **/ 170 | public static void printDigraph(List> graph, 171 | boolean seen[], 172 | int neighbour, 173 | int start) throws Exception { 174 | PrintWriter writer = new PrintWriter(new FileOutputStream("graph.dot", true)); 175 | writer.println("digraph G" + num + "{"); 176 | num++; 177 | writer.println("{"); 178 | writer.println("node [style=filled]"); 179 | for (int i = 0; i < seen.length; i++) 180 | if (i == neighbour) 181 | printColor(writer, i, "blue"); 182 | else if (i == start) 183 | printColor(writer, i, "green"); 184 | else if (seen[i]) 185 | printColor(writer, i, "red"); 186 | 187 | writer.println("}"); 188 | int p = 0; 189 | for (List ns : graph) { 190 | for (int n : ns) 191 | writer.println("n" + p + " -> n" + n); 192 | writer.println(); 193 | p++; 194 | } 195 | writer.println("}"); 196 | writer.close(); 197 | } 198 | 199 | private static void printColor(PrintWriter writer, int node, String color) { 200 | writer.print(String.format("n%d [fillcolor = %s]\n", node, color)); 201 | } 202 | 203 | public static void clearDigraph() throws Exception { 204 | PrintWriter writer = new PrintWriter("graph.dot"); 205 | writer.close(); 206 | } 207 | 208 | /** Returns a randomly connected graph in adjacency list format. **/ 209 | public static List> randomlyConnected(int n) { 210 | List> nodes = new LinkedList<>(); 211 | Random r = new Random(0); 212 | int count = 0; 213 | for (int i = 0; i < n; i++) { 214 | List ns = new LinkedList(); 215 | nodes.add(ns); 216 | for (int j = 0; j < n; j++) 217 | if (i != j && r.nextDouble() < 0.4) 218 | if (j > i || !nodes.get(j).contains(i)) { 219 | ns.add(j); 220 | count++; 221 | } 222 | } 223 | System.out.println("Edge count: " + count); 224 | return nodes; 225 | } 226 | 227 | /** Write a dot graph, highlighting edges in mst with red.**/ 228 | public static void drawMst(List> graph, 229 | List mst, 230 | String filename, 231 | boolean append) throws Exception { 232 | Set drawn = new HashSet<>(); 233 | 234 | PrintWriter pw = new PrintWriter(new FileOutputStream(filename, append)); 235 | pw.println("graph G {"); 236 | 237 | for (List es : graph) { 238 | for (Edge e : es) { 239 | if (drawn.contains(e)) 240 | continue; 241 | pw.print(String.format(" %d -- %d [label=%.1f", 242 | e.from, e.to, e.weight)); 243 | if (mst.contains(e)) 244 | pw.print(", color=red"); 245 | pw.println("]"); 246 | drawn.add(e); 247 | } 248 | } 249 | 250 | pw.println("}"); 251 | pw.close(); 252 | } 253 | 254 | 255 | } 256 | -------------------------------------------------------------------------------- /competitive-programming/5-graphs/solutions/Mst.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | 4 | public class Mst { 5 | 6 | static List convert(List> nodes) { 7 | int pos = 0; 8 | Random r = new Random(0); 9 | List edges = new ArrayList<>(); 10 | for (List ns : nodes) { 11 | for (int n : ns) 12 | edges.add(new Edge(pos, n, r.nextDouble())); 13 | pos++; 14 | } 15 | return edges; 16 | } 17 | 18 | 19 | public static void main(String[] args) throws Exception { 20 | List> graph = GraphLib.readUndirectedGraphFromDotFile("uin.dot"); 21 | 22 | PriorityQueue pq = new PriorityQueue(); 23 | 24 | HashSet nodes = new HashSet<>(); 25 | List mst = new ArrayList<>(); 26 | 27 | nodes.add(0); 28 | for (Edge e : graph.get(0)) { 29 | pq.add(e); 30 | } 31 | 32 | while (nodes.size() < graph.size()) { 33 | Edge minEdge = pq.poll(); 34 | System.out.println(minEdge); 35 | System.out.println(nodes); 36 | if (minEdge == null) { 37 | System.out.println("This should not happen!"); 38 | break; 39 | } 40 | 41 | int newNode = -1; 42 | 43 | if ((nodes.contains(minEdge.from) && 44 | !nodes.contains(minEdge.to))) { 45 | newNode = minEdge.to; 46 | } else if (nodes.contains(minEdge.to) && 47 | !nodes.contains(minEdge.from)) { 48 | newNode = minEdge.from; 49 | } 50 | 51 | if (newNode == -1) 52 | continue; 53 | 54 | nodes.add(newNode); 55 | mst.add(minEdge); 56 | for (Edge e : graph.get(newNode)) { 57 | pq.add(e); 58 | } 59 | GraphLib.drawMst(graph, mst, "mst.dot", true); 60 | } 61 | 62 | // GraphLib.drawMst(graph, mst, "mst.dot"); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /competitive-programming/5-graphs/solutions/Topo.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | 4 | public class Topo { 5 | 6 | static LinkedList order = new LinkedList<>(); 7 | static List> graph; 8 | static boolean seen[]; 9 | 10 | private static void dfs(int start) { 11 | seen[start] = true; 12 | for (int i : graph.get(start)) { 13 | if (!seen[i]) { 14 | dfs(i); 15 | } 16 | } 17 | order.addFirst(start); 18 | } 19 | 20 | private static void topoSort(List> graph) { 21 | order.clear(); 22 | int n = graph.size(); 23 | seen = new boolean[n + 1]; 24 | for (int i = 0; i < n; i++) 25 | if (!seen[i]) 26 | dfs(i); 27 | } 28 | 29 | public static void main(String[] args) throws Exception { 30 | graph = GraphLib.readGraphFromDotFile("in.dot"); 31 | 32 | System.out.println("Read graph:"); 33 | GraphLib.prettyPrintGraph(graph); 34 | 35 | topoSort(graph); 36 | 37 | System.out.println("\nTopological ordering:"); 38 | System.out.println(" " + order); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /competitive-programming/5-graphs/solutions/Traversals.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | 4 | 5 | class Traversals { 6 | 7 | static int num = 0; 8 | static List> nodes; 9 | static boolean seen[]; 10 | static final LinkedList order = new LinkedList<>(); 11 | 12 | /** BFS keeps a queue of nodes to visit. At each iteration a node 13 | is removed from the queue and its neighbours added back (if not 14 | visited already). This happens until no more nodes are left to 15 | visit. **/ 16 | public static void bfs(int start) { 17 | Queue queue = new LinkedList<>(); 18 | 19 | queue.add(start); 20 | seen[start] = true; 21 | while (!queue.isEmpty()) { 22 | int node = queue.remove(); 23 | System.out.println(node); 24 | for (int neighbour : nodes.get(node)) { 25 | if (!seen[neighbour]) { 26 | seen[neighbour] = true; 27 | queue.add(neighbour); 28 | } 29 | } 30 | } 31 | } 32 | 33 | /** To transform BFS into DFS, we only need to change the queue 34 | to a stack (and corresponding method calls). **/ 35 | public static void dfsIterative(int start) { 36 | System.out.println(); 37 | Stack queue = new Stack<>(); 38 | 39 | queue.add(start); 40 | seen[start] = true; 41 | 42 | while (!queue.isEmpty()) { 43 | int node = queue.pop(); 44 | System.out.println(node); 45 | for (int neighbour : nodes.get(node)) { 46 | if (!seen[neighbour]) { 47 | seen[neighbour] = true; 48 | queue.push(neighbour); 49 | } 50 | } 51 | } 52 | } 53 | 54 | /** It's easier to write a DFS traversal recursively, since we can 55 | use the function call stack, instead of writing our 56 | own. Beware though that this may lead to stack overflow for 57 | really large graphs (typically large than 2K nodes). **/ 58 | public static void dfs(int start) throws Exception { 59 | seen[start] = true; 60 | for (int neighbour : nodes.get(start)) { 61 | if (!seen[neighbour]) { 62 | // pretty print the traversal 63 | GraphLib.printDigraph(nodes, seen, neighbour, start); 64 | dfs(neighbour); 65 | } 66 | } 67 | System.out.println(start); 68 | } 69 | 70 | public static void init(int n) { 71 | seen = new boolean[n]; 72 | for (boolean b : seen) { 73 | b = false; 74 | } 75 | order.clear(); 76 | } 77 | 78 | public static void main(String[] args) throws Exception { 79 | 80 | GraphLib.clearDigraph(); 81 | nodes = GraphLib.readGraphFromDotFile("in.dot"); 82 | 83 | int n = nodes.size(); 84 | System.out.println("Read graph: "); 85 | GraphLib.prettyPrintGraph(nodes); 86 | init(n); 87 | 88 | System.out.println("Traversing:"); 89 | for (int i = 0; i < n; i++) { 90 | if (seen[i]) continue; 91 | dfsIterative(i); 92 | GraphLib.printDigraph(nodes, seen, -1, -1); 93 | } 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /competitive-programming/5-graphs/solutions/din.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | 0 -> 1 [label=0.5] 3 | 0 -> 4 [label=0.1] 4 | 0 -> 2 [label=0.2] 5 | 1 -> 2 [label=0.3] 6 | 1 -> 3 [label=0.6] 7 | 4 -> 5 [label=0.3] 8 | 5 -> 1 [label=0.3] 9 | 5 -> 7 [label=0.7] 10 | 6 -> 5 [label=0.3]} -------------------------------------------------------------------------------- /competitive-programming/5-graphs/solutions/in.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | 0 -> 1 3 | 6 -> 2 4 | 7 -> 2 5 | 1 -> 2 6 | 2 -> 3 7 | 4 -> 3 8 | 3 -> 5 9 | } -------------------------------------------------------------------------------- /competitive-programming/5-graphs/solutions/uin.dot: -------------------------------------------------------------------------------- 1 | graph G { 2 | 0 -- 1 [label=0.5] 3 | 0 -- 4 [label=0.1] 4 | 0 -- 2 [label=0.2] 5 | 1 -- 2 [label=0.3] 6 | 1 -- 3 [label=0.6] 7 | 4 -- 5 [label=0.3] 8 | 5 -- 1 [label=0.3] 9 | 5 -- 7 [label=0.7] 10 | 6 -- 5 [label=0.3]} -------------------------------------------------------------------------------- /competitive-programming/5-graphs/templates/Dijkstra.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | class Dijkstra { 4 | 5 | public static void main(String[] args) throws Exception { 6 | 7 | List> graph = GraphLib.readDirectedGraphFromDotFile("din.dot"); 8 | 9 | // TODO implement Dijkstra in heap 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /competitive-programming/5-graphs/templates/GraphLib.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | import java.util.regex.*; 4 | 5 | 6 | /** An edge in the graph. **/ 7 | class Edge implements Comparable { 8 | Integer from, to; 9 | double weight; 10 | 11 | Edge(int from, int to, double weight) { 12 | this.from = from; 13 | this.to = to; 14 | this.weight = weight; 15 | } 16 | 17 | @Override 18 | public String toString() { 19 | return String.format("(%s, %s, %f)", from, to, weight); 20 | } 21 | 22 | @Override 23 | public int compareTo(Edge other) { 24 | return Double.compare(weight, other.weight); 25 | } 26 | 27 | @Override 28 | public int hashCode() { 29 | return from.hashCode() ^ to.hashCode(); 30 | } 31 | 32 | @Override 33 | public boolean equals(Object obj) { 34 | if (obj == null) 35 | return false; 36 | if (!(obj instanceof Edge)) 37 | return false; 38 | Edge other = (Edge) obj; 39 | return (other.from == from && other.to == to) || 40 | (other.from == to && other.to == from); 41 | } 42 | 43 | 44 | } 45 | 46 | 47 | public class GraphLib { 48 | 49 | static int num = 0; 50 | 51 | /** Make sure list has at least size elements. **/ 52 | private static void ensureSize(List> list, int size) { 53 | while (list.size() <= size) { 54 | list.add(new ArrayList()); 55 | } 56 | } 57 | 58 | /** Read a graph from a dot file and return its adjacency list. **/ 59 | public static List> readGraphFromDotFile(String filename) throws Exception { 60 | BufferedReader br = new BufferedReader(new FileReader(filename)); 61 | 62 | br.readLine(); 63 | ArrayList> graph = new ArrayList<>(); 64 | 65 | int max = 0; 66 | 67 | String line; 68 | while ( (line = br.readLine()) != null && !"}".equals(line)) { 69 | String ls[] = line.split("->"); 70 | Integer from = Integer.parseInt(ls[0].trim()); 71 | Integer to = Integer.parseInt(ls[1].trim()); 72 | 73 | max = Math.max(max, from); 74 | max = Math.max(max, to); 75 | 76 | ensureSize(graph, from); 77 | 78 | List neighbours = graph.get(from); 79 | if (neighbours == null) 80 | neighbours = new ArrayList(); 81 | 82 | neighbours.add(to); 83 | } 84 | 85 | ensureSize(graph, max); 86 | 87 | br.close(); 88 | return graph; 89 | } 90 | 91 | /** Read a graph from a dot file and return its adjacency list. **/ 92 | public static List> readDirectedGraphFromDotFile(String filename) throws Exception { 93 | return readFromDotFile(filename, false); 94 | } 95 | 96 | /** Read undirected graph from a dot file and return its adjacency list. **/ 97 | public static List> readUndirectedGraphFromDotFile(String filename) throws Exception { 98 | return readFromDotFile(filename, true); 99 | } 100 | 101 | private static List> readFromDotFile(String filename, 102 | boolean undirected) throws Exception { 103 | Scanner sc = new Scanner(new File(filename)); 104 | 105 | String line = sc.nextLine(); 106 | 107 | ArrayList> graph = new ArrayList<>(); 108 | 109 | int max = 0; 110 | 111 | String pattern = undirected ? 112 | "(\\d*) -- (\\d*) \\[label=(\\d*\\.\\d*)\\]" : 113 | "(\\d*) -> (\\d*) \\[label=(\\d*\\.\\d*)\\]"; 114 | 115 | while (sc.hasNextLine()) { 116 | sc.findInLine(pattern); 117 | 118 | MatchResult result = sc.match(); 119 | sc.nextLine(); 120 | 121 | int from = Integer.parseInt(result.group(1)); 122 | int to = Integer.parseInt(result.group(2)); 123 | double weight = Double.parseDouble(result.group(3)); 124 | 125 | max = Math.max(max, from); 126 | max = Math.max(max, to); 127 | 128 | ensureSize(graph, from); 129 | List neighbours = graph.get(from); 130 | if (neighbours == null) 131 | neighbours = new ArrayList(); 132 | neighbours.add(new Edge(from, to, weight)); 133 | 134 | if (undirected) { 135 | ensureSize(graph, to); 136 | neighbours = graph.get(to); 137 | if (neighbours == null) 138 | neighbours = new ArrayList(); 139 | neighbours.add(new Edge(to, from, weight)); 140 | } 141 | } 142 | 143 | ensureSize(graph, max); 144 | return graph; 145 | } 146 | 147 | /** Pretty print a graph given as an adjacency list. **/ 148 | public static void prettyPrintGraph(List> nodes) { 149 | int pos = 0; 150 | for (List ns : nodes) { 151 | System.out.format(" %d --> ", pos++); 152 | System.out.println(ns); 153 | } 154 | } 155 | 156 | /** Returns a fully connected graph in adjacency list format. **/ 157 | public static List> fullyConnected(int n) { 158 | List> nodes = new LinkedList<>(); 159 | for (int i = 0; i < n; i++) { 160 | List ns = new LinkedList(); 161 | nodes.add(ns); 162 | for (int j = 0; j < n; j++) 163 | if (i != j) 164 | ns.add(j); 165 | } 166 | return nodes; 167 | } 168 | 169 | /** Writes graph.dot containing a dot representation of the given graph. **/ 170 | public static void printDigraph(List> graph, 171 | boolean seen[], 172 | int neighbour, 173 | int start) throws Exception { 174 | PrintWriter writer = new PrintWriter(new FileOutputStream("graph.dot", true)); 175 | writer.println("digraph G" + num + "{"); 176 | num++; 177 | writer.println("{"); 178 | writer.println("node [style=filled]"); 179 | for (int i = 0; i < seen.length; i++) 180 | if (i == neighbour) 181 | printColor(writer, i, "blue"); 182 | else if (i == start) 183 | printColor(writer, i, "green"); 184 | else if (seen[i]) 185 | printColor(writer, i, "red"); 186 | 187 | writer.println("}"); 188 | int p = 0; 189 | for (List ns : graph) { 190 | for (int n : ns) 191 | writer.println("n" + p + " -> n" + n); 192 | writer.println(); 193 | p++; 194 | } 195 | writer.println("}"); 196 | writer.close(); 197 | } 198 | 199 | private static void printColor(PrintWriter writer, int node, String color) { 200 | writer.print(String.format("n%d [fillcolor = %s]\n", node, color)); 201 | } 202 | 203 | public static void clearDigraph() throws Exception { 204 | PrintWriter writer = new PrintWriter("graph.dot"); 205 | writer.close(); 206 | } 207 | 208 | /** Returns a randomly connected graph in adjacency list format. **/ 209 | public static List> randomlyConnected(int n) { 210 | List> nodes = new LinkedList<>(); 211 | Random r = new Random(0); 212 | int count = 0; 213 | for (int i = 0; i < n; i++) { 214 | List ns = new LinkedList(); 215 | nodes.add(ns); 216 | for (int j = 0; j < n; j++) 217 | if (i != j && r.nextDouble() < 0.4) 218 | if (j > i || !nodes.get(j).contains(i)) { 219 | ns.add(j); 220 | count++; 221 | } 222 | } 223 | System.out.println("Edge count: " + count); 224 | return nodes; 225 | } 226 | 227 | /** Write a dot graph, highlighting edges in mst with red.**/ 228 | public static void drawMst(List> graph, 229 | List mst, 230 | String filename, 231 | boolean append) throws Exception { 232 | Set drawn = new HashSet<>(); 233 | 234 | PrintWriter pw = new PrintWriter(new FileOutputStream(filename, append)); 235 | pw.println("graph G {"); 236 | 237 | for (List es : graph) { 238 | for (Edge e : es) { 239 | if (drawn.contains(e)) 240 | continue; 241 | pw.print(String.format(" %d -- %d [label=%.1f", 242 | e.from, e.to, e.weight)); 243 | if (mst.contains(e)) 244 | pw.print(", color=red"); 245 | pw.println("]"); 246 | drawn.add(e); 247 | } 248 | } 249 | 250 | pw.println("}"); 251 | pw.close(); 252 | } 253 | 254 | 255 | } 256 | -------------------------------------------------------------------------------- /competitive-programming/5-graphs/templates/Mst.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | 4 | public class Mst { 5 | 6 | public static void main(String[] args) throws Exception { 7 | List> graph = GraphLib.readUndirectedGraphFromDotFile("uin.dot"); 8 | 9 | List mst = new ArrayList<>(); 10 | // TODO Implement Prim's MST Algorithm 11 | 12 | GraphLib.drawMst(graph, mst, "mst.dot", false); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /competitive-programming/5-graphs/templates/Topo.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | 4 | public class Topo { 5 | 6 | static LinkedList order = new LinkedList<>(); 7 | static List> graph; 8 | static boolean seen[]; 9 | 10 | private static void topoSort(List> graph) { 11 | // TODO add topological sorting of graph 12 | } 13 | 14 | public static void main(String[] args) throws Exception { 15 | graph = GraphLib.readGraphFromDotFile("in.dot"); 16 | 17 | System.out.println("Read graph:"); 18 | GraphLib.prettyPrintGraph(graph); 19 | 20 | topoSort(graph); 21 | 22 | System.out.println("\nTopological ordering:"); 23 | System.out.println(" " + order); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /competitive-programming/5-graphs/templates/Traversals.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | 4 | 5 | class Traversals { 6 | 7 | static int num = 0; 8 | static List> nodes; 9 | static boolean seen[]; 10 | static final LinkedList order = new LinkedList<>(); 11 | 12 | /** BFS keeps a queue of nodes to visit. At each iteration a node 13 | is removed from the queue and its neighbours added back (if not 14 | visited already). This happens until no more nodes are left to 15 | visit. **/ 16 | public static void bfs(int start) { 17 | // TODO add BFS traversal 18 | } 19 | 20 | /** To transform BFS into DFS, we only need to change the queue 21 | to a stack (and corresponding method calls). **/ 22 | public static void dfsIterative(int start) { 23 | // TODO add iterative DFS, similar to BFS 24 | } 25 | 26 | /** It's easier to write a DFS traversal recursively, since we can 27 | use the function call stack, instead of writing our 28 | own. Beware though that this may lead to stack overflow for 29 | really large graphs (typically large than 2K nodes). **/ 30 | public static void dfs(int start) throws Exception { 31 | // TODO add recursive DFS 32 | } 33 | 34 | public static void init(int n) { 35 | seen = new boolean[n]; 36 | for (boolean b : seen) { 37 | b = false; 38 | } 39 | order.clear(); 40 | } 41 | 42 | public static void main(String[] args) throws Exception { 43 | 44 | GraphLib.clearDigraph(); 45 | nodes = GraphLib.readGraphFromDotFile("in.dot"); 46 | 47 | int n = nodes.size(); 48 | System.out.println("Read graph: "); 49 | GraphLib.prettyPrintGraph(nodes); 50 | init(n); 51 | 52 | System.out.println("Traversing:"); 53 | for (int i = 0; i < n; i++) { 54 | if (seen[i]) continue; 55 | dfsIterative(i); 56 | GraphLib.printDigraph(nodes, seen, -1, -1); 57 | } 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /competitive-programming/5-graphs/templates/din.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | 0 -> 1 [label=0.5] 3 | 0 -> 4 [label=0.1] 4 | 0 -> 2 [label=0.2] 5 | 1 -> 2 [label=0.3] 6 | 1 -> 3 [label=0.6] 7 | 4 -> 5 [label=0.3] 8 | 5 -> 1 [label=0.3] 9 | 5 -> 7 [label=0.7] 10 | 6 -> 5 [label=0.3]} -------------------------------------------------------------------------------- /competitive-programming/5-graphs/templates/in.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | 0 -> 1 3 | 6 -> 2 4 | 7 -> 2 5 | 1 -> 2 6 | 2 -> 3 7 | 4 -> 3 8 | 3 -> 5 9 | } -------------------------------------------------------------------------------- /competitive-programming/5-graphs/templates/uin.dot: -------------------------------------------------------------------------------- 1 | graph G { 2 | 0 -- 1 [label=0.5] 3 | 0 -- 4 [label=0.1] 4 | 0 -- 2 [label=0.2] 5 | 1 -- 2 [label=0.3] 6 | 1 -- 3 [label=0.6] 7 | 4 -- 5 [label=0.3] 8 | 5 -- 1 [label=0.3] 9 | 5 -- 7 [label=0.7] 10 | 6 -- 5 [label=0.3]} -------------------------------------------------------------------------------- /competitive-programming/6-geometry/advanced-programming-spring-week7.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paul-g/brabble/a6b88e528d2e7222e41924a136797e9c55903598/competitive-programming/6-geometry/advanced-programming-spring-week7.pdf -------------------------------------------------------------------------------- /competitive-programming/6-geometry/area/solution/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.util.*; 3 | import java.math.*; 4 | 5 | /** Finds the area of a polygon using double and arbitrary precision. 6 | The polygon is given as its set of vertices in plane. 7 | 8 | The main idea is to compute the signed area of all triangles 9 | formed by two adjacent vertices of the polyogn and a fixed 10 | arbitray point in plane (in this case P = (0, 0) is a convenient 11 | choices). 12 | */ 13 | class Main { 14 | 15 | public static void main(String[] args) throws Exception { 16 | long start = System.currentTimeMillis(); 17 | double dpArea = solveDouble(); 18 | System.out.format("%.6f\n", dpArea); 19 | System.out.format("Double took: %f s\n", 20 | (System.currentTimeMillis() - start) / 1000.0); 21 | 22 | start = System.currentTimeMillis(); 23 | double bdArea = solveBigDecimal(); 24 | System.out.format("%.6f\n", bdArea); 25 | System.out.format("BigDecimal took: %f s\n", 26 | (System.currentTimeMillis() - start) / 1000.0); 27 | } 28 | 29 | // using double precision arithmetic. 30 | public static double solveDouble() throws Exception { 31 | Scanner sc = new Scanner(new File("test.in")); 32 | int n = sc.nextInt(); 33 | double x, y, first_x, first_y, area = 0.0; 34 | double prev_x = sc.nextDouble(); 35 | double prev_y = sc.nextDouble(); 36 | first_x = prev_x; 37 | first_y = prev_y; 38 | 39 | for(int i = 0; i < n - 1; i++) { 40 | x = sc.nextDouble(); 41 | y = sc.nextDouble(); 42 | area += prev_x * y - x * prev_y; 43 | prev_x = x; 44 | prev_y = y; 45 | } 46 | area += prev_x * first_y - prev_y * first_x; 47 | 48 | sc.close(); 49 | return area/2; 50 | } 51 | 52 | // Using arbitrary precision arithmetic. 53 | public static double solveBigDecimal() throws Exception { 54 | Scanner sc = new Scanner(new File("test.in")); 55 | int n = sc.nextInt(); 56 | BigDecimal x, y, first_x, first_y, area = new BigDecimal("0"); 57 | BigDecimal prev_x = sc.nextBigDecimal(); 58 | BigDecimal prev_y = sc.nextBigDecimal(); 59 | first_x = prev_x; 60 | first_y = prev_y; 61 | 62 | for(int i = 0; i < n - 1; i++) { 63 | x = sc.nextBigDecimal(); 64 | y = sc.nextBigDecimal(); 65 | area = area.add(prev_x.multiply(y).subtract(x.multiply(prev_y))); 66 | prev_x = x; 67 | prev_y = y; 68 | } 69 | 70 | area = area.add(prev_x.multiply(first_y).subtract(first_x.multiply(prev_y))); 71 | 72 | sc.close(); 73 | return area.divide(new BigDecimal("2")).doubleValue(); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /competitive-programming/6-geometry/area/solution/test.in: -------------------------------------------------------------------------------- 1 | 3 2 | 0 1 3 | 0 2 4 | 1 2 -------------------------------------------------------------------------------- /competitive-programming/6-geometry/area/template/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.util.*; 3 | import java.math.*; 4 | 5 | /** Finds the area of a polygon using double and arbitrary precision. 6 | The polygon is given as its set of vertices in plane. 7 | 8 | The main idea is to compute the signed area of all triangles 9 | formed by two adjacent vertices of the polyogn and a fixed 10 | arbitray point in plane (in this case P = (0, 0) is a convenient 11 | choices). 12 | */ 13 | class Main { 14 | 15 | public static void main(String[] args) throws Exception { 16 | long start = System.currentTimeMillis(); 17 | double dpArea = solveDouble(); 18 | System.out.format("%.6f\n", dpArea); 19 | System.out.format("Double took: %f s\n", 20 | (System.currentTimeMillis() - start) / 1000.0); 21 | 22 | start = System.currentTimeMillis(); 23 | double bdArea = solveBigDecimal(); 24 | System.out.format("%.6f\n", bdArea); 25 | System.out.format("BigDecimal took: %f s\n", 26 | (System.currentTimeMillis() - start) / 1000.0); 27 | } 28 | 29 | // using double precision arithmetic. 30 | public static double solveDouble() throws Exception { 31 | Scanner sc = new Scanner(new File("test.in")); 32 | int n = sc.nextInt(); 33 | double area = 0; 34 | 35 | // TODO implement polygon area using double precision 36 | 37 | sc.close(); 38 | return area; 39 | } 40 | 41 | // Using arbitrary precision arithmetic. 42 | public static double solveBigDecimal() throws Exception { 43 | Scanner sc = new Scanner(new File("test.in")); 44 | int n = sc.nextInt(); 45 | BigDecimal area = new BigDecimal("0"); 46 | 47 | // TODO implement polygon area using big decimal 48 | 49 | sc.close(); 50 | return area.doubleValue(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /competitive-programming/6-geometry/area/template/test.in: -------------------------------------------------------------------------------- 1 | 3 2 | 0 1 3 | 0 2 4 | 1 2 -------------------------------------------------------------------------------- /competitive-programming/6-geometry/convex-hull/solution/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.util.*; 3 | 4 | 5 | class Point { 6 | double x, y; 7 | 8 | Point(double x, double y) { 9 | this.x = x; 10 | this.y = y; 11 | } 12 | 13 | public String toString() { 14 | return String.format("(%f, %f)", x, y); 15 | } 16 | } 17 | 18 | class Main { 19 | 20 | public static boolean turn_left(Point p1, Point p2, Point p3) { 21 | return 22 | (p2.x - p1.x) * (p3.y - p1.y) - 23 | (p2.y - p1.y) * (p3.x - p1.x) < 0; 24 | } 25 | 26 | public static void main(String[] args) throws Exception { 27 | Scanner sc = new Scanner(new File("hull.in")); 28 | 29 | ArrayList points = new ArrayList<>(); 30 | 31 | int n = sc.nextInt(); 32 | 33 | boolean first = true; 34 | double smallestX = 0, smallestY = 0; 35 | 36 | for (int i = 0; i < n; i++) { 37 | double x, y; 38 | x = sc.nextDouble(); 39 | y = sc.nextDouble(); 40 | 41 | if (first || (x < smallestX) || (x == smallestX && y < smallestY)) { 42 | if (!first) 43 | points.add(new Point(smallestX, smallestY)); 44 | smallestX = x; 45 | smallestY = y; 46 | first = false; 47 | } else { 48 | points.add(new Point(x, y)); 49 | } 50 | } 51 | sc.close(); 52 | 53 | Point refPoint = new Point(smallestX, smallestY); 54 | 55 | 56 | // sort 57 | Collections.sort(points, new Comparator() { 58 | public int compare(Point p1, Point p2) { 59 | return Double.compare((p1.y - refPoint.y) * (p2.x - refPoint.x), 60 | (p2.y - refPoint.y) * (p1.x - refPoint.x)); 61 | } 62 | }); 63 | 64 | 65 | points.add(refPoint); 66 | 67 | ArrayList deq = new ArrayList<>(); 68 | 69 | deq.add(refPoint); 70 | deq.add(points.get(0)); 71 | int pos = 1; 72 | 73 | while (pos < n) { 74 | 75 | Point pNext = points.get(pos++); 76 | Point p1 = deq.get(deq.size() - 1); 77 | Point p2 = deq.get(deq.size() - 2); 78 | 79 | while (!turn_left(p1, p2, pNext)) { 80 | deq.remove(deq.size() - 1); 81 | p1 = deq.get(deq.size() - 1); 82 | p2 = deq.get(deq.size() - 2); 83 | } 84 | 85 | deq.add(pNext); 86 | } 87 | 88 | System.out.println(deq.size() - 1); 89 | for (int i = 0; i < deq.size() - 1; i++) { 90 | System.out.format("%.6f %.6f\n", 91 | deq.get(i).x, 92 | deq.get(i).y); 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /competitive-programming/6-geometry/convex-hull/solution/hull.in: -------------------------------------------------------------------------------- 1 | 10 2 | -1 3 3 | 0 2 4 | 1 0 5 | 1 1 6 | 1 2 7 | 1 3 8 | 1 4 9 | 2 2 10 | 3 3 11 | 4 1 -------------------------------------------------------------------------------- /competitive-programming/6-geometry/convex-hull/template/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.util.*; 3 | 4 | class Main { 5 | 6 | public static void main(String[] args) throws Exception { 7 | Scanner sc = new Scanner(new File("hull.in")); 8 | 9 | // TODO implement Convex Hull 10 | 11 | sc.close(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /competitive-programming/6-geometry/convex-hull/template/hull.in: -------------------------------------------------------------------------------- 1 | 10 2 | -1 3 3 | 0 2 4 | 1 0 5 | 1 1 6 | 1 2 7 | 1 3 8 | 1 4 9 | 2 2 10 | 3 3 11 | 4 1 -------------------------------------------------------------------------------- /competitive-programming/7-maths/advanced-programming-spring-week8.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paul-g/brabble/a6b88e528d2e7222e41924a136797e9c55903598/competitive-programming/7-maths/advanced-programming-spring-week8.pdf -------------------------------------------------------------------------------- /competitive-programming/7-maths/solutions/Fib.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | class Fib { 4 | 5 | private static final int MOD = 666013; 6 | 7 | private static final long[][] orig = { 8 | {0, 1}, 9 | {1, 1} 10 | }; 11 | 12 | /** Using recurrence relation - really slow! */ 13 | static int fib(int n) { 14 | if (n <= 1) return n; 15 | return fib(n - 1) + fib(n - 2); 16 | } 17 | 18 | /** Using memoization */ 19 | static long fib2(long n) { 20 | if (n <= 1) return n; 21 | long f2 = 0, f1 = 1; 22 | 23 | for (long i = 2; i <= n; i++) { 24 | long prev_f1 = f1; 25 | f1 = (f1 + f2) % MOD; 26 | f2 = prev_f1; 27 | } 28 | return f1; 29 | } 30 | 31 | /** Using fast exponentation */ 32 | static long fib3(long n) { 33 | // use fast exponentation and matrix formula 34 | long[][] a = { 35 | {0, 1}, 36 | {1, 1} 37 | }; 38 | mat_pow(a, n); 39 | return a[0][1]; 40 | } 41 | 42 | static void mult(long[][] a, long[][] b) { 43 | int n = 2; 44 | long[][] c = new long[n][n]; 45 | for (int i = 0; i < n; i++) 46 | Arrays.fill(c[i], 0); 47 | 48 | for (int i = 0; i < n; i++) 49 | for (int j = 0; j < n; j++) 50 | for (int k = 0; k < n; k++) 51 | c[i][j] = (c[i][j] + (a[i][k] * b[k][j]) % MOD) % MOD; 52 | 53 | for (int i = 0; i < n; i++) 54 | System.arraycopy(c[i], 0, a[i], 0, n); 55 | } 56 | 57 | static void mat_pow(long[][] a, long n) { 58 | if (n == 1) 59 | return; 60 | mat_pow(a, n/2); 61 | mult(a, a); 62 | if (n % 2 == 1) 63 | mult(a, orig); 64 | } 65 | 66 | 67 | public static void main(String[] args) { 68 | long n = 10000000; 69 | 70 | long start = System.currentTimeMillis(); 71 | System.out.println(fib2(n)); 72 | System.out.println("fib2 took " + (System.currentTimeMillis() - start)); 73 | 74 | start = System.currentTimeMillis(); 75 | System.out.println(fib3(n)); 76 | System.out.println("fib3 took " + (System.currentTimeMillis() - start)); 77 | 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /competitive-programming/7-maths/solutions/Gauss.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | 4 | class Gauss { 5 | 6 | private static final double EPS = 0.00000001; 7 | 8 | static void swapRows(double m[][], int i, int j) { 9 | for (int k = 0; k < m[i].length; k++) { 10 | double t = m[i][k]; 11 | m[i][k] = m[j][k]; 12 | m[j][k] = t; 13 | } 14 | } 15 | 16 | static void printMat(double m[][]) { 17 | for (int i = 0; i < m.length; i++) 18 | System.out.println(Arrays.toString(m[i])); 19 | } 20 | 21 | public static void main(String[] args) throws Exception { 22 | 23 | Scanner sc = new Scanner(new File("gauss.in")); 24 | 25 | int n = sc.nextInt(); 26 | int m = sc.nextInt(); 27 | 28 | double mat[][] = new double[n][m + 1]; 29 | for (int i = 0; i < n; i++) { 30 | for (int j = 0; j < m + 1; j++) 31 | mat[i][j] = sc.nextDouble(); 32 | } 33 | 34 | // j represents the column (i.e. the variable), 35 | // i the row (i.e. the equation) 36 | int i = 0, j = 0; 37 | 38 | while (i < n && j < m) { 39 | 40 | // find a non-zero in the current column 41 | int k; 42 | for (k = i; k < n; k++) 43 | if (Math.abs(mat[k][j]) > EPS) 44 | break; 45 | 46 | if (k == n) { 47 | j++; 48 | continue; 49 | } 50 | 51 | // swap this row with the current row i 52 | if (i != k) 53 | swapRows(mat, i, k); 54 | 55 | // divide row by pivot 56 | for (int kk = j + 1; kk < m + 1; kk++) 57 | mat[i][kk] /= mat[i][j]; 58 | mat[i][j] = 1; 59 | 60 | // update all rows below the pivot row 61 | for (int kk = i + 1; kk < n; kk++) { 62 | for (int l = j + 1; l < m + 1; l++) 63 | mat[kk][l] -= mat[kk][j] * mat[i][l]; 64 | mat[kk][j] = 0; 65 | } 66 | 67 | ++i; 68 | ++j; 69 | } 70 | 71 | double x[] = new double[m + 1]; 72 | // rebuild the solution 73 | for (i = n - 1; i >= 0; i--) { 74 | for (j = 0; j < m; j++) { 75 | if (Math.abs(mat[i][j]) < EPS) continue; 76 | x[j] = mat[i][m]; 77 | for (int k = j + 1; k < m; k++) 78 | x[j] -= x[k] * mat[i][k]; 79 | break; 80 | } 81 | } 82 | 83 | System.out.println(Arrays.toString(x)); 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /competitive-programming/7-maths/solutions/Sieve.java: -------------------------------------------------------------------------------- 1 | class Sieve { 2 | 3 | private static final int MAX_PRIME = 1000000; 4 | 5 | public static void main(String[] args) { 6 | 7 | char primes[] = new char[MAX_PRIME]; 8 | 9 | for (int i = 0; i < MAX_PRIME; i++) 10 | primes[i] = 0; 11 | 12 | for (int i = 2; i < MAX_PRIME; i++) { 13 | if (primes[i] == 0) { 14 | System.out.println(i); 15 | for (int k = i; k < MAX_PRIME; k += i) 16 | primes[k] = 1; 17 | } 18 | } 19 | 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /competitive-programming/7-maths/templates/Fib.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | class Fib { 4 | 5 | private static final int MOD = 666013; 6 | 7 | private static final long[][] orig = { 8 | {0, 1}, 9 | {1, 1} 10 | }; 11 | 12 | /** Using recurrence relation - really slow! */ 13 | static int fib(int n) { 14 | return 0; 15 | } 16 | 17 | /** Using memoization */ 18 | static long fib2(long n) { 19 | return 0; 20 | } 21 | 22 | /** Using fast exponentation */ 23 | static long fib3(long n) { 24 | // use fast exponentation and matrix formula 25 | long[][] a = { 26 | {0, 1}, 27 | {1, 1} 28 | }; 29 | mat_pow(a, n); 30 | return a[0][1]; 31 | } 32 | 33 | static void mult(long[][] a, long[][] b) { 34 | int n = 2; 35 | long[][] c = new long[n][n]; 36 | for (int i = 0; i < n; i++) 37 | Arrays.fill(c[i], 0); 38 | 39 | for (int i = 0; i < n; i++) 40 | for (int j = 0; j < n; j++) 41 | for (int k = 0; k < n; k++) 42 | c[i][j] = (c[i][j] + (a[i][k] * b[k][j]) % MOD) % MOD; 43 | 44 | for (int i = 0; i < n; i++) 45 | System.arraycopy(c[i], 0, a[i], 0, n); 46 | } 47 | 48 | static void mat_pow(long[][] a, long n) { 49 | } 50 | 51 | 52 | public static void main(String[] args) { 53 | long n = 10000000; 54 | 55 | long start = System.currentTimeMillis(); 56 | System.out.println(fib2(n)); 57 | System.out.println("fib2 took " + (System.currentTimeMillis() - start)); 58 | 59 | start = System.currentTimeMillis(); 60 | System.out.println(fib3(n)); 61 | System.out.println("fib3 took " + (System.currentTimeMillis() - start)); 62 | 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /competitive-programming/7-maths/templates/Gauss.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | 4 | class Gauss { 5 | 6 | private static final double EPS = 0.00000001; 7 | 8 | static void swapRows(double m[][], int i, int j) { 9 | for (int k = 0; k < m[i].length; k++) { 10 | double t = m[i][k]; 11 | m[i][k] = m[j][k]; 12 | m[j][k] = t; 13 | } 14 | } 15 | 16 | static void printMat(double m[][]) { 17 | for (int i = 0; i < m.length; i++) 18 | System.out.println(Arrays.toString(m[i])); 19 | } 20 | 21 | public static void main(String[] args) throws Exception { 22 | 23 | Scanner sc = new Scanner(new File("gauss.in")); 24 | 25 | int n = sc.nextInt(); 26 | int m = sc.nextInt(); 27 | 28 | double mat[][] = new double[n][m + 1]; 29 | for (int i = 0; i < n; i++) { 30 | for (int j = 0; j < m + 1; j++) 31 | mat[i][j] = sc.nextDouble(); 32 | } 33 | 34 | // j represents the column (i.e. the variable), 35 | // i the row (i.e. the equation) 36 | int i = 0, j = 0; 37 | 38 | // TODO reduce system matrix to row echelon form 39 | while (i < n && j < m) { 40 | 41 | } 42 | 43 | double x[] = new double[m + 1]; 44 | // TODO rebuild the solution 45 | 46 | System.out.println(Arrays.toString(x)); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /competitive-programming/7-maths/templates/Sieve.java: -------------------------------------------------------------------------------- 1 | class Sieve { 2 | 3 | private static final int MAX_PRIME = 1000000; 4 | 5 | public static void main(String[] args) { 6 | 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /competitive-programming/7-maths/templates/gauss.in: -------------------------------------------------------------------------------- 1 | 3 3 2 | 2 1 -1 8 3 | -3 -1 2 -11 4 | -2 1 2 -3 -------------------------------------------------------------------------------- /competitive-programming/readme.md: -------------------------------------------------------------------------------- 1 | About brabble 2 | ============= 3 | 4 | __brabble__ is a crash course in competitive programming held at 5 | Imperial College London as part of the 1st year Advanced Programming 6 | Lectures. 7 | 8 | We go over basic approaches to solve problems which are selected from 9 | an online judge. We use Java and Python. 10 | 11 | 12 | ## Useful Links 13 | 14 | There is a lot of great material on competitive programming: 15 | 16 | 1. [The UVA Online Judge](http://uva.onlinejudge.org/) has a massive 17 | problem collection 18 | 2. Use [uhunt](http://uhunt.felix-halim.net/) to keep track of 19 | interesting problems to solve 20 | 3. [codeforces](http://codeforces.com) and 21 | [TopCoder](http://topcoder.com) provide a host of real-time online 22 | programming contests (often thousands of contestants) so are a 23 | great way to gain some contest experiences 24 | 4. You will also find it useful to read about 25 | [Java Collections API](http://docs.oracle.com/javase/7/docs/api/java/util/Collections.html) 26 | 27 | ## Useful Books 28 | 29 | A few books you will definitely find useful: 30 | 31 | 1. _Introduction to Algorithms_, Charles E. Leiserson, Ronald Rivest, 32 | Thomas H. Cormen, and Clifford Stein 33 | 34 | 2. _Competitive Programming_, Steven Halim, Felix Halim 35 | 36 | 3. _The Algorithm Design Manual_, Steven Skiena 37 | 38 | 39 | ## Topics Covered 40 | 41 | | Week | Topic | 42 | |------|----------------------------------------| 43 | | 1 | Background and Implementation Problems | 44 | | 2 | Complete Search | 45 | | 3 | Divide and Conquer | 46 | | 4 | Greedy, Dynamic Programming | 47 | | 5, 6 | Graphs | 48 | | 7 | Geometry | 49 | | 8 | Maths | 50 | 51 | 52 | There is a directory for each week in which you will find: 53 | 54 | 1. slides for the lecture 55 | 2. templates for the problems to get you started quickly 56 | 3. solutions (usually tested on an online judge) 57 | 58 | Use the provided solution if you get stuck, but try spending at least 59 | 15 mins before resorting to such drastic measures... :) 60 | -------------------------------------------------------------------------------- /performance-aware-programming/Readme.md: -------------------------------------------------------------------------------- 1 | This is a set of four introductory lectures on Performance Aware 2 | Programming. 3 | 4 | 5 | #### Lecture 1 - Measuring 6 | 7 | Defines performance and looks at how we can measure it in our 8 | programs using various Linux builtins and Java method calls. The 9 | [accompanying example](src/lecture1) shows the impact of the loop 10 | interchange optimisation on the performance of matrix 11 | multiplication. A script is provided to run the experiment for 12 | varying input sizes and plot the results. 13 | 14 | ####Lecture 2 -- Algorithms 15 | 16 | We look at the Discrete Knapsack problem and we show just how large 17 | the performance impact of clever algorithms can be: we start by 18 | developing a Complete Search version and then optimise this to cache 19 | re-ocurring subproblems (cf. Dynamic Programming) to great effect. 20 | 21 | #### Lecture 3 -- Hardware 22 | 23 | We analyse the impact of the underlying hardware on the performance of 24 | our programs. In particular we investigate how understanding the cache 25 | hierarchy and CPU architecture can help us write code which is more 26 | easily optimised by the JVM. 27 | 28 | ### In Progress 29 | These lectures are in progress and will be uploaded after they have been presented. 30 | 31 | * __Lecture 4 -- Tools__ -- how to get the most of our tools when programming 32 | 33 | Compiling the slides requires pandoc >= 1.12. Example: 34 | 35 | ``` 36 | pandoc -t beamer lecture1.md -o lecture1.pdf 37 | ``` 38 | 39 | Compiling and running the examples in `src/` requires Oracle Java JDK >= 1.8. Example: 40 | 41 | ``` 42 | cd src/lecture1 43 | javac Measuring.java && java Measuring 44 | ``` 45 | 46 | 47 | ### Requires 48 | 49 | 1. gnuplot and gnuplot-x11 50 | 2. Oracle Java JDK 1.8 51 | 52 | You can install gnuplot using 53 | 54 | ``` 55 | sudo apt-get install gnuplot-x11 56 | ``` 57 | 58 | Instructions on installing Java 1.8 can be found [here](http://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html). 59 | -------------------------------------------------------------------------------- /performance-aware-programming/img/algorithms.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paul-g/brabble/a6b88e528d2e7222e41924a136797e9c55903598/performance-aware-programming/img/algorithms.jpg -------------------------------------------------------------------------------- /performance-aware-programming/img/cache1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paul-g/brabble/a6b88e528d2e7222e41924a136797e9c55903598/performance-aware-programming/img/cache1.png -------------------------------------------------------------------------------- /performance-aware-programming/img/cache2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paul-g/brabble/a6b88e528d2e7222e41924a136797e9c55903598/performance-aware-programming/img/cache2.png -------------------------------------------------------------------------------- /performance-aware-programming/img/cache3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paul-g/brabble/a6b88e528d2e7222e41924a136797e9c55903598/performance-aware-programming/img/cache3.png -------------------------------------------------------------------------------- /performance-aware-programming/img/cache4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paul-g/brabble/a6b88e528d2e7222e41924a136797e9c55903598/performance-aware-programming/img/cache4.png -------------------------------------------------------------------------------- /performance-aware-programming/img/cache5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paul-g/brabble/a6b88e528d2e7222e41924a136797e9c55903598/performance-aware-programming/img/cache5.png -------------------------------------------------------------------------------- /performance-aware-programming/img/cache6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paul-g/brabble/a6b88e528d2e7222e41924a136797e9c55903598/performance-aware-programming/img/cache6.png -------------------------------------------------------------------------------- /performance-aware-programming/img/java.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paul-g/brabble/a6b88e528d2e7222e41924a136797e9c55903598/performance-aware-programming/img/java.png -------------------------------------------------------------------------------- /performance-aware-programming/img/loop-interchange.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paul-g/brabble/a6b88e528d2e7222e41924a136797e9c55903598/performance-aware-programming/img/loop-interchange.png -------------------------------------------------------------------------------- /performance-aware-programming/img/matrix-multiply.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paul-g/brabble/a6b88e528d2e7222e41924a136797e9c55903598/performance-aware-programming/img/matrix-multiply.png -------------------------------------------------------------------------------- /performance-aware-programming/img/matrix_mult.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paul-g/brabble/a6b88e528d2e7222e41924a136797e9c55903598/performance-aware-programming/img/matrix_mult.png -------------------------------------------------------------------------------- /performance-aware-programming/img/no-idea.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paul-g/brabble/a6b88e528d2e7222e41924a136797e9c55903598/performance-aware-programming/img/no-idea.jpg -------------------------------------------------------------------------------- /performance-aware-programming/img/no-questions.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paul-g/brabble/a6b88e528d2e7222e41924a136797e9c55903598/performance-aware-programming/img/no-questions.jpg -------------------------------------------------------------------------------- /performance-aware-programming/img/overlapping.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paul-g/brabble/a6b88e528d2e7222e41924a136797e9c55903598/performance-aware-programming/img/overlapping.png -------------------------------------------------------------------------------- /performance-aware-programming/img/right.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paul-g/brabble/a6b88e528d2e7222e41924a136797e9c55903598/performance-aware-programming/img/right.jpg -------------------------------------------------------------------------------- /performance-aware-programming/img/skiena.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paul-g/brabble/a6b88e528d2e7222e41924a136797e9c55903598/performance-aware-programming/img/skiena.jpg -------------------------------------------------------------------------------- /performance-aware-programming/img/slow.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paul-g/brabble/a6b88e528d2e7222e41924a136797e9c55903598/performance-aware-programming/img/slow.jpg -------------------------------------------------------------------------------- /performance-aware-programming/img/vectorization.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paul-g/brabble/a6b88e528d2e7222e41924a136797e9c55903598/performance-aware-programming/img/vectorization.png -------------------------------------------------------------------------------- /performance-aware-programming/lecture1.md: -------------------------------------------------------------------------------- 1 | % Performance Aware Programming 2 | % Paul Grigoras 3 | 4 | # Aware != Expert 5 | 6 | # What is Performance? 7 | 8 | ## What is Performance? 9 | 10 | * The canonical definition of performance\footnote{Patterson \& 11 | Henessey, Computer Organization and Design} 12 | $$ P = \frac{1}{Wall Clock Time} $$ 13 | 14 | * Wall Clock Time is the total elapsed time when performing a task 15 | * It includes the processing time as well as time spent waiting for 16 | I/O, operating system overhead etc. 17 | * There are other times we may be interested to measure 18 | (e.g. user/kernel CPU time), so it's important to distinguish 19 | 20 | ## What is Performance? 21 | 22 | * System/application designers may also be interested in other measures 23 | * _MIPS_ \ \ \ -- Millions of instructions / sec 24 | * _GFLOPS_ -- Billions of floating point operations / sec 25 | * _GB/s_ \ \ \ -- DRAM/Disk/Cache/Network bandwidth 26 | * _CPI_ \ \ \ \ \ -- Cycles per instruction 27 | * Useful for understanding the bottlenecks of a system 28 | 29 | * But these do not tell the _whole story_ as well as $P$ does 30 | * _As a user I (generally) want my program to run __faster___ 31 | * I don't necessarily care about the factors involved 32 | 33 | ## Is Performance the Most Important Property? 34 | 35 | * No! The most important property of a program is _correctness_ 36 | * But, often _correctness_ requires _performance_: 37 | * Launch abort system on the space shuttle triggers correctly... 38 | * ... 3 seconds after it's supposed to 39 | * Airbags on a car trigger correctly... 40 | * ... 5 seconds after impact 41 | * And often, _correct_ but slow programs are plain _useless_: 42 | * Tomorrow's weather forecast is correct... 43 | * ...the day after tomorrow 44 | * When improving the performance of a program (_optimising_) __always 45 | check the results are correct__ 46 | 47 | # Why Care About Performance? 48 | 49 | ## Motivation 50 | 51 | * Better _performance_ often results in: 52 | * Improved customer experience 53 | * Substantial savings in operating costs 54 | * Facilitating otherwise impossible tasks 55 | * Sample effects of low performance: 56 | * __Operating System__ Laggy UI => Sad customers :( 57 | * __Data Centers__ more servers => increased costs 58 | * __Battery life__ more processing time => shorter battery life 59 | * __Weather prediction__ smaller simulation accuracy => less accurate 60 | results 61 | 62 | ## Challenges 63 | 64 | 1. Maximising performance requires a good understanding of the entire 65 | software and hardware stack 66 | 67 | 2. Complex interaction between the different layers (system, algorithm, 68 | OS, hardware) may lead to surprising, hard to explain results 69 | 70 | 3. Optimisation must not affect correctness of results (sometimes 71 | difficult e.g. when computing with floating point) 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | ## Outline 85 | 86 | Outline for this and next three lectures: 87 | 88 | 1. __Measuring__ -- measuring application performance in Linux/Java 89 | 2. __Algorithms__ -- the impact of smart programs, efficiently 90 | implemented 91 | 3. __Hardware__ -- the impact of the underlying hardware on the 92 | performance of our programs 93 | 4. __Tools__ -- how to get the most of our tools when programming 94 | 95 | # 1. Measuring 96 | 97 | ## Measuring 98 | 99 | * To compare applications on performance we need to 100 | * _estimate_ performance -- predict how fast and application is 101 | based on a well established, generic model 102 | * _measure_ performance -- measure how our implementation performs 103 | in practice 104 | 105 | * We use _computational complexity_ to estimate the performance of an 106 | algorithm 107 | * We use various system and programming language utilities to 108 | _measure_ the performance of an implementation 109 | 110 | ## Estimating Performance - Computational Complexity 111 | 112 | * Model for _estimating_ the relative performance of 113 | algorithms 114 | * Ignores implementation aspects (e.g. all operations identical) 115 | ```Java 116 | for (int i = 0; i < n; i++) 117 | for (int j = 0; j < n; j++) 118 | for (int k = 0; k < n; k++) 119 | sum += i * j * k; 120 | ``` 121 | 122 | . . . 123 | 124 | * This algorithm performs $3n^3$ arithmetic operations 125 | * We may refer to it as having complexity $O(n^3)$ 126 | * it performs no worse than $c n^3$ for some c and large ns 127 | * the constant factor c is ignored in big Oh notation 128 | * in practice, the value of _c_ is often quite important 129 | 130 | . . . 131 | 132 | * So how do we _measure_ the performance of a program? 133 | 134 | ## Measuring Performance 135 | 136 | * We will use $P = \frac{1}{Wall Clock Time}$ 137 | * This means (in general) we measure wall clock _execution time_ 138 | * Assume we normally run our program with 139 | * `$ java Measuring 512` 140 | 141 | . . . 142 | 143 | ### Measuring Execution Time in Linux 144 | 145 | * Can measure runtime from the command line 146 | ``` 147 | $ time java Measuring 512 148 | real 0m18.522s user 0m18.561s sys 0m0.060s 149 | ``` 150 | * But this one is probably better 151 | ``` 152 | $ /usr/bin/time -v java Measuring 512 153 | ``` 154 | 155 | ## Measuring performance 156 | 157 | ``` 158 | $ time java Measuring 512 159 | real 0m18.522s user 0m18.561s sys 0m0.060s 160 | ``` 161 | * `real` -- the _wall clock time_ 162 | * `user` -- time spent running user code 163 | * `sys` -- time spent running operating system kernel code 164 | 165 | ### Important! 166 | * `user` and `sys` are _CPU times_ -- they only include 167 | time spent actually running on the CPU 168 | * the time spent (e.g. on I/O operations), is not included in `user` 169 | and `sys`, but _it is included_ in `real` 170 | * most of the time we are interested in the `real` time 171 | 172 | . . . 173 | 174 | * CPU time is reported across cores, which is why `user` + `sys` may 175 | be greater than `real` 176 | 177 | ## Java Profiler 178 | 179 | ### Command Line 180 | * Use the `-Xprof` flag to enable runtime profiling 181 | ``` 182 | java -Xprof Measuring 183 | ``` 184 | 185 | ### Visual VM 186 | 187 | 1. May find with `locate jvisualvm | grep bin` 188 | 2. Start the profiler, then run an application 189 | 3. Select correct JVM instance from the GUI and poke around 190 | 191 | 192 | * Granularity of the profiler may not be enough so we use language 193 | APIs to measure execution time 194 | * Profiling may introduce overhead which can affect results 195 | 196 | ## Measuring Execution Time In Java 197 | 198 | It is often useful to measure (wall clock) execution time of some 199 | fragments of code ourselves. We can do this easily in Java. 200 | 201 | * Millisecond resolution 202 | ```Java 203 | long start = System.getCurrentTimeMillis(); 204 | // Do work 205 | long tookMs = System.getCurrentTimeMillis() - start; 206 | ``` 207 | 208 | * Nanosecond resolution: 209 | ```Java 210 | long startTime = System.nanoTime(); 211 | ``` 212 | 213 | ## Running Example - Matrix Multiply 214 | 215 | * Let's implement a simple matrix multiply optimisation 216 | * $A B = C$, where A, B, C -- square matrices (same rank) 217 | * $C_{i, j} = \sum\limits_{k=1}^nA_{i,k}B_{k,j}$ 218 | 219 | * Steps 220 | 1. Measure and save the running times for various sizes 221 | 2. Do some post-processing and plot the results (size vs time) 222 | 3. Optimise the matrix multiplication 223 | 4. Plot and compare optimised vs un-optimised 224 | 225 | ## Automating with Shell Scripts 226 | * We don't want to repeat any pre/post processing steps 227 | * We write `scripts` to automate these steps 228 | * Scripts are small programs that glue together a few programs and 229 | can provide easy automation for many use cases 230 | * We can write a script to benchmark our code for various input sizes 231 | ```bash 232 | function run_benchmark() { 233 | javac Measuring.java 234 | for i in {64..1024..32} 235 | do 236 | java Measuring $i | tee -a out 237 | done 238 | } 239 | ``` 240 | 241 | 242 | ## Visualisation 243 | 244 | ### gnuplot 245 | * use to plot raw data, functions etc. e.g.: 246 | ``` 247 | $ gnuplot 248 | $ gnuplot> plot sin(x)/x 249 | ``` 250 | 251 | * we can write _gnuplot scripts_ -- great for automation 252 | * we can even make gnuplot udpate itself using: 253 | ``` 254 | pause