123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792 |
- import java.io.PrintStream;
- import java.util.HashSet;
- import java.util.Iterator;
- public class Node
- {
- Node parent;
- String venn;
- HashSet<Node> children;
- HashSet<Node> linkNodes;
- Node linkNode;
- public Node(Node p, String s)
- {
- this.linkNode = null;
- this.linkNodes = new HashSet<Node>();
- this.venn = s;
- this.parent = p;
- this.children = new HashSet<Node>();
- if (s.length() > 1)
- setChildren(s);
- }
- private void setChildren(String s)
- {
- try
- {
- String vennChildren = s.substring(1, s.length() - 1);
- int count = 0;
- while (count < vennChildren.length())
- if (vennChildren.charAt(count) == '(') {
- int start = count;
- count++;
- int end = 0;
- int brackets = 1;
- while (true)
- {
- if (vennChildren.charAt(count) == '(') {
- brackets++;
- }
- if (vennChildren.charAt(count) == ')') {
- brackets--;
- if (brackets == 0) {
- count++;
- break;
- }
- }
- count++;
- }
- end = count;
- Node child = new Node(this, vennChildren.substring(start, end));
- this.children.add(child);
- } else {
- Node child = new Node(this, vennChildren.charAt(count));
- this.children.add(child);
- count++;
- }
- }
- catch (StringIndexOutOfBoundsException se) {
- throw new BracketException();
- }
- }
- public String getVenn()
- {
- return this.venn;
- }
- public String toString()
- {
- return this.venn;
- }
- public HashSet<Node> getSiblings() {
- if (this.parent != null) {
- HashSet sibs = (HashSet)this.parent.children.clone();
- sibs.remove(this);
- return sibs;
- }
- return new HashSet();
- }
- public boolean equals(Node node)
- {
- String nodeVenn = node.getVenn();
- if ((nodeVenn.length() == 1) &&
- (this.venn.length() == nodeVenn.length())) {
- return nodeVenn.equals(this.venn);
- }
- Iterator nodeIt = node.children.iterator();
- int itCount = 0;
- int eqCount = 0;
- while (nodeIt.hasNext()) {
- Iterator it = this.children.iterator();
- Node toCheck = (Node)nodeIt.next();
- itCount++;
- while (it.hasNext()) {
- if (((Node)it.next()).equals(toCheck)) {
- eqCount++;
- break;
- }
- }
- }
- if (itCount != eqCount) {
- return false;
- }
- itCount = 0;
- eqCount = 0;
- Iterator it = this.children.iterator();
- while (it.hasNext()) {
- Iterator nIt = node.children.iterator();
- Node toCheck = (Node)it.next();
- itCount++;
- while (nIt.hasNext()) {
- if (toCheck.equals((Node)nIt.next())) {
- eqCount++;
- break;
- }
- }
- }
- return itCount == eqCount;
- }
- public boolean equals(Object o)
- {
- Node n = (Node)o;
- return equals(n);
- }
- private int getNumAreas() {
- int count = 0;
- for (int i = 0; i < this.venn.length(); i++) {
- if ((this.venn.charAt(i) != ')') && (this.venn.charAt(i) != '(')) {
- count++;
- }
- }
- return count;
- }
- public HashSet<Node> reducedCombine(Node node) {
- HashSet result = new HashSet();
- if (oneAreaShared(this, node)) {
- result.add(combineAtRoot(node));
- return result;
- }
- HashSet compCombine = combine(node);
- Iterator it = compCombine.iterator();
- if (!it.hasNext()) {
- return result;
- }
- Node curr = (Node)it.next();
- int smallest = curr.getNumAreas();
- result.add(curr);
- while (it.hasNext()) {
- Node curr = (Node)it.next();
- int currAreas = curr.getNumAreas();
- if (currAreas < smallest) {
- smallest = currAreas;
- result.clear();
- result.add(curr);
- } else if (currAreas == smallest) {
- result.add(curr);
- }
- }
- return removeDuplicates(result);
- }
- private HashSet<Node> removeDuplicates(HashSet<Node> h) {
- Iterator it = h.iterator();
- HashSet result = new HashSet();
- while (it.hasNext()) {
- Node curr = (Node)it.next();
- if (!contains(curr, result)) {
- result.add(curr);
- }
- }
- return result;
- }
- private boolean oneAreaShared(Node node1, Node node2)
- {
- HashSet result = new HashSet();
- node2.deepSearch(node1, result);
- HashSet largest = getLNodes(result);
- if (largest.isEmpty()) {
- return false;
- }
- return (Nodes.setNodesSize(largest) == 1) && (largest.size() == 1);
- }
- public HashSet<Node> combine(Node node) {
- Node node1 = node.reduce();
- Node node2 = reduce();
- node2.resetSearch();
- node1.resetSearch();
- HashSet result = new HashSet();
- if (node1.equals(node2)) {
- result.add(node2);
- return result;
- }
- HashSet sResult = new HashSet();
- node2.deepSearch(node1, sResult);
- if (sResult.isEmpty()) {
- result.add(node2.combineAtRoot(node1));
- return result;
- }
- HashSet largest = getLNodes(sResult);
- HashSet unsharedNodes = new HashSet();
- node2.collectUnshared(unsharedNodes);
- node1.collectUnshared(unsharedNodes);
- if ((unsharedNodes.isEmpty()) && (node1.getNumAreas() == node2.getNumAreas())) {
- if (node1.children.size() < node2.children.size()) {
- Node toAdd = new Node(null, node1.getVenn());
- result.add(toAdd);
- return result;
- }if (node2.children.size() < node1.children.size()) {
- Node toAdd = new Node(null, node2.getVenn());
- result.add(toAdd);
- return result;
- }
- }
- if (largest.size() > 0)
- {
- Iterator itLargest = largest.iterator();
- Nodes flargest = (Nodes)itLargest.next();
- HashSet lg1sibs = flargest.node1.getSiblings();
- HashSet lg2sibs = flargest.node2.getSiblings();
- HashSet newSibs = new HashSet();
- HashSet otherSibs1 = new HashSet();
- HashSet otherSibs2 = new HashSet();
- Iterator lg1It = lg1sibs.iterator();
- Iterator lg2It = lg2sibs.iterator();
- sortLargestSibs(lg1It, flargest.node2, newSibs, otherSibs1);
- sortLargestSibs(lg2It, flargest.node1, newSibs, otherSibs2);
- Iterator nsIt = newSibs.iterator();
- if ((otherSibs1.isEmpty()) && (otherSibs2.isEmpty())) {
- while (nsIt.hasNext()) {
- unsharedNodes.add((Node)nsIt.next());
- }
- }
- }
- HashSet newLinkedNodes = getLinkedNodes(unsharedNodes);
- HashSet polys = reviewPolys(newLinkedNodes);
- if (!polys.isEmpty())
- {
- Iterator polyIt = polys.iterator();
- if (polyIt.hasNext()) {
- HashSet polyresult = addPolys((HashSet)polyIt.next());
- Iterator prIt = polyresult.iterator();
- if (prIt.hasNext()) {
- Nodes curr = (Nodes)prIt.next();
- if ((curr.node1.parent != null) && (curr.node1.linkNode.parent != null)) {
- String polyString1 = buildUp(curr.node1.parent, curr.node2.getVenn());
- String polyString2 = buildUp(curr.node1.linkNode.parent, curr.node2.getVenn());
- Node polyOne = new Node(null, polyString1);
- Node polyTwo = new Node(null, polyString2);
- HashSet polyresults = polyOne.combine(polyTwo);
- Iterator prsIt = polyresults.iterator();
- while (prsIt.hasNext())
- result.add((Node)prsIt.next());
- }
- else if (curr.node1.parent != null) {
- String polyString1 = buildUp(curr.node1.parent, curr.node2.getVenn());
- Node polyOne = new Node(null, polyString1);
- result.add(polyOne);
- } else if (curr.node1.linkNode.parent != null) {
- String polyString2 = buildUp(curr.node1.linkNode.parent, curr.node2.getVenn());
- Node polyTwo = new Node(null, polyString2);
- result.add(polyTwo);
- } else {
- System.out.println("What's up Houston?");
- }
- }
- }
- return result;
- }
- Iterator nLNit = newLinkedNodes.iterator();
- if (nLNit.hasNext()) {
- HashSet combined = ((Nodes)nLNit.next()).combineNew();
- Iterator cIt = combined.iterator();
- while (cIt.hasNext()) {
- Nodes curr = (Nodes)cIt.next();
- HashSet newResults = curr.node1.combine(curr.node2);
- Iterator nRit = newResults.iterator();
- while (nRit.hasNext())
- {
- result.add((Node)nRit.next());
- }
- }
- return result;
- }
- if (Nodes.setNodesSize(largest) == 1)
- {
- HashSet unique = getUniqueNodes(sResult);
- Iterator uIt = unique.iterator();
- while (uIt.hasNext()) {
- Node curr = (Node)uIt.next();
- HashSet dupres = curr.getDuplicates(sResult);
- if (dupres.size() > 1) {
- HashSet newDupNodes = getLinkedNodes(dupres);
- Iterator ndIt = newDupNodes.iterator();
- while (ndIt.hasNext()) {
- HashSet combined = ((Nodes)ndIt.next()).combineNew();
- Iterator cIt = combined.iterator();
- while (cIt.hasNext()) {
- Nodes curr2 = (Nodes)cIt.next();
- HashSet newResults = curr2.node1.combine(curr2.node2);
- Iterator nRit = newResults.iterator();
- while (nRit.hasNext())
- {
- result.add((Node)nRit.next());
- }
- }
- }
- }
- else {
- result.add(node2.combineAtRoot(node1));
- }
- }
- return result;
- }
- if (Nodes.setNodesSize(largest) > 1)
- {
- Iterator largeIt = largest.iterator();
- while (largeIt.hasNext()) {
- Nodes currL = (Nodes)largeIt.next();
- HashSet largeResult = subTrees(currL);
- Iterator lrIt = largeResult.iterator();
- while (lrIt.hasNext()) {
- result.add((Node)lrIt.next());
- }
- }
- return result;
- }
- return result;
- }
- private void sortLargestSibs(Iterator<Node> lgsibs, Node lg, HashSet<Node> ns, HashSet<Node> os) {
- while (lgsibs.hasNext()) {
- Node curr = (Node)lgsibs.next();
- Iterator linkIt = curr.linkNodes.iterator();
- boolean linkFlargest = false;
- if (linkIt.hasNext()) {
- linkFlargest = true;
- }
- while (linkIt.hasNext()) {
- Node currLink = (Node)linkIt.next();
- if (!lg.isIn(currLink)) {
- linkFlargest = false;
- }
- }
- if (linkFlargest) {
- ns.add(curr);
- }
- else if (!curr.linkNodes.isEmpty())
- os.add(curr);
- }
- }
- public HashSet<Node> subTrees(Nodes largest)
- {
- HashSet result = new HashSet();
- HashSet n = largest.combineSubTrees();
- Iterator nit = n.iterator();
- while (nit.hasNext()) {
- String curr = ((Node)nit.next()).getVenn();
- if ((curr.length() > 1) && (
- (largest.node1.getSiblings().size() != 1) ||
- (largest.node2.getSiblings().size() != 1))) {
- curr = curr.substring(1, curr.length() - 1);
- }
- String curr1 = "(" + largest.node1.getVenn() + curr + ")";
- String curr2 = "(" + largest.node2.getVenn() + curr + ")";
- if ((largest.node1.parent != null) &&
- (largest.node2.parent != null)) {
- String one = buildUp(largest.node1.parent, curr1);
- String two = buildUp(largest.node2.parent, curr2);
- Node newone = new Node(null, one);
- Node newtwo = new Node(null, two);
- HashSet newresult = newone.combine(newtwo);
- Iterator newit = newresult.iterator();
- while (newit.hasNext()) {
- result.add((Node)newit.next());
- }
- return result;
- }if (largest.node1.parent != null) {
- String one = buildUp(largest.node1.parent, curr1);
- Node newone = new Node(null, one);
- result.add(newone);
- return result;
- }if (largest.node2.parent != null) {
- String two = buildUp(largest.node2.parent, curr2);
- Node newtwo = new Node(null, two);
- result.add(newtwo);
- return result;
- }
- System.out.println("Houston we have a problem.");
- }
- return result;
- }
- private void search(Node node, HashSet<Nodes> h)
- {
- if (equals(node)) {
- this.linkNodes.add(node);
- node.linkNodes.add(this);
- h.add(new Nodes(this, node));
- } else {
- Iterator it = this.children.iterator();
- while (it.hasNext())
- ((Node)(Node)it.next()).search(node, h);
- }
- }
- private HashSet<Nodes> searchBothNodes(Node node)
- {
- HashSet sResult = new HashSet();
- search(node, sResult);
- HashSet nsResult = new HashSet();
- node.search(this, nsResult);
- Iterator it = nsResult.iterator();
- while (it.hasNext()) {
- Nodes curr = (Nodes)it.next();
- Iterator currIt = sResult.iterator();
- boolean inSet = inSet(curr, currIt);
- if (!inSet) {
- sResult.add(curr);
- }
- }
- return sResult;
- }
- public void deepSearch(Node node, HashSet<Nodes> h)
- {
- HashSet first_result = searchBothNodes(node);
- Iterator first_it = first_result.iterator();
- while (first_it.hasNext()) {
- h.add((Nodes)first_it.next());
- }
- Iterator it = node.children.iterator();
- while (it.hasNext())
- deepSearch((Node)it.next(), h);
- }
- private boolean inSet(Nodes n, Iterator<Nodes> it)
- {
- boolean inSet = false;
- while (it.hasNext()) {
- if (n.equals(it.next())) {
- inSet = true;
- break;
- }
- }
- return inSet;
- }
- private void resetSearch() {
- this.linkNodes = new HashSet();
- this.linkNode = null;
- Iterator it = this.children.iterator();
- while (it.hasNext())
- ((Node)it.next()).resetSearch();
- }
- private HashSet<Nodes> getLNodes(HashSet<Nodes> h)
- {
- HashSet result = new HashSet();
- int size = 0;
- Iterator it = h.iterator();
- if (it.hasNext()) {
- Nodes curr = (Nodes)it.next();
- size = curr.nodesSize();
- result.add(curr);
- }
- while (it.hasNext()) {
- Nodes curr = (Nodes)it.next();
- if (size < curr.nodesSize()) {
- size = curr.nodesSize();
- result.clear();
- result.add(curr);
- } else if (size == curr.nodesSize()) {
- result.add(curr);
- }
- }
- return result;
- }
- private Node combineAtRoot(Node node)
- {
- HashSet uniqueNodes = new HashSet();
- Iterator thisIt = this.children.iterator();
- Iterator nodeIt = node.children.iterator();
- boolean reduced = false;
- while (thisIt.hasNext()) {
- Node curr = (Node)thisIt.next();
- if (!contains(curr, uniqueNodes))
- uniqueNodes.add(curr);
- else {
- reduced = true;
- }
- }
- while (nodeIt.hasNext()) {
- Node curr = (Node)nodeIt.next();
- if (!contains(curr, uniqueNodes))
- uniqueNodes.add(curr);
- else {
- reduced = true;
- }
- }
- Iterator unIt = uniqueNodes.iterator();
- String result = "(";
- while (unIt.hasNext()) {
- result = result + unIt.next();
- }
- result = result + ")";
- if (!reduced) {
- return new Node(null, "(" + this.venn + node.getVenn() + ")");
- }
- return new Node(null, result);
- }
- private boolean unshared()
- {
- if (this.linkNodes.isEmpty())
- {
- Iterator it = this.children.iterator();
- if (!it.hasNext()) {
- return true;
- }
- while (it.hasNext()) {
- if (!((Node)it.next()).unshared()) {
- return false;
- }
- }
- return true;
- }
- return false;
- }
- private void collectUnshared(HashSet<Node> h) {
- if (unshared()) {
- h.add(this);
- }
- Iterator it = this.children.iterator();
- while (it.hasNext())
- ((Node)it.next()).collectUnshared(h);
- }
- private HashSet<Nodes> getLinkedNodes(HashSet<Node> h)
- {
- HashSet result = new HashSet();
- Iterator hit = h.iterator();
- while (hit.hasNext()) {
- Node curr = (Node)hit.next();
- if (curr.hasLink() != null)
- result.add(new Nodes(curr, curr.hasLink()));
- }
- return result;
- }
- private Node hasLink() {
- HashSet sibs = getSiblings();
- Iterator it = sibs.iterator();
- while (it.hasNext()) {
- Node curr = (Node)it.next();
- if (!curr.linkNodes.isEmpty()) {
- return curr;
- }
- }
- return null;
- }
- public Node root() {
- if (getSiblings().isEmpty()) {
- return this;
- }
- return this.parent.root();
- }
- private String buildUp(Node n, String s) {
- if (n.parent == null) {
- return s;
- }
- String result = "(" + s;
- if (n.parent != null) {
- HashSet sibs = n.getSiblings();
- Iterator it = sibs.iterator();
- while (it.hasNext()) {
- result = result + ((Node)it.next()).getVenn();
- }
- }
- result = result + ")";
- return buildUp(n.parent, result);
- }
- private HashSet<HashSet<Nodes>> reviewPolys(HashSet<Nodes> h)
- {
- HashSet result = new HashSet();
- Iterator it = h.iterator();
- while (it.hasNext()) {
- HashSet curresult = new HashSet();
- Nodes curr = (Nodes)it.next();
- Iterator currIt = h.iterator();
- while (currIt.hasNext()) {
- Nodes inCurr = (Nodes)currIt.next();
- if (inCurr == curr) {
- continue;
- }
- HashSet linkedNodes = inCurr.node2.linkNodes;
- Iterator lnIt = linkedNodes.iterator();
- boolean found = false;
- while (lnIt.hasNext()) {
- Node currln = (Node)lnIt.next();
- if (currln == curr.node2) {
- found = true;
- inCurr.node2.linkNode = currln;
- break;
- }
- }
- if (found) {
- curresult.add(inCurr);
- }
- }
- if (!curresult.isEmpty()) {
- curresult.add(curr);
- result.add(curresult);
- }
- }
- return result;
- }
- private HashSet<Nodes> addPolys(HashSet<Nodes> h) {
- HashSet setresult = new HashSet();
- Iterator it = h.iterator();
- Nodes first = (Nodes)it.next();
- String result = first.node2.getVenn();
- result = result + first.node1.getVenn();
- while (it.hasNext()) {
- result = result + ((Nodes)it.next()).node1.getVenn();
- }
- Iterator itr = h.iterator();
- while (itr.hasNext()) {
- Nodes toAdd = new Nodes(((Nodes)itr.next()).node2, new Node(null, "(" + result + ")"));
- setresult.add(toAdd);
- }
- return setresult;
- }
- private boolean isIn(Node node) {
- if (this == node) {
- return true;
- }
- Iterator it = this.children.iterator();
- while (it.hasNext()) {
- if (((Node)it.next()).isIn(node)) {
- return true;
- }
- }
- return false;
- }
- private HashSet<Node> getUniqueNodes(HashSet<Nodes> h)
- {
- HashSet result = new HashSet();
- Iterator it = h.iterator();
- while (it.hasNext()) {
- Nodes curr = (Nodes)it.next();
- if (!result.contains(curr.node1)) {
- result.add(curr.node1);
- }
- if (!result.contains(curr.node2)) {
- result.add(curr.node2);
- }
- }
- return result;
- }
- private HashSet<Node> getDuplicates(HashSet<Nodes> h) {
- HashSet result = new HashSet();
- Iterator it = h.iterator();
- while (it.hasNext()) {
- Nodes curr = (Nodes)it.next();
- if (curr.node1 == this)
- result.add(curr.node2);
- else if (curr.node2 == this) {
- result.add(curr.node1);
- }
- }
- return result;
- }
- protected Node reduce()
- {
- HashSet c = this.children;
- HashSet uniqueC = new HashSet();
- HashSet dupC = new HashSet();
- Iterator it = c.iterator();
- while (it.hasNext()) {
- Node curr = (Node)it.next();
- if (contains(curr, uniqueC))
- dupC.add(curr);
- else {
- uniqueC.add(curr);
- }
- }
- if ((dupC.isEmpty()) || (this.venn.length() == 1)) {
- return this;
- }
- Iterator uIt = uniqueC.iterator();
- String result = "";
- if (uIt.hasNext()) {
- result = result + ((Node)uIt.next()).getVenn();
- }
- if (uIt.hasNext()) {
- result = result + "(" + result;
- while (uIt.hasNext()) {
- result = result + ((Node)uIt.next()).getVenn();
- }
- result = result + ")";
- }
- return new Node(null, result);
- }
- private boolean contains(Node n, HashSet<Node> h)
- {
- Iterator it = h.iterator();
- while (it.hasNext()) {
- Node curr = (Node)it.next();
- if (curr.equals(n)) {
- return true;
- }
- }
- return false;
- }
- }
|