Node.java 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709
  1. package com.pact;
  2. import java.util.HashSet;
  3. import java.util.Iterator;
  4. public class Node {
  5. Node parent;
  6. String venn;
  7. HashSet<Node> children;
  8. HashSet<Node> linkNodes;
  9. Node linkNode;
  10. public Node(Node p, String s) {
  11. this.linkNode = null;
  12. this.linkNodes = new HashSet<>();
  13. this.venn = s;
  14. this.parent = p;
  15. this.children = new HashSet<>();
  16. if (s.length() > 1)
  17. setChildren(s);
  18. }
  19. public Node(Node p, char s) {
  20. this(p, ""+s);
  21. }
  22. private void setChildren(String s) {
  23. try {
  24. String vennChildren = s.substring(1, s.length() - 1);
  25. int count = 0;
  26. while (count < vennChildren.length())
  27. if (vennChildren.charAt(count) == '(') {
  28. int start = count;
  29. count++;
  30. int end = 0;
  31. int brackets = 1;
  32. while (true)
  33. {
  34. if (vennChildren.charAt(count) == '(') {
  35. brackets++;
  36. }
  37. if (vennChildren.charAt(count) == ')') {
  38. brackets--;
  39. if (brackets == 0) {
  40. count++;
  41. break;
  42. }
  43. }
  44. count++;
  45. }
  46. end = count;
  47. Node child = new Node(this, vennChildren.substring(start, end));
  48. this.children.add(child);
  49. } else {
  50. Node child = new Node(this, vennChildren.charAt(count));
  51. this.children.add(child);
  52. count++;
  53. }
  54. }
  55. catch (StringIndexOutOfBoundsException se) {
  56. throw new BracketException();
  57. }
  58. }
  59. public String getVenn()
  60. {
  61. return this.venn;
  62. }
  63. public String toString()
  64. {
  65. return this.venn;
  66. }
  67. public HashSet<Node> getSiblings() {
  68. if (this.parent != null) {
  69. HashSet<Node> sibs = (HashSet)this.parent.children.clone();
  70. sibs.remove(this);
  71. return sibs;
  72. }
  73. return new HashSet<>();
  74. }
  75. public boolean equals(Object obj) {
  76. if (!(obj instanceof Node)) return false;
  77. Node node = (Node) obj;
  78. String nodeVenn = node.getVenn();
  79. // Case for leaf nodes
  80. if ((nodeVenn.length() == 1) && (this.venn.length() == 1)) {
  81. return nodeVenn.equals(this.venn);
  82. }
  83. if (children.size() != node.children.size()){
  84. return false;
  85. }
  86. // Check to make sure all of my children exist in node's children
  87. for (Node theirChild : node.children) {
  88. boolean foundMatch = false;
  89. for (Node myChild : this.children) {
  90. if (myChild.equals(theirChild)) {
  91. foundMatch = true;
  92. break;
  93. }
  94. }
  95. if(!foundMatch) return false;
  96. }
  97. return true;
  98. }
  99. // @Override
  100. // public int hashCode() {
  101. // if (children.isEmpty()) {
  102. // return venn.hashCode();
  103. // } else {
  104. // int h = 0;
  105. // for (Node child : children) {
  106. // h += child.hashCode();
  107. // }
  108. // return Integer.hashCode(h);
  109. // }
  110. //
  111. // }
  112. public void deepSearch(Node node, HashSet<NodePair> h) {
  113. HashSet<NodePair> first_result = searchBothNodePair(node);
  114. for(NodePair res : first_result) {
  115. h.add(res);
  116. }
  117. for(Node child : node.children) {
  118. deepSearch(child, h);
  119. }
  120. }
  121. public Node root() {
  122. if (getSiblings().isEmpty()) {
  123. return this;
  124. }
  125. return this.parent.root();
  126. }
  127. private int getNumAreas() {
  128. int count = 0;
  129. for (int i = 0; i < this.venn.length(); i++) {
  130. if ((this.venn.charAt(i) != ')') && (this.venn.charAt(i) != '(')) {
  131. count++;
  132. }
  133. }
  134. return count;
  135. }
  136. private void search(Node node, HashSet<NodePair> h) {
  137. if (equals(node)) {
  138. this.linkNodes.add(node);
  139. node.linkNodes.add(this);
  140. h.add(new NodePair(this, node));
  141. } else {
  142. for(Node child : children) {
  143. child.search(node, h);
  144. }
  145. }
  146. }
  147. private HashSet<NodePair> searchBothNodePair(Node node) {
  148. HashSet<NodePair> sResult = new HashSet<>();
  149. search(node, sResult);
  150. HashSet<NodePair> nsResult = new HashSet<>();
  151. node.search(this, nsResult);
  152. for (NodePair curr : nsResult) {
  153. boolean inSet = inSet(curr, sResult);
  154. if (!inSet) {
  155. sResult.add(curr);
  156. }
  157. }
  158. return sResult;
  159. }
  160. private boolean inSet(NodePair n, Iterable<NodePair> it) {
  161. for (NodePair nodes : it) {
  162. if (n.equals(nodes)) {
  163. return true;
  164. }
  165. }
  166. return false;
  167. }
  168. private boolean isIn(Node node) {
  169. if (this == node) {
  170. return true;
  171. }
  172. for (Node child : this.children) {
  173. if (child.isIn(node)) {
  174. return true;
  175. }
  176. }
  177. return false;
  178. }
  179. private Node hasLink() {
  180. HashSet<Node> sibs = getSiblings();
  181. for (Node curr : sibs) {
  182. if (!curr.linkNodes.isEmpty()) {
  183. return curr;
  184. }
  185. }
  186. return null;
  187. }
  188. private boolean unshared() {
  189. if (this.linkNodes.isEmpty()) {
  190. if(this.children.isEmpty()) {
  191. return true;
  192. } else {
  193. for (Node node : this.children) {
  194. if (!node.unshared()) {
  195. return false;
  196. }
  197. }
  198. }
  199. return true;
  200. } else {
  201. return false;
  202. }
  203. }
  204. private void resetSearch() {
  205. this.linkNodes = new HashSet<>();
  206. this.linkNode = null;
  207. for (Node child : this.children) {
  208. child.resetSearch();
  209. }
  210. }
  211. private HashSet<Node> getDuplicates(HashSet<NodePair> h) {
  212. HashSet<Node> result = new HashSet<>();
  213. for (NodePair curr : h) {
  214. if (curr.node1 == this)
  215. result.add(curr.node2);
  216. else if (curr.node2 == this) {
  217. result.add(curr.node1);
  218. }
  219. }
  220. return result;
  221. }
  222. private Node reduce() {
  223. HashSet<Node> uniqueC = new HashSet<>();
  224. HashSet<Node> dupC = new HashSet<>();
  225. for (Node child : this.children) {
  226. if (child.inSet(uniqueC))
  227. dupC.add(child);
  228. else {
  229. uniqueC.add(child);
  230. }
  231. }
  232. if ((dupC.isEmpty()) || (this.venn.length() == 1)) {
  233. return this;
  234. }
  235. Iterator uIt = uniqueC.iterator();
  236. String result = "";
  237. if (uIt.hasNext()) {
  238. result = result + ((Node)uIt.next()).getVenn();
  239. }
  240. if (uIt.hasNext()) {
  241. result = result + "(" + result;
  242. while (uIt.hasNext()) {
  243. result = result + ((Node)uIt.next()).getVenn();
  244. }
  245. result = result + ")";
  246. }
  247. return new Node(null, result);
  248. }
  249. private boolean inSet(HashSet<Node> h) {
  250. for (Node curr : h) {
  251. if (curr.equals(this)) {
  252. return true;
  253. }
  254. }
  255. return false;
  256. }
  257. private void collectUnshared(HashSet<Node> h) {
  258. if (unshared()) {
  259. h.add(this);
  260. }
  261. for (Node child : children) {
  262. child.collectUnshared(h);
  263. }
  264. }
  265. public static HashSet<Node> combine(Node node1, Node node2) {
  266. node1 = node1.reduce();
  267. node2 = node2.reduce();
  268. node2.resetSearch();
  269. node1.resetSearch();
  270. HashSet result = new HashSet();
  271. if (node1.equals(node2)) {
  272. result.add(node2);
  273. return result;
  274. }
  275. HashSet sResult = new HashSet();
  276. node2.deepSearch(node1, sResult);
  277. if (sResult.isEmpty()) {
  278. result.add(combineAtRoot(node2, node1));
  279. return result;
  280. }
  281. HashSet<NodePair> largest = getLNodePair(sResult);
  282. HashSet<Node> unsharedNodePair = new HashSet<>();
  283. node2.collectUnshared(unsharedNodePair);
  284. node1.collectUnshared(unsharedNodePair);
  285. if ((unsharedNodePair.isEmpty()) && (node1.getNumAreas() == node2.getNumAreas())) {
  286. if (node1.children.size() < node2.children.size()) {
  287. Node toAdd = new Node(null, node1.getVenn());
  288. result.add(toAdd);
  289. return result;
  290. } if (node2.children.size() < node1.children.size()) {
  291. Node toAdd = new Node(null, node2.getVenn());
  292. result.add(toAdd);
  293. return result;
  294. }
  295. }
  296. if (!largest.isEmpty()) {
  297. Iterator itLargest = largest.iterator();
  298. NodePair flargest = (NodePair)itLargest.next();
  299. HashSet<Node> lg1sibs = flargest.node1.getSiblings();
  300. HashSet<Node> lg2sibs = flargest.node2.getSiblings();
  301. HashSet<Node> newSibs = new HashSet<>();
  302. HashSet<Node> otherSibs1 = new HashSet<>();
  303. HashSet<Node> otherSibs2 = new HashSet<>();
  304. Iterator lg1It = lg1sibs.iterator();
  305. Iterator lg2It = lg2sibs.iterator();
  306. sortLargestSibs(lg1It, flargest.node2, newSibs, otherSibs1);
  307. sortLargestSibs(lg2It, flargest.node1, newSibs, otherSibs2);
  308. if ((otherSibs1.isEmpty()) && (otherSibs2.isEmpty())) {
  309. for (Node newSib : newSibs) {
  310. unsharedNodePair.add(newSib);
  311. }
  312. }
  313. }
  314. HashSet<NodePair> newLinkedNodePair = getLinkedNodePair(unsharedNodePair);
  315. HashSet<HashSet<NodePair>> polys = reviewPolys(newLinkedNodePair);
  316. if (!polys.isEmpty()) {
  317. Iterator polyIt = polys.iterator();
  318. if (polyIt.hasNext()) {
  319. HashSet polyresult = addPolys((HashSet)polyIt.next());
  320. Iterator prIt = polyresult.iterator();
  321. if (prIt.hasNext()) {
  322. NodePair curr = (NodePair)prIt.next();
  323. if ((curr.node1.parent != null) && (curr.node1.linkNode.parent != null)) {
  324. String polyString1 = buildUp(curr.node1.parent, curr.node2.getVenn());
  325. String polyString2 = buildUp(curr.node1.linkNode.parent, curr.node2.getVenn());
  326. Node polyOne = new Node(null, polyString1);
  327. Node polyTwo = new Node(null, polyString2);
  328. HashSet<Node> polyresults = combine(polyOne, polyTwo);
  329. for (Node polyResult : polyresults)
  330. result.add(polyResult);
  331. } else if (curr.node1.parent != null) {
  332. String polyString1 = buildUp(curr.node1.parent, curr.node2.getVenn());
  333. Node polyOne = new Node(null, polyString1);
  334. result.add(polyOne);
  335. } else if (curr.node1.linkNode.parent != null) {
  336. String polyString2 = buildUp(curr.node1.linkNode.parent, curr.node2.getVenn());
  337. Node polyTwo = new Node(null, polyString2);
  338. result.add(polyTwo);
  339. } else {
  340. System.out.println("What's up Houston?");
  341. }
  342. }
  343. }
  344. return result;
  345. }
  346. Iterator nLNit = newLinkedNodePair.iterator();
  347. if (nLNit.hasNext()) {
  348. HashSet combined = ((NodePair)nLNit.next()).combineNew();
  349. Iterator cIt = combined.iterator();
  350. while (cIt.hasNext()) {
  351. NodePair curr = (NodePair)cIt.next();
  352. HashSet newResults = combine(curr.node1, curr.node2);
  353. Iterator nRit = newResults.iterator();
  354. while (nRit.hasNext()) {
  355. result.add(nRit.next());
  356. }
  357. }
  358. return result;
  359. }
  360. if (NodePair.getNodesSize(largest) == 1) {
  361. HashSet unique = getUniqueNodePair(sResult);
  362. Iterator uIt = unique.iterator();
  363. while (uIt.hasNext()) {
  364. Node curr = (Node)uIt.next();
  365. HashSet dupres = curr.getDuplicates(sResult);
  366. if (dupres.size() > 1) {
  367. HashSet newDupNodePair = getLinkedNodePair(dupres);
  368. Iterator ndIt = newDupNodePair.iterator();
  369. while (ndIt.hasNext()) {
  370. HashSet combined = ((NodePair)ndIt.next()).combineNew();
  371. Iterator cIt = combined.iterator();
  372. while (cIt.hasNext()) {
  373. NodePair curr2 = (NodePair)cIt.next();
  374. HashSet newResults = combine(curr2.node1, curr2.node2);
  375. Iterator nRit = newResults.iterator();
  376. while (nRit.hasNext()) {
  377. result.add(nRit.next());
  378. }
  379. }
  380. }
  381. }
  382. else {
  383. result.add(combineAtRoot(node2, node1));
  384. }
  385. }
  386. return result;
  387. }
  388. if (NodePair.getNodesSize(largest) > 1) {
  389. for (Object aLargest : largest) {
  390. NodePair currL = (NodePair) aLargest;
  391. HashSet largeResult = subTrees(currL);
  392. Iterator lrIt = largeResult.iterator();
  393. while (lrIt.hasNext()) {
  394. result.add(lrIt.next());
  395. }
  396. }
  397. return result;
  398. }
  399. return result;
  400. }
  401. public static HashSet<Node> reducedCombine(Node node1, Node node2) {
  402. HashSet<Node> result = new HashSet<>();
  403. if (oneAreaShared(node1, node2)) {
  404. result.add(combineAtRoot(node1, node2));
  405. return result;
  406. }
  407. HashSet<Node> compCombine = combine(node1, node2);
  408. int smallest = Integer.MAX_VALUE;
  409. for (Node curr : compCombine) {
  410. int currAreas = curr.getNumAreas();
  411. if (currAreas < smallest) {
  412. smallest = currAreas;
  413. result.clear();
  414. result.add(curr);
  415. } else if (currAreas == smallest) {
  416. result.add(curr);
  417. }
  418. }
  419. return removeDuplicates(result);
  420. }
  421. private static HashSet<Node> removeDuplicates(HashSet<Node> h) {
  422. Iterator it = h.iterator();
  423. HashSet result = new HashSet();
  424. while (it.hasNext()) {
  425. Node curr = (Node)it.next();
  426. if (!curr.inSet(result)) {
  427. result.add(curr);
  428. }
  429. }
  430. return result;
  431. }
  432. private static boolean oneAreaShared(Node node1, Node node2) {
  433. HashSet<NodePair> result = new HashSet<>();
  434. node2.deepSearch(node1, result);
  435. HashSet<NodePair> largest = getLNodePair(result);
  436. if (largest.isEmpty()) {
  437. return false;
  438. }
  439. return (NodePair.getNodesSize(largest) == 1) && (largest.size() == 1);
  440. }
  441. private static void sortLargestSibs(Iterator<Node> lgsibs, Node lg, HashSet<Node> ns, HashSet<Node> os) {
  442. while (lgsibs.hasNext()) {
  443. Node curr = lgsibs.next();
  444. Iterator linkIt = curr.linkNodes.iterator();
  445. boolean linkFlargest = false;
  446. if (linkIt.hasNext()) {
  447. linkFlargest = true;
  448. }
  449. while (linkIt.hasNext()) {
  450. Node currLink = (Node)linkIt.next();
  451. if (!lg.isIn(currLink)) {
  452. linkFlargest = false;
  453. }
  454. }
  455. if (linkFlargest) {
  456. ns.add(curr);
  457. }
  458. else if (!curr.linkNodes.isEmpty())
  459. os.add(curr);
  460. }
  461. }
  462. private static HashSet<Node> subTrees(NodePair largest) {
  463. HashSet<Node> result = new HashSet();
  464. HashSet<Node> n = largest.combineSubTrees();
  465. for (Node aN : n) {
  466. String curr = aN.getVenn();
  467. if ((curr.length() > 1) && (
  468. (largest.node1.getSiblings().size() != 1) ||
  469. (largest.node2.getSiblings().size() != 1))) {
  470. curr = curr.substring(1, curr.length() - 1);
  471. }
  472. String curr1 = "(" + largest.node1.getVenn() + curr + ")";
  473. String curr2 = "(" + largest.node2.getVenn() + curr + ")";
  474. if ((largest.node1.parent != null) &&
  475. (largest.node2.parent != null)) {
  476. String one = buildUp(largest.node1.parent, curr1);
  477. String two = buildUp(largest.node2.parent, curr2);
  478. Node newOne = new Node(null, one);
  479. Node newTwo = new Node(null, two);
  480. HashSet<Node> newResult = combine(newOne, newTwo);
  481. result.addAll(newResult);
  482. return result;
  483. }
  484. if (largest.node1.parent != null) {
  485. String one = buildUp(largest.node1.parent, curr1);
  486. Node newOne = new Node(null, one);
  487. result.add(newOne);
  488. return result;
  489. }
  490. if (largest.node2.parent != null) {
  491. String two = buildUp(largest.node2.parent, curr2);
  492. Node newTwo = new Node(null, two);
  493. result.add(newTwo);
  494. return result;
  495. }
  496. System.out.println("Houston we have a problem.");
  497. }
  498. return result;
  499. }
  500. /**
  501. *
  502. * @param h HashSet
  503. * @return The largest NodePair in h, based on the length of n1's Venn diagram
  504. */
  505. private static HashSet<NodePair> getLNodePair(HashSet<NodePair> h) {
  506. HashSet<NodePair> result = new HashSet<>();
  507. int size = -1;
  508. for(NodePair curr : h){
  509. if (curr.nodesSize() > size) {
  510. size = curr.nodesSize();
  511. result.clear();
  512. result.add(curr);
  513. } else if (curr.nodesSize() == size) {
  514. result.add(curr);
  515. }
  516. }
  517. return result;
  518. }
  519. private static Node combineAtRoot(Node node1, Node node2) {
  520. HashSet<Node> uniqueNodePair = new HashSet<>();
  521. boolean reduced = false;
  522. for(Node curr : node1.children) {
  523. if (!curr.inSet(uniqueNodePair))
  524. uniqueNodePair.add(curr);
  525. else {
  526. reduced = true;
  527. }
  528. }
  529. for(Node curr : node2.children) {
  530. if (!curr.inSet(uniqueNodePair))
  531. uniqueNodePair.add(curr);
  532. else {
  533. reduced = true;
  534. }
  535. }
  536. if (!reduced) {
  537. return new Node(null, "(" + node1.venn + node2.getVenn() + ")");
  538. } else {
  539. String result_venn = "(";
  540. for (Node unique : uniqueNodePair) {
  541. result_venn = result_venn + unique;
  542. }
  543. result_venn = result_venn + ")";
  544. return new Node(null, result_venn);
  545. }
  546. }
  547. private static HashSet<NodePair> getLinkedNodePair(HashSet<Node> h) {
  548. HashSet<NodePair> result = new HashSet<>();
  549. for (Node curr : h) {
  550. if (curr.hasLink() != null)
  551. result.add(new NodePair(curr, curr.hasLink()));
  552. }
  553. return result;
  554. }
  555. private static String buildUp(Node n, String s) {
  556. if (n.parent == null) {
  557. return s;
  558. }
  559. String result = "(" + s;
  560. if (n.parent != null) {
  561. HashSet<Node> sibs = n.getSiblings();
  562. for (Node sib : sibs) {
  563. result = result + sib.getVenn();
  564. }
  565. }
  566. result = result + ")";
  567. return buildUp(n.parent, result);
  568. }
  569. private static HashSet<HashSet<NodePair>> reviewPolys(HashSet<NodePair> h) {
  570. HashSet<HashSet<NodePair>> result = new HashSet<>();
  571. for (NodePair curr : h) {
  572. HashSet<NodePair> curresult = new HashSet<>();
  573. for (NodePair inCurr : h) {
  574. if (inCurr == curr) {
  575. continue;
  576. }
  577. HashSet<Node> linkedNodePair = inCurr.node2.linkNodes;
  578. boolean found = false;
  579. for (Node currln : linkedNodePair) {
  580. if (currln == curr.node2) {
  581. found = true;
  582. inCurr.node2.linkNode = currln;
  583. break;
  584. }
  585. }
  586. if (found) {
  587. curresult.add(inCurr);
  588. }
  589. }
  590. if (!curresult.isEmpty()) {
  591. curresult.add(curr);
  592. result.add(curresult);
  593. }
  594. }
  595. return result;
  596. }
  597. private static HashSet<NodePair> addPolys(HashSet<NodePair> h) {
  598. HashSet<NodePair> setResult = new HashSet<>();
  599. NodePair first = null;
  600. String result = "";
  601. for (NodePair nodes : h) {
  602. if (first == null) {
  603. first = nodes;
  604. result = first.node2.getVenn();
  605. }
  606. result += nodes.node1.getVenn();
  607. }
  608. for (NodePair nodes : h) {
  609. NodePair toAdd = new NodePair((nodes).node2, new Node(null, "(" + result + ")"));
  610. setResult.add(toAdd);
  611. }
  612. return setResult;
  613. }
  614. private static HashSet<Node> getUniqueNodePair(HashSet<NodePair> h) {
  615. HashSet<Node> result = new HashSet<>();
  616. for (NodePair curr : h) {
  617. if (!result.contains(curr.node1)) {
  618. result.add(curr.node1);
  619. }
  620. if (!result.contains(curr.node2)) {
  621. result.add(curr.node2);
  622. }
  623. }
  624. return result;
  625. }
  626. }