-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
464 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4"> | ||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8"> | ||
<output url="file://$MODULE_DIR$/target/classes" /> | ||
<output-test url="file://$MODULE_DIR$/target/test-classes" /> | ||
<content url="file://$MODULE_DIR$"> | ||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" /> | ||
<excludeFolder url="file://$MODULE_DIR$/target" /> | ||
</content> | ||
<orderEntry type="inheritedJdk" /> | ||
<orderEntry type="sourceFolder" forTests="false" /> | ||
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.11" level="project" /> | ||
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" /> | ||
</component> | ||
</module> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
|
||
<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.demo</groupId> | ||
<artifactId>demo</artifactId> | ||
<version>1.0-SNAPSHOT</version> | ||
|
||
<name>demo</name> | ||
|
||
<properties> | ||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
<maven.compiler.source>1.8</maven.compiler.source> | ||
<maven.compiler.target>1.8</maven.compiler.target> | ||
</properties> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>junit</groupId> | ||
<artifactId>junit</artifactId> | ||
<version>4.11</version> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
|
||
<build> | ||
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --> | ||
<plugins> | ||
<plugin> | ||
<artifactId>maven-clean-plugin</artifactId> | ||
<version>3.0.0</version> | ||
</plugin> | ||
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging --> | ||
<plugin> | ||
<artifactId>maven-resources-plugin</artifactId> | ||
<version>3.0.2</version> | ||
</plugin> | ||
<plugin> | ||
<artifactId>maven-compiler-plugin</artifactId> | ||
<version>3.7.0</version> | ||
</plugin> | ||
<plugin> | ||
<artifactId>maven-surefire-plugin</artifactId> | ||
<version>2.20.1</version> | ||
</plugin> | ||
<plugin> | ||
<artifactId>maven-jar-plugin</artifactId> | ||
<version>3.0.2</version> | ||
</plugin> | ||
<plugin> | ||
<artifactId>maven-install-plugin</artifactId> | ||
<version>2.5.2</version> | ||
</plugin> | ||
<plugin> | ||
<artifactId>maven-deploy-plugin</artifactId> | ||
<version>2.8.2</version> | ||
</plugin> | ||
</plugins> | ||
</pluginManagement> | ||
</build> | ||
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package com.demo; | ||
|
||
public class App | ||
{ | ||
public static void main( String[] args ) { | ||
|
||
} | ||
} |
58 changes: 58 additions & 0 deletions
58
hierarchical-parentheses/src/main/java/com/demo/Equation.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package com.demo; | ||
|
||
public class Equation { | ||
private String input; | ||
|
||
/** | ||
* Constructor to set an equation as a string. E.g. "{[(2 + 5) * (2 + 1)] * 2 + 1} * 3" | ||
* @param input the equation. | ||
*/ | ||
public Equation(String input) { | ||
this.input = input; | ||
} | ||
|
||
/** | ||
* Checks if the hierarchy of the parenthesis is valid. | ||
* Validity rules: | ||
* - contains only `(), [], {}` braces | ||
* - all open braces are also closed | ||
* - hierarchy of braces is in the following order: `{[()]}` or `{{{[()]}}}` | ||
* | ||
* @return [boolean] if equation parenthesis are valid. | ||
*/ | ||
public boolean isValid() { | ||
Node root = new Node(true); | ||
|
||
try { | ||
return input.chars() | ||
.filter(c -> Node.OPEN_CLOSE_BRACES.containsKey((char)c) || Node.OPEN_CLOSE_BRACES.containsValue((char)c)) | ||
.mapToObj(v -> new Node((char) v)) | ||
.reduce(root, (currentNode, node) -> { | ||
if (node.isOpenBrace()) { | ||
if (currentNode.canContain(node)) { | ||
node.setParent(currentNode); | ||
currentNode.getChildren().add(node); | ||
return node; | ||
} else throw new BrokenEquationException(currentNode.getValue()+" can not contain subnode "+node.getValue()); | ||
} else { // else is close brace | ||
if (currentNode.isCloseableWith(node) && currentNode.isHierarchicallyComplete()) | ||
return currentNode.getParent(); | ||
else throw new BrokenEquationException(currentNode.getValue()+" is not closeable with "+node.getValue()+" or node does not have any hierarchical sub brace."); | ||
} | ||
}).isRoot(); | ||
} catch (BrokenEquationException ex) { | ||
return false; | ||
} | ||
|
||
} | ||
|
||
public class BrokenEquationException extends RuntimeException { | ||
public BrokenEquationException() { | ||
super(); | ||
} | ||
public BrokenEquationException(String message) { | ||
super(message); | ||
} | ||
} | ||
} | ||
|
203 changes: 203 additions & 0 deletions
203
hierarchical-parentheses/src/main/java/com/demo/Node.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,203 @@ | ||
package com.demo; | ||
|
||
import java.util.*; | ||
|
||
public class Node { | ||
/** | ||
* Contains a map of open and corresponding closing braces. | ||
*/ | ||
protected static final Map<Character, Character> OPEN_CLOSE_BRACES = new HashMap<>(); | ||
|
||
/** | ||
* Each brace should have a weight. | ||
* Starting from most inner brace until most exterior brace they should be weighted in order with a step of 1. | ||
*/ | ||
private static final Map<Character, Integer> WEIGHT = new HashMap<>(); | ||
|
||
/** | ||
* The minimum weight of the braces. | ||
*/ | ||
private static final int MIN_WEIGHT; | ||
|
||
/** | ||
* The maximum weight of the braces. | ||
*/ | ||
private static final int MAX_WEIGHT; | ||
|
||
/* | ||
* Braces configuration. | ||
*/ | ||
static { | ||
OPEN_CLOSE_BRACES.put('(', ')'); | ||
OPEN_CLOSE_BRACES.put('[', ']'); | ||
OPEN_CLOSE_BRACES.put('{', '}'); | ||
// OPEN_CLOSE_BRACES.put('<', '>'); | ||
|
||
WEIGHT.put('(', 1); | ||
WEIGHT.put('[', 2); | ||
WEIGHT.put('{', 3); | ||
// WEIGHT.put('<', 4); | ||
|
||
MIN_WEIGHT = WEIGHT.values().stream().min(Integer::compareTo).orElseThrow(IllegalArgumentException::new); | ||
MAX_WEIGHT = WEIGHT.values().stream().max(Integer::compareTo).orElseThrow(IllegalArgumentException::new); | ||
} | ||
|
||
/** | ||
* It is the starting node that does not contain any value. | ||
*/ | ||
private boolean isRoot; | ||
|
||
/** | ||
* The opening or closing brace of current node. | ||
*/ | ||
private Character value; | ||
private Node parent; | ||
private List<Node> children; | ||
// private boolean isClosed; // YAGNI | ||
|
||
public Node() { | ||
isRoot = false; | ||
children = new ArrayList<>(); | ||
} | ||
|
||
public Node(Character value) { | ||
this(); | ||
this.value = value; | ||
} | ||
|
||
public Node(boolean isRoot) { | ||
this(); | ||
this.isRoot = isRoot; | ||
} | ||
|
||
public Node(Character value, Node parent) { | ||
this(); | ||
this.value = value; | ||
this.parent = parent; | ||
} | ||
|
||
/** | ||
* Checks if current node contains a value of an opening brace. | ||
* | ||
* @return [boolean] | ||
*/ | ||
public boolean isOpenBrace() { | ||
return OPEN_CLOSE_BRACES.containsKey(value); | ||
} | ||
|
||
/** | ||
* Checks if current node contains a value of an closing brace. | ||
* | ||
* @return [boolean] | ||
*/ | ||
public boolean isClosedBrace() { | ||
return OPEN_CLOSE_BRACES.containsValue(value); | ||
} | ||
|
||
/** | ||
* Checks if node can hierarchically be a subnode of current node. | ||
* | ||
* @param node the new node | ||
* @return [boolean] | ||
*/ | ||
public boolean canContain(Node node) { | ||
return isRoot() || (getWeight() > node.getWeight()) || (getWeight()==MAX_WEIGHT && node.getWeight()==MAX_WEIGHT); | ||
} | ||
|
||
/** | ||
* If current node is root node. | ||
* | ||
* @return [boolean] | ||
*/ | ||
public boolean isRoot() { | ||
return isRoot; | ||
} | ||
|
||
/** | ||
* Checks if current node can be closed with specified node. | ||
* | ||
* @param closingNode the node to close current node with | ||
* @return [boolean] | ||
*/ | ||
public boolean isCloseableWith(Node closingNode) { | ||
return OPEN_CLOSE_BRACES.get(value).equals(closingNode.getValue()); | ||
} | ||
|
||
/** | ||
* Checks if current node is hierarchically complete. If it's the lowest weighted or has any direct hierarchical subbraces. | ||
* | ||
* @return [boolean] | ||
*/ | ||
public boolean isHierarchicallyComplete() { | ||
return (getWeight()==MIN_WEIGHT) || hasAnyHierarchicalSubBrace(); | ||
} | ||
|
||
/** | ||
* Checks if current node has any direct hierarchical subbraces. | ||
* | ||
* @return [boolean] | ||
*/ | ||
private boolean hasAnyHierarchicalSubBrace() { | ||
return getChildren().stream().anyMatch(childNode -> (childNode.getWeight()+1==getWeight()) || (childNode.getWeight()==MAX_WEIGHT && getWeight()==MAX_WEIGHT)); | ||
} | ||
|
||
/** | ||
* Returns the weight of the current node from the weight Set. | ||
* | ||
* @return [int] | ||
*/ | ||
public int getWeight() { | ||
return WEIGHT.get(value); | ||
} | ||
|
||
public Character getValue() { | ||
return value; | ||
} | ||
|
||
public void setValue(Character value) { | ||
this.value = value; | ||
} | ||
|
||
public Node getParent() { | ||
return parent; | ||
} | ||
|
||
public void setParent(Node parent) { | ||
this.parent = parent; | ||
} | ||
|
||
public List<Node> getChildren() { | ||
return children; | ||
} | ||
|
||
public void setChildren(List<Node> children) { | ||
this.children = children; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) return true; | ||
if (o == null || getClass() != o.getClass()) return false; | ||
Node node = (Node) o; | ||
return isRoot == node.isRoot && | ||
Objects.equals(value, node.value) && | ||
Objects.equals(parent, node.parent) && | ||
Objects.equals(children, node.children); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(isRoot, value, parent, children); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
final StringBuffer sb = new StringBuffer("Node{"); | ||
sb.append("isRoot=").append(isRoot); | ||
sb.append(", value=").append(value); | ||
sb.append(", parent=").append(parent); | ||
sb.append(", children=").append(children); | ||
sb.append('}'); | ||
return sb.toString(); | ||
} | ||
} |
Oops, something went wrong.