├── .gitignore ├── .idea ├── vcs.xml ├── .gitignore ├── encodings.xml ├── aws.xml ├── sonarlint │ └── issuestore │ │ └── index.pb ├── misc.xml ├── compiler.xml ├── jarRepositories.xml ├── uiDesigner.xml └── inspectionProfiles │ └── Project_Default.xml ├── src ├── main │ ├── resources │ │ └── logback.xml │ └── java │ │ └── org │ │ └── algorithms │ │ ├── fibonacci │ │ └── Fibonacci.java │ │ ├── findnumberspairs │ │ └── NumbersPairsFinder.java │ │ ├── palindrome │ │ └── Palindrome.java │ │ ├── binarysearch │ │ └── BinarySearch.java │ │ ├── recursion │ │ └── Factorial.java │ │ ├── lrucache │ │ └── LruCache.java │ │ ├── graph │ │ ├── BreadthFirstSearch.java │ │ └── DijkstraAlgorithm.java │ │ ├── sorting │ │ ├── QuickSorting.java │ │ └── SelectionSorting.java │ │ └── greedy │ │ └── GreedyAlgorithm.java └── test │ ├── resources │ └── logback.xml │ └── java │ └── org │ └── algorithms │ ├── recursion │ └── FactorialTest.java │ ├── lrucache │ └── LruCacheTest.java │ ├── binarysearch │ └── BinarySearchTest.java │ ├── sorting │ ├── QuickSortingTest.java │ └── SelectionSortingTest.java │ ├── fibonacci │ └── FibonacciTest.java │ ├── findnumberspairs │ └── NumbersPairsFingerTest.java │ ├── palindrome │ └── PalindromeTest.java │ ├── greedy │ └── GreedyAlgorithmTest.java │ └── graph │ ├── DijkstraAlgorithmTest.java │ └── BreadthFirstSearchTest.java └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | # Project exclude paths 2 | /target/ -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /.idea/aws.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 16 | 17 | -------------------------------------------------------------------------------- /.idea/sonarlint/issuestore/index.pb: -------------------------------------------------------------------------------- 1 | 2 | 7 3 | pom.xml,4/4/442292b8a7efeabbe4cc176709b833b1792140ec 4 | g 5 | 7src/main/java/org/algorithms/palindrome/Palindrome.java,2/9/291b8f1fdfd932dcb1ab8d96e4566d888ee472cb 6 | i 7 | 9src/test/java/org/algorithms/fibonacci/FibonacciTest.java,a/2/a29519c4fe41ead3ef27e01d2fe12a0a74cb1722 8 | k 9 | ;src/test/java/org/algorithms/palindrome/PalindromeTest.java,f/3/f399667099a6a204ae4c5890a7199569778bc86d 10 | y 11 | Isrc/test/java/org/algorithms/findnumberspairs/NumbersPairsFingerTest.java,a/c/acea8886637419a575b54f056de4572cc9231cf8 -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | [%d{yyyy-MM-dd'T'HH:mm:ss.sss'Z'}] [%C] [%t] [%L] [%-5p] %m%n 6 | 7 | 8 | 9 | 10 | 11 | [%d{yyyy-MM-dd'T'HH:mm:ss.sss'Z'}] [%C] [%t] [%L] [%-5p] %m%n 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/test/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | [%d{yyyy-MM-dd'T'HH:mm:ss.sss'Z'}] [%C] [%t] [%L] [%-5p] %m%n 6 | 7 | 8 | 9 | 10 | 11 | [%d{yyyy-MM-dd'T'HH:mm:ss.sss'Z'}] [%C] [%t] [%L] [%-5p] %m%n 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/test/java/org/algorithms/recursion/FactorialTest.java: -------------------------------------------------------------------------------- 1 | package org.algorithms.recursion; 2 | 3 | import org.junit.jupiter.params.ParameterizedTest; 4 | import org.junit.jupiter.params.provider.CsvSource; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertEquals; 7 | 8 | class FactorialTest { 9 | 10 | @ParameterizedTest 11 | @CsvSource({"0, 1", 12 | "1, 1", 13 | "2, 2", 14 | "3, 6", 15 | "10, 3628800" 16 | }) 17 | void factorialTest(int number, int expected) { 18 | Factorial factorial = new Factorial(); 19 | assertEquals(expected, factorial.getFactorialRecursionApproach(number)); 20 | assertEquals(expected, factorial.getFactorialStreamsApproach(number)); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | -------------------------------------------------------------------------------- /src/test/java/org/algorithms/lrucache/LruCacheTest.java: -------------------------------------------------------------------------------- 1 | package org.algorithms.lrucache; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.junit.jupiter.api.Assertions.assertEquals; 6 | import static org.junit.jupiter.api.Assertions.assertNull; 7 | 8 | class LruCacheTest { 9 | 10 | @Test 11 | void lruCacheTest() { 12 | LruCache lRUCache = new LruCache<>(2); 13 | lRUCache.put(1, 1); // cache is {1=1} 14 | lRUCache.put(2, 2); // cache is {1=1, 2=2} 15 | assertEquals(1, lRUCache.get(1)); // return 1 16 | lRUCache.put(3, 3); // LRU key was 2, evicts key 2, cache is {1=1, 3=3} 17 | assertNull(lRUCache.get(2)); // returns null (not found) 18 | lRUCache.put(4, 4); // LRU key was 1, evicts key 1, cache is {4=4, 3=3} 19 | assertNull(lRUCache.get(1)); // return null (not found) 20 | assertEquals(3, lRUCache.get(3)); // return 3 21 | assertEquals(4, lRUCache.get(4)); // return 4 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/org/algorithms/fibonacci/Fibonacci.java: -------------------------------------------------------------------------------- 1 | package org.algorithms.fibonacci; 2 | 3 | import java.util.stream.Stream; 4 | 5 | /* 6 | * In mathematics, the Fibonacci numbers, commonly denoted Fn, form a sequence, called the Fibonacci sequence, 7 | * such that each number is the sum of the two preceding ones, starting from 0 and 1. 8 | * That is, 9 | * F 0 = 0 , F 1 = 1 , 10 | * and 11 | * F n = F n − 1 + F n − 2 12 | * for n > 1. 13 | * The sequence starts: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ... 14 | * 15 | * @see Fibonacci number 16 | * */ 17 | public class Fibonacci { 18 | 19 | public Stream firstNFibonacciNumbers(int amount) { 20 | int[] fibs = {1, 0}; 21 | if (amount == 0) return Stream.of(0); 22 | return Stream.generate(() -> { 23 | int result = fibs[1]; 24 | int fib3 = fibs[0] + fibs[1]; 25 | fibs[0] = fibs[1]; 26 | fibs[1] = fib3; 27 | return result; 28 | }).limit(amount); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/org/algorithms/binarysearch/BinarySearchTest.java: -------------------------------------------------------------------------------- 1 | package org.algorithms.binarysearch; 2 | 3 | import org.junit.jupiter.params.ParameterizedTest; 4 | import org.junit.jupiter.params.provider.Arguments; 5 | import org.junit.jupiter.params.provider.MethodSource; 6 | 7 | import java.util.stream.Stream; 8 | 9 | import static org.junit.jupiter.api.Assertions.assertEquals; 10 | 11 | class BinarySearchTest { 12 | private final static int[] input = new int[]{-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; 13 | 14 | private static Stream provideTestDataForBinarySearch() { 15 | return Stream.of( 16 | Arguments.of(input, 10, 15), 17 | Arguments.of(input, 0, 5), 18 | Arguments.of(input, 911, null) 19 | ); 20 | } 21 | 22 | @ParameterizedTest 23 | @MethodSource("provideTestDataForBinarySearch") 24 | void findKSumPairsTest(int[] input, Integer item, Integer expected) { 25 | BinarySearch binarySearch = new BinarySearch(); 26 | assertEquals(expected, binarySearch.search(input, item)); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/org/algorithms/sorting/QuickSortingTest.java: -------------------------------------------------------------------------------- 1 | package org.algorithms.sorting; 2 | 3 | import org.junit.jupiter.params.ParameterizedTest; 4 | import org.junit.jupiter.params.provider.Arguments; 5 | import org.junit.jupiter.params.provider.MethodSource; 6 | 7 | import java.util.List; 8 | import java.util.stream.Stream; 9 | 10 | import static org.junit.jupiter.api.Assertions.assertIterableEquals; 11 | 12 | class QuickSortingTest { 13 | 14 | private static Stream provideTestDataForShouldSortTest() { 15 | return Stream.of( 16 | Arguments.of(List.of(21, -4, 5, 11, 5, -23, 1, 2, 5, 11, 9, 15), 17 | List.of(-23, -4, 1, 2, 5, 5, 5, 9, 11, 11, 15, 21)), 18 | Arguments.of(List.of(-5, 5, -3, 3, -1, 1, 15, 0, 0, 15), 19 | List.of(-5, -3, -1, 0, 0, 1, 3, 5, 15, 15)) 20 | ); 21 | } 22 | 23 | @ParameterizedTest 24 | @MethodSource("provideTestDataForShouldSortTest") 25 | void shouldSortTest(List input, List expected) { 26 | QuickSorting sorting = new QuickSorting(); 27 | assertIterableEquals(expected, sorting.sort(input)); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/org/algorithms/findnumberspairs/NumbersPairsFinder.java: -------------------------------------------------------------------------------- 1 | package org.algorithms.findnumberspairs; 2 | 3 | import org.javatuples.Pair; 4 | 5 | import java.util.HashMap; 6 | import java.util.LinkedList; 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | public class NumbersPairsFinder { 11 | 12 | /* 13 | * Find all K-Sum Pairs 14 | * You are given an integer list nums and an integer k. 15 | * In one operation, you can pick two numbers from the array whose sum equals k, 16 | * than and add it to output and remove them from the array. 17 | * Return the all nums pairs whose sum equals k. 18 | * */ 19 | List> findKSumPairs(int sum, List numbers) { 20 | Map map = new HashMap<>(); 21 | List> pairs = new LinkedList<>(); 22 | for (Integer elem : numbers) { 23 | Integer founded = map.get(sum - elem); 24 | map.put(elem, elem); 25 | if (founded == null) continue; 26 | map.remove(founded); 27 | map.remove(elem); 28 | pairs.add(new Pair<>(founded, elem)); 29 | } 30 | return pairs; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/org/algorithms/palindrome/Palindrome.java: -------------------------------------------------------------------------------- 1 | package org.algorithms.palindrome; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | @Slf4j 9 | public class Palindrome { 10 | 11 | /* 12 | * Checks if a word can be a palindrome if we swapped characters position in it 13 | * */ 14 | public boolean canBePalindrome(String word) { 15 | final int initialCharCount = 1; 16 | Map stats = new HashMap<>(); 17 | for (char aChar : word.toCharArray()) { 18 | stats.computeIfPresent(aChar, (k, v) -> ++v); 19 | stats.putIfAbsent(aChar, initialCharCount); 20 | } 21 | return stats.values().stream().filter(v -> v % 2 > 0).count() < 2; 22 | } 23 | 24 | /* 25 | * Checks if a word is a palindrome 26 | * */ 27 | public boolean isPalindrome(String word) { 28 | char[] chars = word.toCharArray(); 29 | int head = 0; 30 | int tail = chars.length - 1; 31 | while (head < tail) { 32 | if (chars[head] - chars[tail] != 0) return false; 33 | head++; 34 | tail--; 35 | } 36 | return true; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/test/java/org/algorithms/fibonacci/FibonacciTest.java: -------------------------------------------------------------------------------- 1 | package org.algorithms.fibonacci; 2 | 3 | import org.junit.jupiter.params.ParameterizedTest; 4 | import org.junit.jupiter.params.provider.Arguments; 5 | import org.junit.jupiter.params.provider.MethodSource; 6 | 7 | import java.util.List; 8 | import java.util.stream.Collectors; 9 | import java.util.stream.Stream; 10 | 11 | import static org.junit.jupiter.api.Assertions.assertIterableEquals; 12 | 13 | class FibonacciTest { 14 | 15 | private static Stream provideFibonacciNumbers() { 16 | return Stream.of( 17 | Arguments.of(0, List.of(0)), 18 | Arguments.of(1, List.of(0)), 19 | Arguments.of(2, List.of(0, 1)), 20 | Arguments.of(3, List.of(0, 1, 1)), 21 | Arguments.of(4, List.of(0, 1, 1, 2)), 22 | Arguments.of(15, List.of(0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377)) 23 | ); 24 | } 25 | 26 | @ParameterizedTest 27 | @MethodSource("provideFibonacciNumbers") 28 | void shouldGenerateFirstNFibonacciNumbersTest(int input, List expected) { 29 | Fibonacci fibonacci = new Fibonacci(); 30 | assertIterableEquals(expected, fibonacci.firstNFibonacciNumbers(input).collect(Collectors.toList())); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/org/algorithms/binarysearch/BinarySearch.java: -------------------------------------------------------------------------------- 1 | package org.algorithms.binarysearch; 2 | 3 | /* 4 | * Binary search, also known as half-interval search, logarithmic search, or binary chop, is a search algorithm 5 | * that finds the position of a target value within a sorted array. Binary search compares the target value 6 | * to the middle element of the array. If they are not equal, the half in which the target cannot lie is eliminated 7 | * and the search continues on the remaining half, again taking the middle element to compare to the target value, 8 | * and repeating this until the target value is found. If the search ends with the remaining half being empty, 9 | * the target is not in the array. 10 | * 11 | * @see Binary search algorithm 12 | * */ 13 | public class BinarySearch { 14 | 15 | Integer search(int[] input, int item) { 16 | int low = 0; 17 | int high = input.length - 1; 18 | while (low <= high) { 19 | int mid = (low + high) / 2; 20 | int guess = input[mid]; 21 | if (guess == item) return mid; 22 | if (guess > item) { 23 | high = mid - 1; 24 | } else { 25 | low = mid + 1; 26 | } 27 | } 28 | return null; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/org/algorithms/findnumberspairs/NumbersPairsFingerTest.java: -------------------------------------------------------------------------------- 1 | package org.algorithms.findnumberspairs; 2 | 3 | import org.javatuples.Pair; 4 | import org.junit.jupiter.params.ParameterizedTest; 5 | import org.junit.jupiter.params.provider.Arguments; 6 | import org.junit.jupiter.params.provider.MethodSource; 7 | 8 | import java.util.List; 9 | import java.util.stream.Stream; 10 | 11 | import static org.junit.jupiter.api.Assertions.assertIterableEquals; 12 | 13 | class NumbersPairsFingerTest { 14 | 15 | private static Stream provideTestDataForFindKSumPairs() { 16 | return Stream.of( 17 | Arguments.of(5, List.of(2, 4, 7, 9, 0, 2, 3, 5, 1, 98, 3, 11, 23), 18 | List.of(new Pair<>(2, 3), new Pair<>(0, 5), new Pair<>(4, 1))), 19 | Arguments.of(6, List.of(2, 4, 3, 3, 7, 9, 0, 2, 3, 5, 1, 98, 3, 11, 23), 20 | List.of(new Pair<>(2, 4), new Pair<>(3, 3), new Pair<>(5, 1), new Pair<>(3, 3))) 21 | ); 22 | } 23 | 24 | @ParameterizedTest 25 | @MethodSource("provideTestDataForFindKSumPairs") 26 | void findKSumPairsTest(int sum, List input, List expected) { 27 | NumbersPairsFinder pairsFinder = new NumbersPairsFinder(); 28 | assertIterableEquals(expected, pairsFinder.findKSumPairs(sum, input)); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/org/algorithms/palindrome/PalindromeTest.java: -------------------------------------------------------------------------------- 1 | package org.algorithms.palindrome; 2 | 3 | import org.junit.jupiter.params.ParameterizedTest; 4 | import org.junit.jupiter.params.provider.ValueSource; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertFalse; 7 | import static org.junit.jupiter.api.Assertions.assertTrue; 8 | 9 | class PalindromeTest { 10 | 11 | @ParameterizedTest 12 | @ValueSource(strings = {"aabb", "aba", "affa", "abb"}) 13 | void canBePalindromeTest(String input) { 14 | Palindrome palindrome = new Palindrome(); 15 | assertTrue(palindrome.canBePalindrome(input)); 16 | } 17 | 18 | @ParameterizedTest 19 | @ValueSource(strings = {"aaarrrffff", "ab", "aabcdd"}) 20 | void canNotBePalindromeTest(String input) { 21 | Palindrome palindrome = new Palindrome(); 22 | assertFalse(palindrome.canBePalindrome(input)); 23 | } 24 | 25 | @ParameterizedTest 26 | @ValueSource(strings = {"aabfbaa", "aba", "afaaafa", "abba"}) 27 | void isPalindromeTest(String input) { 28 | Palindrome palindrome = new Palindrome(); 29 | assertTrue(palindrome.isPalindrome(input)); 30 | } 31 | 32 | @ParameterizedTest 33 | @ValueSource(strings = {"aaarrrffff", "ab", "aabcdd", "aaddbc"}) 34 | void isNotPalindromeTest(String input) { 35 | Palindrome palindrome = new Palindrome(); 36 | assertFalse(palindrome.isPalindrome(input)); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/org/algorithms/recursion/Factorial.java: -------------------------------------------------------------------------------- 1 | package org.algorithms.recursion; 2 | 3 | import java.util.function.IntPredicate; 4 | import java.util.stream.IntStream; 5 | 6 | /* 7 | * In mathematics, the factorial of a non-negative integer n, denoted by n!, 8 | * is the product of all positive integers less than or equal to n: 9 | * n ! = n * ( n − 1 ) * ( n − 2 ) * ( n − 3 ) * ... * 3 * 2 * 1 10 | * For example, 5 ! = 5 * 4 * 3 * 2 * 1 = 120 11 | * The value of 0! is 1, according to the convention for an empty product. 12 | * The factorial operation is encountered in many areas of mathematics, notably in combinatorics, algebra, 13 | * and mathematical analysis. Its most basic use counts the possible distinct sequences – the permutations – 14 | * of n distinct objects: there are n!. 15 | * 16 | * @see Factorial 17 | * */ 18 | class Factorial { 19 | private static final IntPredicate isZeroOrOne = x -> x < 2; 20 | 21 | /* 22 | * Get factorial using recursion 23 | * */ 24 | int getFactorialRecursionApproach(int n) { 25 | if (isZeroOrOne.test(n)) return 1; 26 | return n * getFactorialRecursionApproach(n - 1); 27 | } 28 | 29 | /* 30 | * Get factorial using java streams reduce 31 | * */ 32 | int getFactorialStreamsApproach(int n) { 33 | if (isZeroOrOne.test(n)) return 1; 34 | return IntStream.rangeClosed(2, n).reduce(1, (a, b) -> a * b); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/org/algorithms/lrucache/LruCache.java: -------------------------------------------------------------------------------- 1 | package org.algorithms.lrucache; 2 | 3 | import java.util.Deque; 4 | import java.util.HashMap; 5 | import java.util.LinkedList; 6 | import java.util.Map; 7 | 8 | /* 9 | * We are given total possible page numbers that can be referred. We are also given cache (or memory) 10 | * size (Number of page frames that cache can hold at a time). The LRU caching scheme is to remove 11 | * the least recently used frame when the cache is full and a new page is referenced which is not there in cache. 12 | * 13 | * @see LRU Cache 14 | * */ 15 | public class LruCache { 16 | private final int capacity; 17 | private final Deque lastToLeastKeys; 18 | private final Map cache; 19 | 20 | public LruCache(int capacity) { 21 | this.capacity = capacity; 22 | lastToLeastKeys = new LinkedList<>(); 23 | cache = new HashMap<>(capacity); 24 | } 25 | 26 | public void put(K key, V value) { 27 | if (cache.size() == capacity) { 28 | K lruKey = lastToLeastKeys.pollLast(); 29 | cache.remove(lruKey); 30 | } 31 | cache.put(key, value); 32 | processLastKey(key); 33 | } 34 | 35 | public V get(K key) { 36 | V value = cache.get(key); 37 | if (cache.containsKey(key)) processLastKey(key); 38 | return value; 39 | } 40 | 41 | private void processLastKey(K key) { 42 | lastToLeastKeys.remove(key); 43 | lastToLeastKeys.addFirst(key); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/test/java/org/algorithms/greedy/GreedyAlgorithmTest.java: -------------------------------------------------------------------------------- 1 | package org.algorithms.greedy; 2 | 3 | import org.junit.jupiter.params.ParameterizedTest; 4 | import org.junit.jupiter.params.provider.Arguments; 5 | import org.junit.jupiter.params.provider.MethodSource; 6 | 7 | import java.util.*; 8 | import java.util.stream.Stream; 9 | 10 | import static org.junit.jupiter.api.Assertions.assertIterableEquals; 11 | 12 | class GreedyAlgorithmTest { 13 | 14 | private static Stream testDataProvider() { 15 | Set states = new HashSet<>(Arrays.asList("mt", "wa", "or", "id", "nv", "ut", "ca", "az")); 16 | Map> stations = new LinkedHashMap<>(); 17 | stations.put("kone", new HashSet<>(Arrays.asList("id", "nv", "ut"))); 18 | stations.put("ktwo", new HashSet<>(Arrays.asList("wa", "id", "mt"))); 19 | stations.put("kthree", new HashSet<>(Arrays.asList("or", "nv", "ca"))); 20 | stations.put("kfour", new HashSet<>(Arrays.asList("nv", "ut"))); 21 | stations.put("kfive", new HashSet<>(Arrays.asList("ca", "az"))); 22 | List expected = List.of("kone", "ktwo", "kthree", "kfive"); 23 | return Stream.of(Arguments.of(states, stations, expected)); 24 | } 25 | 26 | @ParameterizedTest 27 | @MethodSource("testDataProvider") 28 | void shouldFindStationsTest(Set states, Map> stations, List expected) { 29 | GreedyAlgorithm greedyAlgorithm = new GreedyAlgorithm(); 30 | assertIterableEquals(expected, greedyAlgorithm.findStations(states, stations)); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/test/java/org/algorithms/graph/DijkstraAlgorithmTest.java: -------------------------------------------------------------------------------- 1 | package org.algorithms.graph; 2 | 3 | import org.junit.jupiter.params.ParameterizedTest; 4 | import org.junit.jupiter.params.provider.Arguments; 5 | import org.junit.jupiter.params.provider.MethodSource; 6 | 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | import java.util.stream.Stream; 10 | 11 | import static org.algorithms.graph.DijkstraAlgorithm.FIN; 12 | import static org.algorithms.graph.DijkstraAlgorithm.START; 13 | import static org.junit.jupiter.api.Assertions.assertEquals; 14 | 15 | class DijkstraAlgorithmTest { 16 | 17 | private static Stream graphProvider() { 18 | Map> graph = new HashMap<>(); 19 | graph.put(START, new HashMap<>()); 20 | graph.get("start").put("a", 6.0); 21 | graph.get("start").put("b", 2.0); 22 | graph.put("a", new HashMap<>()); 23 | graph.get("a").put("fin", 1.0); 24 | graph.put("b", new HashMap<>()); 25 | graph.get("b").put("a", 3.0); 26 | graph.get("b").put("fin", 5.0); 27 | graph.put(FIN, new HashMap<>()); 28 | Map expectedCosts = new HashMap<>(); 29 | expectedCosts.put("a", 5.0); 30 | expectedCosts.put("b", 2.0); 31 | expectedCosts.put("fin", 6.0); 32 | return Stream.of(Arguments.of(graph, expectedCosts)); 33 | } 34 | 35 | @ParameterizedTest 36 | @MethodSource("graphProvider") 37 | void dijkstraAlgorithmTest(Map> graph, Map expectedCosts) { 38 | DijkstraAlgorithm dijkstraAlgorithm = new DijkstraAlgorithm(); 39 | assertEquals(expectedCosts, dijkstraAlgorithm.shortestPath(graph)); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/org/algorithms/graph/BreadthFirstSearch.java: -------------------------------------------------------------------------------- 1 | package org.algorithms.graph; 2 | 3 | import java.util.*; 4 | import java.util.function.Predicate; 5 | 6 | /* 7 | * Breadth-first search (BFS) is an algorithm for searching a tree data structure for a node that satisfies 8 | * a given property. It starts at the tree root and explores all nodes at the present depth prior to moving 9 | * on to the nodes at the next depth level. Extra memory, usually a queue, is needed to keep track of the child 10 | * nodes that were encountered but not yet explored. 11 | * 12 | * For example, in a chess endgame a chess engine may build the game tree from the current position by applying 13 | * all possible moves, and use breadth-first search to find a win position for white. 14 | * Implicit trees (such as game trees or other problem-solving trees) may be of infinite size, 15 | * breadth-first search is guaranteed to find a solution node if one exists. 16 | * 17 | * @see Breadth-first search 18 | * */ 19 | public class BreadthFirstSearch { 20 | 21 | /* 22 | * This method find person who is seller in friends graph. 23 | * We use Map> for graph representation. 24 | * */ 25 | public String search(Map> graph, String root, Predicate searchCondition) { 26 | Queue queue = new LinkedList<>(graph.get(root)); 27 | List searched = new ArrayList<>(); 28 | while (!queue.isEmpty()) { 29 | String person = queue.poll(); 30 | if (searched.contains(person)) continue; 31 | if (searchCondition.test(person)) return person; 32 | queue.addAll(graph.get(person)); 33 | searched.add(person); 34 | } 35 | return null; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/test/java/org/algorithms/graph/BreadthFirstSearchTest.java: -------------------------------------------------------------------------------- 1 | package org.algorithms.graph; 2 | 3 | import org.junit.jupiter.params.ParameterizedTest; 4 | import org.junit.jupiter.params.provider.MethodSource; 5 | 6 | import java.util.HashMap; 7 | import java.util.List; 8 | import java.util.Map; 9 | import java.util.function.Predicate; 10 | import java.util.stream.Stream; 11 | 12 | import static org.junit.jupiter.api.Assertions.assertEquals; 13 | import static org.junit.jupiter.api.Assertions.assertNull; 14 | 15 | class BreadthFirstSearchTest { 16 | private static final String root = "you"; 17 | 18 | static Stream>> graphProvider() { 19 | Map> graph = new HashMap<>(); 20 | graph.put(root, List.of("alice", "bob", "claire")); 21 | graph.put("bob", List.of("anuj", "peggy")); 22 | graph.put("alice", List.of("peggy", root)); 23 | graph.put("claire", List.of("thom", "jonny")); 24 | graph.put("anuj", List.of()); 25 | graph.put("peggy", List.of("alice")); 26 | graph.put("thom", List.of()); 27 | graph.put("jonny", List.of()); 28 | return Stream.of(graph); 29 | } 30 | 31 | @ParameterizedTest 32 | @MethodSource("graphProvider") 33 | void shouldFindSellerTest(Map> graph) { 34 | final BreadthFirstSearch bfs = new BreadthFirstSearch(); 35 | final Predicate personIsSeller = name -> name.charAt(name.length() - 1) == 'm'; 36 | final String expected = "thom"; 37 | assertEquals(expected, bfs.search(graph, root, personIsSeller)); 38 | } 39 | 40 | @ParameterizedTest 41 | @MethodSource("graphProvider") 42 | void shouldNotFindSellerTest(Map> graph) { 43 | final BreadthFirstSearch bfs = new BreadthFirstSearch(); 44 | final Predicate personIsSeller = name -> name.charAt(name.length() - 1) == 'z'; 45 | assertNull(bfs.search(graph, root, personIsSeller)); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/test/java/org/algorithms/sorting/SelectionSortingTest.java: -------------------------------------------------------------------------------- 1 | package org.algorithms.sorting; 2 | 3 | import org.junit.jupiter.params.ParameterizedTest; 4 | import org.junit.jupiter.params.provider.Arguments; 5 | import org.junit.jupiter.params.provider.MethodSource; 6 | 7 | import java.util.Arrays; 8 | import java.util.List; 9 | import java.util.stream.Collectors; 10 | import java.util.stream.Stream; 11 | 12 | import static org.junit.jupiter.api.Assertions.assertIterableEquals; 13 | 14 | class SelectionSortingTest { 15 | 16 | private static Stream provideTestDataForShouldSortASCTest() { 17 | return Stream.of( 18 | Arguments.of(new int[]{21, -4, 5, 11, 5, -23, 1, 2, 5, 11, 9, 15}, 19 | List.of(-23, -4, 1, 2, 5, 5, 5, 9, 11, 11, 15, 21)), 20 | Arguments.of(new int[]{-5, 5, -3, 3, -1, 1, 15, 0, 0, 15}, 21 | List.of(-5, -3, -1, 0, 0, 1, 3, 5, 15, 15)) 22 | ); 23 | } 24 | 25 | private static Stream provideTestDataForShouldSortDECSTest() { 26 | return Stream.of( 27 | Arguments.of(new int[]{21, -4, 5, 11, 5, -23, 1, 2, 5, 11, 9, 15}, 28 | List.of(21, 15, 11, 11, 9, 5, 5, 5, 2, 1, -4, -23)), 29 | Arguments.of(new int[]{-5, 5, -3, 3, -1, 1, 15, 0, 0, 15}, 30 | List.of(15, 15, 5, 3, 1, 0, 0, -1, -3, -5)) 31 | ); 32 | } 33 | 34 | @ParameterizedTest 35 | @MethodSource("provideTestDataForShouldSortASCTest") 36 | void shouldSortASCTest(int[] input, List expected) { 37 | SelectionSorting sorting = new SelectionSorting(); 38 | assertIterableEquals(expected, Arrays.stream(sorting.sortASC(input)).boxed().collect(Collectors.toList())); 39 | } 40 | 41 | @ParameterizedTest 42 | @MethodSource("provideTestDataForShouldSortDECSTest") 43 | void shouldSortDECSTest(int[] input, List expected) { 44 | SelectionSorting sorting = new SelectionSorting(); 45 | assertIterableEquals(expected, Arrays.stream(sorting.sortDESC(input)).boxed().collect(Collectors.toList())); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/org/algorithms/sorting/QuickSorting.java: -------------------------------------------------------------------------------- 1 | package org.algorithms.sorting; 2 | 3 | import java.util.List; 4 | import java.util.function.Function; 5 | import java.util.function.IntPredicate; 6 | import java.util.stream.Collectors; 7 | import java.util.stream.Stream; 8 | 9 | /* 10 | * Quicksort is an in-place sorting algorithm. Developed by British computer scientist Tony Hoare in 1959 11 | * and published in 1961, it is still a commonly used algorithm for sorting. When implemented well, it can be somewhat 12 | * faster than merge sort and about two or three times faster than heapsort. 13 | * 14 | * Quicksort is a divide-and-conquer algorithm. It works by selecting a 'pivot' element from the array and partitioning 15 | * the other elements into two sub-arrays, according to whether they are less than or greater than the pivot. 16 | * For this reason, it is sometimes called partition-exchange sort. The sub-arrays are then sorted recursively. 17 | * This can be done in-place, requiring small additional amounts of memory to perform the sorting. 18 | * 19 | * Quicksort is a comparison sort, meaning that it can sort items of any type for which a "less-than" relation 20 | * (formally, a total order) is defined. Efficient implementations of Quicksort are not a stable sort, meaning 21 | * that the relative order of equal sort items is not preserved. 22 | * 23 | * Mathematical analysis of quicksort shows that, on average, the algorithm takes O(n log n) comparisons to sort n items. 24 | * In the worst case, it makes O(n2) comparisons. 25 | * 26 | * @see Quicksort 27 | * */ 28 | public class QuickSorting { 29 | private static final IntPredicate isZeroOrOne = x -> x < 2; 30 | 31 | List sort(List input) { 32 | if (isZeroOrOne.test(input.size())) return input; 33 | int pivotElement = input.get(0); 34 | List less = input.stream().skip(1).filter(e -> e <= pivotElement).collect(Collectors.toList()); 35 | Stream pivot = Stream.of(pivotElement); 36 | List greater = input.stream().skip(1).filter(e -> e > pivotElement).collect(Collectors.toList()); 37 | return Stream.of(sort(less).stream(), pivot, sort(greater).stream()) 38 | .flatMap(Function.identity()) 39 | .collect(Collectors.toList()); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/org/algorithms/greedy/GreedyAlgorithm.java: -------------------------------------------------------------------------------- 1 | package org.algorithms.greedy; 2 | 3 | import java.util.*; 4 | 5 | /* 6 | * A greedy algorithm is any algorithm that follows the problem-solving heuristic of making the locally optimal choice 7 | * at each stage. In many problems, a greedy strategy does not produce an optimal solution, but a greedy heuristic can 8 | * yield locally optimal solutions that approximate a globally optimal solution in a reasonable amount of time. 9 | * 10 | * For example, a greedy strategy for the travelling salesman problem (which is of high computational complexity) 11 | * is the following heuristic: "At each step of the journey, visit the nearest unvisited city." 12 | * This heuristic does not intend to find the best solution, but it terminates in a reasonable number of steps, 13 | * finding an optimal solution to such a complex problem typically requires unreasonably many steps. 14 | * In mathematical optimization, greedy algorithms optimally solve combinatorial problems having the properties of 15 | * matroids and give constant-factor approximations to optimization problems with the submodular structure. 16 | * 17 | * @see Greedy algorithm 18 | * */ 19 | class GreedyAlgorithm { 20 | 21 | /* 22 | * You open your own authoring program on the radio and want to be heard in all states. 23 | * You need to decide on which radio stations your program should be broadcast. 24 | * Each station costs money, so the number of stations must be kept to a minimum. 25 | * There is a list of stations. 26 | * */ 27 | List findStations(Set states, Map> stations) { 28 | List finalStations = new ArrayList<>(); 29 | while (!states.isEmpty()) { 30 | Set statesCovered = new HashSet<>(); 31 | String bestStation = null; 32 | for (Map.Entry> entry : stations.entrySet()) { 33 | Set stationCoverages = entry.getValue(); 34 | Set covered = intersection(states, stationCoverages); 35 | if (covered.size() > statesCovered.size()) { 36 | statesCovered = covered; 37 | bestStation = entry.getKey(); 38 | } 39 | } 40 | if (bestStation == null) continue; 41 | finalStations.add(bestStation); 42 | stations.remove(bestStation); 43 | states.removeIf(statesCovered::contains); 44 | } 45 | return finalStations; 46 | } 47 | 48 | private Set intersection(Set states, Set stationCoverages) { 49 | Set result = new HashSet<>(states); 50 | result.retainAll(stationCoverages); 51 | return result; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/org/algorithms/sorting/SelectionSorting.java: -------------------------------------------------------------------------------- 1 | package org.algorithms.sorting; 2 | 3 | import java.util.function.BiPredicate; 4 | 5 | /* 6 | * In computer science, selection sort is an in-place comparison sorting algorithm. 7 | * It has an O(n2) time complexity, which makes it inefficient on large lists, 8 | * and generally performs worse than the similar insertion sort. 9 | * Selection sort is noted for its simplicity and has performance advantages over more complicated algorithms 10 | * in certain situations, particularly where auxiliary memory is limited. 11 | * The algorithm divides the input list into two parts: a sorted sublist of items which is built up from left to right 12 | * at the front (left) of the list and a sublist of the remaining unsorted items that occupy the rest of the list. 13 | * Initially, the sorted sublist is empty and the unsorted sublist is the entire input list. 14 | * The algorithm proceeds by finding the smallest (or largest, depending on sorting order) element in the unsorted sublist, 15 | * exchanging (swapping) it with the leftmost unsorted element (putting it in sorted order), and moving the sublist 16 | * boundaries one element to the right. 17 | * 18 | * @see Selection sort algorithm 19 | * 20 | * This version of algorithm works without extra sorted array. There is used swapping elements in unsorted array. 21 | * */ 22 | class SelectionSorting { 23 | private static final BiPredicate xGreaterThanY = (x, y) -> x > y; 24 | private static final BiPredicate xLessThanY = (x, y) -> x < y; 25 | 26 | int[] sortASC(int[] input) { 27 | return sort(input, true); 28 | } 29 | 30 | int[] sortDESC(int[] input) { 31 | return sort(input, false); 32 | } 33 | 34 | private int[] sort(int[] input, boolean asc) { 35 | for (int i = 0; i < input.length - 1; i++) { 36 | int foundIndex = asc ? findSmallestIndex(input, i) : findBiggestIndex(input, i); 37 | int foundElement = input[foundIndex]; 38 | int currentElement = input[i]; 39 | input[i] = foundElement; 40 | input[foundIndex] = currentElement; 41 | } 42 | return input; 43 | } 44 | 45 | private int findSmallestIndex(int[] input, int startFrom) { 46 | return findIndexByPredicate(input, startFrom, xGreaterThanY); 47 | } 48 | 49 | private int findBiggestIndex(int[] input, int startFrom) { 50 | return findIndexByPredicate(input, startFrom, xLessThanY); 51 | } 52 | 53 | private int findIndexByPredicate(int[] input, int startFrom, BiPredicate predicate) { 54 | int matchingPredicate = input[startFrom]; 55 | int index = startFrom; 56 | for (int i = startFrom + 1; i < input.length; i++) { 57 | if (predicate.test(matchingPredicate, input[i])) { 58 | matchingPredicate = input[i]; 59 | index = i; 60 | } 61 | } 62 | return index; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 4.0.0 6 | 7 | org.algorithms 8 | algorithms 9 | 1.0-SNAPSHOT 10 | 11 | algorithms 12 | 13 | 14 | UTF-8 15 | 11 16 | 11 17 | 18 | 19 | 20 | 21 | 22 | org.javatuples 23 | javatuples 24 | 1.2 25 | 26 | 27 | 28 | 29 | org.projectlombok 30 | lombok 31 | 1.18.22 32 | provided 33 | 34 | 35 | 36 | 37 | ch.qos.logback 38 | logback-classic 39 | 1.2.6 40 | 41 | 42 | 43 | 44 | org.junit.jupiter 45 | junit-jupiter 46 | 5.8.1 47 | test 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | maven-clean-plugin 57 | 3.1.0 58 | 59 | 60 | 61 | maven-resources-plugin 62 | 3.0.2 63 | 64 | 65 | maven-compiler-plugin 66 | 3.8.0 67 | 68 | 69 | maven-surefire-plugin 70 | 2.22.1 71 | 72 | 73 | maven-jar-plugin 74 | 3.0.2 75 | 76 | 77 | maven-install-plugin 78 | 2.5.2 79 | 80 | 81 | maven-deploy-plugin 82 | 2.8.2 83 | 84 | 85 | 86 | maven-site-plugin 87 | 3.7.1 88 | 89 | 90 | maven-project-info-reports-plugin 91 | 3.0.0 92 | 93 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /src/main/java/org/algorithms/graph/DijkstraAlgorithm.java: -------------------------------------------------------------------------------- 1 | package org.algorithms.graph; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | /* 9 | * Dijkstra's algorithm is an algorithm for finding the shortest paths between nodes in a graph, which may represent, 10 | * for example, road networks. It was conceived by computer scientist Edsger W. Dijkstra in 1956 and published three 11 | * years later. The algorithm exists in many variants. Dijkstra's original algorithm found the shortest path between 12 | * two given nodes, but a more common variant fixes a single node as the "source" node and finds shortest paths from 13 | * the source to all other nodes in the graph, producing a shortest-path tree. 14 | * 15 | * For a given source node in the graph, the algorithm finds the shortest path between that node and every other. 16 | * It can also be used for finding the shortest paths from a single node to a single destination node by stopping 17 | * the algorithm once the shortest path to the destination node has been determined. 18 | * For example, if the nodes of the graph represent cities and edge path costs represent driving distances 19 | * between pairs of cities connected by a direct road (for simplicity, ignore red lights, stop signs, toll roads 20 | * and other obstructions), Dijkstra's algorithm can be used to find the shortest route between one city and 21 | * all other cities. A widely used application of shortest path algorithms is network routing protocols, 22 | * most notably IS-IS (Intermediate System to Intermediate System) and Open Shortest Path First (OSPF). 23 | * It is also employed as a subroutine in other algorithms such as Johnson's. 24 | * 25 | * The Dijkstra algorithm uses labels that are positive integers or real numbers, which are totally ordered. 26 | * It can be generalized to use any labels that are partially ordered, provided the subsequent labels 27 | * (a subsequent label is produced when traversing an edge) are monotonically non-decreasing. 28 | * This generalization is called the generic Dijkstra shortest-path algorithm.[8] 29 | * 30 | * @see Dijkstra's algorithm 31 | * */ 32 | class DijkstraAlgorithm { 33 | static final String START = "start"; 34 | static final String FIN = "fin"; 35 | 36 | Map shortestPath(Map> graph) { 37 | Map costs = initCosts(graph); 38 | Map parents = initParents(graph); 39 | List processed = new ArrayList<>(); 40 | String node = findLowestCostNode(costs, processed); 41 | while (node != null) { 42 | Double cost = costs.get(node); 43 | Map neighbours = graph.get(node); 44 | for (Map.Entry neighbour : neighbours.entrySet()) { 45 | Double newCost = cost + neighbour.getValue(); 46 | if (costs.get(neighbour.getKey()) > newCost) { 47 | costs.put(neighbour.getKey(), newCost); 48 | parents.put(neighbour.getKey(), node); 49 | } 50 | } 51 | processed.add(node); 52 | node = findLowestCostNode(costs, processed); 53 | } 54 | return costs; 55 | } 56 | 57 | private String findLowestCostNode(Map costs, List processed) { 58 | Double lowestCost = Double.POSITIVE_INFINITY; 59 | String lowestCostNode = null; 60 | for (Map.Entry node : costs.entrySet()) { 61 | Double cost = node.getValue(); 62 | if (cost < lowestCost && !processed.contains(node.getKey())) { 63 | lowestCost = cost; 64 | lowestCostNode = node.getKey(); 65 | } 66 | } 67 | return lowestCostNode; 68 | } 69 | 70 | private Map initCosts(Map> graph) { 71 | Map costs = new HashMap<>(graph.get(START)); 72 | costs.put(FIN, Double.POSITIVE_INFINITY); 73 | return costs; 74 | } 75 | 76 | private Map initParents(Map> graph) { 77 | Map parents = new HashMap<>(); 78 | graph.get(START).keySet().forEach(k -> parents.put(k, START)); 79 | parents.put(FIN, null); 80 | return parents; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /.idea/uiDesigner.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 54 | --------------------------------------------------------------------------------