├── README.md ├── interview_materials └── interview_basic_questions.docx ├── partners ├── axway-logo.jpg ├── experian-logo.jpg └── nemetschek_logo.jpg ├── week01 ├── Anagrams │ └── README.md ├── Gas-Stations │ └── README.md ├── Parsing │ └── README.md ├── StaticArrays │ ├── Arr.java │ └── README.md ├── Tuesday │ └── README.md └── materials │ ├── Listify.jar │ ├── Parser.java │ ├── README.md │ └── images │ ├── after_compiling.png │ ├── compiling_all_the_files.png │ ├── compiling_the_project.png │ ├── jar_file_compilation.png │ ├── jar_folders_2.png │ ├── jar_folders_start.png │ ├── running_the_project.png │ ├── using_jar_error.png │ └── using_jar_example1.png ├── week02 ├── FunctionCalls │ └── README.md ├── FunctionCallsExtension │ └── README.md ├── GameOfLife │ └── README.md └── Polynomials │ └── README.md ├── week03 ├── Complexities │ └── complexities.md ├── Linked-List │ ├── MyLinkedList.java │ ├── MyLinkedListInterface.java │ ├── MyQueueInterface.java │ ├── MyStackInterface.java │ └── REAMDE.md └── materials │ ├── LinkedList.md │ └── complexity_analysis.md ├── week04 ├── binary_search_tree │ ├── README.md │ └── Tree.java ├── bonus_tasks │ └── breakfast.md ├── materials │ ├── binary_search_trees.md │ ├── exceptions.md │ └── stacks_and_queues.md └── stacks_and_queues │ └── README.md ├── week06 ├── maps │ ├── README.md │ └── example │ │ ├── BucketInterface.java │ │ ├── LinkedBucket.java │ │ ├── Map.java │ │ └── MapInterface.java ├── materials │ ├── maps.md │ └── sorting.md └── sorting │ └── README.md ├── week07 ├── PandaSocialNetwork │ └── README.md ├── materials │ └── soring.md └── sorting │ └── README.md ├── week08 ├── DungeonsAndZombies │ └── README.md └── ZombieApocalypse │ └── README.md ├── week09 ├── 01-SQL-Starter │ ├── README.md │ ├── movies.sql │ ├── movies_schema.png │ └── queries.md └── materials │ └── Main.java ├── week10 ├── Cinema-Reservation │ └── README.md └── Type-Checking │ └── README.md ├── week11 ├── HackUnit │ └── src │ │ └── com │ │ └── hackbulgaria │ │ ├── Main.java │ │ └── hackunit │ │ ├── Assert.java │ │ ├── HackUnitCore.java │ │ ├── Results.java │ │ ├── Test.java │ │ ├── outcomes │ │ ├── Error.java │ │ ├── Failure.java │ │ ├── Outcome.java │ │ └── Success.java │ │ └── tests │ │ └── MyTests.java ├── README.md └── materials │ ├── Model.java │ ├── MySQLHelper.java │ └── ObjectModel.java ├── week12 ├── Drone-Delivery-System │ └── README.md └── materials │ └── README.md ├── week14 ├── Thursday │ ├── IschlemeSoft │ │ └── src │ │ │ └── com │ │ │ └── hackbulgaria │ │ │ ├── Developer.java │ │ │ ├── ProjectManager.java │ │ │ ├── Skill.java │ │ │ ├── Task.java │ │ │ └── Util.java │ └── README.md └── prereadings │ └── README.md ├── week15 ├── Thursday │ ├── DiningPhilosophers │ │ └── src │ │ │ └── com │ │ │ └── hackbulgaria │ │ │ └── philosophers │ │ │ ├── Fork.java │ │ │ ├── Main.java │ │ │ └── Philosopher.java │ └── ThreadSignalling │ │ └── src │ │ └── com │ │ └── hackbulgaria │ │ └── signalling │ │ ├── Main.java │ │ ├── Notifier.java │ │ ├── Signal.java │ │ ├── Util.java │ │ └── Waiter.java ├── Tuesday │ └── README.md └── prereadings │ └── README.md └── week16 └── materials ├── AboutUs.java ├── Index.java ├── aboutus.jsp ├── footer.jsp ├── header.jsp └── index.jsp /README.md: -------------------------------------------------------------------------------- 1 | # Programming101-Java-2016 2 | Course materials & problems for HackBulgaria's Programming 101 with Java. Starting October 2016. 3 | 4 | ## Partners 5 | 6 | The course is happening thanks to: 7 | 8 | [![Experian](/partners/experian-logo.jpg)](http://www.experian.bg/) 9 | [![Axway](/partners/axway-logo.jpg)](https://www.axway.com/en) 10 | [![Nemetschek Bulgaria](/partners/nemetschek_logo.jpg)](https://www.nemetschek.bg/) 11 | 12 | 13 | ## Course weeks 14 | 15 | | Week | Date | Tasks | Presentation | 16 | |---------|-------- |---------|-------------| 17 | | 1 | Tuesday - 18.10|[Tasks for week1](week01/) | [Presentation for week1](https://slides.com/hackbulgaria/deck-40-64/) | 18 | | 1 | Thirsday - 20.10|[Tasks for week1](week01/) | [Presentation for week1](http://slides.com/hackbulgaria/deck-40-64-67/) | 19 | | 2 | Tuesday - 25.10|[Tasks for week2](week02/) | | 20 | | 2 | Thirsday - 27.10|[Tasks for week2](week02/) | | 21 | | 2 | Friday - 28.10|[Pair programming task](week02/GameOfLife/) | | 22 | | 3 | Thirsday - 03.11|[Tasks for week3](week03/) | | 23 | | 4 | Tuesday - 08.11|[Tasks for week4](week04/) | | 24 | | 4 | Thirsday - 10.11|[Tasks for week4](week04/) | | 25 | | 4 | Friday - 11.11|[Tasks for week4](week04/) | | 26 | | 5 | Tuesday - 15.11|Exercising Recursion | | 27 | 28 | ## Course Program 29 | 30 | ### Week 1 31 | 32 | * Introduction to Shell & basic Linux commands 33 | * Java command-line tools - java, javac, jar 34 | * Introduction to Java - syntax, proble solving without IDE 35 | 36 | ### Week 2 37 | * Getting familiar with Java using Eclipse. 38 | * Types, everything’s an object, containers. 39 | * Intuition about generics. 40 | 41 | ### Week 3 42 | * Learning how to deal with the basic OOP concepts so we can use the standard library. 43 | * Introduction to jUnit - testing everything. 44 | 45 | ### Week 4 46 | * Intuition about Java Collections & Data Structures. 47 | * Solving more algorithmic problems. 48 | 49 | ### Week 5 50 | * Solving more algorithmic problems. 51 | 52 | ### Week 6 53 | * Solving more algorithmic problems. 54 | 55 | ### Week 7 56 | * Solving more algorithmic problems. 57 | 58 | ### Week 8 59 | * Revisiting OOP concepts - interfaces, abstract classes, inheritance, polymorphism, generics. 60 | * Java exceptions mechanism. 61 | 62 | ### Week 9 63 | * Revisiting OOP concepts - interfaces, abstract classes, inheritance, polymorphism, generics. 64 | * Java exceptions mechanism. 65 | 66 | ### Week 10 67 | * Introduction to relational databases - dealing with SQL. 68 | 69 | ### Week 11 70 | * Using Java with SQL database - persisting data & state. 71 | 72 | ### Week 12 73 | * Using Java with SQL database - persisting data & state. 74 | 75 | ### Week 13 76 | * Annotations & Reflection 77 | * ORM with Hibernate 78 | 79 | ### Week 14 80 | * Threads. Threads everywhere. 81 | 82 | ### Week 15 83 | * Threads. Threads everywhere. 84 | 85 | ### Week 16 86 | * Interview preparation 87 | -------------------------------------------------------------------------------- /interview_materials/interview_basic_questions.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HackBulgaria/Programming101-Java-2016/f9e042f9c6c4fc844836f938cd8ed8a3e5d6fcdd/interview_materials/interview_basic_questions.docx -------------------------------------------------------------------------------- /partners/axway-logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HackBulgaria/Programming101-Java-2016/f9e042f9c6c4fc844836f938cd8ed8a3e5d6fcdd/partners/axway-logo.jpg -------------------------------------------------------------------------------- /partners/experian-logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HackBulgaria/Programming101-Java-2016/f9e042f9c6c4fc844836f938cd8ed8a3e5d6fcdd/partners/experian-logo.jpg -------------------------------------------------------------------------------- /partners/nemetschek_logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HackBulgaria/Programming101-Java-2016/f9e042f9c6c4fc844836f938cd8ed8a3e5d6fcdd/partners/nemetschek_logo.jpg -------------------------------------------------------------------------------- /week01/Anagrams/README.md: -------------------------------------------------------------------------------- 1 | # Are two words anagrams? 2 | 3 | In a class `Anagrams`, implement a static method `boolen areAnagrams(String a, String b)`. 4 | 5 | For anagrams, check here - https://en.wikipedia.org/wiki/Anagram 6 | 7 | For example, `listen` and `silent` are anagrams. 8 | 9 | The program should read two words from the standard input and output: 10 | 11 | * `ANAGRAMS` if the words are anagrams of each other 12 | * `NOT ANAGRAMS` if the two words are not anagrams of each other 13 | 14 | **Consider lowering the case of the two words since the case does not matter. `SILENT` and `listen` are also anagrams.** 15 | 16 | ## Boilerplate 17 | 18 | ```java 19 | import java.util.Scanner; 20 | 21 | public class Anagrams { 22 | 23 | public static boolean areAnagrams(String a, String b) { 24 | return false; 25 | } 26 | 27 | public static void main(String[] args) { 28 | Scanner scanner = new Scanner(System.in); 29 | 30 | String a = scanner.next(); 31 | String b = scanner.next(); 32 | 33 | if (areAnagrams(a, b)) { 34 | System.out.println("ANAGRAMS"); 35 | } else { 36 | System.out.println("NOT ANAGRAMS"); 37 | } 38 | } 39 | } 40 | ``` 41 | 42 | ## Examples 43 | 44 | Input: 45 | 46 | ``` 47 | silent listen 48 | ``` 49 | 50 | Output: 51 | 52 | ``` 53 | ANAGRAMS 54 | ``` 55 | 56 | --- 57 | 58 | Input: 59 | 60 | ``` 61 | TOP_CODER COTO_PRODE 62 | ``` 63 | 64 | Output: 65 | 66 | ``` 67 | NOT ANAGRAMS 68 | ``` 69 | 70 | --- 71 | 72 | Input: 73 | 74 | ``` 75 | kilata cvetelina_yaneva 76 | ``` 77 | 78 | Output: 79 | 80 | ``` 81 | NOT ANAGRAMS 82 | ``` 83 | 84 | Also, should not make songs together. 85 | 86 | --- 87 | 88 | Input: 89 | 90 | ``` 91 | BRADE BEARD 92 | ``` 93 | 94 | Output: 95 | 96 | ``` 97 | ANAGRAMS 98 | ``` 99 | -------------------------------------------------------------------------------- /week01/Gas-Stations/README.md: -------------------------------------------------------------------------------- 1 | # Gas Stations 2 | 3 | We are implementing a smart GPS software. 4 | 5 | - We are taking a long trip from Sofia to Vratsa and we know the distance between the two cities.It is a positive integer and we mark it as ``tripDistance``. 6 | 7 | - We know how much our car can ride with a full tank of gas. It is a positive integer in kilometers. We mark it as ``tankSize``. 8 | 9 | - We know how much gas stations are there on our roude. It is a positive intager and we mark it as ``gasStationsCount`` 10 | 11 | - We have a list of gas stations. We know the distance between Sofia and the current gas station. ``gasStations = [50, 80, 110, 180, 220, 290]`` The list is sorted! 12 | 13 | By using this information we will implement a function that returns the shortest list of gas stations that we have to visit in order to travel from Sofia to Vratsa. Know that are allways starting with a full tank. 14 | 15 | ##Here is a boilerplate class ready to take console input: 16 | 17 | ```java 18 | public class GPS { 19 | 20 | public static Vector getGasStations(int tripDistance, int tankSize, Vector gasStations) { 21 | return new Vector(); 22 | } 23 | 24 | public static void main(String[] args) { 25 | Scanner scanner = new Scanner(System.in); 26 | int tripDistance = scanner.nextInt(); 27 | int tankSize = scanner.nextInt(); 28 | 29 | int gasStationsCount = scanner.nextInt(); 30 | Vector gasStations = new Vector(); 31 | 32 | for (int i = 0; i < gasStationsCount; i++) { 33 | gasStations.add(scanner.nextInt()); 34 | } 35 | 36 | Vector result = getGasStations(tripDistance, tankSize, gasStations); 37 | 38 | for (int i = 0; i < result.size(); i++) { 39 | System.out.println(result.get(i)); 40 | } 41 | 42 | } 43 | } 44 | ``` 45 | 46 | ## Example 47 | For input 48 | ``` 49 | 320 50 | 90 51 | 6 52 | 50 53 | 80 54 | 140 55 | 180 56 | 220 57 | 290 58 | ``` 59 | 60 | Give the following output: 61 | 62 | ``` 63 | 80 64 | 140 65 | 220 66 | 290 67 | ``` 68 | -------------------------------------------------------------------------------- /week01/Parsing/README.md: -------------------------------------------------------------------------------- 1 | # Parse an .ini file to json 2 | 3 | In a `class Parser`, implement a method that reads an `.ini` file and parses it to json. 4 | 5 | ## What's an INI file? 6 | 7 | The INI file format is an informal standard for configuration files for some platforms or software. INI files are simple text files with a basic structure composed of sections, properties, and values. 8 | 9 | An INI file looks something like this: 10 | 11 | ``` 12 | [panda] 13 | name=Stamat 14 | lazyness=95 15 | cuteness=123 16 | 17 | [unicorn] 18 | name=Pencho 19 | age=0.3 bilion 20 | horns=1 21 | probability=0.1e-50000 22 | ``` 23 | 24 | ## What's a JSON file? 25 | 26 | JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. It is based on a subset of the JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999. 27 | 28 | A JSON file looks something like this: 29 | 30 | ``` 31 | { 32 | "panda": { 33 | "name": "Stamat", 34 | "lazyness": "95", 35 | "cuteness": "123" 36 | }, 37 | "unicorn": { 38 | "name": "Pencho", 39 | "age": "0.3 bilion", 40 | "horns": "1", 41 | "probability": "0.1e-50000" 42 | } 43 | } 44 | ``` 45 | 46 | ## Gotchas 47 | 48 | * There can be multiple blank lines all over the file for readability purposes, they should just be ignored when parsing it. 49 | * Spaces around equal signs and trailing spaces should be ok, although it's a good idea to warn that other parsers might not be as benevolent as ours. 50 | * Lines starting with a semicolon(`;`) are comments, and should be ignored when parsing. 51 | 52 | ## Help at your side 53 | 54 | In order to help you with this task we created a `class Listify` that reads a file and returns its contents as a `String[]` 55 | 56 | ```java 57 | package com.listify; 58 | 59 | import java.util.List; 60 | import java.util.LinkedList; 61 | import java.io.IOException; 62 | import java.nio.file.Files; 63 | import java.nio.file.Paths; 64 | import java.util.function.Consumer; 65 | 66 | public class Listify { 67 | public static String[] readToArray(String filename) { 68 | List contents = new LinkedList<>(); 69 | try{ 70 | contents = read(filename); 71 | }catch(IOException e){ 72 | e.printStackTrace(); 73 | return null; 74 | } 75 | return contents.toArray(new String[contents.size()]); 76 | } 77 | 78 | private static List read(String filename) throws java.io.IOException { 79 | return Files.readAllLines(Paths.get(filename)); 80 | } 81 | } 82 | ``` 83 | -------------------------------------------------------------------------------- /week01/StaticArrays/Arr.java: -------------------------------------------------------------------------------- 1 | package com.hackbulgaria.programming51.week3; 2 | 3 | public class Arr { 4 | public static String toString(int[] a) { 5 | return ""; 6 | } 7 | 8 | public static void sort(int[] a) { 9 | 10 | } 11 | 12 | public static int[] reverse(int[] a) { 13 | return new int[a.length]; 14 | } 15 | 16 | public static String join(int[] a, String glue) { 17 | return ""; 18 | } 19 | 20 | public static int sum(int[] a) { 21 | return 0; 22 | } 23 | 24 | public static int[] range(int a, int b) { 25 | return new int[Math.abs(b - a)]; 26 | } 27 | 28 | public static int[] filterOdd(int[] a) { 29 | return new int[a.length]; 30 | } 31 | 32 | public static void main(String[] args) { 33 | int[] a = {10, 20, -50, 80, 70, 66, -365}; 34 | 35 | System.out.println("Print the array to string:"); 36 | System.out.println(Arr.toString(a)); 37 | 38 | System.out.println("Sort the array a itself and print it sorted:"); 39 | Arr.sort(a); 40 | System.out.println(Arr.toString(a)); 41 | 42 | 43 | System.out.println("Print the reverse of the sorted array"); 44 | System.out.println(Arr.reverse(a)); 45 | 46 | System.out.println("Output each element in a with -> between them"); 47 | System.out.println(Arr.join(a, "->")); 48 | 49 | System.out.println("Output the sum"); 50 | System.out.println(Arr.sum(a)); 51 | 52 | System.out.println("Output array with elements from 1 to 10"); 53 | System.out.println(Arr.toString(Arr.range(1, 10))); 54 | 55 | System.out.println("Print only the odd numbers"); 56 | System.out.println(Arr.filterOdd(a)); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /week01/StaticArrays/README.md: -------------------------------------------------------------------------------- 1 | # 10-Static-Array 2 | 3 | In a `com.hackbulgaria.programming51.week3` package do the following: 4 | 5 | ## Define a `class Arr` where you 6 | 7 | ### Define the following 8 | 9 | * `public static String toString(int[] a)` method that recieves an integer array and returns a string of the array, separated by "," 10 | * `public static void sort(int[] a)` method that recieves an array of int and sorts it 11 | * `public static int[] reverse(int[] a)` method that recieves an integer array and returns the reversed array 12 | * `public static String join(int[] a, String glue)` method that recieves an array of int and a string and returns a String of the array elements with 'glue' between them 13 | * `public static int sum(int[] a)` method that returns the sum of all the elements in 'a' 14 | * `public static int[] range(int a, int b)` that returns an array of int with elements in the range between a and b 15 | * `public static int[] filterOdd(int[] a)` method that returns an array with only the Odd numbers from 'a' 16 | 17 | ## Examples 18 | 19 | You can open [Arr.java](Arr.java) and take the boilerplate code from it. 20 | 21 | 22 | ### Example for `toString(int [] a)` 23 | 24 | ```java 25 | int [] a = {1,2,3,4,5}; 26 | System.out.println(Arr.toString(a)); 27 | ``` 28 | 29 | Should print: 30 | 31 | ``` 32 | 1, 2, 3, 4, 5 33 | ``` 34 | 35 | ### Example for `sort(int [] a)` 36 | 37 | ```java 38 | int [] a = {3,1,-40,200,5}; 39 | Arr.sort(a); 40 | System.out.println(Arr.toString(a)); 41 | ``` 42 | 43 | Should print: 44 | 45 | ``` 46 | -40, 1, 3, 5, 200 47 | ``` 48 | 49 | ### Example for `reverse(int [] a)` 50 | 51 | ```java 52 | int [] a = {3,1,-40,200,5}; 53 | a = Arr.reverse(a); 54 | System.out.println(Arr.toString(a)); 55 | ``` 56 | 57 | Should print: 58 | 59 | ``` 60 | 5, 200, -40, 1, 3 61 | ``` 62 | 63 | ### Example for `join(int [] a, String glue)` 64 | 65 | ```java 66 | int [] a = {3,1,-40,200,5}; 67 | System.out.println(Arr.join(a, ": ")); 68 | System.out.println(Arr.join(a, "->")); 69 | ``` 70 | 71 | Should print: 72 | 73 | ``` 74 | 3: 1: -40: 200: 5 75 | 3->1->-40->200->5 76 | ``` 77 | 78 | ### Example for `sum(int [] a)` 79 | 80 | ```java 81 | int [] a = {1,2,3,4,5}; 82 | int b = Arr.sum(a); 83 | System.out.println(b); 84 | ``` 85 | 86 | Should print: 87 | 88 | ``` 89 | 15 90 | ``` 91 | 92 | ### Example for `range(int a, int b)` 93 | 94 | ```java 95 | int [] a = Arr.range(10, 20); 96 | System.out.println(Arr.join(a, ", ")); 97 | ``` 98 | 99 | Should print: 100 | 101 | ```java 102 | 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 103 | ``` 104 | 105 | ### Example for `filterOdd(int [] a)` 106 | 107 | ```java 108 | int [] a = {2,3,4,8,9,11,13,15}; 109 | int [] temp = Arr.filterOdd(a); 110 | System.out.println(Arr.join(temp, ", ")); 111 | ``` 112 | 113 | Should print: 114 | 115 | ``` 116 | 3, 9, 11, 13, 15 117 | ``` -------------------------------------------------------------------------------- /week01/Tuesday/README.md: -------------------------------------------------------------------------------- 1 | First Problems 2 | ======================== 3 | 4 | Code the solutions to the following problems: 5 | 6 | 7 | 1. Is a given number odd 8 | ---------------- 9 | Check if a given number is Odd or not 10 | 11 | `boolean isNumberOdd(int number)` 12 | 13 | Example: `isNumberOdd(8)` 14 | 15 | Result: `false` 16 | 17 | 2. Is a number prime 18 | ---------------- 19 | Check if a given number is prime 20 | 21 | `boolean isNumberPrime(int number)` 22 | 23 | Example: `isNumberPrime(17)` 24 | 25 | Result: `true` 26 | 27 | 3. Factorial Digits 28 | ---------------- 29 | Implement a function , that takes an integer and returns the sum of the factorials of each digit of n. 30 | 31 | For example, if number is equal to 145, we want the sum of 1! + 4! + 5! 32 | 33 | `int factorialDigits(int number)` 34 | 35 | Example: `factorialDigits(321)` 36 | 37 | Result: `9` 38 | 39 | 4. Fibonacci sequence 40 | ---------------- 41 | Implement a function, which takes an integer n and returns a number, which is formed by concatenating the first n Fibonacci numbers. 42 | 43 | For example, if n = 3, the result must be 112. 44 | 45 | `int fibonacciSequence(int number)` 46 | 47 | Example: `fibonacciSequence(5)` 48 | 49 | Result: `11235` 50 | 51 | 5. Is a given number palindrome 52 | ---------------- 53 | Implement a function, which takes an integer number and checks if the given number is palindrome. 54 | 55 | For example, the integer 121 is palindrome, but 12340321 - not! 56 | 57 | `boolean isPalindrome(int number)` 58 | 59 | Example: `isPalindrome(12321)` 60 | 61 | Result: `true` 62 | 63 | 6. Reverse the odd words in string 64 | ---------------- 65 | Implement a function, which takes a string and returns a string object containing reversed only the words of odd index. 66 | 67 | `String reverseOddWords(String sentence)` 68 | 69 | Example: `reverseOddWords(This is the first lecture for Programming 101 with Java)` 70 | 71 | Result: `This si the tsrif lecture rof Programming 101 with avaJ` 72 | 73 | 74 | 7. Check the sum of number and reversedNumber is palindrome 75 | ---------------- 76 | Write a function, which takes a number and returns boolean if the sum of the number and it's reversed number is palindrome. 77 | 78 | `boolean isSumPalindrome(int input)` 79 | 80 | Example: `isSumPalindrome(123)` 81 | 82 | Result: `true` 83 | 84 | 123 + 321 = 444 85 | 86 | 8. Find the sum of the divisors in array from numberA to numberB 87 | ---------------- 88 | Implement a function, which takes two integer numbers and returns the sum of the divisors from each number in the sequence from numberA to numberB 89 | 90 | `int sumOfDivisors(int numberA, numberB)` 91 | 92 | Example: `sumOfDivisors(4, 7)` 93 | 94 | Divisors of 4: 4, 2, 1 95 | Divisors of 5: 5, 1 96 | Divisors of 6: 6, 3, 2, 1 97 | Divisors of 7: 7, 1 98 | 99 | Result: `33` 100 | 101 | 9. Check the number of vowels, consonants and digits in string 102 | ---------------- 103 | Implement a function, which takes a string sentence and returns the number of the vowels, consonants and numbers in the given string object. 104 | 105 | `String [] vowelsConsonantsDigits(String sentence)` 106 | 107 | Example: `vowelsConsonantsDigits("It is 18th of Oct 2016")` 108 | 109 | Result: `["Vowels: 4", "Consonants: 7", "Digits: 6"]` 110 | 111 | 112 | Extra Tricky Problems 113 | ======================== 114 | The explanation of those tasks is in different file. 115 | 116 | 1. [Gas station](https://github.com/HackBulgaria/Programming101-Java-2016/tree/master/week01/Gas-Stations) 117 | 118 | 2. [Anagrams](https://github.com/HackBulgaria/Programming101-Java-2016/tree/master/week01/Anagrams) 119 | -------------------------------------------------------------------------------- /week01/materials/Listify.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HackBulgaria/Programming101-Java-2016/f9e042f9c6c4fc844836f938cd8ed8a3e5d6fcdd/week01/materials/Listify.jar -------------------------------------------------------------------------------- /week01/materials/Parser.java: -------------------------------------------------------------------------------- 1 | package com.parser; 2 | 3 | import com.listify.Listify; 4 | 5 | class Parser{ 6 | public static void main(String[] args) { 7 | if(args.length < 1) { 8 | System.out.println("File not provided"); 9 | return; 10 | } 11 | 12 | boolean inObject = false; 13 | boolean lastWasPair = false; 14 | 15 | String[] content = Listify.readToArray(args[0]); 16 | 17 | for(String line: content) { 18 | if(isEmpty(line.trim())) { 19 | if(inObject) { 20 | inObject = false; 21 | printObjectEnd(); 22 | } 23 | lastWasPair = false; 24 | continue; 25 | } 26 | if(isObject(line)) { 27 | if(inObject) { 28 | printObjectEnd(); 29 | } 30 | printObject(getObject(line).trim()); 31 | lastWasPair = false; 32 | inObject = true; 33 | continue; 34 | } 35 | line = trimComment(line); 36 | 37 | if(isKeyVal(line)) { 38 | if(lastWasPair) { 39 | System.out.println(","); 40 | } 41 | String[] kvPair = getKeyValPair(line); 42 | printKeyValPair(kvPair[0].trim(), kvPair[1].trim()); 43 | lastWasPair = true; 44 | continue; 45 | } 46 | System.out.println("ERROR"); 47 | } 48 | System.out.println(); 49 | System.out.println("}"); 50 | } 51 | 52 | public static boolean isObject(String line) { 53 | return line.startsWith("[") && line.endsWith("]"); 54 | } 55 | 56 | public static boolean isKeyVal(String line) { 57 | return line.contains("="); 58 | } 59 | 60 | public static boolean isEmpty(String line) { 61 | return line.isEmpty(); 62 | } 63 | 64 | public static String getObject(String line) { 65 | return line.substring(1, line.length() - 1); 66 | } 67 | 68 | public static String[] getKeyValPair(String line) { 69 | int equalsSign = line.indexOf("="); 70 | String[] pair = line.split("=", equalsSign + 1); 71 | 72 | return pair; 73 | } 74 | 75 | public static void printObject(String name) { 76 | System.out.println("\""+name+"\": {"); 77 | } 78 | 79 | public static void printKeyValPair(String key, String value) { 80 | System.out.print(" \""+key+"\": \""+value+"\""); 81 | } 82 | 83 | public static void printObjectEnd() { 84 | System.out.println(); 85 | System.out.println("},"); 86 | } 87 | 88 | public static String trimComment(String line) { 89 | if (line.indexOf(";") > 0) 90 | return line.substring(0, line.indexOf(";")); 91 | return line; 92 | } 93 | } -------------------------------------------------------------------------------- /week01/materials/README.md: -------------------------------------------------------------------------------- 1 | # Week1 Thirsday summary 2 | 3 | On Thirsday we learned how to compile multiple files using `javac` 4 | We also learned that our projects should have a certain file structure that we describe in our `packages`. 5 | 6 | Lets get trough compiling a file one more time: 7 | 8 | ## Preparing the tools 9 | 10 | When making a jar we should have several things first: 11 | 12 | * The `.java` files should first be compilled 13 | * The file structure should be the same as the packages structure 14 | 15 | If we have a project named `jarCompilationExample` with the following file structure: 16 | 17 | [![File Structure](images/jar_folders_start.png)]() 18 | 19 | We can create the files that we want to include in our `.jar` file. 20 | 21 | ### FileReader 22 | 23 | The idea for the `FileReader` is a class that has static methods for reading files and returning the contents as a data structure. 24 | 25 | We can write such file in the following way: 26 | 27 | ```java 28 | package hacktools; 29 | 30 | import java.io.IOException; 31 | import java.util.List; 32 | import java.nio.file.Files; 33 | import java.nio.file.Paths; 34 | 35 | public class FileReader { 36 | public static String[] readToArray(String filename) { 37 | List contents = readToList(filename); 38 | return contents.toArray(new String[contents.size()]); 39 | } 40 | 41 | public static List readToList(String filename) { 42 | try { 43 | return Files.readAllLines(Paths.get(filename)); 44 | } catch(IOException e) { 45 | e.printStackTrace(); 46 | return null; 47 | } 48 | } 49 | } 50 | ``` 51 | 52 | In this file we have methods that receive a filename and return the contents of the file in a `String[]` or a List of Strings. 53 | 54 | **Note** that in the first line of the file we described the package of the file. The package name is the same as the directory(folder) that the file is in. 55 | 56 | ```java 57 | package hacktools; 58 | ``` 59 | 60 | ### ArrayTools 61 | 62 | The idea for the `ArrayTools` is a class that has static methods for working with generic Arrays. 63 | 64 | Here's an example for such a file: 65 | 66 | ```java 67 | package hacktools; 68 | 69 | import java.lang.Comparable; 70 | import java.lang.Math; 71 | 72 | public class ArrayTools { 73 | public static String toString(T[] arr) { 74 | return "[" + glue(arr, ", ") + "]"; 75 | } 76 | 77 | public static String glue(T[] arr, String glue) { 78 | if(arr.length==0) return ""; 79 | String result = ""; 80 | for(int i=0; i < arr.length-1; i++) { 81 | result = result + arr[i] + glue; 82 | } 83 | return result + arr[arr.length-1]; 84 | } 85 | 86 | public static T[] reverse(T[] arr) { 87 | int len = arr.length; 88 | for(int i=0; i < len/2; i++) { 89 | T temp = arr[i]; 90 | arr[i] = arr[len-i-1]; 91 | arr[len-i-1] = temp; 92 | } 93 | return arr; 94 | } 95 | 96 | public static T[] sort(T[] arr) { 97 | for(int i=0; i 135 | 136 | f1(5) = 10 + 6 = 16 137 | 138 | => 139 | 140 | f4(5) = 32 141 | 142 | Now the expression is: 143 | 144 | f1(f2(f3(32))) 145 | 146 | f3(32) = 33 147 | 148 | Now the expression is: 149 | 150 | f1(f2(33)) 151 | 152 | f2(33) = 66 153 | 154 | Now, we need to know f1(66) 155 | 156 | f1(66) = f2(66) + f3(66) 157 | f2(66) = 132 158 | f3(66) = 67 159 | 160 | f1(66) = 199 161 | ``` -------------------------------------------------------------------------------- /week02/FunctionCallsExtension/README.md: -------------------------------------------------------------------------------- 1 | # Function Calls with our Functions 2 | 3 | In order to solve that problem, it is a good idea to solve [Function Calls first](../7-Function-Calls) 4 | 5 | Now, in the previous problem, we had predefined functions. This is easy. **Now, we are going to read our functions from the input.** 6 | 7 | ## Function language 8 | 9 | We are going to use a very simple function language: 10 | 11 | * All functions are defined over the integers. 12 | * All functions are one liners - there are not going to be functions on multiple lines. 13 | * All functions are going to have **1 argument** 14 | * All functions can only do expressions involving valid integers, the argument and the `+` and `-` operations. Brackets, `*` and other operations are not in our language. 15 | * **Functions can include function calls to other functions.** 16 | * **In our function language everyting is separated by exactly one `" "`** You can count on that. 17 | 18 | Here are some example functions, that are valid: 19 | 20 | ``` 21 | f x = x + 1 22 | inc x = x + 1 23 | dec x = x - 1 24 | f2 x = 1 25 | f3 x = x + 1 - 2 26 | f4 x = inc(x) + inc(1) 27 | ``` 28 | 29 | Our functions have the following form: 30 | 31 | ``` 32 | = 33 | ``` 34 | 35 | * `` can be 1 or more characters from `[a-z]` 36 | * `` can be 1 or more characters from `[a-z]` 37 | * ` = | | ` where `|` means or. 38 | * `` are valid integers values. For example: `1`, `12`, `123` 39 | * `` are in the form `()` 40 | * `` can be only `+` and `-` 41 | 42 | ## The new problem 43 | 44 | Now, we have to make a Java program that: 45 | 46 | * Reads one integer `n` 47 | * On the next `n` lines - reads `n` fuctions 48 | * After this, reads one line consisting of function composition - lets call the composition `h` 49 | * On the last line, it reads an integer `x` 50 | 51 | The program should output the result of `h(x)`. 52 | 53 | ## Examples 54 | 55 | * The output is always going to be valid. 56 | * There won't be functions with the same name as the arguments. 57 | 58 | Watch carefully. There are a few corner cases here: 59 | 60 | Example input: 61 | 62 | ``` 63 | 2 64 | inc x = x + 1 65 | dec x = x - 1 66 | inc . inc . dec 67 | 5 68 | ``` 69 | 70 | The output should be: 71 | 72 | ``` 73 | 6 74 | ``` 75 | 76 | We are calling: 77 | 78 | ``` 79 | inc(inc(dec(5)) = inc(inc(4)) = inc(5) = 6 80 | ``` 81 | 82 | --- 83 | 84 | Another input: 85 | 86 | ``` 87 | 1 88 | const x = 1 89 | const . const . const 90 | 100 91 | ``` 92 | 93 | The output should be: 94 | 95 | ``` 96 | 1 97 | ``` 98 | 99 | Here `const` is a constant function. We can have all valid integer values for `x` but the result is always 1. 100 | 101 | --- 102 | 103 | Another input: 104 | 105 | ``` 106 | 1 107 | const x = 1 + 1 - 1 108 | const . const . const 109 | 100 110 | ``` 111 | 112 | The output should be: 113 | 114 | ``` 115 | 1 116 | ``` 117 | 118 | Again, we have a constant function but this time - there is an expression to be calculated. 119 | 120 | --- 121 | 122 | Another input: 123 | 124 | ``` 125 | 2 126 | inc x = x + 1 127 | dec x = inc(x) - 2 128 | dec . dec 129 | 2 130 | ``` 131 | 132 | The result should be: 133 | 134 | ``` 135 | 0 136 | ``` 137 | 138 | Now, the definition of `dec` uses `inc`. We must call `inc` with the `x` value passed to `dec`. 139 | 140 | --- 141 | 142 | Another input: 143 | 144 | ``` 145 | 2 146 | inc x = x + 1 147 | dec x = x - inc(0) 148 | dec . dec 149 | 2 150 | ``` 151 | 152 | The output should be: 153 | 154 | ``` 155 | 0 156 | ``` 157 | 158 | Now, we are calling `inc` again but this time with a specific value - `0`. This is not `x`! 159 | -------------------------------------------------------------------------------- /week02/GameOfLife/README.md: -------------------------------------------------------------------------------- 1 | # Conway's Game of Life 2 | 3 | Your task today is to implement Conway's game of life while pair programming with a friend. 4 | 5 | The restrictions are: 6 | * For the first hour one of you writes code and the other one stands by and helps 7 | * After the first hour you should delete all the code that you've written and you should switch roles for the next hour. 8 | * Work in a plane of atleast 15x15 9 | * Let it be an infinite cycle 10 | * Input the places of the cells with life in them as coordinates and show the output in the console using full and empty utf rectangles (you can find them in google) 11 | 12 | ## Example inputs: 13 | 14 | 15 | ### Block 16 | 17 | ``` 18 | 4 19 | 2 2 20 | 3 2 21 | 2 3 22 | 3 3 23 | ``` 24 | 25 | ### Boat 26 | 27 | ``` 28 | 5 29 | 3 3 30 | 4 3 31 | 3 4 32 | 5 4 33 | 4 5 34 | ``` 35 | 36 | ### Blinker 37 | 38 | ``` 39 | 3 40 | 6 5 41 | 6 6 42 | 6 7 43 | ``` 44 | 45 | ### Toad 46 | 47 | ``` 48 | 6 49 | 6 5 50 | 7 5 51 | 8 5 52 | 5 6 53 | 6 6 54 | 7 6 55 | ``` 56 | 57 | ### Beacon 58 | 59 | ``` 60 | 6 61 | 3 3 62 | 4 3 63 | 3 4 64 | 6 5 65 | 6 6 66 | 5 6 67 | ``` 68 | 69 | ### Glider 70 | 71 | ``` 72 | 5 73 | 3 3 74 | 4 4 75 | 4 5 76 | 3 5 77 | 2 5 78 | ``` 79 | 80 | ### Pulsar 81 | 82 | (coordinates parsed by students) 83 | 84 | ``` 85 | 48 86 | 3 5 87 | 3 6 88 | 3 7 89 | 3 11 90 | 3 12 91 | 3 13 92 | 5 3 93 | 5 8 94 | 5 10 95 | 5 15 96 | 6 3 97 | 6 8 98 | 6 10 99 | 6 15 100 | 7 3 101 | 7 8 102 | 7 10 103 | 7 15 104 | 8 5 105 | 8 6 106 | 8 7 107 | 8 11 108 | 8 12 109 | 8 13 110 | 10 5 111 | 10 6 112 | 10 7 113 | 10 11 114 | 10 12 115 | 10 13 116 | 11 3 117 | 11 8 118 | 11 10 119 | 11 15 120 | 12 3 121 | 12 8 122 | 12 10 123 | 12 15 124 | 13 3 125 | 13 8 126 | 13 10 127 | 13 15 128 | 15 5 129 | 15 6 130 | 15 7 131 | 15 11 132 | 15 12 133 | 15 13 134 | ``` -------------------------------------------------------------------------------- /week02/Polynomials/README.md: -------------------------------------------------------------------------------- 1 | # Polynomial 2 | 3 | ## What is a polynomial? 4 | 5 | In mathematics, a polynomial is an expression consisting of variables and coefficients which only employs the operations of addition, subtraction, multiplication, and non-negative integer exponents. 6 | 7 | ... but you don't need all that for this task. 8 | 9 | A polynomial is an expression of the following type: 10 | 11 | * x2 - 4x + 7 12 | * 2x4 + 3x2 - 10x + 3 13 | * 4x10 - 7x9 + 5x8 ...... - 3x2 + 8x + 5 14 | * Anxn + An-1xn-1 + An-2xn-2 + ... + A2x2 + A1x1 + A0x0 (... if that explains it better) 15 | 16 | At the moment we're interested in Polynomials with only one variable. 17 | 18 | ## The task 19 | 20 | ### 1. Requirements 21 | 22 | Model a Java program that handles Polynomials. 23 | 24 | * Add, substract and multiplicate Polynomials 25 | * `P1 + P2 = P3` where P3 is a result polynom 26 | * `P1 - P2 = P3` where P3 is a result polynom 27 | * `P1 * P2 = P3` where P3 is a result polynom 28 | * Method for multiplicating the polynomial by a constant 29 | * `P1 * c = P3` where c is a constant and P3 is a result polynom 30 | * Method for returning the first derivative of a Polynomial 31 | * `(P1)' = P3` where P3 is a polynom and is the first derivative of P1 32 | * For example the Polynomial `2x^4 + 3x^2 - 10x + 3` has a first derivative `8x^3 + 6x - 10` 33 | * Method for evaluating a Polynomial 34 | * The Polynomial should be **immutable** 35 | * The Polynomial should be parametrised by a Generic type that is a valid number. For example Integer or Double 36 | 37 | ### 2. Hints 38 | 39 | Implementing the following methods will probably make your task easier: 40 | 41 | * `add(..)` for adding a member to the polynomial 42 | * `fromString("..")` a static method to return a polynomial from a string 43 | * For example the string `2x^4 + 3x^2 - 10x + 3` 44 | -------------------------------------------------------------------------------- /week03/Complexities/complexities.md: -------------------------------------------------------------------------------- 1 | # Complexities 2 | 3 | Write down the asymptotic complexities of the following functions: 4 | 5 | ## Checking if a number is prime 6 | 7 | ``` 8 | is_prime(number) { 9 | for (i = 2; i < number; i++) { 10 | if (number % i == 0) { 11 | return false 12 | } 13 | } 14 | return true 15 | } 16 | ``` 17 | 18 | Complexity: ... 19 | 20 | ## Checking if a string is palindrome 21 | 22 | ``` 23 | is_palindrome(string) { 24 | n = length(string) 25 | 26 | i = 0 27 | j = n - 1 28 | while (i < j) { 29 | if (string[i] != string[j]) { 30 | return false 31 | } 32 | i = i + 1 33 | j = j - 1 34 | } 35 | 36 | return true 37 | } 38 | ``` 39 | 40 | Complexity: ... 41 | 42 | ## Summing elements of a matrix 43 | 44 | ``` 45 | for (i = 0; i < n; i++) { 46 | for (j = 0; j < m; j++) { 47 | sum += numbers[i][j] 48 | } 49 | } 50 | ``` 51 | 52 | Complexity: ... 53 | 54 | ## Counting 1 55 | 56 | ``` 57 | for (i = 0; i < n; i++) { 58 | for (j = i; j < n; j++) { 59 | count++ 60 | } 61 | } 62 | ``` 63 | 64 | Complexity: ... 65 | 66 | ## Counting 2 67 | 68 | ``` 69 | for (i = 0; i < n; i++) { 70 | for (j = 1; j < n; j*=2) { 71 | count++ 72 | } 73 | } 74 | ``` 75 | 76 | Complexity: ... 77 | -------------------------------------------------------------------------------- /week03/Linked-List/MyLinkedList.java: -------------------------------------------------------------------------------- 1 | package com.hackbulgaria.java; 2 | 3 | public class MyLinkedList> 4 | implements MyLinkedListInterface, MyQueueInterface, MyStackInterface { 5 | 6 | private Node head; 7 | // the rightmost element of the list 8 | private Node tail; 9 | private int size; 10 | 11 | private class Node { 12 | private T element; 13 | private Node nextNode; 14 | 15 | public Node(T element) { 16 | this.element = element; 17 | } 18 | 19 | public Node(T element, Node nextNode) { 20 | this.element = element; 21 | this.nextNode = nextNode; 22 | } 23 | } 24 | 25 | public MyLinkedList() { 26 | size = 0; 27 | head = null; 28 | tail = null; 29 | } 30 | 31 | private Node getNode(int index) { 32 | Node node = head; 33 | 34 | if (index == size - 1) { 35 | node = tail; 36 | } else { 37 | 38 | for (int i = 0; i < index; i++) { 39 | if (node.nextNode == null) { 40 | throw new IndexOutOfBoundsException("The requested index is greated than the size"); 41 | } 42 | 43 | node = node.nextNode; 44 | } 45 | } 46 | 47 | return node; 48 | } 49 | 50 | private void validateIndex(int index) { 51 | if (index < 0 || index > size) { 52 | throw new IndexOutOfBoundsException("The provided index is out of range: " + index); 53 | } 54 | } 55 | 56 | private T removeHead() { 57 | T firstElement = null; 58 | 59 | if (size != 0) { 60 | firstElement = head.element; 61 | remove(0); 62 | } 63 | 64 | return firstElement; 65 | } 66 | 67 | @Override 68 | public void addFirst(T newElement) { 69 | Node newNode = new Node(newElement, head); 70 | head = newNode; 71 | 72 | if (size == 0) { 73 | tail = newNode; 74 | } 75 | 76 | size++; 77 | } 78 | 79 | @Override 80 | public void addLast(T newElement) { 81 | if (size == 0) { 82 | addFirst(newElement); 83 | } else { 84 | tail.nextNode = new Node(newElement); 85 | tail = tail.nextNode; 86 | size++; 87 | } 88 | } 89 | 90 | @Override 91 | public void add(T newElement, int index) { 92 | validateIndex(index); 93 | 94 | if (index == 0) { 95 | addFirst(newElement); 96 | } else if(index == size -1) { 97 | addLast(newElement); 98 | } else { 99 | Node previousNode = getNode(index - 1); 100 | Node newNode = new Node(newElement, previousNode.nextNode); 101 | previousNode.nextNode = newNode; 102 | size++; 103 | } 104 | } 105 | 106 | @Override 107 | public T getFirst() { 108 | if (head == null) { 109 | return null; 110 | } 111 | 112 | return head.element; 113 | } 114 | 115 | @Override 116 | public T getLast() { 117 | if (head == null) { 118 | return null; 119 | } 120 | 121 | return tail.element; 122 | } 123 | 124 | @Override 125 | public T get(int index) { 126 | validateIndex(index); 127 | 128 | return getNode(index).element; 129 | } 130 | 131 | @Override 132 | public int getSize() { 133 | return size; 134 | } 135 | 136 | @Override 137 | public void remove(int index) { 138 | validateIndex(index); 139 | 140 | if (index == 0 && size == 1) { 141 | head = null; 142 | tail = null; 143 | } else if (index == 0) { 144 | head = head.nextNode; 145 | } else if (index == size - 1) { 146 | tail = getNode(size - 2); 147 | tail.nextNode = null; 148 | } else { 149 | Node previousNode = getNode(index - 1); 150 | previousNode.nextNode = previousNode.nextNode.nextNode; 151 | } 152 | 153 | size--; 154 | } 155 | 156 | @Override 157 | public void addList(MyLinkedListInterface list) { 158 | if (list == null) { 159 | throw new IllegalArgumentException("The provided list cannot be null."); 160 | } 161 | 162 | for (int i = 0; i < list.getSize(); i++) { 163 | addLast(list.get(i)); 164 | } 165 | } 166 | 167 | @Override 168 | public T pop() { 169 | return removeHead(); 170 | } 171 | 172 | @Override 173 | public void push(T element) { 174 | addFirst(element); 175 | } 176 | 177 | @Override 178 | public void enqueue(T element) { 179 | addLast(element); 180 | } 181 | 182 | @Override 183 | public T dequeue() { 184 | return removeHead(); 185 | } 186 | 187 | @Override 188 | public T peek() { 189 | T firstElement = null; 190 | 191 | if (size != 0) { 192 | firstElement = head.element; 193 | } 194 | 195 | return firstElement; 196 | } 197 | 198 | } 199 | -------------------------------------------------------------------------------- /week03/Linked-List/MyLinkedListInterface.java: -------------------------------------------------------------------------------- 1 | package com.hackbulgaria.java; 2 | 3 | public interface MyLinkedListInterface>{ 4 | 5 | public void addFirst(T newElement); 6 | public void addLast(T newElement); 7 | public void add(T newElement, int index); 8 | public T getFirst(); 9 | public T getLast(); 10 | public T get(int index); 11 | public int getSize(); 12 | public void remove(int index); 13 | public void addList(MyLinkedListInterface list); 14 | } 15 | -------------------------------------------------------------------------------- /week03/Linked-List/MyQueueInterface.java: -------------------------------------------------------------------------------- 1 | package com.hackbulgaria.java; 2 | 3 | /** 4 | * Queue Interface 5 | * 6 | * @author vladimir 7 | * 8 | * @param should implement the Comparable interface 9 | */ 10 | public interface MyQueueInterface > { 11 | 12 | /** 13 | * Adds an element to the end of the queue. 14 | * 15 | * @param the element to add. 16 | */ 17 | public void enqueue(T element); 18 | 19 | /** 20 | * Removes and returns the first element in the queue 21 | * 22 | * @return the first element in the queue. 23 | */ 24 | public T dequeue(); 25 | 26 | /** 27 | * @return the element on top of the queue. 28 | */ 29 | public T peek(); 30 | 31 | /** 32 | * @return the number of elements in the queue. 33 | */ 34 | public int getSize(); 35 | } 36 | -------------------------------------------------------------------------------- /week03/Linked-List/MyStackInterface.java: -------------------------------------------------------------------------------- 1 | package com.hackbulgaria.java; 2 | 3 | /** 4 | * Stack interface 5 | * 6 | * @author vladimir 7 | * 8 | * @param should implement the Comparable interface. 9 | * 10 | */ 11 | public interface MyStackInterface > { 12 | 13 | /** 14 | * Removes the element on top of the stack. 15 | * 16 | * @return the element on top of the stack. 17 | */ 18 | public T pop(); 19 | 20 | /** 21 | * Adds an element on top of the stack 22 | * 23 | * @param element the element to be added 24 | */ 25 | public void push(T element); 26 | 27 | /** 28 | * @return the element on top of the stack. 29 | */ 30 | public T peek(); 31 | 32 | /** 33 | * @return the number of elements in the stack. 34 | */ 35 | public int getSize(); 36 | } 37 | -------------------------------------------------------------------------------- /week03/Linked-List/REAMDE.md: -------------------------------------------------------------------------------- 1 | # Linked List 2 | 3 | ## Let's implement our own linked list 4 | 5 | First we will implement it only for ints. 6 | Then we will make it work with generics. 7 | 8 | ### The Interface 9 | 10 | First we will create an interface called MyLinkedListInterface that will describe the functions that our Linked list will have. 11 | 12 | For now we want to have the following functions in our LinkedList: 13 | 14 | - addFirst(int newElement) 15 | - addLast(int newElement) 16 | - add(int newElement, int index) 17 | - getFirst() 18 | - getLast() 19 | - get(int index) 20 | - size() 21 | - remove(int index) 22 | - addList(MylinkedListInterface list) - appends another linked list 23 | 24 | ### After we have created the interface it is time for implementation 25 | 26 | Create a Class named MyLinkedList that should implement our Interface. 27 | 28 | When writing the implementation document the big O() complexity of each function as a java doc. 29 | 30 | ## Some intresting tasks 31 | 32 | Solve the following problems and document their complexities both in terms of time and memory. 33 | 34 | ### Finding kth to last element 35 | 36 | Implement an algorithm to find the kth to last element in our singly linked list without using size() function or iterating twice. 37 | 38 | Try to do it in O(n). 39 | 40 | ### Deleting an element 41 | 42 | Implement an algorithm to delete a node in the middle of a singly linked list, given 43 | only access to that node. 44 | 45 | ### Partitioning a LinkedList 46 | 47 | Write code to partition a linked list around a value x, such that all nodes less than x come before all nodes greater than or equal to x. 48 | 49 | ### Connected lists 50 | 51 | Detect if two lists have at least one common node and find the first common node. 52 | 53 | Example: 54 | 55 | list_1: A->B->C->D 56 | 57 | list_2: F->C->D 58 | 59 | ### (L)oops 60 | 61 | Detect if a given linked list has a loop. 62 | 63 | Example: A->B->C->D->B 64 | 65 | ### First element in a loop 66 | 67 | Given a circular linked list (with a loop), implement an algorithm which returns the node at the beginning of the loop. 68 | 69 | ### Palindroms again 70 | 71 | Check if a given linked list is a palindrom. 72 | 73 | Compare the big O() complexity of each different solutions. 74 | You can do it with additional data structure, iterative, recursive, in place. -------------------------------------------------------------------------------- /week03/materials/LinkedList.md: -------------------------------------------------------------------------------- 1 | ## LinkedList 2 | 3 | List is a data structure that allows us to store unlimited number of 4 | elements without copying them over when expanding. In order to achieve 5 | this it does not store the elements in an Array. Instead, every element 6 | is an object that holds both the value (int, string, float, etc...) and 7 | a pointer to the next element in the list. This way every element of the 8 | list could be accessed starting from the first element (we call this `head` 9 | of the list) and following the links. 10 | 11 | List sacrifices the performance of accessing elements at random position 12 | (this operation runs in O(n) time) so that adding, removing and retrieving 13 | elements from the end of the list is fast (runs in O(1) time). 14 | 15 | [Linked list](http://en.wikipedia.org/wiki/Linked_list) - List with link in one direction. 16 | 17 | [Doubly linked list](http://en.wikipedia.org/wiki/Doubly_linked_list) - List with 18 | links in both directions. 19 | -------------------------------------------------------------------------------- /week03/materials/complexity_analysis.md: -------------------------------------------------------------------------------- 1 | # Complexity analysis 2 | 3 | Complexity analysis is a way of looking at the performance of an 4 | algorithm with respect to its input. This allows us to compare 5 | functions that given an input produce the same results and tell 6 | which one performs better. 7 | 8 | ## Computation model 9 | 10 | In order to discuss algorithms and their complexity we should first choose a 11 | computation model that will be executing our programs. What we need essentially 12 | is a computer that has [memory](http://en.wikipedia.org/wiki/Computer_memory) 13 | and a [processor](http://en.wikipedia.org/wiki/Central_processing_unit). The 14 | memory is a linear sequence of bits and the processor could perform some basic 15 | operations (instructions) on these bits. Here are the instructions that our 16 | processor could execute: 17 | 18 | * Assigning a value to a variable 19 | * Looking up the value of a particular element in an array 20 | * Comparing two values 21 | * Incrementing a value 22 | * Basic arithmetic operations such as addition and multiplication 23 | 24 | ## Counting instructions 25 | 26 | One way of looking at the performance of a piece of code is counting 27 | the number of instructions that are performed by the processor. 28 | 29 | The following snippet is a [Pseudocode](http://en.wikipedia.org/wiki/Pseudocode) 30 | example of how we could obtain the average of the elements in an array. 31 | 32 | ``` 33 | average(numbers) { 34 | n = length(numbers) 35 | sum = 0 36 | 37 | i = 0 38 | while (i < n) { 39 | sum = sum + numbers[i] 40 | i = i + 1 41 | } 42 | 43 | average = sum / n 44 | 45 | return average 46 | } 47 | ``` 48 | 49 | Lets count the number of instructions in the snippet: 50 | 51 | * `length(n)` requires one instruction - looking up the size of the array. 52 | * `n = ...` requires one instruction - assigning the size of the array to `n`. 53 | * So `n = length(numbers)` requires two instructions. 54 | * `sum = 0` requires one instruction - assigning 0 to `sum`. 55 | * `i = 0` requires one instruction - assigning 0 to `i`. 56 | * `i < n` requires one instruction - comparing `i` to `n`. 57 | * `numbers[i]` requires one instruction - looking up the `i`th value in `numbers`. 58 | * `sum + ...` requires one instruction - adding up the two elements 59 | * `sum = ...` requires one instruction - assigning the new value to `sum`. 60 | * So `sum = sum + numbers[i]` requires three instructions. 61 | * `i = i + 1` requires one instruction - incrementing `i`. 62 | * `sum / n` requires one instruction - dividing `sum` by `n`. 63 | * `average = ...` requires one instruction - assigning value to `average`. 64 | * So `average = sum / n` requires two instructions. 65 | 66 | However, `i < n`, `sum = sum + numbers[i]` and `i = i + 1` are not executed 67 | just once. They are in a loop that iterates from 0 to the length of numbers 68 | which happens to be `n`. 69 | 70 | So having this in mind the total number of instructions performed by the 71 | `average` function is: 2 + 1 + 1 + n * (1 + 3 + 1) + 2 = `6 + 5n`. 72 | 73 | However, this holds true for our computational model where basic arithmetic 74 | operations are a single instruction. If for example we are running this code 75 | on a machine where such operations require two instructions the total number 76 | of instructions will be `7 + 6n`. 77 | 78 | So we see that this formula depends on the machine that we run the program on. 79 | Isn't there a way to generalize the formula so that it holds true regardless of 80 | the computational model used for executing the program? 81 | 82 | ## Asymptotic complexity 83 | 84 | Processors, memory access time, language interpretors, virtual machines could 85 | differ. The total running time of our algorithms depends on all those factors. 86 | It is hard to predict the total running time of a function before executing it. 87 | 88 | However, what we could do easily is tell how a function behaves when its input 89 | changes. What is the behaviour of `average` when we run it with list of ten numbers? 90 | `6 + 5 * 10 = 56`. 56 instructions. What about a list of hundred elements? 91 | `6 + 5 * 100 = 506`. Finally, lets look at a thousand. `6 + 5 * 1000 = 5006`. 92 | 93 | What we observe is that the constant `6` is quickly swallowed by the other terms. 94 | `5n` is the dominating term. The whole function changes in a similar manner to the 95 | way `5n` changes. 96 | 97 | This is the big idea of asymptotic analysis. We are allowed to remove terms that 98 | are not contributing much to the value of a function as its input grows. Similarly 99 | to the way we dropped `6` we could also remove the constant in front of `n`. This 100 | way we could say that as the input to the function changes, `average` is similar 101 | to `n` (it is linear). Thus, we say `average` is `O(n)`. 102 | 103 | [Asymptotic computational complexity](http://en.wikipedia.org/wiki/Asymptotic_computational_complexity) 104 | 105 | [Big O notation](http://en.wikipedia.org/wiki/Big_O_notation) 106 | 107 | ## Amortized complexity 108 | 109 | [Amortized complexity](http://en.wikipedia.org/wiki/Amortized_analysis) looks at 110 | the complexity of a batch of operations (not a single operation). For example, 111 | Vector's worst case complexity for adding an element is O(n). However, the 112 | amortized complexity for adding `n` elements to a Vector is O(1). 113 | 114 | ## Best/average/worst analysis 115 | 116 | Lets look at another example - a function that checks if there is an even number 117 | in a sequence. 118 | 119 | ``` 120 | has_even(numbers) { 121 | n = length(numbers) 122 | 123 | i = 0 124 | while (i < n) { 125 | if (numbers[i] % 2 == 0) { 126 | return true 127 | } 128 | i = i + 1 129 | } 130 | 131 | return false 132 | } 133 | ``` 134 | 135 | What is the running time of `has_even`? If first number is even it breaks immediately 136 | so it is O(1). However, if there aren't any even numbers it will go through all elements 137 | increasing the running time to O(n). 138 | 139 | We say that the best case performance of `has_even` is O(1). This means that given 140 | the best possible input (even element in the beginning of the sequence) the function 141 | runs in O(1) time. 142 | 143 | We say that the worst case performance of `has_even` is O(n). This means that given 144 | the worst possible input (even element is not present in the sequence) the function 145 | runs in O(n) time. 146 | 147 | On average the function is O(n) because we have to scan every element until we find 148 | one that is even. 149 | 150 | [A Gentle Introduction to Algorithm Complexity Analysis](http://discrete.gr/complexity/) 151 | -------------------------------------------------------------------------------- /week04/binary_search_tree/README.md: -------------------------------------------------------------------------------- 1 | ## Binary search 2 | 3 | ### Implement binary search 4 | 5 | First lets implement a classical binary search. 6 | 7 | After you have made and tested your implementation lets make some modifications: 8 | 9 | -upperBound() using the same approach it should return the index of the first element that is bigger than the provided one. 10 | 11 | -lowerBound() using the same approach it should return the index of the first element that is smaller than the provided one. 12 | 13 | -interpolationSearch() lets change the condition to determine the middle element using the formulae from the materials for interpolation. 14 | 15 | ### Implement binary search tree 16 | 17 | Lets make our own binary search tree. 18 | It should have the following functions: 19 | 20 | -insert(T element) 21 | -remove(T element) 22 | -find(T element) 23 | 24 | ### Check if two binary trees are equal 25 | 26 | Hint: You can use depth first traversal. 27 | 28 | ### Sort an array using binary search tree 29 | 30 | Lets sort an array using our shiny binary search tree. 31 | After building the tree traverse it to create the sorted array. -------------------------------------------------------------------------------- /week04/binary_search_tree/Tree.java: -------------------------------------------------------------------------------- 1 | package com.hackbulgaria.java; 2 | 3 | public class Tree { 4 | 5 | private Node root; 6 | 7 | private class Node { 8 | private int element; 9 | private Node left; 10 | private Node right; 11 | 12 | public Node(int element) { 13 | this.element = element; 14 | } 15 | } 16 | 17 | public void add(int newElement) { 18 | if(root == null) { 19 | root = new Node(newElement); 20 | } else { 21 | addRecursive(newElement, root); 22 | } 23 | } 24 | 25 | private void addRecursive(int newElement, Node currentNode) { 26 | if (newElement < currentNode.element) { 27 | if(currentNode.left == null) { 28 | currentNode.left = new Node(newElement); 29 | } else { 30 | addRecursive(newElement, currentNode.left); 31 | } 32 | } else if (newElement > currentNode.element){ 33 | if(currentNode.right == null) { 34 | currentNode.right = new Node(newElement); 35 | } else { 36 | addRecursive(newElement, currentNode.right); 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /week04/bonus_tasks/breakfast.md: -------------------------------------------------------------------------------- 1 | В кухнята на ресторант има n котлона. За приготвянето на една мекица на всеки от тези котлони са необходими съответно t1, t2, …, tn секунди. 2 | 3 | Напишете програма, която намира най-малко за колко секунди може да се приготвят x мекици. За пърженето на една мекица може да се използва само един котлон. 4 | 5 | ## Input Format 6 | 7 | От първия ред се въвежда броя на тестовите примери. От първия ред на всеки от тях се въвеждат броят на мекиците x (0 < x < 1015) и броят на котлоните n (0 < n < 20). От втория ред се въвеждат n цели положителни числа, по-малки от 500 – времената t1, t2, …, tn. 8 | 9 | ## Output Format 10 | 11 | За всеки тестов пример на отделен ред програмата трябва да изведе минималното време, за което може да се приготвят мекиците. 12 | 13 | 14 | ## Sample Input 15 | 16 | 1 17 | 18 | 3 2 19 | 20 | 50 70 21 | 22 | 23 | ## Sample Output 24 | 25 | 100 -------------------------------------------------------------------------------- /week04/materials/binary_search_trees.md: -------------------------------------------------------------------------------- 1 | # Searching 2 | 3 | ## Linear search 4 | 5 | A trivial way of finding an element in a sequence is looking at 6 | every element of the sequence. If the collection does not imply some 7 | specific ordering this could be the only way of searching. However, 8 | large collection will definitely cause a performance impact. 9 | 10 | ## Binary search 11 | 12 | [Binary search](https://www.topcoder.com/community/data-science/data-science-tutorials/binary-search/) 13 | is an example of an algorithm that with some amount of 14 | preprocessing is able to solve a hard problem. Sorting a collection 15 | of elements allows consecutive searches to be really fast. 16 | 17 | The strategy that this algorithm employs is very similar to the one 18 | we saw in merge sort and quick sort. 19 | 20 | You can go through each step of the algorithm [here](http://www.cs.armstrong.edu/liang/animation/web/BinarySearch.html). 21 | 22 | ## Interpolation search 23 | 24 | Can we search faster than binary? Yes, if we once again limit the problem 25 | and require knowledge about the range of the values in the searched interval. 26 | If that's the case [Interpolation search](http://www.stoimen.com/blog/2012/01/02/computer-algorithms-interpolation-search/) 27 | does a pretty good job improving the performance of binary search. 28 | 29 | # Binary trees 30 | 31 | ## Binary tree 32 | 33 | [Binary tree](http://www.cs.cmu.edu/~adamchik/15-121/lectures/Trees/trees.html) 34 | is a data structure that allows nodes to have up to two descendants. In that 35 | sense it could be considered a generalization of a 36 | [List](../week1/materials/linear_data_structures.md#list). 37 | 38 | ## Binary search tree 39 | 40 | [Binary search tree](http://www.stoimen.com/blog/2012/06/22/computer-algorithms-binary-search-tree-data-structure/) 41 | enforces order for the values of a binary tree. For every node of the 42 | binary search tree it is true that all values in the left subtree (the one 43 | that has the left descendant as a root) are smaller than the value of the 44 | node and all values in the right subtree (the one that has the right descendant 45 | as a root) are bigger than the value of the node. -------------------------------------------------------------------------------- /week04/materials/exceptions.md: -------------------------------------------------------------------------------- 1 | *Exceptions in Java* 2 | https://www.tutorialspoint.com/java/java_exceptions.htm 3 | 4 | *Overriding methods with Exceptions in java* 5 | http://stackoverflow.com/questions/5875414/method-overriding-and-exceptions -------------------------------------------------------------------------------- /week04/materials/stacks_and_queues.md: -------------------------------------------------------------------------------- 1 | ## Queue 2 | 3 | [Queue](http://en.wikipedia.org/wiki/Queue_%28abstract_data_type%29) is an 4 | abstract data type. This means that it does not define a specific implementation. 5 | It just provides an interface for the supported operations. 6 | 7 | The interface of a Queue data type is: 8 | 9 | ``` 10 | Queue { 11 | 12 | // Adds value to the end of the Queue. 13 | enqueue(value) 14 | 15 | // Returns value from the front of the Queue and removes it. 16 | dequeue() 17 | 18 | // Returns value from the front of the Queue without removing it. 19 | peek() 20 | 21 | // Returns the number of elements in the Queue. 22 | size() 23 | } 24 | ``` 25 | 26 | It could be implemented with both ArrayList and LinkedList. 27 | 28 | ## Stack 29 | 30 | [Stack](http://en.wikipedia.org/wiki/Stack_%28abstract_data_type%29) is an 31 | abstract data type. This means that it does not define a specific implementation. 32 | It just provides an interface for the supported operations. 33 | 34 | The interface of a Stack data type is: 35 | 36 | ``` 37 | Stack { 38 | 39 | // Adds value to the end of the Stack. 40 | push(value) 41 | 42 | // Returns value from the end of the Stack and removes it. 43 | pop() 44 | 45 | // Returns value from the end of the Stack without removing it. 46 | peek() 47 | 48 | // Returns the number of elements in the Stack. 49 | size() 50 | } 51 | ``` 52 | 53 | It could be implemented with both ArrayList and LinkedList. 54 | -------------------------------------------------------------------------------- /week04/stacks_and_queues/README.md: -------------------------------------------------------------------------------- 1 | # Stacks and Queues 2 | 3 | ## Creating our own stack and queue 4 | 5 | ### The Interfaces 6 | 7 | Lets make interfaces for stack and queue 8 | 9 | stack: 10 | -pop() 11 | -push(T element) 12 | -peek() 13 | 14 | queue: 15 | -enqueue(T element) 16 | -dequeue() 17 | -peek() 18 | 19 | Feel free to add more functions to the interfaces if necessary. 20 | 21 | ### Enhance our own linked list 22 | 23 | We already have implemented a linked list. Lets enhance it so that it implements our newly created interfaces. 24 | 25 | We should have proper exception handling. 26 | Document the the complexity of each function. 27 | 28 | ## Tasks 29 | 30 | ### Stacked Queue 31 | 32 | Implement a MyQueue class which implements a queue using two stacks. 33 | 34 | ### Stack with a minimum bonus 35 | 36 | How would you design a stack which, in addition to push and pop, also has a 37 | function min which returns the minimum element? Push, pop and min should 38 | all operate in O(1) time. 39 | 40 | ### Sorting with stacks 41 | 42 | Write a program to sort a stack in ascending order (with biggest items on top). 43 | You may use at most one additional stack to hold items, but you may not copy the 44 | elements into any other data structure (such as an array). The stack supports the 45 | following operations: push, pop, peek, and isEmpty. 46 | 47 | ### Not too high 48 | 49 | Imagine a (literal) stack of plates. If the stack gets too high, it might topple. 50 | Therefore, in real life, we would likely start a new stack when the previous stack 51 | exceeds some threshold. Implement a data structure SetOfStacks that mimics 52 | this. SetOfStacks should be composed of several stacks and should create a 53 | new stack once the previous one exceeds capacity. SetOfStacks.push() and 54 | SetOfStacks.pop() should behave identically to a single stack (that is, pop() 55 | should return the same values as it would if there were just a single stack) 56 | 57 | Bonus: Implement a function popAt(int index) which performs a pop operation on a specific index. 58 | -------------------------------------------------------------------------------- /week06/maps/README.md: -------------------------------------------------------------------------------- 1 | ## Map 2 | 3 | ### Implement your own HashMap 4 | 5 | It should use separate chaining for collision resolution. 6 | 7 | It should have the following methods: 8 | 9 | -put(K key, V value) 10 | 11 | -get(K key) 12 | 13 | -remove(K key) 14 | 15 | -containsKey(K key) 16 | 17 | Create an interface for the data structure you will use at each bucket. 18 | 19 | When done, play around with the load factor and the data structure you use to see how the performance of your HashMap changes. -------------------------------------------------------------------------------- /week06/maps/example/BucketInterface.java: -------------------------------------------------------------------------------- 1 | package com.hackbulgaria.java; 2 | 3 | public interface BucketInterface { 4 | 5 | public void add(K key, V value); 6 | public void remove(K key); 7 | public V get(K key); 8 | } 9 | -------------------------------------------------------------------------------- /week06/maps/example/LinkedBucket.java: -------------------------------------------------------------------------------- 1 | package com.hackbulgaria.java; 2 | 3 | import java.util.LinkedList; 4 | 5 | public class LinkedBucket implements BucketInterface{ 6 | 7 | private class Entry { 8 | private K key; 9 | private V value; 10 | 11 | public Entry(K key, V value) { 12 | this.key = key; 13 | this.value = value; 14 | } 15 | 16 | public K getKey() { 17 | return key; 18 | } 19 | 20 | 21 | public V getValue() { 22 | return value; 23 | } 24 | 25 | public void setValue(V newValue) { 26 | this.value = newValue; 27 | } 28 | } 29 | 30 | private LinkedList list; 31 | 32 | public LinkedBucket() { 33 | list = new LinkedList<>(); 34 | } 35 | 36 | @Override 37 | public void add(K key, V value) { 38 | if(get(key) == null) { 39 | list.add(new Entry(key, value)); 40 | } else { 41 | Entry entry = getEntry(key); 42 | entry.setValue(value); 43 | } 44 | } 45 | 46 | private Entry getEntry(K key) { 47 | for(Entry entry : list) { 48 | if(entry.getKey().equals(key)) { 49 | return entry; 50 | } 51 | } 52 | return null; 53 | } 54 | 55 | @Override 56 | public void remove(K key) { 57 | list.remove(getEntry(key)); 58 | } 59 | 60 | @Override 61 | public V get(K key) { 62 | Entry entry = getEntry(key); 63 | V value = null; 64 | 65 | if(entry != null) { 66 | value = entry.getValue(); 67 | } 68 | 69 | return value; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /week06/maps/example/Map.java: -------------------------------------------------------------------------------- 1 | package com.hackbulgaria.java; 2 | 3 | public class Map implements MapInterface{ 4 | 5 | BucketInterface[] buckets; 6 | private double loadFactor; 7 | private int size; 8 | 9 | 10 | public Map() { 11 | size = 8; 12 | loadFactor = 5; 13 | buckets = new LinkedBucket[size]; 14 | for(int i=0; i(); 16 | } 17 | } 18 | 19 | @Override 20 | public void put(K key, V value) { 21 | int bucketIndex = calculateBucketIndex(key); 22 | buckets[bucketIndex].add(key, value); 23 | } 24 | 25 | @Override 26 | public V get(K key) { 27 | int bucketIndex = calculateBucketIndex(key); 28 | 29 | return buckets[bucketIndex].get(key); 30 | } 31 | 32 | @Override 33 | public void remove(K key) { 34 | int bucketIndex = calculateBucketIndex(key); 35 | buckets[bucketIndex].remove(key); 36 | } 37 | 38 | @Override 39 | public boolean containsKey(K key) { 40 | return (get(key) != null); 41 | } 42 | 43 | private int calculateBucketIndex(K key) { 44 | return key.hashCode() % size; 45 | } 46 | 47 | /* 48 | * hint for resizing 49 | * 50 | * 1. create newList new LinkedBucked[size*2] 51 | * 52 | * 2. oldList = this.list 53 | * 3. list = newList 54 | * 55 | * 4. for each element in oldList -> call put() 56 | * 57 | */ 58 | } 59 | -------------------------------------------------------------------------------- /week06/maps/example/MapInterface.java: -------------------------------------------------------------------------------- 1 | package com.hackbulgaria.java; 2 | 3 | public interface MapInterface { 4 | public void put(K key, V value); 5 | public V get(K key); 6 | public void remove(K key); 7 | public boolean containsKey(K key); 8 | } 9 | -------------------------------------------------------------------------------- /week06/materials/maps.md: -------------------------------------------------------------------------------- 1 | *A HashMap example* 2 | http://www.tutorialspoint.com/java/java_hashmap_class.htm 3 | 4 | *Equals and hashcode in java* 5 | http://stackoverflow.com/questions/27581/overriding-equals-and-hashcode-in-java 6 | 7 | *How HashMap works* 8 | http://www.javacodegeeks.com/2014/03/how-hashmap-works-in-java.html -------------------------------------------------------------------------------- /week06/materials/sorting.md: -------------------------------------------------------------------------------- 1 | # Sorting 2 | 3 | Sorting a sequence of elements is a well-known problem with many solutions. 4 | We could learn a lot just by looking at the steps that different algorithms 5 | take to produce a solution. 6 | 7 | ## Selection sort 8 | 9 | [Selection sort](http://en.wikipedia.org/wiki/Selection_sort) is probably 10 | the simplest way of sorting a collection - take the minimum element and 11 | put in the first postion, take the next smallest element and put it next 12 | to the previous. Do this for all elements and you have a sorted collection! 13 | [Here](http://courses.cs.vt.edu/~csonline/Algorithms/Lessons/SelectionSort/index.html) 14 | is a description of the steps of the algorithm. 15 | [Here](https://www.cs.usfca.edu/~galles/visualization/ComparisonSort.html) 16 | you can find a nice visualization of the steps of the algorithm. 17 | 18 | ## Insertion sort 19 | 20 | [Insertion sort](http://en.wikipedia.org/wiki/Insertion_sort) builds the 21 | sorted array by constantly adding elements to it in the correct position. 22 | [Here](http://courses.cs.vt.edu/csonline/Algorithms/Lessons/InsertionSort/index.html) 23 | is a description of the steps of the algorithm. 24 | [Here](https://www.cs.usfca.edu/~galles/visualization/ComparisonSort.html) 25 | you can find a nice visualization of the steps of the algorithm. 26 | 27 | ## Bubble sort 28 | 29 | [Bubble sort](http://en.wikipedia.org/wiki/Bubble_sort) produces a sorted sequence 30 | by comparing and swapping adjacent elements. 31 | [Here](https://www.cs.usfca.edu/~galles/visualization/ComparisonSort.html) 32 | you can find a nice visualization of the steps of the algorithm. 33 | 34 | ## Counting sort 35 | 36 | [Counting sort](http://en.wikipedia.org/wiki/Counting_sort) is a genious algorithm 37 | that exploits the fact that arrays allow us to make n-way decisions (not just binary 38 | like if/else) to improve the performance for certain sequences. 39 | [Here](https://www.cs.usfca.edu/~galles/visualization/CountingSort.html) 40 | you can find a nice visualization of the steps it executes. -------------------------------------------------------------------------------- /week06/sorting/README.md: -------------------------------------------------------------------------------- 1 | # Sorting 2 | 3 | ## Lets implement some sorting algorithms 4 | 5 | ### Implement Selection Sort 6 | 7 | ### Implement Insertion Sort 8 | 9 | ### Implement Bubble Sort 10 | 11 | ### Implement Counting Sort 12 | 13 | ## Bonus task 14 | 15 | Here you can see the problem and submit your solution: 16 | 17 | https://www.hackerrank.com/challenges/missing-numbers 18 | 19 | https://www.hackerrank.com/challenges/sherlock-and-array 20 | 21 | https://www.hackerrank.com/challenges/flipping-the-matrix -------------------------------------------------------------------------------- /week07/PandaSocialNetwork/README.md: -------------------------------------------------------------------------------- 1 | # We are going to make a social network for Pandas 2 | 3 | This is the next big thing. We promise! 4 | 5 | ## Panda 6 | 7 | For our social network, we are going to need a `Panda` class which should behave like this: 8 | 9 | ```java 10 | Panda ivo = new Panda("Ivo", "ivo@pandamail.com", "male"); 11 | 12 | ivo.getName() == "Ivo" # true 13 | ivo.getEmail() == "ivo@pandamail.com" # true 14 | ivo.getGender() == "male" # true 15 | ivo.isMale() == true # true 16 | ivo.isFemale() == false # true 17 | ``` 18 | 19 | The `Panda` class should also: 20 | 21 | * Be turned into a string 22 | * **Make sure that the `email` is a valid email!** 23 | 24 | Two `Panda` instances are equal if they have matching `name`, `email` and `gender` attributes. 25 | 26 | ## SocialNetwork 27 | 28 | Now it is time for our social network! 29 | 30 | Implement a class, called `PandaSocialNetwork`, which has the following public methods: 31 | 32 | * `addPanda(panda)` - this method adds a `panda` to the social network. The panda has no friends for now. If the panda is already in the network don't add it again. 33 | * `hasPanda(panda)` - returns `true` or `false` if the `panda` is in the network or not. 34 | * `makeFriends(panda1, panda2)` - makes the two pandas friends. **The friendship is two-ways** - `panda1` is a friend with `panda2` and `panda2` is a friend with `panda1`. **If `panda1` or `panda2` are not members of the network, add them!** 35 | * `areFriends(panda1, panda2)` - returns `true` if the pandas are friends. Otherwise, `false` 36 | * `friendsOf(panda)` - returns a list of `Panda` with the friends of the given `panda`. Throws an exception if the `panda` is not a member of the network. 37 | * `connectionLevel(panda1, panda2)` - returns the connection level between `panda1` and `panda2`. If they are friends, the level is 1. Otherwise, count the number of friends you need to go through from `panda` in order to get to `panda2`. If they are not connected at all, return `-1`! Raise an error if one of the pandas are not member of the network. 38 | * `areConnected(panda1, panda2)` - return `true` if the pandas are connected somehow, between friends, or `false` otherwise. 39 | * `howManyGenderInNetwork(level, panda, gender)` - returns the number of pandas with gender `gender` (male of female) that are in the `panda` network in `level` levels deep. If `level == 2`, we will have to look in all friends of `panda` and all of their friends too. 40 | 41 | ## An example 42 | 43 | ```python 44 | PandaSocialNetwork network = new PandaSocialNetwork(); 45 | Panda ivo = new Panda("Ivo", "ivo@pandamail.com", "male"); 46 | Panda rado = new Panda("Rado", "rado@pandamail.com", "male"); 47 | Panda tony = new Panda("Tony", "tony@pandamail.com", "female"); 48 | 49 | network.addPanda(ivo); 50 | network.addPanda(rado); 51 | network.addPanda(tony); 52 | 53 | network.makeFriends(ivo, rado); 54 | network.makeFriends(rado, tony); 55 | 56 | network.connectionLevel(ivo, rado) == 1 # true 57 | network.connectionLevel(ivo, tony) == 2 # true 58 | 59 | network.howManyGenderInNetwork(1, rado, "female") == 1 # true 60 | ``` 61 | 62 | ## Save and load from file 63 | 64 | The next thing our social network is going to do is ``saving to your hard drive``. 65 | 66 | ### socialNetwork.save(file_name) 67 | 68 | Write a function that saves the whole social network to a file. The format of that file is not important but you have to be able to load it in the program. So all the data in the network must be written down to that file. 69 | 70 | ### socialNetwork.load(file_name) 71 | 72 | Write a function that loads the whole social network from a file. All the pandas and all the relations. 73 | 74 | *Note* you can use the JAR we introduced in the first week. -------------------------------------------------------------------------------- /week07/materials/soring.md: -------------------------------------------------------------------------------- 1 | # Sorting 2 | 3 | Sorting a sequence of elements is a well-known problem with many solutions. 4 | We could learn a lot just by looking at the steps that different algorithms 5 | take to produce a solution. 6 | 7 | ## Merge sort 8 | 9 | [Merge sort](http://en.wikipedia.org/wiki/Merge_sort) is a nice way of sorting 10 | a sequence of elements. It is a divide and conquer algorithm that divides the 11 | problem in smaller parts, solves them separately and then combines the solutions 12 | to produce a result. 13 | [Here](https://www.cs.usfca.edu/~galles/visualization/ComparisonSort.html) 14 | you can find a nice visualization of the steps of the algorithm. 15 | 16 | ## Quick sort 17 | 18 | The name speaks for itself. [Quick sort](http://en.wikipedia.org/wiki/Quicksort) 19 | is one of the fastest ways for sorting a sequence of arbitrary elements known to 20 | mankind. 21 | [Here](https://www.cs.usfca.edu/~galles/visualization/ComparisonSort.html) 22 | you can find a nice visualization of the steps of the algorithm. 23 | -------------------------------------------------------------------------------- /week07/sorting/README.md: -------------------------------------------------------------------------------- 1 | # Sorting 2 | 3 | ## Lets implement two of the fastest sorting algorithms 4 | 5 | ### Implement Quick Sort 6 | 7 | Lets implement quick sort choosing random pivot. 8 | 9 | ### Implement Merge Sort 10 | 11 | Lets implement classical merge sort. 12 | 13 | ### Enchance the Merge Sort 14 | 15 | Although it is very fast, Merge sort can be made a bit faster. 16 | It does not make sense to keep slicing the array into smaller ones below a given thershold lets say 32. 17 | 18 | We can use insertion sort for arrays smaller than 32. 19 | 20 | ## Exercise Comparator and Comparable 21 | 22 | Create a class Student that has First, Third name and grade. 23 | The Student class should implement the Comparable interface. 24 | 25 | Create a list of students and sort them according to their names using the compare to method. 26 | 27 | Create a list of students and sort them according to their grades using a custom Comparator class. -------------------------------------------------------------------------------- /week08/DungeonsAndZombies/README.md: -------------------------------------------------------------------------------- 1 | # Dungeons and Zombies 2 | 3 | We are going to make a simple, 2D turn-based console game filled with dungeons and zombies! 4 | 5 | We are going to have hero, enemies, weapons, treasures and magic! 6 | 7 | So lets start with the basic stuff: 8 | 9 | ## Our Hero 10 | 11 | Make a `Hero(name, title, health, mana, manaRegenRate)` class which can be initialized by that (all constructor arguments are shown in the example): 12 | 13 | ```java 14 | Hero hero = new Hero("Bron", "Dragonslayer", 100, 100, 2); 15 | ``` 16 | 17 | Our hero should have the following methods: 18 | 19 | ### `knownAs()` method 20 | 21 | Add a `knownAs()` method to our Hero, which returns a string, formatted in the following way: 22 | `"{hero_name} the {hero_title}"` 23 | 24 | __For example:__ 25 | 26 | ```java 27 | >>> h.knownAs() 28 | Bron the DragonSlayer 29 | ``` 30 | 31 | ### `getHealth()` and `getMana()` and `isAlive()` and `canCast()` 32 | 33 | Every hero starts with the given `health` and `mana` points. 34 | 35 | __Those `health` and `mana` points are the maximum health and mana for the hero!__ 36 | 37 | * When a hero reaches 0 `health` he is considered death. 38 | * When a hero reaches `mana` lower than the mana needed for the spell he knows, he cannot cast any spells 39 | 40 | Implement the following methods: 41 | 42 | * `isAlive()` which returns `true`, if our hero is still alive. Otherwise - `false`. 43 | * `getHealth()` which returns the current `health` 44 | * `getMana()` which returns the current `mana` 45 | * `canCast()` which returns `true`, if our hero can cast the magic he has been given. Otherwise - `false` 46 | 47 | ### `takeDamage(damagePoints)` 48 | 49 | So, our hero can take damage which reduces his health. 50 | 51 | Implement a method, called `takeDamage(damage_points)`. 52 | 53 | This method should reduce the hero's health by `damage` 54 | 55 | __If we inflict more damage than we have health, health will always be equal to zero and we cannot get below that!__ 56 | 57 | ### `takeHealing(healingPoints)` 58 | 59 | Our hero can also be healed! 60 | 61 | Implement a method, called `takeHealing(healingPoints)` which heals our hero. 62 | 63 | Note that: 64 | 65 | * We cannot heal our hero above the maximum health, which is given by `health` 66 | 67 | ### `takeMana(manaPoints)` 68 | 69 | Our hero can also increase his mana in two ways: 70 | 71 | * Each time he makes a move, his `mana` is increased by `manaRegenerationRate` amount. 72 | * He can drink a mana potion, which will increse his mana by the amount of mana points the potion have. 73 | 74 | **Hero's mana cannot go above the start `mana` given to him, neither he can go down below 0 mana.** 75 | 76 | ### `equip(weapon)` method 77 | 78 | Our hero can equip one weapon and one spell in order to have damage. 79 | 80 | Check the weapon example for more information. 81 | 82 | ### `learn(spell)` method 83 | 84 | The same as `equip`, but takes a `Spell` class. 85 | 86 | Our hero can learn only 1 spell at a time. 87 | 88 | If you learn a given spell, and after this learn another one, the hero can use only the latest. 89 | 90 | ### `attack()` method 91 | 92 | The method should return the demage done either from the weapon or from the spell (more on that, later) 93 | 94 | If the hero has not been equiped with weapon or he has no spells, his attack points are 0. (or maybe something low like 2. It's your choice) 95 | 96 | The method can be called in two ways: 97 | 98 | * `attack("weapon")` - returns the damage of the weapon if equiped or 0 otherwise (same as above) 99 | * `attack("magic")` - returns the damage of the spell, if equiped or 0 otherwise (same as above) 100 | 101 | ## The Enemies 102 | 103 | Implement a class `Enemy(health, mana, damage)` which is initialized like that: 104 | 105 | ```java 106 | Enemy enemy = new Enemy(100, 100, 20); 107 | ``` 108 | 109 | The `Enemy` should have the following methods, just like our hero: 110 | 111 | * `isAlive()` 112 | * `canCast()` 113 | * `getHealth()` 114 | * `getMana()` 115 | * `takeHealing()` 116 | * `takeMana()` 117 | * `attack()` 118 | * `takeDamage(damage)` 119 | 120 | * **Enemies cannot regenerate mana!** 121 | * **Enemies have starting damage, which is different from a weapon or a spell. They can equip weapons or learn spells but it is not required for them to have any damage, as it is for our hero.** 122 | 123 | ## The weapons and spells 124 | 125 | In order for our hero to have proper damage, he must be equiped with either a weapon or a spell. 126 | 127 | One hero can carry at max 1 weapon and 1 spell. 128 | 129 | ### Weapon class 130 | 131 | Implement a simple class `Weapon(name, damage)` which behaves like that: 132 | 133 | ```java 134 | Hero h = new Hero("Bron", "Dragonslayer", 100, 100, 2); 135 | Weapon w = new Weapon("The Axe of Destiny", 20); 136 | 137 | h.equip(w); 138 | 139 | h.attack("weapon"); // == 20 140 | ``` 141 | 142 | ### Spell class 143 | 144 | This should be more complex. Implement a spell class `Spell(name, damage, manaCost, castRange)`, which behaves like this: 145 | 146 | ```java 147 | Spell s = new Spell("Fireball", 30, 50, 2); 148 | ``` 149 | 150 | `name` and `damage` are self explanatory. 151 | 152 | * `manaCost` means that the spell needs at least that much amount of mana in order to be casted. 153 | * `castRange` is a bit more special and related to the Dungeon. You can cast that spell on an enemy, which is within the `castRange`. If `castRange` is 1, you can attack enemies, that are next to you. If cast range is greater than 1, you can attack enemies from distance, that is `castRange` squares away. **Casting range is only calculated in a straight line. You cannot curve spells** 154 | 155 | ## The Dungeons and treasures 156 | 157 | We are going to need a dungeon, where our hero can fight his enemies and find powerful weapons and spells! 158 | 159 | Our dungeon is going to be a 2D map that looks like that: 160 | 161 | ``` 162 | S.##.....T 163 | #T##..###. 164 | #.###E###E 165 | #.E...###. 166 | ###T#####G 167 | ``` 168 | 169 | Where: 170 | 171 | * `S` means a starting point for our hero. 172 | * `G` means gateway - the end of the dungeon (and most propably the enter to another) 173 | * `#` is an obstacle 174 | * `.` is a walkable path. 175 | * `T` is a treasure that can be either mana, health, weapon or spell 176 | * `E` is an enemy that our hero can fight 177 | 178 | We are going to load the layout of the map from a `String[][]` at the start. And when the task is almost ready - we will load it from a file so we can have multiple levels 179 | 180 | We create new dungeon like this: 181 | 182 | ``` 183 | S.##.....T 184 | #T##..###. 185 | #.###E###E 186 | #.E...###. 187 | ###T#####G 188 | ``` 189 | 190 | Our `Dungeon` should have the following methods: 191 | 192 | ### `printMap()` 193 | 194 | This should print the map to the console. Check the example above. 195 | 196 | ### `spawn` 197 | 198 | We want to spawn our hero in the `S` location of the map. 199 | 200 | Implement a method, called `spawn(hero)` where: 201 | 202 | * `hero` is a `Hero` instance 203 | 204 | This one takes the first free spawning point in the map and populates it with `H`. 205 | 206 | The first free spawning point is the one, that we get if we start from top-left and walk right. 207 | 208 | If the spawning is successful - return True. Otherwise (If there are no more spawning points, return False) 209 | 210 | **If our hero dies, he can respawn at the next spawning point. If there are no free spawning points, game is over** 211 | 212 | 213 | So, if we have the map above, let's take the following example: 214 | 215 | ```java 216 | Hero h = new Hero("Bron", "Dragonslayer", 100, 100, 2); 217 | dungeon.spawn(hero); 218 | dungeon.printMap(); 219 | ``` 220 | 221 | ``` 222 | H.##.....T 223 | #T##..###. 224 | #.###E###E 225 | #.E...###. 226 | ###T#####G 227 | ``` 228 | 229 | ### `moveHero()` 230 | 231 | Now, implemented a method `moveHero(direction)` where: 232 | 233 | * `direction` is either `"up"`, `"down"`, `"left"` and `"right"` 234 | 235 | This should move our hero in the desired direction. 236 | 237 | __For example:__ 238 | ```java 239 | dungeon.moveHero("right"); 240 | ``` 241 | 242 | 243 | ``` 244 | .H##.....T 245 | #T##..###. 246 | #.###E###E 247 | #.E...###. 248 | ###T#####G 249 | ``` 250 | 251 | ```java 252 | dungeon.moveHero("up"); 253 | dungeon.moveHero("down"); 254 | dungeon.printMap(); 255 | ``` 256 | 257 | ``` 258 | Found treasure! 259 | ..##.....T 260 | #H##..###. 261 | #.###E###E 262 | #.E...###. 263 | ###T#####G 264 | ``` 265 | 266 | Here are the cases: 267 | 268 | * If you move into an obstacle, don't make the move. 269 | * If you move outside the map - don't make the move. 270 | * If you move into an enemy, a `Fight` is automatically started. Otherwise, you have options, which we will describe in the `Fight` class 271 | * If you move into `Treasure`, roll a dice to decide what it can be - a mana or health potion, a weapon or a spell 272 | 273 | ### Treasures 274 | 275 | It is a good idea to have a finite list of treasures that can be found in a given dungeon. 276 | 277 | One idea is to keep a list of treasure in the **txt** file, where the map is. Other idea is to have a separate file that keeps the loot for each map. But that can be done last. 278 | 279 | Our suggestion for you is to keep a track of all treasures in the `Dungeon` class and have a method `pickTreasure()` that returns an instance of randomly picked treasure. 280 | 281 | ## Fights 282 | 283 | The interesting part is here. 284 | 285 | Our hero must fight his enemies in order to reach the exit of the dungeon. 286 | 287 | Our `Dungeon` should have a `heroAttack(by)` method, which checks if our hero can attack either by weapon or by spell, again having a `by` argument, like the `weapon` 288 | 289 | 290 | A fight happens when: 291 | 292 | * Our hero walks into the same position as the enemy - then the fights start automatically 293 | * Our hero is within some range of the enemy and triggers `heroAttack` method call. Then we can attack our enemy, but our enemy must walk to our place in order to start attacking us. This is really helpful with spells! 294 | 295 | Implement a `Fight` class that takes a hero and an emeny and simulates a fight between them. 296 | 297 | The `Fight` is over when either our hero or the enemy is dead. 298 | 299 | Here is a full example: 300 | 301 | ```java 302 | Hero h = Hero("Bron", "Dragonslayer", 100, 100, 2); 303 | Weapon w = Weapon("The Axe of Destiny", 20); 304 | h.equip(w); 305 | Spell s = Spell("Fireball", 30, 50, 2); 306 | h.learn(s); 307 | Dungeon map = new Dungeon("level1.txt"); 308 | map.spawn(h); 309 | map.printMap(); 310 | ``` 311 | 312 | ``` 313 | H.##.....T 314 | #T##..###. 315 | #.###E###E 316 | #.E...###. 317 | ###T#####G 318 | ``` 319 | 320 | ``` 321 | map.moveHero("right"); 322 | map.moveHero("down"); 323 | map.printMap(); 324 | ``` 325 | 326 | ```java 327 | Found health potion. Hero health is max. 328 | ..##.....T 329 | #H##..###. 330 | #.###E###E 331 | #.E...###. 332 | ###T#####G 333 | ``` 334 | 335 | ```java 336 | map.heroAttack("spell"); 337 | ``` 338 | 339 | ``` 340 | Nothing in casting range 2 341 | ``` 342 | 343 | ```java 344 | map.moveHero("down"); 345 | map.moveHero("down"); 346 | map.printMap(); 347 | ``` 348 | 349 | ``` 350 | ..##.....T 351 | #.##..###. 352 | #.###E###E 353 | #HE...###. 354 | ###T#####G 355 | ``` 356 | 357 | ``` 358 | map.heroAttack("spell"); 359 | ``` 360 | A fight is started between our Hero(health=100, mana=100) and Enemey(health=100, mana=100, damage=20) 361 | Hero casts a Fireball, hits enemy for 20 dmg. Enemy health is 80 362 | Enemy moves one square to the left in order to get to the hero. This is his move. 363 | Hero casts a Fireball, hits enemy for 20 dmg. Enemy health is 60 364 | Enemy hits hero for 20 dmg. Hero health is 80 365 | Hero does not have mana for another Fireball. 366 | Hero hits with Axe for 20 dmg. Enemy health is 40 367 | Enemy hits hero for 20 dmg. Hero health is 60. 368 | Hero hits with Axe for 20 dmg. Enemy health is 20 369 | Enemy hits hero for 20 dmg. Hero health is 40. 370 | Hero hits with Axe for 20 dmg. Emely health is 0 371 | Enemy is dead! 372 | ``` 373 | 374 | ### Fight steps 375 | 376 | The fight follows this algorithm: 377 | 378 | * Our hero always attacks first 379 | * We always use the attack that deals more damage 380 | * If our weapon and our spell deals the same amount of damage, use the spell first. 381 | * When you run out of mana, use the weapon (if any) 382 | * Think of how you can make the enemies cast spells? 383 | 384 | ## Creativity and Improvisation 385 | 386 | As you can see, this is a big and a fat problem. There are things that are not well defined. 387 | 388 | **This is up to you. Make an interesting game!** 389 | -------------------------------------------------------------------------------- /week08/ZombieApocalypse/README.md: -------------------------------------------------------------------------------- 1 | # Zombie Apocalypse 2 | 3 | The time has come. Zombies are everywhere. It is the zombie apocalypse! 4 | 5 | You are in a room with zombies. You grab a weapon and start to fight them. 6 | 7 | And since you are a Java programmer, you fight them by writing a Java program to fight them. 8 | 9 | You have an interface for a weapon: 10 | 11 | ```java 12 | public interface Weapon { 13 | public int getDamage(); 14 | public int getDurability(); 15 | public String getType(); // can return "TO_SMASH" or "TO_SHOOT" 16 | } 17 | ``` 18 | 19 | The possible weapons around you are: 20 | 21 | * An `Axe` with damage of 10 and durability of 50. 22 | * A `Shotgun` with damage of 25 and durability of 10. 23 | * An `AncientSword` with damage of 50 and durability of 10. 24 | * A `Revolver` with damage of 15 and durability of 6. 25 | 26 | ## Durability, damage and types 27 | 28 | Depending on the weapon type, you have the following fighting dynamics: 29 | 30 | ### TO_SMASH weapons 31 | 32 | Weapons with type `TO_SMASH` lose their durability, everytime you hit a zombie. 33 | 34 | Once the durability of the weapon goes below 50% of the original durability value, the weapon deals 1 damage less with each hit. 35 | 36 | **For example** if you have `Axe` with damage = 10 and durability = 4 we have: 37 | 38 | * First hit, `durability = 4`. 4 >= 4 / 2, so the weapon deals 10 damage. Durability decreases to 3. 39 | * Second hit, `durability = 3`. 3 >= 4 / 2, so the weapon deals 10 damage. Durability decreases to 2. 40 | * Third hit, `durability = 2`. 2 >= 4 / 2, so the weapon deals 10 damage. Durability decreases to 1. 41 | * Fourth hit, `durability = 1`, 1 < 4 / 2, so the weapon deals 9 damage. Durability goes to 0 and stays there. 42 | 43 | Every hit that comes after this, will decrease the damage by 1, until the damage becomes 1. This is the lowest point for damage. 44 | 45 | ### TO_SHOOT weapons 46 | 47 | Weapons with type `TO_SHOOT` have bullets. The durability for that weapon is equal to the amount of bullets they have. 48 | 49 | Once the durability (bullets) goes to `0`, your can start smashing your enemies with the weapon (in cold blood). 50 | 51 | The damage of the weapon is always `1`, when you run out of bullets. 52 | 53 | ## Zombies 54 | 55 | There is a `Zombie` interface: 56 | 57 | ```java 58 | public interface Zombie { 59 | public int getTotalHealth(); 60 | public int getCurrentHealth(); 61 | public void hit(int damage); 62 | public boolean isDead(); 63 | } 64 | ``` 65 | 66 | Implement the interface with a proper class. This is your job. The name of the methods should give you a clue of their implementation. 67 | 68 | We need to be able to kill Zombies. 69 | 70 | ## The game 71 | 72 | Implement a Java program, that: 73 | 74 | * Reads one integer `n` from the input - this is the number of zombies in your room 75 | * Reads another integer `zombieHealth` from the input - this is going to be the total health of each zombie. 76 | * Reads one string `weapon` which is either one of the values `{"axe", "shotgun", "sword", "revolver"}` - this is the weapon you are going to have in the room. 77 | 78 | **On one line of the standard input, print the number of hits you have to make in order to kill all zombies in the room.** 79 | 80 | ## Example 81 | 82 | Input: 83 | 84 | ``` 85 | 2 10 86 | Axe 87 | ``` 88 | 89 | Output: 90 | 91 | ``` 92 | 2 93 | ``` 94 | 95 | We kill the first zombie (`damage = 10`, `health = 10`) with the first hit. We do the same with the second hit. 96 | 97 | --- 98 | 99 | Input: 100 | 101 | ``` 102 | 3 100 103 | sword 104 | ``` 105 | 106 | Output: 107 | 108 | ``` 109 | 7 110 | ``` 111 | 112 | * We kill the fist zombie with two hits. `Durability = 8` 113 | * We kill the second zombie with two hits. `Durability = 6` 114 | * We hit the third zombie once, `Durability = 5`. The next hit will deal `49` damage. So we need another hit, with `48` damage to kill it. 115 | * A total of `7` hits. 116 | -------------------------------------------------------------------------------- /week09/01-SQL-Starter/README.md: -------------------------------------------------------------------------------- 1 | # First steps in Databases and SQL 2 | 3 | ## Tables, tables everywhere! SELECT, UPDATE, INSERT, DELETE 4 | 5 | Now, we know that our languages table looks like this: 6 | 7 | | id | language | answer | answered | guide | 8 | | ------------- |:-------------:| --- | --- |-----:| 9 | 1|Python|google|0|A folder named Python was created. Go there and fight with program.py! 10 | 2|Go|200 OK|0|A folder named Go was created. Go there and try to make Google Go run. 11 | 3|Java|object oriented programming|0|A folder named Java was created. Can you handle the class? 12 | 4|Haskell|Lambda|0|Something pure has landed. Go to Haskell folder and see it! 13 | 5|C#|NDI=|0|Do you see sharp? Go to the C# folder and check out. 14 | 6|Ruby|https://www.ruby-lang.org/bg/|0|Ruby, ruby, rubyyy, aaahaaaahaa! (music). Go to Ruby folder! 15 | 7|C++|header files|0|Here be dragons! It's C++ time. Go to the C++ folder. 16 | 8|JavaScript|Douglas Crockford|0|NodeJS time. Go to JavaScript folder and Node your way! 17 | 18 | 19 | A ```SELECT``` statement, returns a list of rows. We ```SELECT``` by giving the name of the columns we want. 20 | 21 | Run the following SELECT statements in the sqilite3 shell: 22 | 23 | 24 | ```sql 25 | SELECT id FROM languages; 26 | ``` 27 | 28 | ```sql 29 | SELECT id, language FROM languages; 30 | ``` 31 | 32 | ```sql 33 | SELECT id, language, answer, answered FROM languages; 34 | ``` 35 | 36 | ```sql 37 | SELECT id, language FROM languages WHERE answered = 0; 38 | ``` 39 | 40 | ```sql 41 | SELECT id, language FROM languages WHERE answered = 1; 42 | ``` 43 | 44 | __Now, lets update few languages to be answered. We will change the answered value for each language from 0 to 1:__ 45 | 46 | 47 | ```sql 48 | UPDATE languages SET answered = 1 WHERE language = "Python"; 49 | ``` 50 | 51 | ```sql 52 | SELECT id, language FROM languages WHERE answered = 1; 53 | ``` 54 | 55 | Now, if we run the ```polyglot.py``` program and give the ```list``` command, we will see: 56 | 57 | ``` 58 | DONE [1] - Python 59 | NOT_DONE [2] - Go 60 | NOT_DONE [3] - Java 61 | NOT_DONE [4] - Haskell 62 | NOT_DONE [5] - C# 63 | NOT_DONE [6] - Ruby 64 | NOT_DONE [7] - C++ 65 | NOT_DONE [8] - JavaScript 66 | ``` 67 | 68 | As you can see, if we control the data, we control the program! 69 | 70 | __Now, let's insert a new language in our table!__ 71 | 72 | Execute the following statements: 73 | 74 | 75 | ```sql 76 | INSERT INTO languages(id, language, answer, answered, guide) VALUES(9, "PHP", "$$$", 0, "Can you handle this piece of PHP?"); 77 | ``` 78 | 79 | ```sql 80 | SELECT language FROM languages; 81 | ``` 82 | 83 | Now, if we go to our Polyglot program, again, we will see that PHP was added too: 84 | 85 | ``` 86 | DONE [1] - Python 87 | NOT_DONE [2] - Go 88 | NOT_DONE [3] - Java 89 | NOT_DONE [4] - Haskell 90 | NOT_DONE [5] - C# 91 | NOT_DONE [6] - Ruby 92 | NOT_DONE [7] - C++ 93 | NOT_DONE [8] - JavaScript 94 | NOT_DONE [9] - PHP 95 | ``` 96 | 97 | Now, to finish the cycles of SQL statements, we are going to ```DELETE``` the added PHP language 98 | 99 | We can achieve that by running the following query: 100 | 101 | ```sql 102 | DELETE FROM languages WHERE language = "PHP"; 103 | ``` 104 | 105 | Now, if we run: 106 | 107 | ```sql 108 | SELECT language FROM languages; 109 | ``` 110 | 111 | We wont see PHP! 112 | 113 | ### SUID = CRUD 114 | 115 | We were talking about CRUD operations - Create, Read, Update, Delete of a given object. 116 | 117 | If we take a look at the SQL query statements, we can relate: 118 | 119 | * `SELECT` = Read 120 | * `UPDATE` = Update 121 | * `INSERT` = Create 122 | * `DELETE` = Delete 123 | -------------------------------------------------------------------------------- /week09/01-SQL-Starter/movies.sql: -------------------------------------------------------------------------------- 1 | 2 | DROP DATABASE MOVIES; 3 | CREATE DATABASE MOVIES; 4 | USE MOVIES; 5 | 6 | DROP TABLE IF EXISTS MOVIEEXEC; 7 | DROP TABLE IF EXISTS MOVIE; 8 | DROP TABLE IF EXISTS MOVIESTAR; 9 | DROP TABLE IF EXISTS STARSIN; 10 | DROP TABLE IF EXISTS STUDIO; 11 | 12 | CREATE TABLE MOVIEEXEC ( 13 | CERT INTEGER NOT NULL PRIMARY KEY, 14 | NAME CHAR(30), 15 | ADDRESS VARCHAR(255), 16 | NETWORTH INTEGER 17 | ); 18 | 19 | CREATE TABLE STUDIO ( 20 | NAME CHAR(50) NOT NULL PRIMARY KEY, 21 | ADDRESS VARCHAR(255), 22 | PRESC INTEGER 23 | ); 24 | 25 | CREATE TABLE MOVIE ( 26 | TITLE VARCHAR(255) NOT NULL, 27 | YEAR INTEGER NOT NULL, 28 | LENGTH INTEGER, 29 | INCOLOR CHAR(1), 30 | STUDIONAME CHAR(50), 31 | PRODUCER INTEGER, 32 | PRIMARY KEY( TITLE, YEAR), 33 | FOREIGN KEY(PRODUCER) REFERENCES MOVIEEXEC(CERT), 34 | FOREIGN KEY(STUDIONAME) REFERENCES STUDIO(NAME) 35 | ); 36 | 37 | CREATE TABLE MOVIESTAR ( 38 | NAME CHAR(30) NOT NULL PRIMARY KEY, 39 | ADDRESS VARCHAR(255), 40 | GENDER CHAR(1), 41 | BIRTHDATE DATE 42 | ); 43 | 44 | CREATE TABLE STARSIN ( 45 | MOVIETITLE VARCHAR(255) NOT NULL, 46 | MOVIEYEAR INTEGER NOT NULL, 47 | STARNAME CHAR(30) NOT NULL, 48 | FOREIGN KEY(MOVIETITLE) REFERENCES MOVIE(TITLE), 49 | FOREIGN KEY(STARNAME) REFERENCES MOVIESTAR(NAME), 50 | PRIMARY KEY(MOVIETITLE, MOVIEYEAR, STARNAME) 51 | ); 52 | 53 | INSERT INTO STUDIO (NAME, ADDRESS, PRESC) 54 | VALUES ('Disney','USA, 234534 CF, World',4); 55 | 56 | INSERT INTO STUDIO (NAME, ADDRESS, PRESC) 57 | VALUES ('Fox','USA, 234576 CF, Fox Str',3); 58 | 59 | INSERT INTO STUDIO (NAME, ADDRESS, PRESC) 60 | VALUES ('MGM','USA, 127823 NY, 8th Str',1); 61 | 62 | INSERT INTO STUDIO (NAME, ADDRESS, PRESC) 63 | VALUES ('Paramount','USA, 986745 CF, Para Str',1); 64 | 65 | INSERT INTO STUDIO (NAME, ADDRESS, PRESC) 66 | VALUES ('USA Entertainm.','USA, 213243 CF, Uni Str',3); 67 | 68 | INSERT INTO STUDIO (NAME, ADDRESS, PRESC) 69 | VALUES ('Warner Bros','USA, 324235 NY, Bacon Str',2); 70 | 71 | INSERT INTO MOVIEEXEC (NAME, ADDRESS, CERT, NETWORTH) 72 | VALUES ('George Lucas', 'Oak Rd.', 555, 200000000); 73 | 74 | INSERT INTO MOVIEEXEC (NAME, ADDRESS, CERT, NETWORTH) 75 | VALUES ('Ted Turner', 'Turner Av.', 333, 125000000); 76 | 77 | INSERT INTO MOVIEEXEC (NAME, ADDRESS, CERT, NETWORTH) 78 | VALUES ('Stephen Spielberg', '123 ET road', 222, 100000000); 79 | 80 | INSERT INTO MOVIEEXEC (NAME, ADDRESS, CERT, NETWORTH) 81 | VALUES ('Merv Griffin', 'Riot Rd.', 199, 112000000); 82 | 83 | INSERT INTO MOVIEEXEC (NAME, ADDRESS, CERT, NETWORTH) 84 | VALUES ('Calvin Coolidge', 'Fast Lane', 123, 20000000); 85 | 86 | INSERT INTO MOVIESTAR 87 | VALUES ('Jane Fonda', 'Turner Av.', 'F', '1977-07-07'); 88 | 89 | INSERT INTO MOVIESTAR 90 | VALUES ('Alec Baldwin', 'Baldwin Av.', 'M', '1977-07-06'); 91 | 92 | INSERT INTO MOVIESTAR 93 | VALUES ('Kim Basinger', 'Baldwin Av.', 'F', '1979-07-05'); 94 | 95 | INSERT INTO MOVIESTAR 96 | VALUES ('Harrison Ford', 'Prefect Rd.', 'M', '1955-05-05'); 97 | 98 | INSERT INTO MOVIESTAR 99 | VALUES ('Debra Winger', 'A way', 'F', '1978-06-05'); 100 | 101 | INSERT INTO MOVIESTAR 102 | VALUES ('Jack Nicholson', 'X path', 'M', '1949-05-05'); 103 | 104 | INSERT INTO MOVIE 105 | VALUES ('Pretty Woman', 1990, 119, 'y', 'Disney', 199); 106 | 107 | INSERT INTO MOVIE 108 | VALUES ('The Man Who Wasn''t There', 2001, 116, 'N', 'USA Entertainm.', 109 | 555); 110 | 111 | INSERT INTO MOVIE 112 | VALUES ('Logan''s run', 1976, NULL, 'Y', 'Fox', 333); 113 | 114 | INSERT INTO MOVIE 115 | VALUES ('Star Wars', 1977, 124, 'Y', 'Fox', 555); 116 | 117 | INSERT INTO MOVIE 118 | VALUES ('Empire Strikes Back', 1980, 111, 'Y', 'Fox', 555); 119 | 120 | INSERT INTO MOVIE 121 | VALUES ('Star Trek', 1979, 132, 'Y', 'Paramount', 222); 122 | 123 | INSERT INTO MOVIE 124 | VALUES ('Star Trek: Nemesis', 2002, 116, 'Y', 'Paramount', 123); 125 | 126 | INSERT INTO MOVIE 127 | VALUES ('Terms of Endearment', 1983, 132, 'Y', 'MGM', 123); 128 | 129 | INSERT INTO MOVIE 130 | VALUES ('The Usual Suspects', 1995, 106, 'Y', 'MGM', 199); 131 | 132 | INSERT INTO MOVIE 133 | VALUES ('Gone With the Wind', 1938, 238, 'Y', 'MGM', 123); 134 | 135 | INSERT INTO STARSIN 136 | VALUES ('Star Wars', 1977, 'Kim Basinger'); 137 | 138 | INSERT INTO STARSIN 139 | VALUES ('Star Wars', 1977, 'Alec Baldwin'); 140 | 141 | INSERT INTO STARSIN 142 | VALUES ('Star Wars', 1977, 'Harrison Ford'); 143 | 144 | INSERT INTO STARSIN 145 | VALUES ('Empire Strikes Back', 1980, 'Harrison Ford'); 146 | 147 | INSERT INTO STARSIN 148 | VALUES ('The Usual Suspects', 1995, 'Jack Nicholson'); 149 | 150 | INSERT INTO STARSIN 151 | VALUES ('Terms of Endearment', 1983, 'Jane Fonda'); 152 | 153 | INSERT INTO STARSIN 154 | VALUES ('Terms of Endearment', 1983, 'Jack Nicholson'); 155 | -------------------------------------------------------------------------------- /week09/01-SQL-Starter/movies_schema.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HackBulgaria/Programming101-Java-2016/f9e042f9c6c4fc844836f938cd8ed8a3e5d6fcdd/week09/01-SQL-Starter/movies_schema.png -------------------------------------------------------------------------------- /week09/01-SQL-Starter/queries.md: -------------------------------------------------------------------------------- 1 | ## Database schema 2 | ![Schema](movies_schema.png) 3 | 4 | ## First Queries 5 | 1. Напишете заявка, която извежда адреса на студио ‘MGM’ 6 | 2. Напишете заявка, която извежда рождената дата на актрисата Sandra 7 | Bullock 8 | 3. Напишете заявка, която извежда имената всички продуценти на филми с 9 | нетни активи (networth) над 10 000 000 долара 10 | 4. Напишете заявка, която извежда имената на всички актьори, които са 11 | мъже или живеят на Prefect Rd 12 | 5. Добавате нова филмова звезда 'Zahari Baharov', с адрес и рожденна дата по ваш избор. 13 | 6. Изтрийте всички студия, които имат в адреса си числото 5. 14 | 7. Променете студио да бъде "Fox" на тези филми, които в имената си имат 'star. 15 | 16 | 17 | ## Relations 18 | 19 | 1. Напишете заявка, която извежда имената на актьорите мъже участвали в ‘Terms 20 | 2. of Endearment’ 21 | 3. Напишете заявка, която извежда имената на актьорите участвали във филми 22 | продуцирани от ‘MGM’през 1995 г. 23 | 4. Добавете колона "име на президент"на таблицата Студио и съответно и задайте стойности.Напишете заявка, която извежда името на президента на ‘MGM’ 24 | 5. Напишете заявка, която извежда имената на всички филми с дължина по-голяма 25 | от дължината на филма ‘Gone With the Wind’ 26 | 6. Напишете заявка, която извежда имената на тези продукции на стойност по- 27 | голяма от ‘Merv Griffin’ 28 | -------------------------------------------------------------------------------- /week09/materials/Main.java: -------------------------------------------------------------------------------- 1 | package sql; 2 | 3 | import java.sql.*; 4 | 5 | public class Main { 6 | 7 | static final String DB_URL = "jdbc:mysql://localhost/sqTesting"; 8 | static final String USER = "root"; 9 | static final String PASS = "123"; 10 | 11 | public static void main(String[] args) { 12 | try { 13 | Connection conn = null; 14 | Statement stmt = null; 15 | //STEP 2: Register JDBC driver 16 | Class.forName("com.mysql.jdbc.Driver"); 17 | 18 | //STEP 3: Open a connection 19 | System.out.println("Connecting to database..."); 20 | conn = DriverManager.getConnection(DB_URL,USER,PASS); 21 | 22 | //STEP 4: Execute a query 23 | System.out.println("Creating statement..."); 24 | stmt = conn.createStatement(); 25 | String sql; 26 | sql = "SELECT id, name, age FROM Clients"; 27 | ResultSet rs = stmt.executeQuery(sql); 28 | 29 | //STEP 5: Extract data from result set 30 | while(rs.next()){ 31 | //Retrieve by column name 32 | int id = rs.getInt("id"); 33 | int age = rs.getInt("age"); 34 | String name = rs.getString("name"); 35 | 36 | //Display values 37 | System.out.print("ID: " + id); 38 | System.out.print(", Age: " + age); 39 | System.out.print(", Name: " + name); 40 | } 41 | //STEP 6: Clean-up environment 42 | rs.close(); 43 | stmt.close(); 44 | conn.close(); 45 | } catch(Exception se) { 46 | se.printStackTrace(); 47 | } 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /week10/Cinema-Reservation/README.md: -------------------------------------------------------------------------------- 1 | # Cinema Reservation System 2 | We are going to the cinema! But the reservation systems are down and the cinema officials don't let people enter without reservations. So we offered to make them a new reservation system that will allow us to go and watch the newest **"Aliens came, we built transformers and destroyed them..."** movie. 3 | 4 | ## Problem 0 - The database 5 | No complex stuff here. Just a few simple tables: 6 | 7 | **Movies** 8 | 9 | | id | name | rating | 10 | | ------------- |:-------------| :---: | 11 | |1|The Hunger Games: Catching Fire |7.9| 12 | |2|Wreck-It Ralph|7.8| 13 | |3|Her|8.3| 14 | 15 | **Projections** 16 | 17 | | id | movie_id | type | date | time | 18 | | ---|----------|:----:| :--: | :--: | 19 | |1|1|3D|2014-04-01|19:10 20 | |2|1|2D|2014-04-01|19:00 21 | |3|1|4DX|2014-04-02|21:00 22 | |4|3|2D|2014-04-05|20:20 23 | |5|2|3D|2014-04-02|22:00 24 | |6|2|2D|2014-04-02|19:30 25 | 26 | **Reservations** 27 | 28 | | id | username | projection_id | row | col | 29 | | ---|----------|---------------|:----:|:---:| 30 | |1|RadoRado|1|2|1| 31 | |2|RadoRado|1|3|5| 32 | |3|RadoRado|1|7|8| 33 | |4|Ivo|3|1|1| 34 | |5|Ivo|3|1|2| 35 | |6|Kamen|5|2|3| 36 | |7|Kamen|5|2|4| 37 | 38 | **Things to note** 39 | * For each projection we assume the hall to be a 10x10 matrix. 40 | * All data presented here is just an example. If you want, you can make up your own data (perhaps you are the creator of the aforementioned movie and want to include it). 41 | 42 | ## Problem 1 - The CLI (Command-Line Interface) 43 | We don't need no GUIs! A console with green text and transparent background is all a hacker requires. 44 | Implement a script that takes magic commands and casts an appropriate spell. Here's an ancient page of Merlin's Book: 45 | * On spell ```show movies``` - print all movies ORDERed BY rating 46 | * On spell ```show movie projections []``` - print all projections of a given movie for the given date (date is optional). 47 | 1. ORDER the results BY date 48 | 2. For each projection, show the total number of spots available. 49 | 50 | * On spell ```make reservation``` - It's showtime! 51 | 1. Make the hacker choose a name and number of tickets 52 | 2. Cast ```show movies``` and make the hacker choose a movie by id 53 | 3. Cast ```show movie projections``` for the chosen `````` and make the hacker choose a projection 54 | * *If the available spots for a projection are less than the number of tickets needed, print an appropriate message and stay at step 3*; 55 | 4. Cast a spell to show all available spots for the chosen projection 56 | 5. For each number of tickets, make the hacker choose ```(row, col)```. Check for validity (10x10 matrix) and availability (reservations table) 57 | 6. Cast a spell to show the info in an appropriate format. Then prompt for ```finalize``` spell 58 | 7. On ```finalize``` spell, save all the info and wish a happy cinema! 59 | 0. **At each step, allow for ```give up``` spell to be cast. This...wait for it...waaaiit... gives up the reservation!!!** (Thanks, cap'n) 60 | 61 | * On spell ```cancel reservation ``` - disintegrate given person's reservation (**NOTE**: reservations cannot be so easily removed, but this is a magical system, after all) 62 | * On spell ```exit``` - close Pandora's Box before it's too late. 63 | * On spell ```help``` - show a list of learned spells 64 | 65 | 66 | **Things to note** 67 | * Notice how you are required to reuse code (or you'll be one messy hacker!!!). 68 | * Try not to build everything in one place. 69 | * Make use of the following techniques (Merlin used them to destroy the Decepticons): **OOP, TDD, SQL**. 70 | 71 | 72 | 73 | ## Examples 74 | 75 | ### Show movies 76 | 77 | ``` 78 | > show movies 79 | Current movies: 80 | [1] - The Hunger Games: Catching Fire (7.9) 81 | [2] - Wreck-It Ralph (7.8) 82 | [3] - Her (8.3) 83 | ``` 84 | 85 | ### Show movie projections ### 86 | 87 | ``` 88 | > show movie projections 2 89 | Projections for movie 'Wreck-It Ralph': 90 | [5] - 2014-04-02 19:30 (2D) 91 | [6] - 2014-04-02 22:00 (3D) 92 | > show movie projections 1 2014-04-01 93 | Projections for movie 'The Hunger Games: Catching Fire' on date 2014-04-01: 94 | [1] - 19:00 (3D) 95 | [2] - 19:10 (2D) 96 | ``` 97 | 98 | 99 | ### Make a reservation 100 | 101 | ``` 102 | > make reservation 103 | Step 1 (User): Choose name>Tedi 104 | Step 1 (User): Choose number of tickets> 2 105 | Current movies: 106 | [1] - The Hunger Games: Catching Fire (7.9) 107 | [2] - Wreck-It Ralph (7.8) 108 | [3] - Her (8.3) 109 | Step 2 (Movie): Choose a movie> 2 110 | Projections for movie 'Wreck-It Ralph': 111 | [5] - 2014-04-02 19:30 (2D) - 98 spots available 112 | [6] - 2014-04-02 22:00 (3D) - 100 spots availabe 113 | Step 3 (Projection): Choose a projection> 5 114 | Available seats (marked with a dot): 115 | 1 2 3 4 5 6 7 8 9 10 116 | 1 . . . . . . . . . . 117 | 2 . . X X . . . . . . 118 | 3 . . . . . . . . . . 119 | 4 . . . . . . . . . . 120 | 5 . . . . . . . . . . 121 | 6 . . . . . . . . . . 122 | 7 . . . . . . . . . . 123 | 8 . . . . . . . . . . 124 | 9 . . . . . . . . . . 125 | 10 . . . . . . . . . . 126 | Step 4 (Seats): Choose seat 1> (2,3) 127 | This seat is already taken! 128 | Step 4 (Seats): Choose seat 1> (15, 16) 129 | Lol...NO! 130 | Step 4 (Seats): Choose seat 1> (7,8) 131 | Step 4 (Seats): Choose seat 2> (7,7) 132 | This is your reservation: 133 | Movie: Wreck-It Ralph (7.8) 134 | Date and Time: 2014-04-02 19:30 (2D) 135 | Seats: (7,7), (7.8)` 136 | Step 5 (Confirm - type 'finalize') > finalize 137 | Thanks. 138 | ``` 139 | 140 | # DISCLAIMER 141 | The purpose of these tasks is to train your casting (programming) skills. 142 | The purpose of these tasks is NOT to abide by the rules (we = hackers). 143 | If you decide that something is not structured/explained/invented enough, feel free to discuss it with us! 144 | Happy hacking! 145 | -------------------------------------------------------------------------------- /week10/Type-Checking/README.md: -------------------------------------------------------------------------------- 1 | # Type Checking 2 | 3 | We are going to define a dead-simple functional language, where we can define 1-argument functions and give them **type signatures**. 4 | 5 | ## The language 6 | 7 | The language looks like this: 8 | 9 | ``` 10 | f :: A -> B 11 | ``` 12 | 13 | This is the type signature for functional with name `f` which takes 1 argument of type `A` and returns a result of type `B`. 14 | 15 | We are not interested in the body of the function. **We are going to work only with type signatures.** 16 | 17 | Few things to have in mind: 18 | 19 | * The syntax rules are going to be fixed: ` :: T1 -> T2`. 20 | * There is exactly 1 ` ` between `` and `::` and `::` and the types. 21 | * There is exactly 1 ` ` between `T1` and `->` and `->` and `T2`. 22 | * We are going to have only 1 argumented functions. 23 | * Function names can be camel-cased and will always start with a lower case. 24 | * Type names are always starting with a capital letter. 25 | 26 | ## Function composition 27 | 28 | Our language will support function composition: 29 | 30 | ``` 31 | f :: A -> B 32 | g :: B -> A 33 | 34 | f . g 35 | ``` 36 | 37 | Function composition is a binary operation between functions that returns a new function. 38 | 39 | For example, if we have two 1-argumented functions `f` and `g`, then `h = f . g` is a new function. 40 | 41 | When we call `h`: we do the following: `h(x) = f(g(x))` 42 | 43 | ## The problem 44 | 45 | You are given some function definitions in our language & exactly 1 functiom composition, as the last thing in the input. 46 | 47 | You need to output `True` or `False` **if the given function composition is valid.** 48 | 49 | Given function composition is valid if all types are matching properly. 50 | 51 | For example: 52 | 53 | ``` 54 | f :: String -> Int 55 | g :: Int -> String 56 | 57 | f . g 58 | ``` 59 | 60 | If we are to call the composition `f . g`: 61 | 62 | * `g` takes `Int` and returns `String` 63 | * We are calling `f` with the result from `g`. `g` takes `String` as an input => **everything's OK and this is a valid composition.** 64 | 65 | Lets see another example: 66 | 67 | 68 | ``` 69 | f :: String -> Int 70 | g :: Int -> String 71 | 72 | f . f 73 | ``` 74 | 75 | * First, we are calling `f` which will return `Int` 76 | * Then, we will try to call `f` with `Int`, but `f` requires `String`. We have type mismatch => **this is not a valid composition** 77 | 78 | --- 79 | 80 | **You need to write a program, that reads from the standard input some definitions & one function composition.** 81 | 82 | Your program should output `True` to the standard output, if the given composition is valid, according to the types. Otherwise - `False`. 83 | 84 | The format of the input will be: 85 | 86 | * First `n` lines are going to be function definitions 87 | * The last line will be the function composition. 88 | * Between the definitions and the composition, there will be **exactly 1 empty line** 89 | 90 | ### Example input: 91 | 92 | ``` 93 | f :: String -> Int 94 | g :: Int -> String 95 | 96 | f . g 97 | ``` 98 | 99 | Example output: 100 | 101 | ``` 102 | True 103 | ``` -------------------------------------------------------------------------------- /week11/HackUnit/src/com/hackbulgaria/Main.java: -------------------------------------------------------------------------------- 1 | package com.hackbulgaria; 2 | 3 | import com.hackbulgaria.hackunit.HackUnitCore; 4 | import com.hackbulgaria.hackunit.Results; 5 | import com.hackbulgaria.hackunit.tests.MyTests; 6 | 7 | public class Main { 8 | 9 | public static void main(String[] args) { 10 | Results results = new HackUnitCore() 11 | .runClasses(MyTests.class) 12 | .getResults(); 13 | 14 | System.out.println(results); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /week11/HackUnit/src/com/hackbulgaria/hackunit/Assert.java: -------------------------------------------------------------------------------- 1 | package com.hackbulgaria.hackunit; 2 | 3 | public class Assert { 4 | 5 | public static void fail(String message) { 6 | if (message == null) { 7 | throw new AssertionError(); 8 | } 9 | throw new AssertionError(message); 10 | } 11 | 12 | public static void fail() { 13 | fail(null); 14 | } 15 | 16 | public static void assertTrue(String message, boolean condition) { 17 | if (!condition) { 18 | fail(message); 19 | } 20 | } 21 | 22 | public static void assertTrue(boolean condition) { 23 | assertTrue(null, condition); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /week11/HackUnit/src/com/hackbulgaria/hackunit/HackUnitCore.java: -------------------------------------------------------------------------------- 1 | package com.hackbulgaria.hackunit; 2 | 3 | import java.lang.reflect.Constructor; 4 | import java.lang.reflect.InvocationTargetException; 5 | import java.lang.reflect.Method; 6 | 7 | import com.hackbulgaria.hackunit.outcomes.Error; 8 | import com.hackbulgaria.hackunit.outcomes.Failure; 9 | import com.hackbulgaria.hackunit.outcomes.Success; 10 | 11 | public class HackUnitCore { 12 | 13 | private Results results = new Results(); 14 | 15 | public Results getResults() { 16 | return results; 17 | } 18 | 19 | public HackUnitCore runClasses(Class... classes) { 20 | 21 | for (Class cls : classes) { 22 | 23 | Constructor constructor; 24 | try { 25 | constructor = cls.getConstructor(); 26 | } catch (NoSuchMethodException e) { 27 | results.add(new Error(cls, e)); 28 | continue; 29 | } 30 | 31 | Method[] methods = cls.getMethods(); 32 | for (Method method : methods) { 33 | if (method.isAnnotationPresent(Test.class)) { 34 | try { 35 | Object obj = constructor.newInstance(); 36 | try { 37 | method.invoke(obj); 38 | results.add(new Success(cls, method)); 39 | } catch (InvocationTargetException e) { 40 | Throwable cause = e.getCause(); 41 | if (cause instanceof AssertionError) { 42 | results.add(new Failure(cls, method, (AssertionError) cause)); 43 | } else if (cause instanceof Exception) { 44 | results.add(new Error(cls, (Exception) cause)); 45 | } else { 46 | throw new IllegalStateException(); 47 | } 48 | } 49 | 50 | } catch (Exception e) { 51 | e.printStackTrace(); 52 | } 53 | } 54 | } 55 | } 56 | 57 | return this; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /week11/HackUnit/src/com/hackbulgaria/hackunit/Results.java: -------------------------------------------------------------------------------- 1 | package com.hackbulgaria.hackunit; 2 | 3 | import com.hackbulgaria.hackunit.outcomes.Failure; 4 | import com.hackbulgaria.hackunit.outcomes.Outcome; 5 | import com.hackbulgaria.hackunit.outcomes.Success; 6 | import com.hackbulgaria.hackunit.outcomes.Error; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | public class Results { 12 | private List successes = new ArrayList<>(); 13 | private List failures = new ArrayList<>(); 14 | private List errors = new ArrayList<>(); 15 | private List outcomes = new ArrayList<>(); 16 | 17 | @Override 18 | public String toString() { 19 | StringBuilder sb = new StringBuilder(); 20 | 21 | sb.append("Results: ["); 22 | 23 | successes.forEach(s -> sb.append("✓")); 24 | failures.forEach(s -> sb.append("X")); 25 | errors.forEach(s -> sb.append("E")); 26 | 27 | sb.append("]\n"); 28 | 29 | if (!failures.isEmpty()) { 30 | sb.append("\nFailures:\n"); 31 | failures.forEach(f -> sb.append(f.toString()).append("\n")); 32 | } 33 | 34 | if (!errors.isEmpty()) { 35 | sb.append("\nErrors:\n"); 36 | errors.forEach(e -> sb.append(e.toString()).append("\n")); 37 | } 38 | 39 | return sb.toString(); 40 | } 41 | 42 | private void addOutcome(Outcome o) { 43 | outcomes.add(o); 44 | } 45 | 46 | public void add(Success s) { 47 | successes.add(s); 48 | addOutcome(s); 49 | } 50 | 51 | public void add(Failure f) { 52 | failures.add(f); 53 | addOutcome(f); 54 | } 55 | 56 | public void add(Error e) { 57 | errors.add(e); 58 | addOutcome(e); 59 | } 60 | 61 | public List getSuccesses() { 62 | return successes; 63 | } 64 | 65 | public List getFailures() { 66 | return failures; 67 | } 68 | 69 | public List getErrors() { 70 | return errors; 71 | } 72 | 73 | public List getOutcomes() { 74 | return outcomes; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /week11/HackUnit/src/com/hackbulgaria/hackunit/Test.java: -------------------------------------------------------------------------------- 1 | package com.hackbulgaria.hackunit; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | //@Retention(RetentionPolicy.RUNTIME) 9 | @Target({ElementType.METHOD}) 10 | public @interface Test { 11 | } 12 | -------------------------------------------------------------------------------- /week11/HackUnit/src/com/hackbulgaria/hackunit/outcomes/Error.java: -------------------------------------------------------------------------------- 1 | package com.hackbulgaria.hackunit.outcomes; 2 | 3 | public class Error extends Outcome { 4 | 5 | private Exception e; 6 | 7 | public Error(Class cls, Exception e) { 8 | super(cls); 9 | this.e = e; 10 | } 11 | 12 | @Override 13 | String getMessage() { 14 | return String.format("Error in %s: %s", getCls().toString(), e.toString()); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /week11/HackUnit/src/com/hackbulgaria/hackunit/outcomes/Failure.java: -------------------------------------------------------------------------------- 1 | package com.hackbulgaria.hackunit.outcomes; 2 | 3 | import java.lang.reflect.Method; 4 | 5 | public class Failure extends Outcome { 6 | 7 | private Method method; 8 | private AssertionError error; 9 | 10 | public Failure(Class cls, Method method, AssertionError error) { 11 | super(cls); 12 | this.method = method; 13 | this.error = error; 14 | } 15 | 16 | @Override 17 | String getMessage() { 18 | String message = error.getMessage() == null ? "" : error.getMessage(); 19 | 20 | return String.format("Failure in %s, method %s: %s", 21 | getCls().toString(), 22 | method.toString(), 23 | message); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /week11/HackUnit/src/com/hackbulgaria/hackunit/outcomes/Outcome.java: -------------------------------------------------------------------------------- 1 | package com.hackbulgaria.hackunit.outcomes; 2 | 3 | public abstract class Outcome { 4 | private Class cls; 5 | 6 | public Class getCls() { 7 | return cls; 8 | } 9 | 10 | public Outcome(Class cls) { 11 | this.cls = cls; 12 | } 13 | 14 | abstract String getMessage(); 15 | 16 | @Override 17 | public String toString() { 18 | return getMessage(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /week11/HackUnit/src/com/hackbulgaria/hackunit/outcomes/Success.java: -------------------------------------------------------------------------------- 1 | package com.hackbulgaria.hackunit.outcomes; 2 | 3 | import java.lang.reflect.Method; 4 | 5 | /** 6 | * Created by plamen on 12.01.17. 7 | */ 8 | public class Success extends Outcome { 9 | 10 | private Method method; 11 | 12 | public Success(Class cls, Method method) { 13 | super(cls); 14 | this.method = method; 15 | } 16 | 17 | @Override 18 | String getMessage() { 19 | return String.format("Success in %s, method %s", getCls().toString(), method.toString()); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /week11/HackUnit/src/com/hackbulgaria/hackunit/tests/MyTests.java: -------------------------------------------------------------------------------- 1 | package com.hackbulgaria.hackunit.tests; 2 | 3 | import com.hackbulgaria.hackunit.Assert; 4 | import com.hackbulgaria.hackunit.Test; 5 | 6 | public class MyTests { 7 | 8 | @Test 9 | public void onePlusOneShouldBeTwo() { 10 | Assert.assertTrue(1 + 1 == 2); 11 | } 12 | 13 | @Test 14 | public void falseIsTrue() { 15 | Assert.assertTrue("Why isn't true false???", true == false); 16 | } 17 | 18 | @Test 19 | public void oops() { 20 | throw new RuntimeException("Oops"); 21 | } 22 | 23 | @Test 24 | public void multiplicationByZeroShouldBeZero() { 25 | Assert.assertTrue("Maths pls", 123 * 0 == 1); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /week11/README.md: -------------------------------------------------------------------------------- 1 | ## Thursday 2 | 3 | ### Functional LinkedList implementation 4 | 5 | Materials: 6 | - [Practical introduction to functional programming](https://maryrosecook.com/blog/post/a-practical-introduction-to-functional-programming) 7 | - [Java 8 Functional API](http://winterbe.com/posts/2014/03/16/java-8-tutorial/) 8 | 9 | ### Java reflection and annotations 10 | 11 | Materials: 12 | - [Reflection](http://tutorials.jenkov.com/java-reflection/index.html) 13 | - [Annotations](http://tutorials.jenkov.com/java/annotations.html) 14 | 15 | We will be implementing our own testing framework similar to JUnit - HackUnit! 16 | Think about how JUnit works internally and try to reproduce its functionality. 17 | -------------------------------------------------------------------------------- /week11/materials/Model.java: -------------------------------------------------------------------------------- 1 | package orm; 2 | 3 | import java.util.List; 4 | import java.util.LinkedList; 5 | 6 | import sql.MySQLHelper; 7 | 8 | import java.lang.reflect.*; 9 | 10 | public abstract class Model { 11 | 12 | MySQLHelper db = new MySQLHelper("//localhost/SchoolSystem", "root", "facepalm"); 13 | 14 | public class ObjectModel { 15 | Class classIns; 16 | ObjectModel(Class classIns) { 17 | this.classIns = classIns; 18 | } 19 | public List all() { 20 | List res = new LinkedList(); 21 | for(List item: db.selectFrom(classIns.getSimpleName()+"s")) { 22 | res.add(listStringToObject(item)); 23 | } 24 | return res; 25 | } 26 | 27 | public void get() { 28 | System.out.println("Here is just a single item"); 29 | } 30 | } 31 | 32 | private void fillInInstance(Object instance, Field field, String value) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { 33 | 34 | Method setter = instance.getClass().getMethod( 35 | "set" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1), 36 | field.getType() 37 | ); 38 | 39 | switch(field.getType().getSimpleName()) { 40 | case "int" : { setter.invoke(instance, Integer.parseInt(value)); break; } 41 | case "String" : { setter.invoke(instance, value); break; } 42 | } 43 | } 44 | 45 | private T listStringToObject(List item) { 46 | try { 47 | Object instance = this.getClass().newInstance(); 48 | 49 | Field[] fields = this.getClass().getDeclaredFields(); 50 | 51 | for(int i=0; i < fields.length; i++) { 52 | fillInInstance(instance, fields[i], item.get(i)); 53 | } 54 | 55 | return (T) instance; 56 | } catch (Exception e) { 57 | // TODO Auto-generated catch block 58 | e.printStackTrace(); 59 | } 60 | return null; 61 | } 62 | 63 | public abstract List update(); 64 | public ObjectModel objects() { 65 | return new ObjectModel(this.getClass()); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /week11/materials/MySQLHelper.java: -------------------------------------------------------------------------------- 1 | package sql; 2 | 3 | import java.sql.*; 4 | import java.lang.reflect.*; 5 | import java.util.List; 6 | import java.util.LinkedList; 7 | 8 | public class MySQLHelper { 9 | private Connection conn; 10 | 11 | public MySQLHelper(String dbURL, String dbUser, String dbPass) { 12 | try { 13 | Class.forName("com.mysql.jdbc.Driver"); 14 | 15 | conn = DriverManager.getConnection("jdbc:mysql:"+dbURL,dbUser,dbPass); 16 | } catch (SQLException e) { 17 | e.printStackTrace(); 18 | } catch (ClassNotFoundException e) { 19 | e.printStackTrace(); 20 | } 21 | } 22 | 23 | public List> executeSQL(String sql) { 24 | try { 25 | List> result = new LinkedList<>(); 26 | 27 | Statement stmt; 28 | stmt = conn.createStatement(); 29 | ResultSet rs = stmt.executeQuery(sql); 30 | 31 | while(rs.next()){ 32 | ResultSetMetaData md = rs.getMetaData(); 33 | int columns = md.getColumnCount(); 34 | List row = new LinkedList(); 35 | 36 | for (int i = 1; i <= columns; i++) { 37 | String colName = md.getColumnName(i); 38 | row.add(rs.getString(colName)); 39 | } 40 | result.add(row); 41 | } 42 | return result; 43 | 44 | } catch (SQLException e) { 45 | e.printStackTrace(); 46 | return null; 47 | } 48 | } 49 | 50 | private String makeFirstLetterCapital(String s) { 51 | return s.substring(0,1).toUpperCase() + s.substring(1); 52 | } 53 | 54 | public boolean insertInto(String table, Object item) { 55 | 56 | Field[] fields = item.getClass().getDeclaredFields(); 57 | 58 | try { 59 | LinkedList fieldsList = new LinkedList<>(); 60 | LinkedList fieldsNamesList = new LinkedList<>(); 61 | for(Field f: fields) { 62 | if(f.getName().equals("id")) continue; 63 | fieldsNamesList.add(f.getName()); 64 | fieldsList.add(item.getClass().getMethod("get"+makeFirstLetterCapital(f.getName())).invoke(item).toString()); 65 | } 66 | 67 | String[] zz = new String[fieldsList.size()]; 68 | fieldsList.toArray(zz); 69 | 70 | String fieldsSQL = String.join(" , ", zz); 71 | 72 | String[] s2 = new String[fieldsNamesList.size()]; 73 | fieldsNamesList.toArray(s2); 74 | 75 | String fieldsNamesSQL = String.join(" , ", s2); 76 | String sql = "INSERT INTO "+table+"("+fieldsNamesSQL+") VALUES ("+fieldsSQL+");"; 77 | 78 | // System.out.println(sql); 79 | 80 | this.executeSQL(sql); 81 | 82 | } catch (Exception e) { 83 | e.printStackTrace(); 84 | } 85 | return false; 86 | } 87 | 88 | public boolean deleteFrom(String table, int id) { 89 | return false; 90 | } 91 | 92 | public boolean update(String table, Object ob) { 93 | return false; 94 | } 95 | 96 | public List> selectFrom(String table) { 97 | return selectFrom(table, "1"); 98 | } 99 | 100 | public List> selectFrom(String table, String where) { 101 | return executeSQL("SELECT * FROM " + table + " WHERE " + where); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /week11/materials/ObjectModel.java: -------------------------------------------------------------------------------- 1 | package week11; 2 | 3 | import java.util.List; 4 | import java.util.LinkedList; 5 | import java.lang.reflect.*; 6 | 7 | import sql.MySQLHelper; 8 | 9 | public class ObjectsModel { 10 | MySQLHelper db = new MySQLHelper("//localhost/SchoolSystem", "", ""); 11 | Class callerClass; 12 | 13 | public ObjectsModel(Class callerClass) { 14 | this.callerClass = callerClass; 15 | } 16 | 17 | private String makeFirstLetterCapital(String s) { 18 | return s.substring(0,1).toUpperCase() + s.substring(1); 19 | } 20 | 21 | private T convertToObject(List row) { 22 | try { 23 | Field[] fields = callerClass.getDeclaredFields(); 24 | Object instance = callerClass.newInstance(); 25 | 26 | for(int i=0;i all() { 43 | List res = new LinkedList(); 44 | 45 | for(List row: db.selectFrom(callerClass.getSimpleName() + "s")) { 46 | res.add(convertToObject(row)); 47 | } 48 | return res; 49 | } 50 | 51 | public T getById(int id) { 52 | String tableName = callerClass.getSimpleName() + "s"; 53 | return convertToObject(db.selectFrom(tableName, "id = " + id).get(0)); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /week12/Drone-Delivery-System/README.md: -------------------------------------------------------------------------------- 1 | # Drone Delivery System 2 | 3 | Last year the geeks at Amazon turn up with the cool idea to use drones to deliver goods right in front of your front door. Nice idea! However it may be not so simple to implement. 4 | 5 | We are going to design and implement a system controlling and scheduling deliveries with drones. 6 | 7 | ## Our city 8 | 9 | For the sake of simplicity our city will be a 1000x1000 square matrix. Our drones will fly around it and deliver the goods. 10 | 11 | ## Drones 12 | 13 | * Each drone has a: 14 | * unique id - we should have a way to distinguish them 15 | * battery - unfortunately they cannot run forever but will usually last a flight to the end of the city and back, then they must recharge. We will measure them with BU (battery units). 16 | * capacity - they cannot take infinitely many products as well. We will measure their capacity with WU (weight units) 17 | * charging rate - measured in BU per minutes 18 | 19 | ## Products 20 | 21 | * Each product has a: 22 | * unique id 23 | * name (e.g. keyboard) 24 | * weight (e.g. 0.5 kg for 1 keyboard) 25 | 26 | ## Warehouse 27 | 28 | At the warehouse we will store the goods that should be delivered. 29 | 30 | * Each warehouse has a: 31 | * coordinates - the place in our city 32 | * information about the available products - we should keep track of the quantities we have of a given product. 33 | 34 | ## Requests 35 | 36 | Lets suppose that we will receive the requests from console as a simple text. 37 | 38 | We will support the following requests: 39 | 40 | ### Delivery request 41 | 42 | It will look like this: 43 | 44 | delivery <id> <timestamp> <target coordinates> <product id 1> <quantity> <product id 2> <quantity> ... 45 | 46 | e.g. "delivery 4 2016-10-25 12:31 420,369 23 5 54 20" 47 | 48 | ## How deliveries are made 49 | 50 | * When we receive a delivery request we will try to execute it. If we can execute the delivery request we should log a message. If we cannot process the current request now we should log a message with the reason why we cannot process the task. 51 | 52 | 53 | ### Executing 54 | 55 | If we have the needed amount of each product for a given delivery task we should be able to process it. If the WU (weight capacity) of one drone is not enough for processing the delivery we should use as much drones as we need. 56 | 57 | If we do not have the needed amount of at least one product we should log an error message. 58 | 59 | ## Drone Delivery System v1 60 | 61 | For our first version of the delivery system: 62 | 63 | * Our 50 drones will have: 64 | * 2 000 BU 65 | * 5 BU/min charging rate 66 | * 500 WU capacity 67 | 68 | * The warehouse is at coordinates [42, 42] 69 | 70 | ## Drone Delivery System v2 71 | 72 | Thanks to the great first version of the Delivery System, our delivery business has expnaded ! Now more companies are using our drones for their delivery requests. 73 | 74 | ### More Drones 75 | 76 | In order to keep up with the new loads we have bought 30 more drones: 77 | 78 | * Our new Chinese drones have: 79 | * 1 200 BU 80 | * 3 BU/min charging rate 81 | * 200 WU capacity 82 | 83 | ### More Warehouses 84 | 85 | We have a second warehouse located at 420, 420 86 | 87 | ### Supply request 88 | 89 | We should also support supply requests 90 | 91 | It will look like this: 92 | 93 | supply <id> <warehouse id> <timestamp YYYY-MM-DD HH:MM> <product id 1> <quantity> <product id 2> <quantity> 94 | 95 | e.g. "supply 5 2016-10-25 12:32 5 100 6 50 2 4" 96 | 97 | Bonus points if we execute a delivery previously impossible after a supply. 98 | 99 | 100 | ### ETA (estimated time of arrival) 101 | 102 | In the second version of our delivery system we should be able to calculate the ETA of a given delivery 103 | 104 | 105 | ### Estimating ETA 106 | 107 | Each drone needs a minute for each DU (distance unit) travelled and will use 1 BU (battery unit) for each DU. 108 | 109 | The DUs are calculated as follows: The distance from cell [x1, y1] to cell [x2, y2] is calculated as ((x1 - x2)^2 + (y1 - y2)^2)^1/2 (two-dimensional Euclidean distance). 110 | 111 | Moreover the drone needs a minute for each different product to load and a minute for each different product to unload at the target location. No BUs are used during loading/unloading. 112 | 113 | The batteries of the drones can be charged only at the warehouse. 114 | Take this in consideration when calculating the ETA. 115 | 116 | The ETA is the time that the last drone has unloaded the goods at the location. 117 | -------------------------------------------------------------------------------- /week12/materials/README.md: -------------------------------------------------------------------------------- 1 | # KISS principle 2 | 3 | https://en.wikipedia.org/wiki/KISS_principle 4 | 5 | # DRY prinicple 6 | 7 | https://en.wikipedia.org/wiki/Don't_repeat_yourself 8 | 9 | # SOLID OOP principles 10 | 11 | https://en.wikipedia.org/wiki/SOLID_(object-oriented_design) 12 | 13 | ## Agile methodology 14 | 15 | https://en.wikipedia.org/wiki/Agile_software_development 16 | 17 | # Scrum 18 | 19 | https://en.wikipedia.org/wiki/Scrum_(software_development) -------------------------------------------------------------------------------- /week14/Thursday/IschlemeSoft/src/com/hackbulgaria/Developer.java: -------------------------------------------------------------------------------- 1 | package com.hackbulgaria; 2 | 3 | import java.util.List; 4 | import java.util.concurrent.ThreadLocalRandom; 5 | 6 | public class Developer implements Runnable { 7 | private String name; 8 | private Skill skill; 9 | private List tasks; 10 | 11 | @Override 12 | public void run() { 13 | Thread.currentThread().setName("Developer " + name); 14 | try { 15 | for (Task t : tasks) { 16 | double distraction = ThreadLocalRandom.current().nextDouble(1, 2); 17 | double timeTaken = t.getWorkingTimeMillis() 18 | * skill.multiplier() * distraction; 19 | Thread.sleep((long) Math.floor(timeTaken)); 20 | Util.threadMessage(t.getDescription()); 21 | } 22 | } catch (InterruptedException e) { 23 | Util.threadMessage("Hey! I wasn't done!"); 24 | } 25 | } 26 | 27 | public void assign(List tasks) { 28 | this.tasks = tasks; 29 | } 30 | 31 | public Developer(String name, Skill skill) { 32 | this.name = name; 33 | this.skill = skill; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /week14/Thursday/IschlemeSoft/src/com/hackbulgaria/ProjectManager.java: -------------------------------------------------------------------------------- 1 | package com.hackbulgaria; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class ProjectManager { 7 | public static void main(String[] args) throws InterruptedException { 8 | Thread.currentThread().setName("Project Manager"); 9 | double patience = 1.2; 10 | 11 | if (args.length > 0) { 12 | try { 13 | patience = Double.parseDouble(args[0]); 14 | } catch (NumberFormatException e) { 15 | System.err.println("Patience must a double"); 16 | } 17 | } 18 | 19 | Developer pesho = new Developer("Pesho", Skill.JUNIOR); 20 | 21 | List tasks = new ArrayList<>(); 22 | tasks.add(new Task("Write some ugly CSS", 5)); 23 | tasks.add(new Task("Parse XML", 2)); 24 | tasks.add(new Task("Drink coffee", 3)); 25 | 26 | long expectedTime = (long)(patience * tasks.stream() 27 | .mapToLong(Task::getWorkingTimeMillis).sum()); 28 | 29 | pesho.assign(tasks); 30 | 31 | long startTime = System.currentTimeMillis(); 32 | Thread peshoAtWork = new Thread(pesho); 33 | peshoAtWork.start(); 34 | 35 | while (peshoAtWork.isAlive()) { 36 | Util.threadMessage("Waiting..."); 37 | peshoAtWork.join(1000); 38 | long elapsedTime = System.currentTimeMillis(); 39 | if (((elapsedTime - startTime) > expectedTime) && peshoAtWork.isAlive()) { 40 | peshoAtWork.interrupt(); 41 | Util.threadMessage(peshoAtWork.getName() + " is useless!. He will be fired."); 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /week14/Thursday/IschlemeSoft/src/com/hackbulgaria/Skill.java: -------------------------------------------------------------------------------- 1 | package com.hackbulgaria; 2 | 3 | public enum Skill { 4 | CODE_MONKEY(7.5), 5 | NOVICE(3.5), 6 | JUNIOR(1), 7 | SENIOR(0.25); 8 | 9 | private double multiplier; 10 | 11 | Skill(double multiplier) { 12 | this.multiplier = multiplier; 13 | } 14 | 15 | public double multiplier() { 16 | return multiplier; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /week14/Thursday/IschlemeSoft/src/com/hackbulgaria/Task.java: -------------------------------------------------------------------------------- 1 | package com.hackbulgaria; 2 | 3 | public class Task { 4 | private String description; 5 | private long workingTime; 6 | 7 | public Task(String description, long workingTime) { 8 | this.description = description; 9 | this.workingTime = workingTime; 10 | } 11 | 12 | public String getDescription() { 13 | return description; 14 | } 15 | 16 | public long getWorkingTime() { 17 | return workingTime; 18 | } 19 | 20 | public long getWorkingTimeMillis() { 21 | return workingTime * 1000; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /week14/Thursday/IschlemeSoft/src/com/hackbulgaria/Util.java: -------------------------------------------------------------------------------- 1 | package com.hackbulgaria; 2 | 3 | public class Util { 4 | public static void threadMessage(String msg) { 5 | System.out.format("%s: %s%n", Thread.currentThread().getName(), msg); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /week14/Thursday/README.md: -------------------------------------------------------------------------------- 1 | # First steps in concurrency 2 | 3 | ## The Runnable 4 | 5 | Everybody loves abstraction! Thats why we have the Runnable interface. It has only one method - void run(). 6 | It represents basically a task (a unit of work) that someone should do. 7 | 8 | Lets define(implement) our task. 9 | We would like to make prime factorization of a number. 10 | 11 | ## The Thread 12 | 13 | Now that we have work to do it is time to give it to someone that has to execute it. 14 | In оur case this will be a Thread. 15 | We can pass our Runnable implementation to the Thread constructor. 16 | Now the Thread know about the work it should do. 17 | What remains is to start the Thread. 18 | 19 | Well just .start() it! 20 | 21 | 22 | ## Use thread pools 23 | 24 | Creating several threads can be a bit tedious and if we make new treads for every new task it can be expensive. 25 | We can reuse threads - when they are ready with their task we can reuse them 26 | 27 | Luckily Java provides us with the ExecutorService classes. 28 | It manages the threads for us. 29 | One such ExecutorService can be created with Executors.newCachedThreadPool() 30 | 31 | It will create and maintain the needed number of threads for the tasks we send to it. 32 | For example if we give the pool 2 tasks that have to be executed concurrently it will create and manage the threads for us. 33 | 34 | Lets try to run our tasks via cachedThreadPool. 35 | Lets try to execute 3 tasks using Executors.newFixedThreadPool(2) 36 | 37 | ## Create Callable 38 | 39 | What if we want to return some kind of a result from our task? 40 | We can implement the Callable<> Interface. 41 | 42 | Just like the Runnable interface it has only one method. 43 | In this case this is the call() 44 | 45 | Later we can submit our Callable objects to the ExecutorService that will manage the threads that will execute the task. 46 | 47 | ## Future for results 48 | 49 | After we submit our task for execution we will receive an Future which we can use to check if the task is done using isDone(). 50 | Or to block and wait for the result using .get() method. 51 | 52 | 53 | 54 | ## Parallel closest point calculations 55 | 56 | Create a static method generatePoints() which returns a List - create your Point impl (with maybe different implementations (dimensions)) 57 | Implement it, generating a 100 000 points (in java that is written 100_000) points with random coordinates - ranging from 0 to 10_000. 58 | 59 | Now, for each of those points, I'd like you to find it's nearest point. Do this in a method calculateClosestPoint(List generatedPoints) 60 | For now it should only print the closest point for each of the points. 61 | 62 | It takes a while. By calculations, it should take like lots of seconds to complete (depending on your CPU speed). 63 | 64 | Now lets introduce some multithreading to speed it up. 65 | Declare and implement a method doCalculations(List inPoints, int indexFrom, int indexTo) Move calculations logic from calculateClosestPoint to doCalculations, but work strictly from indexFrom, to indexTo. 66 | 67 | Now in calculateClosestPoint(List generatedPoints) method, start two Threads that call doCalculations, in their run methods, one from 0 to half of the elements, the other from half of the elements to the last of them. 68 | 69 | Measure speedup between the two implementations (See System.currentTimeMillis()). 70 | 71 | Introduce a third and forth thread. Does your implementation go faster? 72 | 73 | Think how to generalize the number of threads and how to implement it. 74 | 75 | Lets change our implementation and use a pool to handle the treads instead of us. 76 | 77 | Lets change again our implementation. 78 | Lets make our thread to return the closest point instead of printing. 79 | Finally we should gather the closest point of each point in a Map 80 | 81 | ## Getting some practice - The Impatient Project Manager 82 | In the software company `ИшлемеSoft` there is a very grumpy and impatient `Project Manager` that assigns a lot of tasks to his `Developers` and expects them to be done in time. Sometimes, they aren't skilled enough, they get distracted or piss off the Project Manager and fail their tasks. Let's present this scenario using `Threads`. 83 | 84 | 85 | - Write a class Task 86 | 87 | It represents a task for a `Developer` and has a description and a working time (in seconds for the sake of example). 88 | The expected completion time for a task is the working time, adjusted by the skill of the `Developer`. 89 | 90 | 91 | - Write an enum Skill 92 | 93 | It should represent the skill of a developer using a time multiplier that adjusts the time a developer takes to complete a certain task. 94 | 95 | 96 | - Write a class Developer that implements Runnable 97 | 98 | It should have a name, `Skill` and a list of `Tasks`. A `Developer` completes his tasks sequentially in the `run` method, but he might get distracted and take longer to complete a task. Generate a random distraction multiplier in the range [1; 2) to adjust the time taken. Do not forget the skill multiplier as well. 99 | 100 | 101 | - Write a class ProjectManager that instantiates a Developer 102 | 103 | A `Project Manager` comes up with the tasks for the `Developers` and assigns them. He has a patience threshold, provided as a command-line argument in the range [1, 2). If a `Developer` takes more than the expected time for a task, the `Project Manager` must fire him. (use interrupts for this). Think of a good way to implement an algorithm to check for task completion without wasting computing resources. 104 | -------------------------------------------------------------------------------- /week14/prereadings/README.md: -------------------------------------------------------------------------------- 1 | # Multithreading 2 | 3 | ## Oracle's concurency trail 4 | 5 | Have a look at this: 6 | http://docs.oracle.com/javase/tutorial/essential/concurrency/index.html 7 | 8 | Try to answer these questions: 9 | * What is the difference between process and thread? 10 | * What is Runnable? Whats is Thread? 11 | * What are the most important methods in Thread ? 12 | * What is starvation, livelock and deadlock ? 13 | * What is thread interference and memory consistency errors ? 14 | 15 | ## Example in Tutorialspoint 16 | 17 | http://www.tutorialspoint.com/java/java_multithreading.htm 18 | -------------------------------------------------------------------------------- /week15/Thursday/DiningPhilosophers/src/com/hackbulgaria/philosophers/Fork.java: -------------------------------------------------------------------------------- 1 | package com.hackbulgaria.philosophers; 2 | 3 | import java.util.concurrent.locks.Lock; 4 | import java.util.concurrent.locks.ReentrantLock; 5 | 6 | public class Fork { 7 | private final int id; 8 | private Lock lock = new ReentrantLock(); 9 | 10 | public Fork(int id) { 11 | this.id = id; 12 | } 13 | 14 | public void pickUp(Philosopher p) { 15 | lock.lock(); 16 | System.out.println(p + " picked up " + this); 17 | } 18 | 19 | public void putDown(Philosopher p) { 20 | lock.unlock(); 21 | System.out.println(p + " put down " + this); 22 | } 23 | 24 | @Override 25 | public String toString() { 26 | return "Fork " + id; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /week15/Thursday/DiningPhilosophers/src/com/hackbulgaria/philosophers/Main.java: -------------------------------------------------------------------------------- 1 | package com.hackbulgaria.philosophers; 2 | 3 | import java.util.concurrent.ExecutorService; 4 | import java.util.concurrent.Executors; 5 | 6 | public class Main { 7 | public static void main(String[] args) { 8 | final int PHILOSOPHERS_COUNT = 5; 9 | 10 | ExecutorService service = Executors.newFixedThreadPool(PHILOSOPHERS_COUNT); 11 | 12 | Fork[] forks = new Fork[PHILOSOPHERS_COUNT]; 13 | 14 | for (int i = 0; i < PHILOSOPHERS_COUNT; i++) { 15 | forks[i] = new Fork(i); 16 | } 17 | 18 | for (int i = 0; i < PHILOSOPHERS_COUNT; i++) { 19 | Philosopher p = new Philosopher(i, forks[i], forks[(i + 1) % PHILOSOPHERS_COUNT]); 20 | service.execute(p); 21 | } 22 | 23 | service.shutdown(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /week15/Thursday/DiningPhilosophers/src/com/hackbulgaria/philosophers/Philosopher.java: -------------------------------------------------------------------------------- 1 | package com.hackbulgaria.philosophers; 2 | 3 | import java.util.Random; 4 | import java.util.concurrent.ThreadLocalRandom; 5 | 6 | public class Philosopher implements Runnable { 7 | private final int id; 8 | private Random random = ThreadLocalRandom.current(); 9 | private Fork leftFork; 10 | private Fork rightFork; 11 | 12 | public Philosopher(int id, Fork a, Fork b) { 13 | this.id = id; 14 | this.leftFork = a; 15 | this.rightFork = b; 16 | } 17 | 18 | @Override 19 | public void run() { 20 | try { 21 | while (true) { 22 | think(); 23 | leftFork.pickUp(this); 24 | rightFork.pickUp(this); 25 | eat(); 26 | leftFork.putDown(this); 27 | rightFork.putDown(this); 28 | } 29 | } catch (InterruptedException e) { 30 | System.out.println("WTF"); 31 | } 32 | } 33 | 34 | private void think() throws InterruptedException { 35 | System.out.println(this + " is thinking"); 36 | Thread.sleep(random.nextInt(2000)); 37 | } 38 | 39 | private void eat() throws InterruptedException { 40 | System.out.println(this + " is eating"); 41 | Thread.sleep(random.nextInt(2000)); 42 | } 43 | 44 | @Override 45 | public String toString() { 46 | return "Philosher " + id; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /week15/Thursday/ThreadSignalling/src/com/hackbulgaria/signalling/Main.java: -------------------------------------------------------------------------------- 1 | package com.hackbulgaria.signalling; 2 | 3 | import java.util.concurrent.ExecutorService; 4 | import java.util.concurrent.Executors; 5 | 6 | public class Main { 7 | public static void main(String[] args) throws InterruptedException { 8 | Signal s = new Signal(); 9 | 10 | ExecutorService service = Executors.newCachedThreadPool(); 11 | service.submit(new Notifier(s)); 12 | service.submit(new Waiter(s)); 13 | 14 | service.shutdown(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /week15/Thursday/ThreadSignalling/src/com/hackbulgaria/signalling/Notifier.java: -------------------------------------------------------------------------------- 1 | package com.hackbulgaria.signalling; 2 | 3 | import java.util.concurrent.ThreadLocalRandom; 4 | 5 | public class Notifier implements Runnable { 6 | private Signal s; 7 | 8 | public Notifier(Signal s) { 9 | this.s = s; 10 | } 11 | 12 | @Override 13 | public void run() { 14 | Thread.currentThread().setName("Notifier"); 15 | try { 16 | Thread.sleep(ThreadLocalRandom.current().nextInt(3000, 5001)); 17 | } catch (InterruptedException e) { 18 | e.printStackTrace(); 19 | } 20 | Util.threadMsg("Sending notify signal..."); 21 | s.doNotify(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /week15/Thursday/ThreadSignalling/src/com/hackbulgaria/signalling/Signal.java: -------------------------------------------------------------------------------- 1 | package com.hackbulgaria.signalling; 2 | 3 | import java.util.concurrent.locks.ReentrantLock; 4 | 5 | public class Signal { 6 | private Object obj = new Object(); 7 | private boolean wasSignalled = false; 8 | 9 | public void doWait() { 10 | synchronized (obj) { 11 | try { 12 | while (!wasSignalled) { 13 | obj.wait(); 14 | } 15 | wasSignalled = false; 16 | } catch (InterruptedException e) { 17 | e.printStackTrace(); 18 | } 19 | } 20 | } 21 | 22 | public void doNotify() { 23 | synchronized (obj) { 24 | while (!wasSignalled) { 25 | wasSignalled = true; 26 | obj.notify(); 27 | } 28 | } 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /week15/Thursday/ThreadSignalling/src/com/hackbulgaria/signalling/Util.java: -------------------------------------------------------------------------------- 1 | package com.hackbulgaria.signalling; 2 | 3 | public class Util { 4 | public static void threadMsg(String msg) { 5 | System.out.format("%s: %s%n", Thread.currentThread().getName(), msg); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /week15/Thursday/ThreadSignalling/src/com/hackbulgaria/signalling/Waiter.java: -------------------------------------------------------------------------------- 1 | package com.hackbulgaria.signalling; 2 | 3 | public class Waiter implements Runnable { 4 | private Signal s; 5 | 6 | public Waiter(Signal s) { 7 | this.s = s; 8 | } 9 | 10 | @Override 11 | public void run() { 12 | Thread.currentThread().setName("Waiter"); 13 | Util.threadMsg("Waiting to be notified..."); 14 | s.doWait(); 15 | Util.threadMsg("Woo! I was notified!"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /week15/Tuesday/README.md: -------------------------------------------------------------------------------- 1 | ## Concurrent architecture showcase - Google Chrome 2 | 3 | Modern websites contain a lot of dynamic content and use JavaScript extensively to provide a rich browsing experience. Sadly, modern websites also tend to consume a lot of CPU and contain a lot of bugs. This wouldn't be a problem if browsers rendered one page at a time, but every contemporary browser provides so called tabs to open several websites at once. The problem with this is that if a single tab crashed, the entire browser crashes as well. 4 | 5 | Google Chrome addresses this problem by using a multiprocess architecture, using three types of processes: 6 | 7 | - Browser process 8 | 9 | The browser process is responsible for managing the user interface as 10 | well as disk and network I/O. A new browser process is created when 11 | Chrome is started. Only one browser process is created. 12 | 13 | - Renderer process 14 | 15 | Renderer processes contain logic for rendering web pages - HTML, Javascript, images, and so on. As 16 | a general rule, a new renderer process is created for each website opened 17 | in a new tab, and so several renderer processes may be active at the same 18 | time. 19 | 20 | - Plugin process 21 | 22 | A plugin process is created for each plugin in use. 23 | 24 | The advantage of the multiprocess approach is that websites run in 25 | isolation from one another. If one website crashes, only its renderer process 26 | is affected, all other processes remain unharmed. Furthermore, renderer 27 | processes run in a sandbox, which means that access to disk and network 28 | I/O is restricted, minimizing the effects of any security exploits. 29 | 30 | ## Sudoku solution validator 31 | 32 | A Sudoku puzzle comprises of a 9x9 grid in which each row and column, as well as each of the nine 3x3 subgrids, must contain the digits in the range [1; 9]. Design a multithreaded application that determines whether a certain solution to a Sudoku puzzle is valid. 33 | 34 | Points to think about: 35 | - What types of threads will be needed? 36 | - Which logic shouldn't be separated into a thread? 37 | - How will you collect results? 38 | 39 | Your solution must provide a class which accepts a sudoku board as a two-dimensional 9x9 array and returns a boolean value that represents whether the array is a valid solution. 40 | 41 | Hint: you could write a Runnable that checks a row/column/3x3 box and execute one for each row/column/3x3 box 42 | 43 | ## The dining philosophers 44 | 45 | Five silent philosophers sit at a round table with bowls of spaghetti. Forks are placed between each pair of adjacent philosophers. 46 | 47 | Each philosopher must alternately think and eat. However, a philosopher can only eat spaghetti when they have both left and right forks. Each fork can be held by only one philosopher and so a philosopher can use the fork only if it is not being used by another philosopher. After an individual philosopher finishes eating, they need to put down both forks so that the forks become available to others. A philosopher can take the fork on their right or the one on their left as they 48 | become available, but cannot start eating before getting both forks. 49 | 50 | Eating is not limited by the remaining amounts of spaghetti or stomach space; an infinite supply and an infinite demand are assumed. 51 | 52 | You must design a concurrent program such that no no philosopher will starve - each can forever continue to alternate between eating and thinking, assuming that no philosopher can know when others may want to eat or think. 53 | 54 | Source: Wikipedia 55 | 56 | -------------------------------------------------------------------------------- /week15/prereadings/README.md: -------------------------------------------------------------------------------- 1 | # Concurrency issues: 2 | 3 | Here you can see some of the most common problems briefly described: 4 | 5 | http://jeremymanson.blogspot.bg/2007/08/atomicity-visibility-and-ordering.html 6 | 7 | Synchronized keyword: 8 | 9 | http://tutorials.jenkov.com/java-concurrency/synchronized.html 10 | 11 | Volatile keyword: 12 | 13 | http://tutorials.jenkov.com/java-concurrency/volatile.html -------------------------------------------------------------------------------- /week16/materials/AboutUs.java: -------------------------------------------------------------------------------- 1 | package com.hackbulgaria; 2 | 3 | import java.io.IOException; 4 | 5 | import javax.servlet.RequestDispatcher; 6 | import javax.servlet.ServletException; 7 | import javax.servlet.annotation.WebServlet; 8 | import javax.servlet.http.HttpServlet; 9 | import javax.servlet.http.HttpServletRequest; 10 | import javax.servlet.http.HttpServletResponse; 11 | 12 | @WebServlet("/AboutUs") 13 | public class AboutUs extends HttpServlet { 14 | private static final long serialVersionUID = 1L; 15 | 16 | protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 17 | 18 | request.getSession().setAttribute("servletName", "aboutUs"); 19 | request.getSession().setAttribute("title", "About Us"); 20 | 21 | RequestDispatcher view = 22 | request.getRequestDispatcher("aboutus.jsp"); 23 | view.forward(request, response); 24 | } 25 | 26 | protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /week16/materials/Index.java: -------------------------------------------------------------------------------- 1 | package com.hackbulgaria; 2 | 3 | import java.io.IOException; 4 | import java.util.LinkedList; 5 | 6 | import javax.servlet.RequestDispatcher; 7 | import javax.servlet.ServletException; 8 | import javax.servlet.annotation.WebServlet; 9 | import javax.servlet.http.HttpServlet; 10 | import javax.servlet.http.HttpServletRequest; 11 | import javax.servlet.http.HttpServletResponse; 12 | 13 | @WebServlet("/Index") 14 | public class Index extends HttpServlet { 15 | private static final long serialVersionUID = 1L; 16 | 17 | protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 18 | LinkedList l = new LinkedList<>(); 19 | 20 | l.add("Kamen"); 21 | l.add("Mamen"); 22 | 23 | request.getSession().setAttribute("servletName", "index"); 24 | request.getSession().setAttribute("message", "hello"); 25 | request.getSession().setAttribute("title", "Home Page"); 26 | request.getSession().setAttribute("users", l); 27 | 28 | RequestDispatcher view = 29 | request 30 | .getRequestDispatcher("index.jsp"); 31 | 32 | view.forward(request,response); 33 | } 34 | 35 | protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /week16/materials/aboutus.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="header.jsp" %> 2 |

About us

3 | <%@ include file="footer.jsp" %> -------------------------------------------------------------------------------- /week16/materials/footer.jsp: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /week16/materials/header.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" contentType="text/html; charset=UTF-8" 2 | pageEncoding="UTF-8"%> 3 | 4 | 5 | 6 | 7 | ${title} 8 | 9 | 54 | 55 | 79 | 80 | 81 | 82 | <% String servlet = (String)session.getAttribute("servletName"); %> 83 | selected<% } %>">Home 84 | selected<% } %>">About us 85 | Home 86 | About us 87 | Home 88 | About us 89 | 90 |
91 |
92 |
93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /week16/materials/index.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="header.jsp" %> 2 | 3 | <%@ page import="java.util.List"%> 4 | <% List eList = (List)session.getAttribute("users");%> 5 | 6 | 7 |

Hello Hack!

8 | ${message} 9 |

Users:

10 | 11 |
    12 | <% for(int i=0; i< eList.size(); i++) { %> 13 |
  • <%=eList.get(i)%>
  • 14 | <% } %> 15 |
16 | <%@ include file="footer.jsp" %> 17 | --------------------------------------------------------------------------------