commit
						576d4d80ab
					
				
							
								
								
									
										12
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -4,6 +4,7 @@ bin/ | ||||
| *.class | ||||
| 
 | ||||
| # Package Files # | ||||
| *.jar | ||||
| *.war | ||||
| *.ear | ||||
| 
 | ||||
| @ -29,7 +30,7 @@ out/ | ||||
| .DS_Store | ||||
| 
 | ||||
| # Maven | ||||
| log/ | ||||
| log/* | ||||
| target/ | ||||
| 
 | ||||
| # Gradle | ||||
| @ -82,4 +83,11 @@ jta/transaction-logs/ | ||||
| software-security/sql-injection-samples/derby.log | ||||
| spring-soap/src/main/java/com/baeldung/springsoap/gen/ | ||||
| /report-*.json | ||||
| transaction.log | ||||
| transaction.log | ||||
| *-shell.log | ||||
| 
 | ||||
| apache-cxf/cxf-aegis/baeldung.xml | ||||
| apache-fop/src/test/resources/input.xml | ||||
| apache-fop/src/test/resources/output_herold.pdf | ||||
| apache-fop/src/test/resources/output_html2fo.pdf | ||||
| apache-fop/src/test/resources/output_jtidy.pdf | ||||
| @ -1,3 +1,7 @@ | ||||
| ## Relevant articles: | ||||
| ## Akka HTTP | ||||
| 
 | ||||
| This module contains articles about Akka HTTP.  | ||||
| 
 | ||||
| ### Relevant articles: | ||||
| 
 | ||||
| - [Introduction to Akka HTTP](https://www.baeldung.com/akka-http) | ||||
|  | ||||
| @ -1,3 +1,7 @@ | ||||
| ## Akka Streams | ||||
| 
 | ||||
| This module contains articles about Akka Streams.  | ||||
| 
 | ||||
| ### Relevant articles | ||||
| 
 | ||||
| - [Guide to Akka Streams](http://www.baeldung.com/akka-streams) | ||||
| - [Guide to Akka Streams](https://www.baeldung.com/akka-streams) | ||||
|  | ||||
| @ -1,6 +1,10 @@ | ||||
| ## Relevant articles: | ||||
| ## Genetic Algorithms | ||||
| 
 | ||||
| - [Introduction to Jenetics Library](http://www.baeldung.com/jenetics) | ||||
| - [Ant Colony Optimization](http://www.baeldung.com/java-ant-colony-optimization) | ||||
| This module contains articles about genetic algorithms.  | ||||
| 
 | ||||
| ### Relevant articles: | ||||
| 
 | ||||
| - [Introduction to Jenetics Library](https://www.baeldung.com/jenetics) | ||||
| - [Ant Colony Optimization](https://www.baeldung.com/java-ant-colony-optimization) | ||||
| - [Design a Genetic Algorithm in Java](https://www.baeldung.com/java-genetic-algorithm) | ||||
| - [The Traveling Salesman Problem in Java](https://www.baeldung.com/java-simulated-annealing-for-traveling-salesman) | ||||
|  | ||||
							
								
								
									
										4
									
								
								algorithms-miscellaneous-1/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								algorithms-miscellaneous-1/.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1,4 +0,0 @@ | ||||
| /target/ | ||||
| .settings/ | ||||
| .classpath | ||||
| .project | ||||
| @ -1,18 +1,15 @@ | ||||
| ## Relevant articles: | ||||
| ## Algorithms - Miscellaneous | ||||
| 
 | ||||
| - [Validating Input With Finite Automata in Java](http://www.baeldung.com/java-finite-automata) | ||||
| - [Example of Hill Climbing Algorithm](http://www.baeldung.com/java-hill-climbing-algorithm) | ||||
| - [Monte Carlo Tree Search for Tic-Tac-Toe Game](http://www.baeldung.com/java-monte-carlo-tree-search) | ||||
| - [Binary Search Algorithm in Java](http://www.baeldung.com/java-binary-search) | ||||
| - [Introduction to Minimax Algorithm](http://www.baeldung.com/java-minimax-algorithm) | ||||
| - [How to Calculate Levenshtein Distance in Java?](http://www.baeldung.com/java-levenshtein-distance) | ||||
| - [How to Find the Kth Largest Element in Java](http://www.baeldung.com/java-kth-largest-element) | ||||
| - [Multi-Swarm Optimization Algorithm in Java](http://www.baeldung.com/java-multi-swarm-algorithm) | ||||
| - [String Search Algorithms for Large Texts](http://www.baeldung.com/java-full-text-search-algorithms) | ||||
| - [Check If a String Contains All The Letters of The Alphabet](https://www.baeldung.com/java-string-contains-all-letters) | ||||
| - [Find the Middle Element of a Linked List](http://www.baeldung.com/java-linked-list-middle-element) | ||||
| - [Calculate Factorial in Java](https://www.baeldung.com/java-calculate-factorial) | ||||
| - [Find Substrings That Are Palindromes in Java](https://www.baeldung.com/java-palindrome-substrings) | ||||
| - [Find the Longest Substring without Repeating Characters](https://www.baeldung.com/java-longest-substring-without-repeated-characters) | ||||
| - [Permutations of an Array in Java](https://www.baeldung.com/java-array-permutations) | ||||
| - [Generate Combinations in Java](https://www.baeldung.com/java-combinations-algorithm) | ||||
| This module contains articles about algorithms. Some classes of algorithms, e.g., [sorting](/../algorithms-sorting) and | ||||
| [genetic algorithms](/../algorithms-genetic), have their own dedicated modules.  | ||||
| 
 | ||||
| ### Relevant articles: | ||||
| 
 | ||||
| - [Validating Input With Finite Automata in Java](https://www.baeldung.com/java-finite-automata) | ||||
| - [Example of Hill Climbing Algorithm](https://www.baeldung.com/java-hill-climbing-algorithm) | ||||
| - [Monte Carlo Tree Search for Tic-Tac-Toe Game](https://www.baeldung.com/java-monte-carlo-tree-search) | ||||
| - [Binary Search Algorithm in Java](https://www.baeldung.com/java-binary-search) | ||||
| - [Introduction to Minimax Algorithm](https://www.baeldung.com/java-minimax-algorithm) | ||||
| - [How to Calculate Levenshtein Distance in Java?](https://www.baeldung.com/java-levenshtein-distance) | ||||
| - [How to Find the Kth Largest Element in Java](https://www.baeldung.com/java-kth-largest-element) | ||||
| - More articles: [[next -->]](/../algorithms-miscellaneous-2) | ||||
|  | ||||
							
								
								
									
										4
									
								
								algorithms-miscellaneous-2/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								algorithms-miscellaneous-2/.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1,4 +0,0 @@ | ||||
| /target/ | ||||
| .settings/ | ||||
| .classpath | ||||
| .project | ||||
| @ -1,19 +1,16 @@ | ||||
| ## Relevant articles: | ||||
| ## Algorithms - Miscellaneous | ||||
| 
 | ||||
| - [Dijkstra Algorithm in Java](http://www.baeldung.com/java-dijkstra) | ||||
| - [Introduction to Cobertura](http://www.baeldung.com/cobertura) | ||||
| - [Test a Linked List for Cyclicity](http://www.baeldung.com/java-linked-list-cyclicity) | ||||
| - [Introduction to JGraphT](http://www.baeldung.com/jgrapht) | ||||
| - [A Maze Solver in Java](http://www.baeldung.com/java-solve-maze) | ||||
| - [Create a Sudoku Solver in Java](http://www.baeldung.com/java-sudoku) | ||||
| - [Displaying Money Amounts in Words](http://www.baeldung.com/java-money-into-words) | ||||
| - [A Collaborative Filtering Recommendation System in Java](http://www.baeldung.com/java-collaborative-filtering-recommendations) | ||||
| - [Check If Two Rectangles Overlap In Java](https://www.baeldung.com/java-check-if-two-rectangles-overlap) | ||||
| - [Calculate the Distance Between Two Points in Java](https://www.baeldung.com/java-distance-between-two-points) | ||||
| - [Find the Intersection of Two Lines in Java](https://www.baeldung.com/java-intersection-of-two-lines) | ||||
| - [Round Up to the Nearest Hundred](https://www.baeldung.com/java-round-up-nearest-hundred) | ||||
| - [Calculate Percentage in Java](https://www.baeldung.com/java-calculate-percentage) | ||||
| - [Converting Between Byte Arrays and Hexadecimal Strings in Java](https://www.baeldung.com/java-byte-arrays-hex-strings) | ||||
| - [Convert Latitude and Longitude to a 2D Point in Java](https://www.baeldung.com/java-convert-latitude-longitude) | ||||
| - [Reversing a Binary Tree in Java](https://www.baeldung.com/java-reversing-a-binary-tree) | ||||
| - [Find If Two Numbers Are Relatively Prime in Java](https://www.baeldung.com/java-two-relatively-prime-numbers) | ||||
| This module contains articles about algorithms. Some classes of algorithms, e.g., [sorting](/../algorithms-sorting) and | ||||
| [genetic algorithms](/../algorithms-genetic), have their own dedicated modules.  | ||||
| 
 | ||||
| ### Relevant articles: | ||||
| 
 | ||||
| - [Dijkstra Shortest Path Algorithm in Java](https://www.baeldung.com/java-dijkstra) | ||||
| - [Introduction to Cobertura](https://www.baeldung.com/cobertura) | ||||
| - [Test a Linked List for Cyclicity](https://www.baeldung.com/java-linked-list-cyclicity) | ||||
| - [Introduction to JGraphT](https://www.baeldung.com/jgrapht) | ||||
| - [A Maze Solver in Java](https://www.baeldung.com/java-solve-maze) | ||||
| - [Create a Sudoku Solver in Java](https://www.baeldung.com/java-sudoku) | ||||
| - [Displaying Money Amounts in Words](https://www.baeldung.com/java-money-into-words) | ||||
| - [A Collaborative Filtering Recommendation System in Java](https://www.baeldung.com/java-collaborative-filtering-recommendations) | ||||
| - More articles: [[<-- prev]](/../algorithms-miscellaneous-1) [[next -->]](/../algorithms-miscellaneous-3) | ||||
|  | ||||
| @ -0,0 +1,30 @@ | ||||
| package com.baeldung.algorithms.astar; | ||||
| 
 | ||||
| import java.util.Map; | ||||
| import java.util.Set; | ||||
| import java.util.stream.Collectors; | ||||
| 
 | ||||
| 
 | ||||
| public class Graph<T extends GraphNode> { | ||||
|     private final Set<T> nodes; | ||||
| 
 | ||||
|     private final Map<String, Set<String>> connections; | ||||
| 
 | ||||
|     public Graph(Set<T> nodes, Map<String, Set<String>> connections) { | ||||
|         this.nodes = nodes; | ||||
|         this.connections = connections; | ||||
|     } | ||||
| 
 | ||||
|     public T getNode(String id) { | ||||
|         return nodes.stream() | ||||
|             .filter(node -> node.getId().equals(id)) | ||||
|             .findFirst() | ||||
|             .orElseThrow(() -> new IllegalArgumentException("No node found with ID")); | ||||
|     } | ||||
| 
 | ||||
|     public Set<T> getConnections(T node) { | ||||
|         return connections.get(node.getId()).stream() | ||||
|             .map(this::getNode) | ||||
|             .collect(Collectors.toSet()); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,5 @@ | ||||
| package com.baeldung.algorithms.astar; | ||||
| 
 | ||||
| public interface GraphNode { | ||||
|     String getId(); | ||||
| } | ||||
| @ -0,0 +1,66 @@ | ||||
| package com.baeldung.algorithms.astar; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashMap; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.PriorityQueue; | ||||
| import java.util.Queue; | ||||
| import java.util.stream.Collectors; | ||||
| 
 | ||||
| public class RouteFinder<T extends GraphNode> { | ||||
|     private final Graph<T> graph; | ||||
|     private final Scorer<T> nextNodeScorer; | ||||
|     private final Scorer<T> targetScorer; | ||||
| 
 | ||||
|     public RouteFinder(Graph<T> graph, Scorer<T> nextNodeScorer, Scorer<T> targetScorer) { | ||||
|         this.graph = graph; | ||||
|         this.nextNodeScorer = nextNodeScorer; | ||||
|         this.targetScorer = targetScorer; | ||||
|     } | ||||
| 
 | ||||
|     public List<T> findRoute(T from, T to) { | ||||
|         Map<T, RouteNode<T>> allNodes = new HashMap<>(); | ||||
|         Queue<RouteNode> openSet = new PriorityQueue<>(); | ||||
| 
 | ||||
|         RouteNode<T> start = new RouteNode<>(from, null, 0d, targetScorer.computeCost(from, to)); | ||||
|         allNodes.put(from, start); | ||||
|         openSet.add(start); | ||||
| 
 | ||||
|         while (!openSet.isEmpty()) { | ||||
|             System.out.println("Open Set contains: " + openSet.stream().map(RouteNode::getCurrent).collect(Collectors.toSet())); | ||||
|             RouteNode<T> next = openSet.poll(); | ||||
|             System.out.println("Looking at node: " + next); | ||||
|             if (next.getCurrent().equals(to)) { | ||||
|                 System.out.println("Found our destination!"); | ||||
| 
 | ||||
|                 List<T> route = new ArrayList<>(); | ||||
|                 RouteNode<T> current = next; | ||||
|                 do { | ||||
|                     route.add(0, current.getCurrent()); | ||||
|                     current = allNodes.get(current.getPrevious()); | ||||
|                 } while (current != null); | ||||
| 
 | ||||
|                 System.out.println("Route: " + route); | ||||
|                 return route; | ||||
|             } | ||||
| 
 | ||||
|             graph.getConnections(next.getCurrent()).forEach(connection -> { | ||||
|                 double newScore = next.getRouteScore() + nextNodeScorer.computeCost(next.getCurrent(), connection); | ||||
|                 RouteNode<T> nextNode = allNodes.getOrDefault(connection, new RouteNode<>(connection)); | ||||
|                 allNodes.put(connection, nextNode); | ||||
| 
 | ||||
|                 if (nextNode.getRouteScore() > newScore) { | ||||
|                     nextNode.setPrevious(next.getCurrent()); | ||||
|                     nextNode.setRouteScore(newScore); | ||||
|                     nextNode.setEstimatedScore(newScore + targetScorer.computeCost(connection, to)); | ||||
|                     openSet.add(nextNode); | ||||
|                     System.out.println("Found a better route to node: " + nextNode); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
| 
 | ||||
|         throw new IllegalStateException("No route found"); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,67 @@ | ||||
| package com.baeldung.algorithms.astar; | ||||
| 
 | ||||
| import java.util.StringJoiner; | ||||
| 
 | ||||
| class RouteNode<T extends GraphNode> implements Comparable<RouteNode> { | ||||
|     private final T current; | ||||
|     private T previous; | ||||
|     private double routeScore; | ||||
|     private double estimatedScore; | ||||
| 
 | ||||
|     RouteNode(T current) { | ||||
|         this(current, null, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY); | ||||
|     } | ||||
| 
 | ||||
|     RouteNode(T current, T previous, double routeScore, double estimatedScore) { | ||||
|         this.current = current; | ||||
|         this.previous = previous; | ||||
|         this.routeScore = routeScore; | ||||
|         this.estimatedScore = estimatedScore; | ||||
|     } | ||||
| 
 | ||||
|     T getCurrent() { | ||||
|         return current; | ||||
|     } | ||||
| 
 | ||||
|     T getPrevious() { | ||||
|         return previous; | ||||
|     } | ||||
| 
 | ||||
|     double getRouteScore() { | ||||
|         return routeScore; | ||||
|     } | ||||
| 
 | ||||
|     double getEstimatedScore() { | ||||
|         return estimatedScore; | ||||
|     } | ||||
| 
 | ||||
|     void setPrevious(T previous) { | ||||
|         this.previous = previous; | ||||
|     } | ||||
| 
 | ||||
|     void setRouteScore(double routeScore) { | ||||
|         this.routeScore = routeScore; | ||||
|     } | ||||
| 
 | ||||
|     void setEstimatedScore(double estimatedScore) { | ||||
|         this.estimatedScore = estimatedScore; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public int compareTo(RouteNode other) { | ||||
|         if (this.estimatedScore > other.estimatedScore) { | ||||
|             return 1; | ||||
|         } else if (this.estimatedScore < other.estimatedScore) { | ||||
|             return -1; | ||||
|         } else { | ||||
|             return 0; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public String toString() { | ||||
|         return new StringJoiner(", ", RouteNode.class.getSimpleName() + "[", "]").add("current=" + current) | ||||
|             .add("previous=" + previous).add("routeScore=" + routeScore).add("estimatedScore=" + estimatedScore) | ||||
|             .toString(); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,5 @@ | ||||
| package com.baeldung.algorithms.astar; | ||||
| 
 | ||||
| public interface Scorer<T extends GraphNode> { | ||||
|     double computeCost(T from, T to); | ||||
| } | ||||
| @ -0,0 +1,19 @@ | ||||
| package com.baeldung.algorithms.astar.underground; | ||||
| 
 | ||||
| import com.baeldung.algorithms.astar.Scorer; | ||||
| 
 | ||||
| public class HaversineScorer implements Scorer<Station> { | ||||
|     @Override | ||||
|     public double computeCost(Station from, Station to) { | ||||
|         double R = 6372.8; // In kilometers | ||||
| 
 | ||||
|         double dLat = Math.toRadians(to.getLatitude() - from.getLatitude()); | ||||
|         double dLon = Math.toRadians(to.getLongitude() - from.getLongitude()); | ||||
|         double lat1 = Math.toRadians(from.getLatitude()); | ||||
|         double lat2 = Math.toRadians(to.getLatitude()); | ||||
| 
 | ||||
|         double a = Math.pow(Math.sin(dLat / 2),2) + Math.pow(Math.sin(dLon / 2),2) * Math.cos(lat1) * Math.cos(lat2); | ||||
|         double c = 2 * Math.asin(Math.sqrt(a)); | ||||
|         return R * c; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,643 @@ | ||||
| package com.baeldung.algorithms.astar.underground; | ||||
| 
 | ||||
| import java.util.HashMap; | ||||
| import java.util.HashSet; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.Set; | ||||
| import java.util.stream.Collectors; | ||||
| import java.util.stream.Stream; | ||||
| 
 | ||||
| import com.baeldung.algorithms.astar.Graph; | ||||
| import com.baeldung.algorithms.astar.RouteFinder; | ||||
| import org.junit.Before; | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| public class RouteFinderIntegrationTest { | ||||
| 
 | ||||
|     private Graph<Station> underground; | ||||
| 
 | ||||
|     private RouteFinder<Station> routeFinder; | ||||
| 
 | ||||
|     @Before | ||||
|     public void setUp() throws Exception { | ||||
|         Set<Station> stations = new HashSet<>(); | ||||
|         Map<String, Set<String>> connections = new HashMap<>(); | ||||
| 
 | ||||
|         stations.add(new Station("1", "Acton Town", 51.5028, -0.2801)); | ||||
|         stations.add(new Station("2", "Aldgate", 51.5143, -0.0755)); | ||||
|         stations.add(new Station("3", "Aldgate East", 51.5154, -0.0726)); | ||||
|         stations.add(new Station("4", "All Saints", 51.5107, -0.013)); | ||||
|         stations.add(new Station("5", "Alperton", 51.5407, -0.2997)); | ||||
|         stations.add(new Station("6", "Amersham", 51.6736, -0.607)); | ||||
|         stations.add(new Station("7", "Angel", 51.5322, -0.1058)); | ||||
|         stations.add(new Station("8", "Archway", 51.5653, -0.1353)); | ||||
|         stations.add(new Station("9", "Arnos Grove", 51.6164, -0.1331)); | ||||
|         stations.add(new Station("10", "Arsenal", 51.5586, -0.1059)); | ||||
|         stations.add(new Station("11", "Baker Street", 51.5226, -0.1571)); | ||||
|         stations.add(new Station("12", "Balham", 51.4431, -0.1525)); | ||||
|         stations.add(new Station("13", "Bank", 51.5133, -0.0886)); | ||||
|         stations.add(new Station("14", "Barbican", 51.5204, -0.0979)); | ||||
|         stations.add(new Station("15", "Barking", 51.5396, 0.081)); | ||||
|         stations.add(new Station("16", "Barkingside", 51.5856, 0.0887)); | ||||
|         stations.add(new Station("17", "Barons Court", 51.4905, -0.2139)); | ||||
|         stations.add(new Station("18", "Bayswater", 51.5121, -0.1879)); | ||||
|         stations.add(new Station("19", "Beckton", 51.5148, 0.0613)); | ||||
|         stations.add(new Station("20", "Beckton Park", 51.5087, 0.055)); | ||||
|         stations.add(new Station("21", "Becontree", 51.5403, 0.127)); | ||||
|         stations.add(new Station("22", "Belsize Park", 51.5504, -0.1642)); | ||||
|         stations.add(new Station("23", "Bermondsey", 51.4979, -0.0637)); | ||||
|         stations.add(new Station("24", "Bethnal Green", 51.527, -0.0549)); | ||||
|         stations.add(new Station("25", "Blackfriars", 51.512, -0.1031)); | ||||
|         stations.add(new Station("26", "Blackhorse Road", 51.5867, -0.0417)); | ||||
|         stations.add(new Station("27", "Blackwall", 51.5079, -0.0066)); | ||||
|         stations.add(new Station("28", "Bond Street", 51.5142, -0.1494)); | ||||
|         stations.add(new Station("29", "Borough", 51.5011, -0.0943)); | ||||
|         stations.add(new Station("30", "Boston Manor", 51.4956, -0.325)); | ||||
|         stations.add(new Station("31", "Bounds Green", 51.6071, -0.1243)); | ||||
|         stations.add(new Station("32", "Bow Church", 51.5273, -0.0208)); | ||||
|         stations.add(new Station("33", "Bow Road", 51.5269, -0.0247)); | ||||
|         stations.add(new Station("34", "Brent Cross", 51.5766, -0.2136)); | ||||
|         stations.add(new Station("35", "Brixton", 51.4627, -0.1145)); | ||||
|         stations.add(new Station("36", "Bromley-By-Bow", 51.5248, -0.0119)); | ||||
|         stations.add(new Station("37", "Buckhurst Hill", 51.6266, 0.0471)); | ||||
|         stations.add(new Station("38", "Burnt Oak", 51.6028, -0.2641)); | ||||
|         stations.add(new Station("39", "Caledonian Road", 51.5481, -0.1188)); | ||||
|         stations.add(new Station("40", "Camden Town", 51.5392, -0.1426)); | ||||
|         stations.add(new Station("41", "Canada Water", 51.4982, -0.0502)); | ||||
|         stations.add(new Station("42", "Canary Wharf", 51.5051, -0.0209)); | ||||
|         stations.add(new Station("43", "Canning Town", 51.5147, 0.0082)); | ||||
|         stations.add(new Station("44", "Cannon Street", 51.5113, -0.0904)); | ||||
|         stations.add(new Station("45", "Canons Park", 51.6078, -0.2947)); | ||||
|         stations.add(new Station("46", "Chalfont & Latimer", 51.6679, -0.561)); | ||||
|         stations.add(new Station("47", "Chalk Farm", 51.5441, -0.1538)); | ||||
|         stations.add(new Station("48", "Chancery Lane", 51.5185, -0.1111)); | ||||
|         stations.add(new Station("49", "Charing Cross", 51.508, -0.1247)); | ||||
|         stations.add(new Station("50", "Chesham", 51.7052, -0.611)); | ||||
|         stations.add(new Station("51", "Chigwell", 51.6177, 0.0755)); | ||||
|         stations.add(new Station("52", "Chiswick Park", 51.4946, -0.2678)); | ||||
|         stations.add(new Station("53", "Chorleywood", 51.6543, -0.5183)); | ||||
|         stations.add(new Station("54", "Clapham Common", 51.4618, -0.1384)); | ||||
|         stations.add(new Station("55", "Clapham North", 51.4649, -0.1299)); | ||||
|         stations.add(new Station("56", "Clapham South", 51.4527, -0.148)); | ||||
|         stations.add(new Station("57", "Cockfosters", 51.6517, -0.1496)); | ||||
|         stations.add(new Station("58", "Colindale", 51.5955, -0.2502)); | ||||
|         stations.add(new Station("59", "Colliers Wood", 51.418, -0.1778)); | ||||
|         stations.add(new Station("60", "Covent Garden", 51.5129, -0.1243)); | ||||
|         stations.add(new Station("61", "Crossharbour & London Arena", 51.4957, -0.0144)); | ||||
|         stations.add(new Station("62", "Croxley", 51.647, -0.4412)); | ||||
|         stations.add(new Station("63", "Custom House", 51.5095, 0.0276)); | ||||
|         stations.add(new Station("64", "Cutty Sark", 51.4827, -0.0096)); | ||||
|         stations.add(new Station("65", "Cyprus", 51.5085, 0.064)); | ||||
|         stations.add(new Station("66", "Dagenham East", 51.5443, 0.1655)); | ||||
|         stations.add(new Station("67", "Dagenham Heathway", 51.5417, 0.1469)); | ||||
|         stations.add(new Station("68", "Debden", 51.6455, 0.0838)); | ||||
|         stations.add(new Station("69", "Deptford Bridge", 51.474, -0.0216)); | ||||
|         stations.add(new Station("70", "Devons Road", 51.5223, -0.0173)); | ||||
|         stations.add(new Station("71", "Dollis Hill", 51.552, -0.2387)); | ||||
|         stations.add(new Station("72", "Ealing Broadway", 51.5152, -0.3017)); | ||||
|         stations.add(new Station("73", "Ealing Common", 51.5101, -0.2882)); | ||||
|         stations.add(new Station("74", "Earl's Court", 51.492, -0.1973)); | ||||
|         stations.add(new Station("75", "Eastcote", 51.5765, -0.397)); | ||||
|         stations.add(new Station("76", "East Acton", 51.5168, -0.2474)); | ||||
|         stations.add(new Station("77", "East Finchley", 51.5874, -0.165)); | ||||
|         stations.add(new Station("78", "East Ham", 51.5394, 0.0518)); | ||||
|         stations.add(new Station("79", "East India", 51.5093, -0.0021)); | ||||
|         stations.add(new Station("80", "East Putney", 51.4586, -0.2112)); | ||||
|         stations.add(new Station("81", "Edgware", 51.6137, -0.275)); | ||||
|         stations.add(new Station("82", "Edgware Road (B)", 51.5199, -0.1679)); | ||||
|         stations.add(new Station("83", "Edgware Road (C)", 51.5203, -0.17)); | ||||
|         stations.add(new Station("84", "Elephant & Castle", 51.4943, -0.1001)); | ||||
|         stations.add(new Station("85", "Elm Park", 51.5496, 0.1977)); | ||||
|         stations.add(new Station("86", "Elverson Road", 51.4693, -0.0174)); | ||||
|         stations.add(new Station("87", "Embankment", 51.5074, -0.1223)); | ||||
|         stations.add(new Station("88", "Epping", 51.6937, 0.1139)); | ||||
|         stations.add(new Station("89", "Euston", 51.5282, -0.1337)); | ||||
|         stations.add(new Station("90", "Euston Square", 51.526, -0.1359)); | ||||
|         stations.add(new Station("91", "Fairlop", 51.596, 0.0912)); | ||||
|         stations.add(new Station("92", "Farringdon", 51.5203, -0.1053)); | ||||
|         stations.add(new Station("93", "Finchley Central", 51.6012, -0.1932)); | ||||
|         stations.add(new Station("94", "Finchley Road", 51.5472, -0.1803)); | ||||
|         stations.add(new Station("95", "Finsbury Park", 51.5642, -0.1065)); | ||||
|         stations.add(new Station("96", "Fulham Broadway", 51.4804, -0.195)); | ||||
|         stations.add(new Station("97", "Gallions Reach", 51.5096, 0.0716)); | ||||
|         stations.add(new Station("98", "Gants Hill", 51.5765, 0.0663)); | ||||
|         stations.add(new Station("99", "Gloucester Road", 51.4945, -0.1829)); | ||||
|         stations.add(new Station("100", "Golders Green", 51.5724, -0.1941)); | ||||
|         stations.add(new Station("101", "Goldhawk Road", 51.5018, -0.2267)); | ||||
|         stations.add(new Station("102", "Goodge Street", 51.5205, -0.1347)); | ||||
|         stations.add(new Station("103", "Grange Hill", 51.6132, 0.0923)); | ||||
|         stations.add(new Station("104", "Great Portland Street", 51.5238, -0.1439)); | ||||
|         stations.add(new Station("105", "Greenford", 51.5423, -0.3456)); | ||||
|         stations.add(new Station("106", "Greenwich", 51.4781, -0.0149)); | ||||
|         stations.add(new Station("107", "Green Park", 51.5067, -0.1428)); | ||||
|         stations.add(new Station("108", "Gunnersbury", 51.4915, -0.2754)); | ||||
|         stations.add(new Station("109", "Hainault", 51.603, 0.0933)); | ||||
|         stations.add(new Station("110", "Hammersmith", 51.4936, -0.2251)); | ||||
|         stations.add(new Station("111", "Hampstead", 51.5568, -0.178)); | ||||
|         stations.add(new Station("112", "Hanger Lane", 51.5302, -0.2933)); | ||||
|         stations.add(new Station("113", "Harlesden", 51.5362, -0.2575)); | ||||
|         stations.add(new Station("114", "Harrow & Wealdston", 51.5925, -0.3351)); | ||||
|         stations.add(new Station("115", "Harrow-on-the-Hill", 51.5793, -0.3366)); | ||||
|         stations.add(new Station("116", "Hatton Cross", 51.4669, -0.4227)); | ||||
|         stations.add(new Station("117", "Heathrow Terminals 1, 2 & 3", 51.4713, -0.4524)); | ||||
|         stations.add(new Station("118", "Heathrow Terminal 4", 51.4598, -0.4476)); | ||||
|         stations.add(new Station("119", "Hendon Central", 51.5829, -0.2259)); | ||||
|         stations.add(new Station("120", "Heron Quays", 51.5033, -0.0215)); | ||||
|         stations.add(new Station("121", "High Barnet", 51.6503, -0.1943)); | ||||
|         stations.add(new Station("122", "High Street Kensington", 51.5009, -0.1925)); | ||||
|         stations.add(new Station("123", "Highbury & Islington", 51.546, -0.104)); | ||||
|         stations.add(new Station("124", "Highgate", 51.5777, -0.1458)); | ||||
|         stations.add(new Station("125", "Hillingdon", 51.5538, -0.4499)); | ||||
|         stations.add(new Station("126", "Holborn", 51.5174, -0.12)); | ||||
|         stations.add(new Station("127", "Holland Park", 51.5075, -0.206)); | ||||
|         stations.add(new Station("128", "Holloway Road", 51.5526, -0.1132)); | ||||
|         stations.add(new Station("129", "Hornchurch", 51.5539, 0.2184)); | ||||
|         stations.add(new Station("130", "Hounslow Central", 51.4713, -0.3665)); | ||||
|         stations.add(new Station("131", "Hounslow East", 51.4733, -0.3564)); | ||||
|         stations.add(new Station("132", "Hounslow West", 51.4734, -0.3855)); | ||||
|         stations.add(new Station("133", "Hyde Park Corner", 51.5027, -0.1527)); | ||||
|         stations.add(new Station("134", "Ickenham", 51.5619, -0.4421)); | ||||
|         stations.add(new Station("135", "Island Gardens", 51.4871, -0.0101)); | ||||
|         stations.add(new Station("136", "Kennington", 51.4884, -0.1053)); | ||||
|         stations.add(new Station("137", "Kensal Green", 51.5304, -0.225)); | ||||
|         stations.add(new Station("138", "Kensington (Olympia)", 51.4983, -0.2106)); | ||||
|         stations.add(new Station("139", "Kentish Town", 51.5507, -0.1402)); | ||||
|         stations.add(new Station("140", "Kenton", 51.5816, -0.3162)); | ||||
|         stations.add(new Station("141", "Kew Gardens", 51.477, -0.285)); | ||||
|         stations.add(new Station("142", "Kilburn", 51.5471, -0.2047)); | ||||
|         stations.add(new Station("143", "Kilburn Park", 51.5351, -0.1939)); | ||||
|         stations.add(new Station("144", "Kingsbury", 51.5846, -0.2786)); | ||||
|         stations.add(new Station("145", "King's Cross St. Pancras", 51.5308, -0.1238)); | ||||
|         stations.add(new Station("146", "Knightsbridge", 51.5015, -0.1607)); | ||||
|         stations.add(new Station("147", "Ladbroke Grove", 51.5172, -0.2107)); | ||||
|         stations.add(new Station("148", "Lambeth North", 51.4991, -0.1115)); | ||||
|         stations.add(new Station("149", "Lancaster Gate", 51.5119, -0.1756)); | ||||
|         stations.add(new Station("150", "Latimer Road", 51.5139, -0.2172)); | ||||
|         stations.add(new Station("151", "Leicester Square", 51.5113, -0.1281)); | ||||
|         stations.add(new Station("152", "Lewisham", 51.4657, -0.0142)); | ||||
|         stations.add(new Station("153", "Leyton", 51.5566, -0.0053)); | ||||
|         stations.add(new Station("154", "Leytonstone", 51.5683, 0.0083)); | ||||
|         stations.add(new Station("155", "Limehouse", 51.5123, -0.0396)); | ||||
|         stations.add(new Station("156", "Liverpool Street", 51.5178, -0.0823)); | ||||
|         stations.add(new Station("157", "London Bridge", 51.5052, -0.0864)); | ||||
|         stations.add(new Station("158", "Loughton", 51.6412, 0.0558)); | ||||
|         stations.add(new Station("159", "Maida Vale", 51.53, -0.1854)); | ||||
|         stations.add(new Station("160", "Manor House", 51.5712, -0.0958)); | ||||
|         stations.add(new Station("161", "Mansion House", 51.5122, -0.094)); | ||||
|         stations.add(new Station("162", "Marble Arch", 51.5136, -0.1586)); | ||||
|         stations.add(new Station("163", "Marylebone", 51.5225, -0.1631)); | ||||
|         stations.add(new Station("164", "Mile End", 51.5249, -0.0332)); | ||||
|         stations.add(new Station("165", "Mill Hill East", 51.6082, -0.2103)); | ||||
|         stations.add(new Station("166", "Monument", 51.5108, -0.0863)); | ||||
|         stations.add(new Station("167", "Moorgate", 51.5186, -0.0886)); | ||||
|         stations.add(new Station("168", "Moor Park", 51.6294, -0.432)); | ||||
|         stations.add(new Station("169", "Morden", 51.4022, -0.1948)); | ||||
|         stations.add(new Station("170", "Mornington Crescent", 51.5342, -0.1387)); | ||||
|         stations.add(new Station("171", "Mudchute", 51.4902, -0.0145)); | ||||
|         stations.add(new Station("172", "Neasden", 51.5542, -0.2503)); | ||||
|         stations.add(new Station("173", "Newbury Park", 51.5756, 0.0899)); | ||||
|         stations.add(new Station("174", "New Cross", 51.4767, -0.0327)); | ||||
|         stations.add(new Station("175", "New Cross Gate", 51.4757, -0.0402)); | ||||
|         stations.add(new Station("176", "Northfields", 51.4995, -0.3142)); | ||||
|         stations.add(new Station("177", "Northolt", 51.5483, -0.3687)); | ||||
|         stations.add(new Station("178", "Northwick Park", 51.5784, -0.3184)); | ||||
|         stations.add(new Station("179", "Northwood", 51.6111, -0.424)); | ||||
|         stations.add(new Station("180", "Northwood Hills", 51.6004, -0.4092)); | ||||
|         stations.add(new Station("181", "North Acton", 51.5237, -0.2597)); | ||||
|         stations.add(new Station("182", "North Ealing", 51.5175, -0.2887)); | ||||
|         stations.add(new Station("183", "North Greenwich", 51.5005, 0.0039)); | ||||
|         stations.add(new Station("184", "North Harrow", 51.5846, -0.3626)); | ||||
|         stations.add(new Station("185", "North Wembley", 51.5621, -0.3034)); | ||||
|         stations.add(new Station("186", "Notting Hill Gate", 51.5094, -0.1967)); | ||||
|         stations.add(new Station("187", "Oakwood", 51.6476, -0.1318)); | ||||
|         stations.add(new Station("188", "Old Street", 51.5263, -0.0873)); | ||||
|         stations.add(new Station("189", "Osterley", 51.4813, -0.3522)); | ||||
|         stations.add(new Station("190", "Oval", 51.4819, -0.113)); | ||||
|         stations.add(new Station("191", "Oxford Circus", 51.515, -0.1415)); | ||||
|         stations.add(new Station("192", "Paddington", 51.5154, -0.1755)); | ||||
|         stations.add(new Station("193", "Park Royal", 51.527, -0.2841)); | ||||
|         stations.add(new Station("194", "Parsons Green", 51.4753, -0.2011)); | ||||
|         stations.add(new Station("195", "Perivale", 51.5366, -0.3232)); | ||||
|         stations.add(new Station("196", "Picadilly Circus", 51.5098, -0.1342)); | ||||
|         stations.add(new Station("197", "Pimlico", 51.4893, -0.1334)); | ||||
|         stations.add(new Station("198", "Pinner", 51.5926, -0.3805)); | ||||
|         stations.add(new Station("199", "Plaistow", 51.5313, 0.0172)); | ||||
|         stations.add(new Station("200", "Poplar", 51.5077, -0.0173)); | ||||
|         stations.add(new Station("201", "Preston Road", 51.572, -0.2954)); | ||||
|         stations.add(new Station("202", "Prince Regent", 51.5093, 0.0336)); | ||||
|         stations.add(new Station("203", "Pudding Mill Lane", 51.5343, -0.0139)); | ||||
|         stations.add(new Station("204", "Putney Bridge", 51.4682, -0.2089)); | ||||
|         stations.add(new Station("205", "Queen's Park", 51.5341, -0.2047)); | ||||
|         stations.add(new Station("206", "Queensbury", 51.5942, -0.2861)); | ||||
|         stations.add(new Station("207", "Queensway", 51.5107, -0.1877)); | ||||
|         stations.add(new Station("208", "Ravenscourt Park", 51.4942, -0.2359)); | ||||
|         stations.add(new Station("209", "Rayners Lane", 51.5753, -0.3714)); | ||||
|         stations.add(new Station("210", "Redbridge", 51.5763, 0.0454)); | ||||
|         stations.add(new Station("211", "Regent's Park", 51.5234, -0.1466)); | ||||
|         stations.add(new Station("212", "Richmond", 51.4633, -0.3013)); | ||||
|         stations.add(new Station("213", "Rickmansworth", 51.6404, -0.4733)); | ||||
|         stations.add(new Station("214", "Roding Valley", 51.6171, 0.0439)); | ||||
|         stations.add(new Station("215", "Rotherhithe", 51.501, -0.0525)); | ||||
|         stations.add(new Station("216", "Royal Albert", 51.5084, 0.0465)); | ||||
|         stations.add(new Station("217", "Royal Oak", 51.519, -0.188)); | ||||
|         stations.add(new Station("218", "Royal Victoria", 51.5091, 0.0181)); | ||||
|         stations.add(new Station("219", "Ruislip", 51.5715, -0.4213)); | ||||
|         stations.add(new Station("220", "Ruislip Gardens", 51.5606, -0.4103)); | ||||
|         stations.add(new Station("221", "Ruislip Manor", 51.5732, -0.4125)); | ||||
|         stations.add(new Station("222", "Russell Square", 51.523, -0.1244)); | ||||
|         stations.add(new Station("223", "Seven Sisters", 51.5822, -0.0749)); | ||||
|         stations.add(new Station("224", "Shadwell", 51.5117, -0.056)); | ||||
|         stations.add(new Station("225", "Shepherd's Bush (C)", 51.5046, -0.2187)); | ||||
|         stations.add(new Station("226", "Shepherd's Bush (H)", 51.5058, -0.2265)); | ||||
|         stations.add(new Station("227", "Shoreditch", 51.5227, -0.0708)); | ||||
|         stations.add(new Station("228", "Sloane Square", 51.4924, -0.1565)); | ||||
|         stations.add(new Station("229", "Snaresbrook", 51.5808, 0.0216)); | ||||
|         stations.add(new Station("230", "Southfields", 51.4454, -0.2066)); | ||||
|         stations.add(new Station("231", "Southgate", 51.6322, -0.128)); | ||||
|         stations.add(new Station("232", "Southwark", 51.501, -0.1052)); | ||||
|         stations.add(new Station("233", "South Ealing", 51.5011, -0.3072)); | ||||
|         stations.add(new Station("234", "South Harrow", 51.5646, -0.3521)); | ||||
|         stations.add(new Station("235", "South Kensington", 51.4941, -0.1738)); | ||||
|         stations.add(new Station("236", "South Kenton", 51.5701, -0.3081)); | ||||
|         stations.add(new Station("237", "South Quay", 51.5007, -0.0191)); | ||||
|         stations.add(new Station("238", "South Ruislip", 51.5569, -0.3988)); | ||||
|         stations.add(new Station("239", "South Wimbledon", 51.4154, -0.1919)); | ||||
|         stations.add(new Station("240", "South Woodford", 51.5917, 0.0275)); | ||||
|         stations.add(new Station("241", "Stamford Brook", 51.495, -0.2459)); | ||||
|         stations.add(new Station("242", "Stanmore", 51.6194, -0.3028)); | ||||
|         stations.add(new Station("243", "Stepney Green", 51.5221, -0.047)); | ||||
|         stations.add(new Station("244", "Stockwell", 51.4723, -0.123)); | ||||
|         stations.add(new Station("245", "Stonebridge Park", 51.5439, -0.2759)); | ||||
|         stations.add(new Station("246", "Stratford", 51.5416, -0.0042)); | ||||
|         stations.add(new Station("247", "St. James's Park", 51.4994, -0.1335)); | ||||
|         stations.add(new Station("248", "St. John's Wood", 51.5347, -0.174)); | ||||
|         stations.add(new Station("249", "St. Paul's", 51.5146, -0.0973)); | ||||
|         stations.add(new Station("250", "Sudbury Hill", 51.5569, -0.3366)); | ||||
|         stations.add(new Station("251", "Sudbury Town", 51.5507, -0.3156)); | ||||
|         stations.add(new Station("252", "Surrey Quays", 51.4933, -0.0478)); | ||||
|         stations.add(new Station("253", "Swiss Cottage", 51.5432, -0.1738)); | ||||
|         stations.add(new Station("254", "Temple", 51.5111, -0.1141)); | ||||
|         stations.add(new Station("255", "Theydon Bois", 51.6717, 0.1033)); | ||||
|         stations.add(new Station("256", "Tooting Bec", 51.4361, -0.1598)); | ||||
|         stations.add(new Station("257", "Tooting Broadway", 51.4275, -0.168)); | ||||
|         stations.add(new Station("258", "Tottenham Court Road", 51.5165, -0.131)); | ||||
|         stations.add(new Station("259", "Tottenham Hale", 51.5882, -0.0594)); | ||||
|         stations.add(new Station("260", "Totteridge & Whetstone", 51.6302, -0.1791)); | ||||
|         stations.add(new Station("261", "Tower Gateway", 51.5106, -0.0743)); | ||||
|         stations.add(new Station("262", "Tower Hill", 51.5098, -0.0766)); | ||||
|         stations.add(new Station("263", "Tufnell Park", 51.5567, -0.1374)); | ||||
|         stations.add(new Station("264", "Turnham Green", 51.4951, -0.2547)); | ||||
|         stations.add(new Station("265", "Turnpike Lane", 51.5904, -0.1028)); | ||||
|         stations.add(new Station("266", "Upminster", 51.559, 0.251)); | ||||
|         stations.add(new Station("267", "Upminster Bridge", 51.5582, 0.2343)); | ||||
|         stations.add(new Station("268", "Upney", 51.5385, 0.1014)); | ||||
|         stations.add(new Station("269", "Upton Park", 51.5352, 0.0343)); | ||||
|         stations.add(new Station("270", "Uxbridge", 51.5463, -0.4786)); | ||||
|         stations.add(new Station("271", "Vauxhall", 51.4861, -0.1253)); | ||||
|         stations.add(new Station("272", "Victoria", 51.4965, -0.1447)); | ||||
|         stations.add(new Station("273", "Walthamstow Central", 51.583, -0.0195)); | ||||
|         stations.add(new Station("274", "Wanstead", 51.5775, 0.0288)); | ||||
|         stations.add(new Station("275", "Wapping", 51.5043, -0.0558)); | ||||
|         stations.add(new Station("276", "Warren Street", 51.5247, -0.1384)); | ||||
|         stations.add(new Station("277", "Warwick Avenue", 51.5235, -0.1835)); | ||||
|         stations.add(new Station("278", "Waterloo", 51.5036, -0.1143)); | ||||
|         stations.add(new Station("279", "Watford", 51.6573, -0.4177)); | ||||
|         stations.add(new Station("280", "Wembley Central", 51.5519, -0.2963)); | ||||
|         stations.add(new Station("281", "Wembley Park", 51.5635, -0.2795)); | ||||
|         stations.add(new Station("282", "Westbourne Park", 51.521, -0.2011)); | ||||
|         stations.add(new Station("283", "Westferry", 51.5097, -0.0265)); | ||||
|         stations.add(new Station("284", "Westminster", 51.501, -0.1254)); | ||||
|         stations.add(new Station("285", "West Acton", 51.518, -0.2809)); | ||||
|         stations.add(new Station("286", "West Brompton", 51.4872, -0.1953)); | ||||
|         stations.add(new Station("287", "West Finchley", 51.6095, -0.1883)); | ||||
|         stations.add(new Station("288", "West Ham", 51.5287, 0.0056)); | ||||
|         stations.add(new Station("289", "West Hampstead", 51.5469, -0.1906)); | ||||
|         stations.add(new Station("290", "West Harrow", 51.5795, -0.3533)); | ||||
|         stations.add(new Station("291", "West India Quay", 51.507, -0.0203)); | ||||
|         stations.add(new Station("292", "West Kensington", 51.4907, -0.2065)); | ||||
|         stations.add(new Station("293", "West Ruislip", 51.5696, -0.4376)); | ||||
|         stations.add(new Station("294", "Whitechapel", 51.5194, -0.0612)); | ||||
|         stations.add(new Station("295", "White City", 51.512, -0.2239)); | ||||
|         stations.add(new Station("296", "Willesden Green", 51.5492, -0.2215)); | ||||
|         stations.add(new Station("297", "Willesden Junction", 51.5326, -0.2478)); | ||||
|         stations.add(new Station("298", "Wimbledon", 51.4214, -0.2064)); | ||||
|         stations.add(new Station("299", "Wimbledon Park", 51.4343, -0.1992)); | ||||
|         stations.add(new Station("300", "Woodford", 51.607, 0.0341)); | ||||
|         stations.add(new Station("301", "Woodside Park", 51.6179, -0.1856)); | ||||
|         stations.add(new Station("302", "Wood Green", 51.5975, -0.1097)); | ||||
| 
 | ||||
|         connections.put("1", Stream.of("52","73","73","233","264").collect(Collectors.toSet())); | ||||
|         connections.put("2", Stream.of("156","262","156").collect(Collectors.toSet())); | ||||
|         connections.put("3", Stream.of("262","294","156","294").collect(Collectors.toSet())); | ||||
|         connections.put("4", Stream.of("70","200").collect(Collectors.toSet())); | ||||
|         connections.put("5", Stream.of("193","251").collect(Collectors.toSet())); | ||||
|         connections.put("6", Stream.of("46").collect(Collectors.toSet())); | ||||
|         connections.put("7", Stream.of("145","188").collect(Collectors.toSet())); | ||||
|         connections.put("8", Stream.of("124","263").collect(Collectors.toSet())); | ||||
|         connections.put("9", Stream.of("31","231").collect(Collectors.toSet())); | ||||
|         connections.put("10", Stream.of("95","128").collect(Collectors.toSet())); | ||||
|         connections.put("11", Stream.of("163","211","83","104","83","104","28","248","94","104").collect(Collectors.toSet())); | ||||
|         connections.put("12", Stream.of("56","256").collect(Collectors.toSet())); | ||||
|         connections.put("13", Stream.of("156","249","224","157","167","278").collect(Collectors.toSet())); | ||||
|         connections.put("14", Stream.of("92","167","92","167","92","167").collect(Collectors.toSet())); | ||||
|         connections.put("15", Stream.of("78","268","78").collect(Collectors.toSet())); | ||||
|         connections.put("16", Stream.of("91","173").collect(Collectors.toSet())); | ||||
|         connections.put("17", Stream.of("110","292","74","110").collect(Collectors.toSet())); | ||||
|         connections.put("18", Stream.of("186","192","186","192").collect(Collectors.toSet())); | ||||
|         connections.put("19", Stream.of("97").collect(Collectors.toSet())); | ||||
|         connections.put("20", Stream.of("65","216").collect(Collectors.toSet())); | ||||
|         connections.put("21", Stream.of("67","268").collect(Collectors.toSet())); | ||||
|         connections.put("22", Stream.of("47","111").collect(Collectors.toSet())); | ||||
|         connections.put("23", Stream.of("41","157").collect(Collectors.toSet())); | ||||
|         connections.put("24", Stream.of("156","164").collect(Collectors.toSet())); | ||||
|         connections.put("25", Stream.of("161","254","161","254").collect(Collectors.toSet())); | ||||
|         connections.put("26", Stream.of("259","273").collect(Collectors.toSet())); | ||||
|         connections.put("27", Stream.of("79","200").collect(Collectors.toSet())); | ||||
|         connections.put("28", Stream.of("162","191","11","107").collect(Collectors.toSet())); | ||||
|         connections.put("29", Stream.of("84","157").collect(Collectors.toSet())); | ||||
|         connections.put("30", Stream.of("176","189").collect(Collectors.toSet())); | ||||
|         connections.put("31", Stream.of("9","302").collect(Collectors.toSet())); | ||||
|         connections.put("32", Stream.of("70","203").collect(Collectors.toSet())); | ||||
|         connections.put("33", Stream.of("36","164","36","164").collect(Collectors.toSet())); | ||||
|         connections.put("34", Stream.of("100","119").collect(Collectors.toSet())); | ||||
|         connections.put("35", Stream.of("244").collect(Collectors.toSet())); | ||||
|         connections.put("36", Stream.of("33","288","33","288").collect(Collectors.toSet())); | ||||
|         connections.put("37", Stream.of("158","300").collect(Collectors.toSet())); | ||||
|         connections.put("38", Stream.of("58","81").collect(Collectors.toSet())); | ||||
|         connections.put("39", Stream.of("128","145").collect(Collectors.toSet())); | ||||
|         connections.put("40", Stream.of("47","89","139","170").collect(Collectors.toSet())); | ||||
|         connections.put("41", Stream.of("215","252","23","42").collect(Collectors.toSet())); | ||||
|         connections.put("42", Stream.of("120","291","41","183").collect(Collectors.toSet())); | ||||
|         connections.put("43", Stream.of("79","218","183","288").collect(Collectors.toSet())); | ||||
|         connections.put("44", Stream.of("161","166","161","166").collect(Collectors.toSet())); | ||||
|         connections.put("45", Stream.of("206","242").collect(Collectors.toSet())); | ||||
|         connections.put("46", Stream.of("6","50","53").collect(Collectors.toSet())); | ||||
|         connections.put("47", Stream.of("22","40").collect(Collectors.toSet())); | ||||
|         connections.put("48", Stream.of("126","249").collect(Collectors.toSet())); | ||||
|         connections.put("49", Stream.of("87","196","87","151").collect(Collectors.toSet())); | ||||
|         connections.put("50", Stream.of("46").collect(Collectors.toSet())); | ||||
|         connections.put("51", Stream.of("103","214").collect(Collectors.toSet())); | ||||
|         connections.put("52", Stream.of("1","264").collect(Collectors.toSet())); | ||||
|         connections.put("53", Stream.of("46","213").collect(Collectors.toSet())); | ||||
|         connections.put("54", Stream.of("55","56").collect(Collectors.toSet())); | ||||
|         connections.put("55", Stream.of("54","244").collect(Collectors.toSet())); | ||||
|         connections.put("56", Stream.of("12","54").collect(Collectors.toSet())); | ||||
|         connections.put("57", Stream.of("187").collect(Collectors.toSet())); | ||||
|         connections.put("58", Stream.of("38","119").collect(Collectors.toSet())); | ||||
|         connections.put("59", Stream.of("239","257").collect(Collectors.toSet())); | ||||
|         connections.put("60", Stream.of("126","151").collect(Collectors.toSet())); | ||||
|         connections.put("61", Stream.of("171","237").collect(Collectors.toSet())); | ||||
|         connections.put("62", Stream.of("168","279").collect(Collectors.toSet())); | ||||
|         connections.put("63", Stream.of("202","218").collect(Collectors.toSet())); | ||||
|         connections.put("64", Stream.of("106","135").collect(Collectors.toSet())); | ||||
|         connections.put("65", Stream.of("20","97").collect(Collectors.toSet())); | ||||
|         connections.put("66", Stream.of("67","85").collect(Collectors.toSet())); | ||||
|         connections.put("67", Stream.of("21","66").collect(Collectors.toSet())); | ||||
|         connections.put("68", Stream.of("158","255").collect(Collectors.toSet())); | ||||
|         connections.put("69", Stream.of("86","106").collect(Collectors.toSet())); | ||||
|         connections.put("70", Stream.of("4","32").collect(Collectors.toSet())); | ||||
|         connections.put("71", Stream.of("172","296").collect(Collectors.toSet())); | ||||
|         connections.put("72", Stream.of("285","73").collect(Collectors.toSet())); | ||||
|         connections.put("73", Stream.of("72","1","1","182").collect(Collectors.toSet())); | ||||
|         connections.put("74", Stream.of("99","122","138","286","292","17","99").collect(Collectors.toSet())); | ||||
|         connections.put("75", Stream.of("209","221","209","221").collect(Collectors.toSet())); | ||||
|         connections.put("76", Stream.of("181","295").collect(Collectors.toSet())); | ||||
|         connections.put("77", Stream.of("93","124").collect(Collectors.toSet())); | ||||
|         connections.put("78", Stream.of("15","269","15","269").collect(Collectors.toSet())); | ||||
|         connections.put("79", Stream.of("27","43").collect(Collectors.toSet())); | ||||
|         connections.put("80", Stream.of("204","230").collect(Collectors.toSet())); | ||||
|         connections.put("81", Stream.of("38").collect(Collectors.toSet())); | ||||
|         connections.put("82", Stream.of("163","192").collect(Collectors.toSet())); | ||||
|         connections.put("83", Stream.of("11","192","192","11","192").collect(Collectors.toSet())); | ||||
|         connections.put("84", Stream.of("148","29","136").collect(Collectors.toSet())); | ||||
|         connections.put("85", Stream.of("66","129").collect(Collectors.toSet())); | ||||
|         connections.put("86", Stream.of("69","152").collect(Collectors.toSet())); | ||||
|         connections.put("87", Stream.of("49","278","254","284","254","284","49","278").collect(Collectors.toSet())); | ||||
|         connections.put("88", Stream.of("255").collect(Collectors.toSet())); | ||||
|         connections.put("89", Stream.of("40","145","170","276","145","276").collect(Collectors.toSet())); | ||||
|         connections.put("90", Stream.of("104","145","104","145","104","145").collect(Collectors.toSet())); | ||||
|         connections.put("91", Stream.of("16","109").collect(Collectors.toSet())); | ||||
|         connections.put("92", Stream.of("14","145","14","145","14","145").collect(Collectors.toSet())); | ||||
|         connections.put("93", Stream.of("77","165","287").collect(Collectors.toSet())); | ||||
|         connections.put("94", Stream.of("253","289","11","281").collect(Collectors.toSet())); | ||||
|         connections.put("95", Stream.of("10","160","123","223").collect(Collectors.toSet())); | ||||
|         connections.put("96", Stream.of("194","286").collect(Collectors.toSet())); | ||||
|         connections.put("97", Stream.of("19","65").collect(Collectors.toSet())); | ||||
|         connections.put("98", Stream.of("173","210").collect(Collectors.toSet())); | ||||
|         connections.put("99", Stream.of("122","235","74","235","74","235").collect(Collectors.toSet())); | ||||
|         connections.put("100", Stream.of("34","111").collect(Collectors.toSet())); | ||||
|         connections.put("101", Stream.of("110","226").collect(Collectors.toSet())); | ||||
|         connections.put("102", Stream.of("258","276").collect(Collectors.toSet())); | ||||
|         connections.put("103", Stream.of("51","109").collect(Collectors.toSet())); | ||||
|         connections.put("104", Stream.of("11","90","11","90","11","90").collect(Collectors.toSet())); | ||||
|         connections.put("105", Stream.of("177","195").collect(Collectors.toSet())); | ||||
|         connections.put("106", Stream.of("64","69").collect(Collectors.toSet())); | ||||
|         connections.put("107", Stream.of("28","284","133","196","191","272").collect(Collectors.toSet())); | ||||
|         connections.put("108", Stream.of("141","264").collect(Collectors.toSet())); | ||||
|         connections.put("109", Stream.of("91","103").collect(Collectors.toSet())); | ||||
|         connections.put("110", Stream.of("17","208","101","17","264").collect(Collectors.toSet())); | ||||
|         connections.put("111", Stream.of("22","100").collect(Collectors.toSet())); | ||||
|         connections.put("112", Stream.of("181","195").collect(Collectors.toSet())); | ||||
|         connections.put("113", Stream.of("245","297").collect(Collectors.toSet())); | ||||
|         connections.put("114", Stream.of("140").collect(Collectors.toSet())); | ||||
|         connections.put("115", Stream.of("178","184","290").collect(Collectors.toSet())); | ||||
|         connections.put("116", Stream.of("117","118","132").collect(Collectors.toSet())); | ||||
|         connections.put("117", Stream.of("116","118").collect(Collectors.toSet())); | ||||
|         connections.put("118", Stream.of("116","117").collect(Collectors.toSet())); | ||||
|         connections.put("119", Stream.of("34","58").collect(Collectors.toSet())); | ||||
|         connections.put("120", Stream.of("42","237").collect(Collectors.toSet())); | ||||
|         connections.put("121", Stream.of("260").collect(Collectors.toSet())); | ||||
|         connections.put("122", Stream.of("99","186","74","186").collect(Collectors.toSet())); | ||||
|         connections.put("123", Stream.of("95","145").collect(Collectors.toSet())); | ||||
|         connections.put("124", Stream.of("8","77").collect(Collectors.toSet())); | ||||
|         connections.put("125", Stream.of("134","270","134","270").collect(Collectors.toSet())); | ||||
|         connections.put("126", Stream.of("48","258","60","222").collect(Collectors.toSet())); | ||||
|         connections.put("127", Stream.of("186","225").collect(Collectors.toSet())); | ||||
|         connections.put("128", Stream.of("10","39").collect(Collectors.toSet())); | ||||
|         connections.put("129", Stream.of("85","267").collect(Collectors.toSet())); | ||||
|         connections.put("130", Stream.of("131","132").collect(Collectors.toSet())); | ||||
|         connections.put("131", Stream.of("130","189").collect(Collectors.toSet())); | ||||
|         connections.put("132", Stream.of("116","130").collect(Collectors.toSet())); | ||||
|         connections.put("133", Stream.of("107","146").collect(Collectors.toSet())); | ||||
|         connections.put("134", Stream.of("125","219","125","219").collect(Collectors.toSet())); | ||||
|         connections.put("135", Stream.of("64","171").collect(Collectors.toSet())); | ||||
|         connections.put("136", Stream.of("84","190","278").collect(Collectors.toSet())); | ||||
|         connections.put("137", Stream.of("205","297").collect(Collectors.toSet())); | ||||
|         connections.put("138", Stream.of("74").collect(Collectors.toSet())); | ||||
|         connections.put("139", Stream.of("40","263").collect(Collectors.toSet())); | ||||
|         connections.put("140", Stream.of("114","236").collect(Collectors.toSet())); | ||||
|         connections.put("141", Stream.of("108","212").collect(Collectors.toSet())); | ||||
|         connections.put("142", Stream.of("289","296").collect(Collectors.toSet())); | ||||
|         connections.put("143", Stream.of("159","205").collect(Collectors.toSet())); | ||||
|         connections.put("144", Stream.of("206","281").collect(Collectors.toSet())); | ||||
|         connections.put("145", Stream.of("90","92","90","92","90","92","7","89","39","222","89","123").collect(Collectors.toSet())); | ||||
|         connections.put("146", Stream.of("133","235").collect(Collectors.toSet())); | ||||
|         connections.put("147", Stream.of("150","282").collect(Collectors.toSet())); | ||||
|         connections.put("148", Stream.of("84","278").collect(Collectors.toSet())); | ||||
|         connections.put("149", Stream.of("162","207").collect(Collectors.toSet())); | ||||
|         connections.put("150", Stream.of("147","226").collect(Collectors.toSet())); | ||||
|         connections.put("151", Stream.of("49","258","60","196").collect(Collectors.toSet())); | ||||
|         connections.put("152", Stream.of("86").collect(Collectors.toSet())); | ||||
|         connections.put("153", Stream.of("154","246").collect(Collectors.toSet())); | ||||
|         connections.put("154", Stream.of("153","229","274").collect(Collectors.toSet())); | ||||
|         connections.put("155", Stream.of("224","283").collect(Collectors.toSet())); | ||||
|         connections.put("156", Stream.of("13","24","2","167","3","167","2","167").collect(Collectors.toSet())); | ||||
|         connections.put("157", Stream.of("23","232","13","29").collect(Collectors.toSet())); | ||||
|         connections.put("158", Stream.of("37","68").collect(Collectors.toSet())); | ||||
|         connections.put("159", Stream.of("143","277").collect(Collectors.toSet())); | ||||
|         connections.put("160", Stream.of("95","265").collect(Collectors.toSet())); | ||||
|         connections.put("161", Stream.of("25","44","25","44").collect(Collectors.toSet())); | ||||
|         connections.put("162", Stream.of("28","149").collect(Collectors.toSet())); | ||||
|         connections.put("163", Stream.of("11","82").collect(Collectors.toSet())); | ||||
|         connections.put("164", Stream.of("24","246","33","243","33","243").collect(Collectors.toSet())); | ||||
|         connections.put("165", Stream.of("93").collect(Collectors.toSet())); | ||||
|         connections.put("166", Stream.of("44","262","44","262").collect(Collectors.toSet())); | ||||
|         connections.put("167", Stream.of("14","156","14","156","14","156","13","188").collect(Collectors.toSet())); | ||||
|         connections.put("168", Stream.of("62","179","213").collect(Collectors.toSet())); | ||||
|         connections.put("169", Stream.of("239").collect(Collectors.toSet())); | ||||
|         connections.put("170", Stream.of("40","89").collect(Collectors.toSet())); | ||||
|         connections.put("171", Stream.of("61","135").collect(Collectors.toSet())); | ||||
|         connections.put("172", Stream.of("71","281").collect(Collectors.toSet())); | ||||
|         connections.put("173", Stream.of("16","98").collect(Collectors.toSet())); | ||||
|         connections.put("174", Stream.of("252").collect(Collectors.toSet())); | ||||
|         connections.put("175", Stream.of("252").collect(Collectors.toSet())); | ||||
|         connections.put("176", Stream.of("30","233").collect(Collectors.toSet())); | ||||
|         connections.put("177", Stream.of("105","238").collect(Collectors.toSet())); | ||||
|         connections.put("178", Stream.of("115","201").collect(Collectors.toSet())); | ||||
|         connections.put("179", Stream.of("168","180").collect(Collectors.toSet())); | ||||
|         connections.put("180", Stream.of("179","198").collect(Collectors.toSet())); | ||||
|         connections.put("181", Stream.of("76","112","285").collect(Collectors.toSet())); | ||||
|         connections.put("182", Stream.of("73","193").collect(Collectors.toSet())); | ||||
|         connections.put("183", Stream.of("42","43").collect(Collectors.toSet())); | ||||
|         connections.put("184", Stream.of("115","198").collect(Collectors.toSet())); | ||||
|         connections.put("185", Stream.of("236","280").collect(Collectors.toSet())); | ||||
|         connections.put("186", Stream.of("127","207","18","122","18","122").collect(Collectors.toSet())); | ||||
|         connections.put("187", Stream.of("57","231").collect(Collectors.toSet())); | ||||
|         connections.put("188", Stream.of("7","167").collect(Collectors.toSet())); | ||||
|         connections.put("189", Stream.of("30","131").collect(Collectors.toSet())); | ||||
|         connections.put("190", Stream.of("136","244").collect(Collectors.toSet())); | ||||
|         connections.put("191", Stream.of("196","211","28","258","107","276").collect(Collectors.toSet())); | ||||
|         connections.put("192", Stream.of("82","277","18","83","18","83","83","217").collect(Collectors.toSet())); | ||||
|         connections.put("193", Stream.of("5","182").collect(Collectors.toSet())); | ||||
|         connections.put("194", Stream.of("96","204").collect(Collectors.toSet())); | ||||
|         connections.put("195", Stream.of("105","112").collect(Collectors.toSet())); | ||||
|         connections.put("196", Stream.of("49","191","107","151").collect(Collectors.toSet())); | ||||
|         connections.put("197", Stream.of("271","272").collect(Collectors.toSet())); | ||||
|         connections.put("198", Stream.of("180","184").collect(Collectors.toSet())); | ||||
|         connections.put("199", Stream.of("269","288","269","288").collect(Collectors.toSet())); | ||||
|         connections.put("200", Stream.of("4","27","283","291").collect(Collectors.toSet())); | ||||
|         connections.put("201", Stream.of("178","281").collect(Collectors.toSet())); | ||||
|         connections.put("202", Stream.of("63","216").collect(Collectors.toSet())); | ||||
|         connections.put("203", Stream.of("32","246").collect(Collectors.toSet())); | ||||
|         connections.put("204", Stream.of("80","194").collect(Collectors.toSet())); | ||||
|         connections.put("205", Stream.of("137","143").collect(Collectors.toSet())); | ||||
|         connections.put("206", Stream.of("45","144").collect(Collectors.toSet())); | ||||
|         connections.put("207", Stream.of("149","186").collect(Collectors.toSet())); | ||||
|         connections.put("208", Stream.of("110","241").collect(Collectors.toSet())); | ||||
|         connections.put("209", Stream.of("75","290","75","234").collect(Collectors.toSet())); | ||||
|         connections.put("210", Stream.of("98","274").collect(Collectors.toSet())); | ||||
|         connections.put("211", Stream.of("11","191").collect(Collectors.toSet())); | ||||
|         connections.put("212", Stream.of("141").collect(Collectors.toSet())); | ||||
|         connections.put("213", Stream.of("53","168").collect(Collectors.toSet())); | ||||
|         connections.put("214", Stream.of("51","300").collect(Collectors.toSet())); | ||||
|         connections.put("215", Stream.of("41","275").collect(Collectors.toSet())); | ||||
|         connections.put("216", Stream.of("20","202").collect(Collectors.toSet())); | ||||
|         connections.put("217", Stream.of("192","282").collect(Collectors.toSet())); | ||||
|         connections.put("218", Stream.of("43","63").collect(Collectors.toSet())); | ||||
|         connections.put("219", Stream.of("134","221","134","221").collect(Collectors.toSet())); | ||||
|         connections.put("220", Stream.of("238","293").collect(Collectors.toSet())); | ||||
|         connections.put("221", Stream.of("75","219","75","219").collect(Collectors.toSet())); | ||||
|         connections.put("222", Stream.of("126","145").collect(Collectors.toSet())); | ||||
|         connections.put("223", Stream.of("95","259").collect(Collectors.toSet())); | ||||
|         connections.put("224", Stream.of("13","155","261","275","294").collect(Collectors.toSet())); | ||||
|         connections.put("225", Stream.of("127","295").collect(Collectors.toSet())); | ||||
|         connections.put("226", Stream.of("101","150").collect(Collectors.toSet())); | ||||
|         connections.put("227", Stream.of("294").collect(Collectors.toSet())); | ||||
|         connections.put("228", Stream.of("235","272","235","272").collect(Collectors.toSet())); | ||||
|         connections.put("229", Stream.of("154","240").collect(Collectors.toSet())); | ||||
|         connections.put("230", Stream.of("80","299").collect(Collectors.toSet())); | ||||
|         connections.put("231", Stream.of("9","187").collect(Collectors.toSet())); | ||||
|         connections.put("232", Stream.of("157","278").collect(Collectors.toSet())); | ||||
|         connections.put("233", Stream.of("1","176").collect(Collectors.toSet())); | ||||
|         connections.put("234", Stream.of("209","250").collect(Collectors.toSet())); | ||||
|         connections.put("235", Stream.of("99","228","99","228","99","146").collect(Collectors.toSet())); | ||||
|         connections.put("236", Stream.of("140","185").collect(Collectors.toSet())); | ||||
|         connections.put("237", Stream.of("61","120").collect(Collectors.toSet())); | ||||
|         connections.put("238", Stream.of("177","220").collect(Collectors.toSet())); | ||||
|         connections.put("239", Stream.of("59","169").collect(Collectors.toSet())); | ||||
|         connections.put("240", Stream.of("229","300").collect(Collectors.toSet())); | ||||
|         connections.put("241", Stream.of("208","264").collect(Collectors.toSet())); | ||||
|         connections.put("242", Stream.of("45").collect(Collectors.toSet())); | ||||
|         connections.put("243", Stream.of("164","294","164","294").collect(Collectors.toSet())); | ||||
|         connections.put("244", Stream.of("55","190","35","271").collect(Collectors.toSet())); | ||||
|         connections.put("245", Stream.of("113","280").collect(Collectors.toSet())); | ||||
|         connections.put("246", Stream.of("153","164","203","288").collect(Collectors.toSet())); | ||||
|         connections.put("247", Stream.of("272","284","272","284").collect(Collectors.toSet())); | ||||
|         connections.put("248", Stream.of("11","253").collect(Collectors.toSet())); | ||||
|         connections.put("249", Stream.of("13","48").collect(Collectors.toSet())); | ||||
|         connections.put("250", Stream.of("234","251").collect(Collectors.toSet())); | ||||
|         connections.put("251", Stream.of("5","250").collect(Collectors.toSet())); | ||||
|         connections.put("252", Stream.of("41","174","175").collect(Collectors.toSet())); | ||||
|         connections.put("253", Stream.of("94","248").collect(Collectors.toSet())); | ||||
|         connections.put("254", Stream.of("25","87","25","87").collect(Collectors.toSet())); | ||||
|         connections.put("255", Stream.of("68","88").collect(Collectors.toSet())); | ||||
|         connections.put("256", Stream.of("12","257").collect(Collectors.toSet())); | ||||
|         connections.put("257", Stream.of("59","256").collect(Collectors.toSet())); | ||||
|         connections.put("258", Stream.of("126","191","102","151").collect(Collectors.toSet())); | ||||
|         connections.put("259", Stream.of("26","223").collect(Collectors.toSet())); | ||||
|         connections.put("260", Stream.of("121","301").collect(Collectors.toSet())); | ||||
|         connections.put("261", Stream.of("224").collect(Collectors.toSet())); | ||||
|         connections.put("262", Stream.of("2","166","3","166").collect(Collectors.toSet())); | ||||
|         connections.put("263", Stream.of("8","139").collect(Collectors.toSet())); | ||||
|         connections.put("264", Stream.of("52","108","241","1","110").collect(Collectors.toSet())); | ||||
|         connections.put("265", Stream.of("160","302").collect(Collectors.toSet())); | ||||
|         connections.put("266", Stream.of("267").collect(Collectors.toSet())); | ||||
|         connections.put("267", Stream.of("129","266").collect(Collectors.toSet())); | ||||
|         connections.put("268", Stream.of("15","21").collect(Collectors.toSet())); | ||||
|         connections.put("269", Stream.of("78","199","78","199").collect(Collectors.toSet())); | ||||
|         connections.put("270", Stream.of("125","125").collect(Collectors.toSet())); | ||||
|         connections.put("271", Stream.of("197","244").collect(Collectors.toSet())); | ||||
|         connections.put("272", Stream.of("228","247","228","247","107","197").collect(Collectors.toSet())); | ||||
|         connections.put("273", Stream.of("26").collect(Collectors.toSet())); | ||||
|         connections.put("274", Stream.of("154","210").collect(Collectors.toSet())); | ||||
|         connections.put("275", Stream.of("215","224").collect(Collectors.toSet())); | ||||
|         connections.put("276", Stream.of("89","102","89","191").collect(Collectors.toSet())); | ||||
|         connections.put("277", Stream.of("159","192").collect(Collectors.toSet())); | ||||
|         connections.put("278", Stream.of("87","148","232","284","87","136","13").collect(Collectors.toSet())); | ||||
|         connections.put("279", Stream.of("62").collect(Collectors.toSet())); | ||||
|         connections.put("280", Stream.of("185","245").collect(Collectors.toSet())); | ||||
|         connections.put("281", Stream.of("144","172","94","201").collect(Collectors.toSet())); | ||||
|         connections.put("282", Stream.of("147","217").collect(Collectors.toSet())); | ||||
|         connections.put("283", Stream.of("155","200","291").collect(Collectors.toSet())); | ||||
|         connections.put("284", Stream.of("87","247","87","247","107","278").collect(Collectors.toSet())); | ||||
|         connections.put("285", Stream.of("72","181").collect(Collectors.toSet())); | ||||
|         connections.put("286", Stream.of("74","96").collect(Collectors.toSet())); | ||||
|         connections.put("287", Stream.of("93","301").collect(Collectors.toSet())); | ||||
|         connections.put("288", Stream.of("36","199","36","199","43","246").collect(Collectors.toSet())); | ||||
|         connections.put("289", Stream.of("94","142").collect(Collectors.toSet())); | ||||
|         connections.put("290", Stream.of("115","209").collect(Collectors.toSet())); | ||||
|         connections.put("291", Stream.of("42","200","283").collect(Collectors.toSet())); | ||||
|         connections.put("292", Stream.of("17","74").collect(Collectors.toSet())); | ||||
|         connections.put("293", Stream.of("220").collect(Collectors.toSet())); | ||||
|         connections.put("294", Stream.of("3","243","224","227","3","243").collect(Collectors.toSet())); | ||||
|         connections.put("295", Stream.of("76","225").collect(Collectors.toSet())); | ||||
|         connections.put("296", Stream.of("71","142").collect(Collectors.toSet())); | ||||
|         connections.put("297", Stream.of("113","137").collect(Collectors.toSet())); | ||||
|         connections.put("298", Stream.of("299").collect(Collectors.toSet())); | ||||
|         connections.put("299", Stream.of("230","298").collect(Collectors.toSet())); | ||||
|         connections.put("300", Stream.of("37","214","240").collect(Collectors.toSet())); | ||||
|         connections.put("301", Stream.of("260","287").collect(Collectors.toSet())); | ||||
|         connections.put("302", Stream.of("31","265").collect(Collectors.toSet())); | ||||
| 
 | ||||
|         underground = new Graph<>(stations, connections); | ||||
|         routeFinder = new RouteFinder<>(underground, new HaversineScorer(), new HaversineScorer()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void findRoute() { | ||||
|         List<Station> route = routeFinder.findRoute(underground.getNode("74"), underground.getNode("7")); | ||||
| 
 | ||||
|         System.out.println(route.stream().map(Station::getName).collect(Collectors.toList())); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,42 @@ | ||||
| package com.baeldung.algorithms.astar.underground; | ||||
| 
 | ||||
| import java.util.StringJoiner; | ||||
| 
 | ||||
| import com.baeldung.algorithms.astar.GraphNode; | ||||
| 
 | ||||
| public class Station implements GraphNode { | ||||
|     private final String id; | ||||
|     private final String name; | ||||
|     private final double latitude; | ||||
|     private final double longitude; | ||||
| 
 | ||||
|     public Station(String id, String name, double latitude, double longitude) { | ||||
|         this.id = id; | ||||
|         this.name = name; | ||||
|         this.latitude = latitude; | ||||
|         this.longitude = longitude; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public String getId() { | ||||
|         return id; | ||||
|     } | ||||
| 
 | ||||
|     public String getName() { | ||||
|         return name; | ||||
|     } | ||||
| 
 | ||||
|     public double getLatitude() { | ||||
|         return latitude; | ||||
|     } | ||||
| 
 | ||||
|     public double getLongitude() { | ||||
|         return longitude; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public String toString() { | ||||
|         return new StringJoiner(", ", Station.class.getSimpleName() + "[", "]").add("id='" + id + "'") | ||||
|             .add("name='" + name + "'").add("latitude=" + latitude).add("longitude=" + longitude).toString(); | ||||
|     } | ||||
| } | ||||
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 10 KiB | 
| @ -1,10 +1,21 @@ | ||||
| ## Algorithms - Miscellaneous | ||||
| 
 | ||||
| This module contains articles about algorithms. Some classes of algorithms, e.g., [sorting](/algorithms-sorting) and | ||||
| [genetic algorithms](/algorithms-genetic), have their own dedicated modules.  | ||||
| 
 | ||||
| ## Relevant Articles: | ||||
| 
 | ||||
| - [Java Two Pointer Technique](https://www.baeldung.com/java-two-pointer-technique) | ||||
| - [Implementing Simple State Machines with Java Enums](https://www.baeldung.com/java-enum-simple-state-machine) | ||||
| - [Converting Between Roman and Arabic Numerals in Java](http://www.baeldung.com/java-convert-roman-arabic) | ||||
| - [Practical Java Examples of the Big O Notation](http://www.baeldung.com/java-algorithm-complexity) | ||||
| - [Converting Between Roman and Arabic Numerals in Java](https://www.baeldung.com/java-convert-roman-arabic) | ||||
| - [Practical Java Examples of the Big O Notation](https://www.baeldung.com/java-algorithm-complexity) | ||||
| - [Checking If a List Is Sorted in Java](https://www.baeldung.com/java-check-if-list-sorted) | ||||
| - [Checking if a Java Graph has a Cycle](https://www.baeldung.com/java-graph-has-a-cycle) | ||||
| - [A Guide to the Folding Technique in Java](https://www.baeldung.com/folding-hashing-technique) | ||||
| - [Creating a Triangle with for Loops in Java](https://www.baeldung.com/java-print-triangle) | ||||
| - [Efficient Word Frequency Calculator in Java](https://www.baeldung.com/java-word-frequency) | ||||
| - [Interpolation Search in Java](https://www.baeldung.com/java-interpolation-search) | ||||
| - [The K-Means Clustering Algorithm in Java](https://www.baeldung.com/java-k-means-clustering-algorithm) | ||||
| - [Creating a Custom Annotation in Java](https://www.baeldung.com/java-custom-annotation) | ||||
| - [Breadth-First Search Algorithm in Java](https://www.baeldung.com/java-breadth-first-search) | ||||
| - More articles: [[<-- prev]](/algorithms-miscellaneous-2) [[next -->]](/algorithms-miscellaneous-4) | ||||
|  | ||||
| @ -54,6 +54,21 @@ | ||||
|             <version>1.1.0</version> | ||||
|             <scope>test</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.openjdk.jmh</groupId> | ||||
|             <artifactId>jmh-core</artifactId> | ||||
|             <version>${jmh-core.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.openjdk.jmh</groupId> | ||||
|             <artifactId>jmh-generator-annprocess</artifactId> | ||||
|             <version>${jmh-generator.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.openjdk.jmh</groupId> | ||||
|             <artifactId>jmh-generator-bytecode</artifactId> | ||||
|             <version>${jmh-generator.version}</version> | ||||
|         </dependency> | ||||
|     </dependencies> | ||||
| 
 | ||||
|     <build> | ||||
| @ -73,5 +88,7 @@ | ||||
|         <commons-collections4.version>4.3</commons-collections4.version> | ||||
|         <guava.version>28.0-jre</guava.version> | ||||
|         <retrofit.version>2.6.0</retrofit.version> | ||||
|         <jmh-core.version>1.19</jmh-core.version> | ||||
|         <jmh-generator.version>1.19</jmh-generator.version> | ||||
|     </properties> | ||||
| </project> | ||||
| @ -0,0 +1,54 @@ | ||||
| package com.baeldung.algorithms.breadthfirstsearch; | ||||
| 
 | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| 
 | ||||
| import java.util.*; | ||||
| 
 | ||||
| public class BreadthFirstSearchAlgorithm { | ||||
| 
 | ||||
|     private static final Logger LOGGER = LoggerFactory.getLogger(BreadthFirstSearchAlgorithm.class); | ||||
| 
 | ||||
|     public static <T> Optional<Tree<T>> search(T value, Tree<T> root) { | ||||
|         Queue<Tree<T>> queue = new ArrayDeque<>(); | ||||
|         queue.add(root); | ||||
| 
 | ||||
|         Tree<T> currentNode; | ||||
|         while (!queue.isEmpty()) { | ||||
|             currentNode = queue.remove(); | ||||
|             LOGGER.info("Visited node with value: {}", currentNode.getValue()); | ||||
| 
 | ||||
|             if (currentNode.getValue().equals(value)) { | ||||
|                 return Optional.of(currentNode); | ||||
|             } else { | ||||
|                 queue.addAll(currentNode.getChildren()); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return Optional.empty(); | ||||
|     } | ||||
| 
 | ||||
|     public static <T> Optional<Node<T>> search(T value, Node<T> start) { | ||||
|         Queue<Node<T>> queue = new ArrayDeque<>(); | ||||
|         queue.add(start); | ||||
| 
 | ||||
|         Node<T> currentNode; | ||||
|         Set<Node<T>> alreadyVisited = new HashSet<>(); | ||||
| 
 | ||||
|         while (!queue.isEmpty()) { | ||||
|             currentNode = queue.remove(); | ||||
|             LOGGER.info("Visited node with value: {}", currentNode.getValue()); | ||||
| 
 | ||||
|             if (currentNode.getValue().equals(value)) { | ||||
|                 return Optional.of(currentNode); | ||||
|             } else { | ||||
|                 alreadyVisited.add(currentNode); | ||||
|                 queue.addAll(currentNode.getNeighbors()); | ||||
|                 queue.removeAll(alreadyVisited); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return Optional.empty(); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,31 @@ | ||||
| package com.baeldung.algorithms.breadthfirstsearch; | ||||
| 
 | ||||
| import java.util.Collections; | ||||
| import java.util.HashSet; | ||||
| import java.util.Set; | ||||
| 
 | ||||
| public class Node<T> { | ||||
| 
 | ||||
|     private T value; | ||||
|     private Set<Node<T>> neighbors; | ||||
| 
 | ||||
|     public Node(T value) { | ||||
|         this.value = value; | ||||
|         this.neighbors = new HashSet<>(); | ||||
|     } | ||||
| 
 | ||||
|     public T getValue() { | ||||
|         return value; | ||||
|     } | ||||
| 
 | ||||
|     public Set<Node<T>> getNeighbors() { | ||||
|         return Collections.unmodifiableSet(neighbors); | ||||
|     } | ||||
| 
 | ||||
|     public void connect(Node<T> node) { | ||||
|         if (this == node) throw new IllegalArgumentException("Can't connect node to itself"); | ||||
|         this.neighbors.add(node); | ||||
|         node.neighbors.add(this); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,34 @@ | ||||
| package com.baeldung.algorithms.breadthfirstsearch; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.Collections; | ||||
| import java.util.List; | ||||
| 
 | ||||
| public class Tree<T> { | ||||
| 
 | ||||
|     private T value; | ||||
|     private List<Tree<T>> children; | ||||
| 
 | ||||
|     private Tree(T value) { | ||||
|         this.value = value; | ||||
|         this.children = new ArrayList<>(); | ||||
|     } | ||||
| 
 | ||||
|     public static <T> Tree<T> of(T value) { | ||||
|         return new Tree<>(value); | ||||
|     } | ||||
| 
 | ||||
|     public T getValue() { | ||||
|         return value; | ||||
|     } | ||||
| 
 | ||||
|     public List<Tree<T>> getChildren() { | ||||
|         return Collections.unmodifiableList(children); | ||||
|     } | ||||
| 
 | ||||
|     public Tree<T> addChild(T value) { | ||||
|         Tree<T> newChild = new Tree<>(value); | ||||
|         children.add(newChild); | ||||
|         return newChild; | ||||
|     } | ||||
| } | ||||
| @ -1,70 +0,0 @@ | ||||
| package com.baeldung.bucketsort; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.Comparator; | ||||
| import java.util.List; | ||||
| 
 | ||||
| public class IntegerBucketSorter implements Sorter<Integer> { | ||||
| 
 | ||||
|     private final Comparator<Integer> comparator; | ||||
| 
 | ||||
|     public IntegerBucketSorter(Comparator<Integer> comparator) { | ||||
|         this.comparator = comparator; | ||||
|     } | ||||
| 
 | ||||
|     public IntegerBucketSorter() { | ||||
|         comparator = Comparator.naturalOrder(); | ||||
|     } | ||||
| 
 | ||||
|     public List<Integer> sort(List<Integer> arrayToSort) { | ||||
| 
 | ||||
|         List<List<Integer>> buckets = splitIntoUnsortedBuckets(arrayToSort); | ||||
| 
 | ||||
|         for(List<Integer> bucket  : buckets){ | ||||
|             bucket.sort(comparator); | ||||
|         } | ||||
| 
 | ||||
|         return concatenateSortedBuckets(buckets); | ||||
|     } | ||||
| 
 | ||||
|     private List<Integer> concatenateSortedBuckets(List<List<Integer>> buckets){ | ||||
|         List<Integer> sortedArray = new ArrayList<>(); | ||||
|         int index = 0; | ||||
|         for(List<Integer> bucket : buckets){ | ||||
|             for(int number : bucket){ | ||||
|                 sortedArray.add(index++, number); | ||||
|             } | ||||
|         } | ||||
|         return sortedArray; | ||||
|     } | ||||
| 
 | ||||
|     private List<List<Integer>> splitIntoUnsortedBuckets(List<Integer> initialList){ | ||||
| 
 | ||||
|         final int[] codes = createHashes(initialList); | ||||
| 
 | ||||
|         List<List<Integer>> buckets = new ArrayList<>(codes[1]); | ||||
|         for(int i = 0; i < codes[1]; i++) buckets.add(new ArrayList<>()); | ||||
| 
 | ||||
|         //distribute the data | ||||
|         for (int i : initialList) { | ||||
|             buckets.get(hash(i, codes)).add(i); | ||||
|         } | ||||
|         return buckets; | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     private int[] createHashes(List<Integer> input){ | ||||
|         int m = input.get(0); | ||||
|         for (int i = 1; i < input.size(); i++) { | ||||
|             if (m < input.get(i)) { | ||||
|                 m = input.get(i); | ||||
|             } | ||||
|         } | ||||
|         return new int[]{m, (int) Math.sqrt(input.size())}; | ||||
|     } | ||||
| 
 | ||||
|     private static int hash(int i, int[] code) { | ||||
|         return (int) ((double) i / code[0] * (code[1] - 1)); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,86 @@ | ||||
| package com.baeldung.algorithms.breadthfirstsearch; | ||||
| 
 | ||||
| import org.junit.jupiter.api.Test; | ||||
| 
 | ||||
| import static org.assertj.core.api.Assertions.assertThat; | ||||
| 
 | ||||
| class BreadthFirstSearchAlgorithmUnitTest { | ||||
| 
 | ||||
|     private Tree<Integer> root; | ||||
|     private Tree<Integer> rootFirstChild; | ||||
|     private Tree<Integer> depthMostChild; | ||||
|     private Tree<Integer> rootSecondChild; | ||||
| 
 | ||||
|     private Node<Integer> start; | ||||
|     private Node<Integer> firstNeighbor; | ||||
|     private Node<Integer> firstNeighborNeighbor; | ||||
|     private Node<Integer> secondNeighbor; | ||||
| 
 | ||||
|     @Test | ||||
|     void givenTree_whenSearchTen_thenRoot() { | ||||
|         initTree(); | ||||
|         assertThat(BreadthFirstSearchAlgorithm.search(10, root)).isPresent().contains(root); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void givenTree_whenSearchThree_thenDepthMostValue() { | ||||
|         initTree(); | ||||
|         assertThat(BreadthFirstSearchAlgorithm.search(3, root)).isPresent().contains(depthMostChild); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void givenTree_whenSearchFour_thenRootSecondChild() { | ||||
|         initTree(); | ||||
|         assertThat(BreadthFirstSearchAlgorithm.search(4, root)).isPresent().contains(rootSecondChild); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void givenTree_whenSearchFive_thenNotFound() { | ||||
|         initTree(); | ||||
|         assertThat(BreadthFirstSearchAlgorithm.search(5, root)).isEmpty(); | ||||
|     } | ||||
| 
 | ||||
|     private void initTree() { | ||||
|         root = Tree.of(10); | ||||
|         rootFirstChild = root.addChild(2); | ||||
|         depthMostChild = rootFirstChild.addChild(3); | ||||
|         rootSecondChild = root.addChild(4); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void givenNode_whenSearchTen_thenStart() { | ||||
|         initNode(); | ||||
|         assertThat(BreadthFirstSearchAlgorithm.search(10, firstNeighborNeighbor)).isPresent().contains(start); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void givenNode_whenSearchThree_thenNeighborNeighbor() { | ||||
|         initNode(); | ||||
|         assertThat(BreadthFirstSearchAlgorithm.search(3, firstNeighborNeighbor)).isPresent().contains(firstNeighborNeighbor); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void givenNode_whenSearchFour_thenSecondNeighbor() { | ||||
|         initNode(); | ||||
|         assertThat(BreadthFirstSearchAlgorithm.search(4, firstNeighborNeighbor)).isPresent().contains(secondNeighbor); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void givenNode_whenSearchFive_thenNotFound() { | ||||
|         initNode(); | ||||
|         assertThat(BreadthFirstSearchAlgorithm.search(5, firstNeighborNeighbor)).isEmpty(); | ||||
|     } | ||||
| 
 | ||||
|     private void initNode() { | ||||
|         start = new Node<>(10); | ||||
|         firstNeighbor = new Node<>(2); | ||||
|         start.connect(firstNeighbor); | ||||
| 
 | ||||
|         firstNeighborNeighbor = new Node<>(3); | ||||
|         firstNeighbor.connect(firstNeighborNeighbor); | ||||
|         firstNeighborNeighbor.connect(start); | ||||
| 
 | ||||
|         secondNeighbor = new Node<>(4); | ||||
|         start.connect(secondNeighbor); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										14
									
								
								algorithms-miscellaneous-4/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								algorithms-miscellaneous-4/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | ||||
| ## Algorithms - Miscellaneous | ||||
| 
 | ||||
| This module contains articles about algorithms. Some classes of algorithms, e.g., [sorting](https://github.com/eugenp/tutorials/blob/algorithms-sorting) and [genetic algorithms](https://github.com/eugenp/tutorials/blob/algorithms-genetic), have their own dedicated modules. | ||||
| 
 | ||||
| ### Relevant articles: | ||||
| 
 | ||||
| - [Multi-Swarm Optimization Algorithm in Java](https://www.baeldung.com/java-multi-swarm-algorithm) | ||||
| - [String Search Algorithms for Large Texts](https://www.baeldung.com/java-full-text-search-algorithms) | ||||
| - [Check If a String Contains All The Letters of The Alphabet](https://www.baeldung.com/java-string-contains-all-letters) | ||||
| - [Find the Middle Element of a Linked List](https://www.baeldung.com/java-linked-list-middle-element) | ||||
| - [Find Substrings That Are Palindromes in Java](https://www.baeldung.com/java-palindrome-substrings) | ||||
| - [Find the Longest Substring without Repeating Characters](https://www.baeldung.com/java-longest-substring-without-repeated-characters) | ||||
| - [Permutations of an Array in Java](https://www.baeldung.com/java-array-permutations) | ||||
| - More articles: [[<-- prev]](/algorithms-miscellaneous-3) [[next -->]](/algorithms-miscellaneous-5) | ||||
							
								
								
									
										51
									
								
								algorithms-miscellaneous-4/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								algorithms-miscellaneous-4/pom.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,51 @@ | ||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
|     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||
|     <modelVersion>4.0.0</modelVersion> | ||||
|     <artifactId>algorithms-miscellaneous-4</artifactId> | ||||
|     <version>0.0.1-SNAPSHOT</version> | ||||
|     <name>algorithms-miscellaneous-4</name> | ||||
|      | ||||
|     <parent> | ||||
|         <groupId>com.baeldung</groupId> | ||||
|         <artifactId>parent-modules</artifactId> | ||||
|         <version>1.0.0-SNAPSHOT</version> | ||||
|     </parent> | ||||
| 
 | ||||
|     <dependencies> | ||||
|         <dependency> | ||||
|             <groupId>com.google.guava</groupId> | ||||
|             <artifactId>guava</artifactId> | ||||
|             <version>${guava.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.projectlombok</groupId> | ||||
|             <artifactId>lombok</artifactId> | ||||
|             <version>${lombok.version}</version> | ||||
|             <scope>provided</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.assertj</groupId> | ||||
|             <artifactId>assertj-core</artifactId> | ||||
|             <version>${org.assertj.core.version}</version> | ||||
|             <scope>test</scope> | ||||
|         </dependency> | ||||
|     </dependencies> | ||||
| 
 | ||||
|     <build> | ||||
|         <pluginManagement> | ||||
|             <plugins> | ||||
|                 <plugin> | ||||
|                     <groupId>org.codehaus.mojo</groupId> | ||||
|                     <artifactId>exec-maven-plugin</artifactId> | ||||
|                     <version>${exec-maven-plugin.version}</version> | ||||
|                 </plugin> | ||||
|             </plugins> | ||||
|         </pluginManagement> | ||||
|     </build> | ||||
| 
 | ||||
|     <properties> | ||||
|         <org.assertj.core.version>3.9.0</org.assertj.core.version> | ||||
|         <guava.version>27.0.1-jre</guava.version> | ||||
|     </properties> | ||||
| 
 | ||||
| </project> | ||||
| @ -0,0 +1,37 @@ | ||||
| package com.baeldung.algorithms.smallestinteger; | ||||
| 
 | ||||
| import java.util.Arrays; | ||||
| 
 | ||||
| public class SmallestMissingPositiveInteger { | ||||
|     public static int searchInSortedArray(int[] input) { | ||||
|         for (int i = 0; i < input.length; i++) { | ||||
|             if (i != input[i]) { | ||||
|                 return i; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return input.length; | ||||
|     } | ||||
| 
 | ||||
|     public static int searchInUnsortedArraySortingFirst(int[] input) { | ||||
|         Arrays.sort(input); | ||||
|         return searchInSortedArray(input); | ||||
|     } | ||||
| 
 | ||||
|     public static int searchInUnsortedArrayBooleanArray(int[] input) { | ||||
|         boolean[] flags = new boolean[input.length]; | ||||
|         for (int number : input) { | ||||
|             if (number < flags.length) { | ||||
|                 flags[number] = true; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         for (int i = 0; i < flags.length; i++) { | ||||
|             if (!flags[i]) { | ||||
|                 return i; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return flags.length; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,88 @@ | ||||
| package com.baeldung.algorithms.smallestinteger; | ||||
| 
 | ||||
| import org.junit.jupiter.api.Test; | ||||
| 
 | ||||
| import static org.assertj.core.api.Assertions.assertThat; | ||||
| 
 | ||||
| class SmallestMissingPositiveIntegerUnitTest { | ||||
|     @Test | ||||
|     void givenArrayWithThreeMissing_whenSearchInSortedArray_thenThree() { | ||||
|         int[] input = new int[] {0, 1, 2, 4, 5}; | ||||
| 
 | ||||
|         int result = SmallestMissingPositiveInteger.searchInSortedArray(input); | ||||
| 
 | ||||
|         assertThat(result).isEqualTo(3); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void givenArrayWithOneAndThreeMissing_whenSearchInSortedArray_thenOne() { | ||||
|         int[] input = new int[] {0, 2, 4, 5}; | ||||
| 
 | ||||
|         int result = SmallestMissingPositiveInteger.searchInSortedArray(input); | ||||
| 
 | ||||
|         assertThat(result).isEqualTo(1); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void givenArrayWithoutMissingInteger_whenSearchInSortedArray_thenArrayLength() { | ||||
|         int[] input = new int[] {0, 1, 2, 3, 4, 5}; | ||||
| 
 | ||||
|         int result = SmallestMissingPositiveInteger.searchInSortedArray(input); | ||||
| 
 | ||||
|         assertThat(result).isEqualTo(input.length); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void givenArrayWithThreeMissing_whenSearchInUnsortedArraySortingFirst_thenThree() { | ||||
|         int[] input = new int[] {1, 4, 0, 5, 2}; | ||||
| 
 | ||||
|         int result = SmallestMissingPositiveInteger.searchInUnsortedArraySortingFirst(input); | ||||
| 
 | ||||
|         assertThat(result).isEqualTo(3); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void givenArrayWithOneAndThreeMissing_whenSearchInUnsortedArraySortingFirst_thenOne() { | ||||
|         int[] input = new int[] {4, 2, 0, 5}; | ||||
| 
 | ||||
|         int result = SmallestMissingPositiveInteger.searchInUnsortedArraySortingFirst(input); | ||||
| 
 | ||||
|         assertThat(result).isEqualTo(1); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void givenArrayWithoutMissingInteger_whenSearchInUnsortedArraySortingFirst_thenArrayLength() { | ||||
|         int[] input = new int[] {4, 5, 1, 3, 0, 2}; | ||||
| 
 | ||||
|         int result = SmallestMissingPositiveInteger.searchInUnsortedArraySortingFirst(input); | ||||
| 
 | ||||
|         assertThat(result).isEqualTo(input.length); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void givenArrayWithThreeMissing_whenSearchInUnsortedArrayBooleanArray_thenThree() { | ||||
|         int[] input = new int[] {1, 4, 0, 5, 2}; | ||||
| 
 | ||||
|         int result = SmallestMissingPositiveInteger.searchInUnsortedArrayBooleanArray(input); | ||||
| 
 | ||||
|         assertThat(result).isEqualTo(3); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void givenArrayWithOneAndThreeMissing_whenSearchInUnsortedArrayBooleanArray_thenOne() { | ||||
|         int[] input = new int[] {4, 2, 0, 5}; | ||||
| 
 | ||||
|         int result = SmallestMissingPositiveInteger.searchInUnsortedArrayBooleanArray(input); | ||||
| 
 | ||||
|         assertThat(result).isEqualTo(1); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void givenArrayWithoutMissingInteger_whenSearchInUnsortedArrayBooleanArray_thenArrayLength() { | ||||
|         int[] input = new int[] {4, 5, 1, 3, 0, 2}; | ||||
| 
 | ||||
|         int result = SmallestMissingPositiveInteger.searchInUnsortedArrayBooleanArray(input); | ||||
| 
 | ||||
|         assertThat(result).isEqualTo(input.length); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										12
									
								
								algorithms-miscellaneous-5/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								algorithms-miscellaneous-5/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | ||||
| ## Algorithms - Miscellaneous | ||||
| 
 | ||||
| This module contains articles about algorithms. Some classes of algorithms, e.g., [sorting](/../algorithms-sorting) and | ||||
| [genetic algorithms](/../algorithms-genetic), have their own dedicated modules.  | ||||
| 
 | ||||
| ### Relevant articles: | ||||
| 
 | ||||
| - [Converting Between Byte Arrays and Hexadecimal Strings in Java](https://www.baeldung.com/java-byte-arrays-hex-strings) | ||||
| - [Reversing a Binary Tree in Java](https://www.baeldung.com/java-reversing-a-binary-tree) | ||||
| - [Find If Two Numbers Are Relatively Prime in Java](https://www.baeldung.com/java-two-relatively-prime-numbers) | ||||
| - [Knapsack Problem Implementation in Java](https://www.baeldung.com/java-knapsack) | ||||
| - More articles: [[<-- prev]](/../algorithms-miscellaneous-4) | ||||
							
								
								
									
										64
									
								
								algorithms-miscellaneous-5/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								algorithms-miscellaneous-5/pom.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,64 @@ | ||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
|     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||
|     <modelVersion>4.0.0</modelVersion> | ||||
|     <artifactId>algorithms-miscellaneous-5</artifactId> | ||||
|     <version>0.0.1-SNAPSHOT</version> | ||||
|     <name>algorithms-miscellaneous-5</name> | ||||
| 
 | ||||
|     <parent> | ||||
|         <groupId>com.baeldung</groupId> | ||||
|         <artifactId>parent-modules</artifactId> | ||||
|         <version>1.0.0-SNAPSHOT</version> | ||||
|     </parent> | ||||
| 
 | ||||
|     <dependencies> | ||||
|         <dependency> | ||||
|             <groupId>commons-codec</groupId> | ||||
|             <artifactId>commons-codec</artifactId> | ||||
|             <version>${commons-codec.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.apache.commons</groupId> | ||||
|             <artifactId>commons-math3</artifactId> | ||||
|             <version>${commons-math3.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.projectlombok</groupId> | ||||
|             <artifactId>lombok</artifactId> | ||||
|             <version>${lombok.version}</version> | ||||
|             <scope>provided</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>pl.allegro.finance</groupId> | ||||
|             <artifactId>tradukisto</artifactId> | ||||
|             <version>${tradukisto.version}</version> | ||||
|         </dependency> | ||||
| 
 | ||||
|         <dependency> | ||||
|             <groupId>org.assertj</groupId> | ||||
|             <artifactId>assertj-core</artifactId> | ||||
|             <version>${org.assertj.core.version}</version> | ||||
|             <scope>test</scope> | ||||
|         </dependency> | ||||
|     </dependencies> | ||||
| 
 | ||||
|     <build> | ||||
|         <pluginManagement> | ||||
|             <plugins> | ||||
|                 <plugin> | ||||
|                     <groupId>org.codehaus.mojo</groupId> | ||||
|                     <artifactId>exec-maven-plugin</artifactId> | ||||
|                     <version>${exec-maven-plugin.version}</version> | ||||
|                 </plugin> | ||||
|             </plugins> | ||||
|         </pluginManagement> | ||||
|     </build> | ||||
| 
 | ||||
|     <properties> | ||||
|         <tradukisto.version>1.0.1</tradukisto.version> | ||||
|         <org.assertj.core.version>3.9.0</org.assertj.core.version> | ||||
|         <commons-codec.version>1.11</commons-codec.version> | ||||
|         <commons-math3.version>3.6.1</commons-math3.version> | ||||
|     </properties> | ||||
| 
 | ||||
| </project> | ||||
| @ -0,0 +1,33 @@ | ||||
| package com.baeldung.algorithms.balancedbinarytree; | ||||
| 
 | ||||
| public class BalancedBinaryTree { | ||||
| 
 | ||||
|     public static boolean isBalanced(Tree tree) { | ||||
|         return isBalancedRecursive(tree, -1).isBalanced; | ||||
|     } | ||||
| 
 | ||||
|     private static Result isBalancedRecursive(Tree tree, int depth) { | ||||
|         if (tree == null) { | ||||
|             return new Result(true, -1); | ||||
|         } | ||||
| 
 | ||||
|         Result leftSubtreeResult = isBalancedRecursive(tree.left(), depth + 1); | ||||
|         Result rightSubtreeResult = isBalancedRecursive(tree.right(), depth + 1); | ||||
| 
 | ||||
|         boolean isBalanced = Math.abs(leftSubtreeResult.height - rightSubtreeResult.height) <= 1; | ||||
|         boolean subtreesAreBalanced = leftSubtreeResult.isBalanced && rightSubtreeResult.isBalanced; | ||||
|         int height = Math.max(leftSubtreeResult.height, rightSubtreeResult.height) + 1; | ||||
| 
 | ||||
|         return new Result(isBalanced && subtreesAreBalanced, height); | ||||
|     } | ||||
| 
 | ||||
|     private static final class Result { | ||||
|         private final boolean isBalanced; | ||||
|         private final int height; | ||||
| 
 | ||||
|         private Result(boolean isBalanced, int height) { | ||||
|             this.isBalanced = isBalanced; | ||||
|             this.height = height; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,34 @@ | ||||
| package com.baeldung.algorithms.balancedbinarytree; | ||||
| 
 | ||||
| public class Tree { | ||||
|     private final int value; | ||||
|     private final Tree left; | ||||
|     private final Tree right; | ||||
| 
 | ||||
|     public Tree(int value, Tree left, Tree right) { | ||||
|         this.value = value; | ||||
|         this.left = left; | ||||
|         this.right = right; | ||||
|     } | ||||
| 
 | ||||
|     public int value() { | ||||
|         return value; | ||||
|     } | ||||
| 
 | ||||
|     public Tree left() { | ||||
|         return left; | ||||
|     } | ||||
| 
 | ||||
|     public Tree right() { | ||||
|         return right; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public String toString() { | ||||
|         return String.format("[%s, %s, %s]", | ||||
|             value, | ||||
|             left == null ? "null" : left.toString(), | ||||
|             right == null ? "null" : right.toString() | ||||
|         ); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,17 @@ | ||||
| package com.baeldung.algorithms.binarygap; | ||||
| 
 | ||||
| public class BinaryGap { | ||||
|     static int calculateBinaryGap(int n) { | ||||
|         return calculateBinaryGap(n >>> Integer.numberOfTrailingZeros(n), 0, 0); | ||||
|     } | ||||
| 
 | ||||
|     static int calculateBinaryGap(int n, int current, int maximum) { | ||||
|         if (n == 0) { | ||||
|             return maximum; | ||||
|         } else if ((n & 1) == 0) { | ||||
|             return calculateBinaryGap(n >>> 1, current + 1, maximum); | ||||
|         } else { | ||||
|             return calculateBinaryGap(n >>> 1, 0, Math.max(maximum, current)); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,83 @@ | ||||
| package com.baeldung.algorithms.caesarcipher; | ||||
| 
 | ||||
| import org.apache.commons.math3.stat.inference.ChiSquareTest; | ||||
| 
 | ||||
| import java.util.Arrays; | ||||
| import java.util.stream.IntStream; | ||||
| 
 | ||||
| public class CaesarCipher { | ||||
|     private static final char LETTER_A = 'a'; | ||||
|     private static final char LETTER_Z = 'z'; | ||||
|     private static final int ALPHABET_SIZE = LETTER_Z - LETTER_A + 1; | ||||
|     private static final double[] ENGLISH_LETTERS_PROBABILITIES = {0.073, 0.009, 0.030, 0.044, 0.130, 0.028, 0.016, 0.035, 0.074, 0.002, 0.003, 0.035, 0.025, 0.078, 0.074, 0.027, 0.003, 0.077, 0.063, 0.093, 0.027, 0.013, 0.016, 0.005, 0.019, 0.001}; | ||||
| 
 | ||||
|     public String cipher(String message, int offset) { | ||||
|         StringBuilder result = new StringBuilder(); | ||||
| 
 | ||||
|         for (char character : message.toCharArray()) { | ||||
|             if (character != ' ') { | ||||
|                 int originalAlphabetPosition = character - LETTER_A; | ||||
|                 int newAlphabetPosition = (originalAlphabetPosition + offset) % ALPHABET_SIZE; | ||||
|                 char newCharacter = (char) (LETTER_A + newAlphabetPosition); | ||||
|                 result.append(newCharacter); | ||||
|             } else { | ||||
|                 result.append(character); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return result.toString(); | ||||
|     } | ||||
| 
 | ||||
|     public String decipher(String message, int offset) { | ||||
|         return cipher(message, ALPHABET_SIZE - (offset % ALPHABET_SIZE)); | ||||
|     } | ||||
| 
 | ||||
|     public int breakCipher(String message) { | ||||
|         return probableOffset(chiSquares(message)); | ||||
|     } | ||||
| 
 | ||||
|     private double[] chiSquares(String message) { | ||||
|         double[] expectedLettersFrequencies = expectedLettersFrequencies(message.length()); | ||||
| 
 | ||||
|         double[] chiSquares = new double[ALPHABET_SIZE]; | ||||
| 
 | ||||
|         for (int offset = 0; offset < chiSquares.length; offset++) { | ||||
|             String decipheredMessage = decipher(message, offset); | ||||
|             long[] lettersFrequencies = observedLettersFrequencies(decipheredMessage); | ||||
|             double chiSquare = new ChiSquareTest().chiSquare(expectedLettersFrequencies, lettersFrequencies); | ||||
|             chiSquares[offset] = chiSquare; | ||||
|         } | ||||
| 
 | ||||
|         return chiSquares; | ||||
|     } | ||||
| 
 | ||||
|     private long[] observedLettersFrequencies(String message) { | ||||
|         return IntStream.rangeClosed(LETTER_A, LETTER_Z) | ||||
|           .mapToLong(letter -> countLetter((char) letter, message)) | ||||
|           .toArray(); | ||||
|     } | ||||
| 
 | ||||
|     private long countLetter(char letter, String message) { | ||||
|         return message.chars() | ||||
|           .filter(character -> character == letter) | ||||
|           .count(); | ||||
|     } | ||||
| 
 | ||||
|     private double[] expectedLettersFrequencies(int messageLength) { | ||||
|         return Arrays.stream(ENGLISH_LETTERS_PROBABILITIES) | ||||
|           .map(probability -> probability * messageLength) | ||||
|           .toArray(); | ||||
|     } | ||||
| 
 | ||||
|     private int probableOffset(double[] chiSquares) { | ||||
|         int probableOffset = 0; | ||||
|         for (int offset = 0; offset < chiSquares.length; offset++) { | ||||
|             System.out.println(String.format("Chi-Square for offset %d: %.2f", offset, chiSquares[offset])); | ||||
|             if (chiSquares[offset] < chiSquares[probableOffset]) { | ||||
|                 probableOffset = offset; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return probableOffset; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,36 @@ | ||||
| package com.baeldung.algorithms.knapsack; | ||||
| 
 | ||||
| public class Knapsack { | ||||
| 
 | ||||
|     public int knapsackRec(int[] w, int[] v, int n, int W) { | ||||
|         if (n <= 0) { | ||||
|             return 0; | ||||
|         } else if (w[n - 1] > W) { | ||||
|             return knapsackRec(w, v, n - 1, W); | ||||
|         } else { | ||||
|             return Math.max(knapsackRec(w, v, n - 1, W), v[n - 1] + knapsackRec(w, v, n - 1, W - w[n - 1])); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public int knapsackDP(int[] w, int[] v, int n, int W) { | ||||
|         if (n <= 0 || W <= 0) { | ||||
|             return 0; | ||||
|         } | ||||
| 
 | ||||
|         int[][] m = new int[n + 1][W + 1]; | ||||
|         for (int j = 0; j <= W; j++) { | ||||
|             m[0][j] = 0; | ||||
|         } | ||||
| 
 | ||||
|         for (int i = 1; i <= n; i++) { | ||||
|             for (int j = 1; j <= W; j++) { | ||||
|                 if (w[i - 1] > j) { | ||||
|                     m[i][j] = m[i - 1][j]; | ||||
|                 } else { | ||||
|                     m[i][j] = Math.max(m[i - 1][j], m[i - 1][j - w[i - 1]] + v[i - 1]); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return m[n][W]; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,26 @@ | ||||
| package com.baeldung.algorithms.balancedbinarytree; | ||||
| 
 | ||||
| import org.junit.Test; | ||||
| import static org.junit.Assert.assertTrue; | ||||
| import static org.junit.Assert.assertFalse; | ||||
| 
 | ||||
| public class BalancedBinaryTreeUnitTest extends BinaryTreeDataProvider { | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenBalancedTrees_whenCallingIsBalanced_ShouldReturnTrue() { | ||||
|         for (Tree tree : balancedTrees()) { | ||||
|             assertTrue(toString(tree) + " should be balanced", BalancedBinaryTree.isBalanced(tree)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenUnbalancedTrees_whenCallingIsBalanced_ShouldReturnFalse() { | ||||
|         for (Tree tree : unbalancedTrees()) { | ||||
|             assertFalse(toString(tree) + " should not be balanced", BalancedBinaryTree.isBalanced(tree)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private String toString(Tree tree) { | ||||
|         return tree != null ? tree.toString() : "null"; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,69 @@ | ||||
| package com.baeldung.algorithms.balancedbinarytree; | ||||
| 
 | ||||
| import java.util.Arrays; | ||||
| import java.util.Collection; | ||||
| 
 | ||||
| class BinaryTreeDataProvider { | ||||
| 
 | ||||
|     static Collection<Tree> balancedTrees() { | ||||
|         return Arrays.asList( | ||||
|             null, | ||||
|             leaf(1), | ||||
|             tree(1, leaf(2), leaf(3)), | ||||
|             tree( | ||||
|                 1, | ||||
|                 leaf(2), | ||||
|                 tree(3, leaf(4), null) | ||||
|             ), | ||||
|             tree( | ||||
|                 1, | ||||
|                 tree( | ||||
|                     2, | ||||
|                     tree(3, leaf(4), null), | ||||
|                     leaf(5) | ||||
|                 ), | ||||
|                 tree( | ||||
|                     6, | ||||
|                     leaf(7), | ||||
|                     tree(8, null, leaf(9)) | ||||
|                 ) | ||||
|             ) | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     static Collection<Tree> unbalancedTrees() { | ||||
|         return Arrays.asList( | ||||
|             tree( | ||||
|                 1, | ||||
|                 tree(2, leaf(3), null), | ||||
|                 null | ||||
|             ), | ||||
|             tree( | ||||
|                 1, | ||||
|                 tree( | ||||
|                     2, | ||||
|                     tree(3, leaf(4), leaf(5)), | ||||
|                     null | ||||
|                 ), | ||||
|                 tree(6, leaf(7), null) | ||||
|             ), | ||||
|             tree( | ||||
|                 1, | ||||
|                 tree(2, leaf(3), null), | ||||
|                 tree( | ||||
|                     4, | ||||
|                     tree(5, leaf(6), leaf(7)), | ||||
|                     null | ||||
|                 ) | ||||
|             ) | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     private static Tree leaf(int value) { | ||||
|         return new Tree(value, null, null); | ||||
|     } | ||||
| 
 | ||||
|     private static Tree tree(int value, Tree left, Tree right) { | ||||
|         return new Tree(value, left, right); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,34 @@ | ||||
| package com.baeldung.algorithms.binarygap; | ||||
| 
 | ||||
| import static com.baeldung.algorithms.binarygap.BinaryGap.calculateBinaryGap; | ||||
| import static org.junit.jupiter.api.Assertions.assertEquals; | ||||
| 
 | ||||
| import org.junit.jupiter.api.Test; | ||||
| 
 | ||||
| public class BinaryGapUnitTest { | ||||
| 
 | ||||
|     @Test public void givenNoOccurrenceOfBoundedZeros_whenCalculateBinaryGap_thenOutputCorrectResult() { | ||||
| 
 | ||||
|         int result = calculateBinaryGap(63); | ||||
|         assertEquals(0, result); | ||||
|     } | ||||
| 
 | ||||
|     @Test public void givenTrailingZeros_whenCalculateBinaryGap_thenOutputCorrectResult() { | ||||
| 
 | ||||
|         int result = calculateBinaryGap(40); | ||||
|         assertEquals(1, result); | ||||
|     } | ||||
| 
 | ||||
|     @Test public void givenSingleOccurrenceOfBoundedZeros_whenCalculateBinaryGap_thenOutputCorrectResult() { | ||||
| 
 | ||||
|         int result = calculateBinaryGap(9); | ||||
|         assertEquals(2, result); | ||||
|     } | ||||
| 
 | ||||
|     @Test public void givenMultipleOccurrenceOfBoundedZeros_whenCalculateBinaryGap_thenOutputCorrectResult() { | ||||
| 
 | ||||
|         int result = calculateBinaryGap(145); | ||||
|         assertEquals(3, result); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,83 @@ | ||||
| package com.baeldung.algorithms.caesarcipher; | ||||
| 
 | ||||
| import org.junit.jupiter.api.Test; | ||||
| 
 | ||||
| import static org.assertj.core.api.Assertions.assertThat; | ||||
| 
 | ||||
| class CaesarCipherUnitTest { | ||||
|     private static final String SENTENCE = "he told me i could never teach a llama to drive"; | ||||
|     private static final String SENTENCE_SHIFTED_THREE = "kh wrog ph l frxog qhyhu whdfk d oodpd wr gulyh"; | ||||
|     private static final String SENTENCE_SHIFTED_TEN = "ro dyvn wo s myevn xofob dokmr k vvkwk dy nbsfo"; | ||||
| 
 | ||||
|     private CaesarCipher algorithm = new CaesarCipher(); | ||||
| 
 | ||||
|     @Test | ||||
|     void givenSentenceAndShiftThree_whenCipher_thenCipheredMessageWithoutOverflow() { | ||||
|         String cipheredSentence = algorithm.cipher(SENTENCE, 3); | ||||
| 
 | ||||
|         assertThat(cipheredSentence) | ||||
|           .isEqualTo(SENTENCE_SHIFTED_THREE); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void givenSentenceAndShiftTen_whenCipher_thenCipheredMessageWithOverflow() { | ||||
|         String cipheredSentence = algorithm.cipher(SENTENCE, 10); | ||||
| 
 | ||||
|         assertThat(cipheredSentence) | ||||
|           .isEqualTo(SENTENCE_SHIFTED_TEN); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void givenSentenceAndShiftThirtySix_whenCipher_thenCipheredLikeTenMessageWithOverflow() { | ||||
|         String cipheredSentence = algorithm.cipher(SENTENCE, 36); | ||||
| 
 | ||||
|         assertThat(cipheredSentence) | ||||
|           .isEqualTo(SENTENCE_SHIFTED_TEN); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void givenSentenceShiftedThreeAndShiftThree_whenDecipher_thenOriginalSentenceWithoutOverflow() { | ||||
|         String decipheredSentence = algorithm.decipher(SENTENCE_SHIFTED_THREE, 3); | ||||
| 
 | ||||
|         assertThat(decipheredSentence) | ||||
|           .isEqualTo(SENTENCE); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void givenSentenceShiftedTenAndShiftTen_whenDecipher_thenOriginalSentenceWithOverflow() { | ||||
|         String decipheredSentence = algorithm.decipher(SENTENCE_SHIFTED_TEN, 10); | ||||
| 
 | ||||
|         assertThat(decipheredSentence) | ||||
|           .isEqualTo(SENTENCE); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void givenSentenceShiftedTenAndShiftThirtySix_whenDecipher_thenOriginalSentenceWithOverflow() { | ||||
|         String decipheredSentence = algorithm.decipher(SENTENCE_SHIFTED_TEN, 36); | ||||
| 
 | ||||
|         assertThat(decipheredSentence) | ||||
|           .isEqualTo(SENTENCE); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void givenSentenceShiftedThree_whenBreakCipher_thenOriginalSentence() { | ||||
|         int offset = algorithm.breakCipher(SENTENCE_SHIFTED_THREE); | ||||
| 
 | ||||
|         assertThat(offset) | ||||
|           .isEqualTo(3); | ||||
| 
 | ||||
|         assertThat(algorithm.decipher(SENTENCE_SHIFTED_THREE, offset)) | ||||
|           .isEqualTo(SENTENCE); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void givenSentenceShiftedTen_whenBreakCipher_thenOriginalSentence() { | ||||
|         int offset = algorithm.breakCipher(SENTENCE_SHIFTED_TEN); | ||||
| 
 | ||||
|         assertThat(offset) | ||||
|           .isEqualTo(10); | ||||
| 
 | ||||
|         assertThat(algorithm.decipher(SENTENCE_SHIFTED_TEN, offset)) | ||||
|           .isEqualTo(SENTENCE); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,44 @@ | ||||
| package com.baeldung.algorithms.knapsack; | ||||
| 
 | ||||
| import static org.junit.jupiter.api.Assertions.assertEquals; | ||||
| 
 | ||||
| import org.junit.jupiter.api.Test; | ||||
| 
 | ||||
| public class KnapsackUnitTest { | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenWeightsandValues_whenCalculateMax_thenOutputCorrectResult() { | ||||
|         final int[] w = new int[] { 23, 26, 20, 18, 32, 27, 29, 26, 30, 27 }; | ||||
|         final int[] v = new int[] { 505, 352, 458, 220, 354, 414, 498, 545, 473, 543 }; | ||||
|         final int n = 10; | ||||
|         final int W = 67; | ||||
|         final Knapsack knapsack = new Knapsack(); | ||||
| 
 | ||||
|         assertEquals(1270, knapsack.knapsackRec(w, v, n, W)); | ||||
|         assertEquals(1270, knapsack.knapsackDP(w, v, n, W)); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenZeroItems_whenCalculateMax_thenOutputZero() { | ||||
|         final int[] w = new int[] {}; | ||||
|         final int[] v = new int[] {}; | ||||
|         final int n = 0; | ||||
|         final int W = 67; | ||||
|         final Knapsack knapsack = new Knapsack(); | ||||
| 
 | ||||
|         assertEquals(0, knapsack.knapsackRec(w, v, n, W)); | ||||
|         assertEquals(0, knapsack.knapsackDP(w, v, n, W)); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenZeroWeightLimit_whenCalculateMax_thenOutputZero() { | ||||
|         final int[] w = new int[] { 23, 26, 20, 18, 32, 27, 29, 26, 30, 27 }; | ||||
|         final int[] v = new int[] { 505, 352, 458, 220, 354, 414, 498, 545, 473, 543 }; | ||||
|         final int n = 10; | ||||
|         final int W = 0; | ||||
|         final Knapsack knapsack = new Knapsack(); | ||||
| 
 | ||||
|         assertEquals(0, knapsack.knapsackRec(w, v, n, W)); | ||||
|         assertEquals(0, knapsack.knapsackDP(w, v, n, W)); | ||||
|     } | ||||
| } | ||||
| @ -1,9 +1,20 @@ | ||||
| ## Relevant articles: | ||||
| ## Algorithms - Sorting | ||||
| 
 | ||||
| - [Bubble Sort in Java](http://www.baeldung.com/java-bubble-sort) | ||||
| This module contains articles about sorting algorithms. | ||||
| 
 | ||||
| ### Relevant articles: | ||||
| 
 | ||||
| - [Bubble Sort in Java](https://www.baeldung.com/java-bubble-sort) | ||||
| - [Merge Sort in Java](https://www.baeldung.com/java-merge-sort) | ||||
| - [Quicksort Algorithm Implementation in Java](https://www.baeldung.com/java-quicksort) | ||||
| - [Insertion Sort in Java](https://www.baeldung.com/java-insertion-sort) | ||||
| - [Heap Sort in Java](https://www.baeldung.com/java-heap-sort) | ||||
| - [Shell Sort in Java](https://www.baeldung.com/java-shell-sort) | ||||
| - [Counting Sort in Java](https://www.baeldung.com/java-counting-sort) | ||||
| - [Sorting Strings by Contained Numbers in Java](https://www.baeldung.com/java-sort-strings-contained-numbers) | ||||
| - [How an In-Place Sorting Algorithm Works](https://www.baeldung.com/java-in-place-sorting) | ||||
| - [Selection Sort in Java](https://www.baeldung.com/java-selection-sort) | ||||
| - [Sorting Strings by Contained Numbers in Java](https://www.baeldung.com/java-sort-strings-contained-numbers) | ||||
| - [Radix Sort in Java](https://www.baeldung.com/java-radix-sort) | ||||
| - [Sorting a String Alphabetically in Java](https://www.baeldung.com/java-sort-string-alphabetically) | ||||
| - [Bucket Sort in Java](https://www.baeldung.com/java-bucket-sort) | ||||
|  | ||||
| @ -28,6 +28,12 @@ | ||||
|             <version>${lombok.version}</version> | ||||
|             <scope>provided</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.junit.jupiter</groupId> | ||||
|             <artifactId>junit-jupiter-api</artifactId> | ||||
|             <version>${junit-jupiter-api.version}</version> | ||||
|             <scope>test</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.assertj</groupId> | ||||
|             <artifactId>assertj-core</artifactId> | ||||
| @ -52,6 +58,7 @@ | ||||
|         <commons-math3.version>3.6.1</commons-math3.version> | ||||
|         <org.assertj.core.version>3.9.0</org.assertj.core.version> | ||||
|         <commons-codec.version>1.11</commons-codec.version> | ||||
|         <junit-jupiter-api.version>5.3.1</junit-jupiter-api.version> | ||||
|     </properties> | ||||
| 
 | ||||
| </project> | ||||
| @ -0,0 +1,68 @@ | ||||
| package com.baeldung.bucketsort; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.Comparator; | ||||
| import java.util.LinkedList; | ||||
| import java.util.List; | ||||
| 
 | ||||
| public class IntegerBucketSorter implements Sorter<Integer> { | ||||
| 
 | ||||
|     private final Comparator<Integer> comparator; | ||||
| 
 | ||||
|     public IntegerBucketSorter(Comparator<Integer> comparator) { | ||||
|         this.comparator = comparator; | ||||
|     } | ||||
| 
 | ||||
|     public IntegerBucketSorter() { | ||||
|         comparator = Comparator.naturalOrder(); | ||||
|     } | ||||
| 
 | ||||
|     public List<Integer> sort(List<Integer> arrayToSort) { | ||||
| 
 | ||||
|         List<List<Integer>> buckets = splitIntoUnsortedBuckets(arrayToSort); | ||||
| 
 | ||||
|         for(List<Integer> bucket  : buckets){ | ||||
|             bucket.sort(comparator); | ||||
|         } | ||||
| 
 | ||||
|         return concatenateSortedBuckets(buckets); | ||||
|     } | ||||
| 
 | ||||
|     private List<Integer> concatenateSortedBuckets(List<List<Integer>> buckets){ | ||||
|         List<Integer> sortedArray = new LinkedList<>(); | ||||
|         for(List<Integer> bucket : buckets){ | ||||
|             sortedArray.addAll(bucket); | ||||
|         } | ||||
|         return sortedArray; | ||||
|     } | ||||
| 
 | ||||
|     private List<List<Integer>> splitIntoUnsortedBuckets(List<Integer> initialList){ | ||||
| 
 | ||||
|         final int max = findMax(initialList); | ||||
|         final int numberOfBuckets = (int) Math.sqrt(initialList.size()); | ||||
| 
 | ||||
|         List<List<Integer>> buckets = new ArrayList<>(); | ||||
|         for(int i = 0; i < numberOfBuckets; i++) buckets.add(new ArrayList<>()); | ||||
| 
 | ||||
|         //distribute the data | ||||
|         for (int i : initialList) { | ||||
|             buckets.get(hash(i, max, numberOfBuckets)).add(i); | ||||
|         } | ||||
|         return buckets; | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     private int findMax(List<Integer> input){ | ||||
|         int m = Integer.MIN_VALUE; | ||||
|         for (int i : input){ | ||||
|             m = Math.max(i, m); | ||||
|         } | ||||
|         return m; | ||||
|     } | ||||
| 
 | ||||
|     private static int hash(int i, int max, int numberOfBuckets) { | ||||
|         return (int) ((double) i / max * (numberOfBuckets - 1)); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| @ -1,4 +1,4 @@ | ||||
| package com.baeldung.string.sorting; | ||||
| package com.baeldung.algorithms.stringsort; | ||||
| 
 | ||||
| import java.util.Arrays; | ||||
| 
 | ||||
| @ -1,12 +1,10 @@ | ||||
| package com.baeldung.string.sorting; | ||||
| package com.baeldung.algorithms.stringsort; | ||||
| 
 | ||||
| 
 | ||||
| import static org.junit.jupiter.api.Assertions.assertTrue; | ||||
| import static org.junit.jupiter.api.Assertions.assertFalse; | ||||
| 
 | ||||
| import org.junit.jupiter.api.Test; | ||||
| 
 | ||||
| import com.baeldung.string.sorting.AnagramValidator; | ||||
| import static org.junit.jupiter.api.Assertions.assertFalse; | ||||
| import static org.junit.jupiter.api.Assertions.assertTrue; | ||||
| 
 | ||||
| class AnagramValidatorUnitTest { | ||||
|      | ||||
| @ -1,9 +1,9 @@ | ||||
| package com.baeldung.string.sorting; | ||||
| 
 | ||||
| import java.util.Arrays; | ||||
| package com.baeldung.algorithms.stringsort; | ||||
| 
 | ||||
| import org.junit.jupiter.api.Test; | ||||
| 
 | ||||
| import java.util.Arrays; | ||||
| 
 | ||||
| import static org.assertj.core.api.Assertions.assertThat; | ||||
| 
 | ||||
| class SortStringUnitTest { | ||||
| @ -1,3 +1,7 @@ | ||||
| ## Relevant articles: | ||||
| ## Animal Sniffer Maven Plugin | ||||
| 
 | ||||
| [Introduction to Animal Sniffer Maven Plugin](http://www.baeldung.com/maven-animal-sniffer) | ||||
| This module contains articles about the Animal Sniffer Maven Plugin | ||||
| 
 | ||||
| ### Relevant articles: | ||||
| 
 | ||||
| [Introduction to Animal Sniffer Maven Plugin](https://www.baeldung.com/maven-animal-sniffer) | ||||
|  | ||||
| @ -1,7 +1,6 @@ | ||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
|     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> | ||||
|     <modelVersion>4.0.0</modelVersion> | ||||
|     <groupId>com.baeldung</groupId> | ||||
|     <artifactId>animal-sniffer-mvn-plugin</artifactId> | ||||
|     <version>1.0-SNAPSHOT</version> | ||||
|     <name>animal-sniffer-mvn-plugin</name> | ||||
|  | ||||
							
								
								
									
										7
									
								
								annotations/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								annotations/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| ## Annotations | ||||
| 
 | ||||
| This module contains articles about Java annotations | ||||
| 
 | ||||
| ### Relevant Articles: | ||||
| 
 | ||||
| - [Java Annotation Processing and Creating a Builder](https://www.baeldung.com/java-annotation-processing-builder) | ||||
| @ -1,2 +0,0 @@ | ||||
| ### Relevant Articles: | ||||
| - [Java Annotation Processing and Creating a Builder](http://www.baeldung.com/java-annotation-processing-builder) | ||||
| @ -1,3 +1,7 @@ | ||||
| ## ANTLR | ||||
| 
 | ||||
| This module contains articles about ANTLR | ||||
| 
 | ||||
| ### Relevant Articles:  | ||||
| 
 | ||||
| - [Java with ANTLR](http://www.baeldung.com/java-antlr) | ||||
| - [Java with ANTLR](https://www.baeldung.com/java-antlr) | ||||
|  | ||||
| @ -1,2 +1,6 @@ | ||||
| ## Apache Avro | ||||
| 
 | ||||
| This module contains articles about Apache Avro | ||||
| 
 | ||||
| ### Relevant Articles: | ||||
| - [Guide to Apache Avro](http://www.baeldung.com/java-apache-avro) | ||||
| - [Guide to Apache Avro](https://www.baeldung.com/java-apache-avro) | ||||
|  | ||||
| @ -14,12 +14,6 @@ | ||||
|     </parent> | ||||
| 
 | ||||
|     <dependencies> | ||||
|         <dependency> | ||||
|             <groupId>junit</groupId> | ||||
|             <artifactId>junit</artifactId> | ||||
|             <version>${junit.version}</version> | ||||
|             <scope>test</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.slf4j</groupId> | ||||
|             <artifactId>slf4j-simple</artifactId> | ||||
| @ -46,15 +40,6 @@ | ||||
| 
 | ||||
|     <build> | ||||
|         <plugins> | ||||
|             <plugin> | ||||
|                 <groupId>org.apache.maven.plugins</groupId> | ||||
|                 <artifactId>maven-compiler-plugin</artifactId> | ||||
|                 <version>${compiler-plugin.version}</version> | ||||
|                 <configuration> | ||||
|                     <source>${java.version}</source> | ||||
|                     <target>${java.version}</target> | ||||
|                 </configuration> | ||||
|             </plugin> | ||||
|             <plugin> | ||||
|                 <groupId>org.apache.avro</groupId> | ||||
|                 <artifactId>avro-maven-plugin</artifactId> | ||||
| @ -79,8 +64,6 @@ | ||||
|     </build> | ||||
| 
 | ||||
|     <properties> | ||||
|         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||||
|         <compiler-plugin.version>3.5</compiler-plugin.version> | ||||
|         <avro.version>1.8.2</avro.version> | ||||
|         <slf4j.version>1.7.25</slf4j.version> | ||||
|     </properties> | ||||
|  | ||||
| @ -1,2 +1,7 @@ | ||||
| ## Apache BVal | ||||
| 
 | ||||
| This module contains articles about Apache BVal | ||||
| 
 | ||||
| ### Relevant Articles: | ||||
| - [Intro to Apache BVal](http://www.baeldung.com/apache-bval) | ||||
| 
 | ||||
| - [Intro to Apache BVal](https://www.baeldung.com/apache-bval) | ||||
|  | ||||
| @ -1,3 +1,7 @@ | ||||
| ## Apache Curator | ||||
| 
 | ||||
| This module contains articles about Apache Curator | ||||
| 
 | ||||
| ### Relevant Articles: | ||||
| 
 | ||||
| - [Introduction to Apache Curator](http://www.baeldung.com/apache-curator) | ||||
| - [Introduction to Apache Curator](https://www.baeldung.com/apache-curator) | ||||
|  | ||||
| @ -1,6 +1,10 @@ | ||||
| ## Apache CXF | ||||
| 
 | ||||
| This module contains articles about Apache CXF | ||||
| 
 | ||||
| ## Relevant Articles: | ||||
| - [Introduction to Apache CXF Aegis Data Binding](http://www.baeldung.com/aegis-data-binding-in-apache-cxf) | ||||
| - [Apache CXF Support for RESTful Web Services](http://www.baeldung.com/apache-cxf-rest-api) | ||||
| - [A Guide to Apache CXF with Spring](http://www.baeldung.com/apache-cxf-with-spring) | ||||
| - [Introduction to Apache CXF](http://www.baeldung.com/introduction-to-apache-cxf) | ||||
| - [Introduction to Apache CXF Aegis Data Binding](https://www.baeldung.com/aegis-data-binding-in-apache-cxf) | ||||
| - [Apache CXF Support for RESTful Web Services](https://www.baeldung.com/apache-cxf-rest-api) | ||||
| - [A Guide to Apache CXF with Spring](https://www.baeldung.com/apache-cxf-with-spring) | ||||
| - [Introduction to Apache CXF](https://www.baeldung.com/introduction-to-apache-cxf) | ||||
| - [Server-Sent Events (SSE) In JAX-RS](https://www.baeldung.com/java-ee-jax-rs-sse) | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| ========= | ||||
| ## Apache FOP | ||||
| 
 | ||||
| ## Core Java Cookbooks and Examples | ||||
| This module contains articles about Apache FOP | ||||
| 
 | ||||
| ### Relevant Articles:  | ||||
|  | ||||
| @ -1,7 +1,6 @@ | ||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
|     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||
|     <modelVersion>4.0.0</modelVersion> | ||||
|     <groupId>com.baeldung</groupId> | ||||
|     <artifactId>apache-fop</artifactId> | ||||
|     <version>0.1-SNAPSHOT</version> | ||||
|     <name>apache-fop</name> | ||||
|  | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| @ -1,3 +1,7 @@ | ||||
| ## Apache Geode | ||||
| 
 | ||||
| This module contains articles about Apache Geode | ||||
| 
 | ||||
| ### Relevant Articles:  | ||||
| 
 | ||||
| - [A Quick Guide to Apache Geode](https://www.baeldung.com/apache-geode) | ||||
|  | ||||
| @ -19,25 +19,7 @@ | ||||
|             <artifactId>geode-core</artifactId> | ||||
|             <version>${geode.core}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>junit</groupId> | ||||
|             <artifactId>junit</artifactId> | ||||
|             <version>${junit.version}</version> | ||||
|         </dependency> | ||||
|     </dependencies> | ||||
|      | ||||
|     <build> | ||||
|         <plugins> | ||||
|             <plugin> | ||||
|                 <groupId>org.apache.maven.plugins</groupId> | ||||
|                 <artifactId>maven-compiler-plugin</artifactId> | ||||
|                 <configuration> | ||||
|                     <source>${java.version}</source> | ||||
|                     <target>${java.version}</target> | ||||
|                 </configuration> | ||||
|             </plugin> | ||||
|         </plugins> | ||||
|     </build> | ||||
| 	 | ||||
|     <properties> | ||||
|         <geode.core>1.6.0</geode.core> | ||||
|  | ||||
| @ -1,3 +1,7 @@ | ||||
| ## Apache Meecrowave | ||||
| 
 | ||||
| This module contains articles about Apache Meecrowave | ||||
| 
 | ||||
| ### Relevant Articles:  | ||||
| ================================ | ||||
| - [Building a Microservice with Apache Meecrowave](http://www.baeldung.com/apache-meecrowave) | ||||
| 
 | ||||
| - [Building a Microservice with Apache Meecrowave](https://www.baeldung.com/apache-meecrowave) | ||||
| @ -1,7 +1,6 @@ | ||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
|     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||
|     <modelVersion>4.0.0</modelVersion> | ||||
|     <groupId>com.baeldung</groupId> | ||||
|     <artifactId>apache-meecrowave</artifactId> | ||||
|     <version>0.0.1</version> | ||||
|     <name>apache-meecrowave</name> | ||||
| @ -38,13 +37,6 @@ | ||||
|             <version>${meecrowave-junit.version}</version> | ||||
|             <scope>test</scope> | ||||
|         </dependency> | ||||
|         <!-- https://mvnrepository.com/artifact/junit/junit --> | ||||
|         <dependency> | ||||
|             <groupId>junit</groupId> | ||||
|             <artifactId>junit</artifactId> | ||||
|             <version>${junit.version}</version> | ||||
|             <scope>test</scope> | ||||
|         </dependency> | ||||
|     </dependencies> | ||||
| 	 | ||||
|     <build> | ||||
|  | ||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user