diff --git a/spotbugs-exclude.xml b/spotbugs-exclude.xml index cbf8bf0..ae50214 100644 --- a/spotbugs-exclude.xml +++ b/spotbugs-exclude.xml @@ -2,7 +2,7 @@ - + diff --git a/src/main/java/org/nintynine/problems/BTreeP60.java b/src/main/java/org/nintynine/problems/BTreeP60.java deleted file mode 100644 index 1852510..0000000 --- a/src/main/java/org/nintynine/problems/BTreeP60.java +++ /dev/null @@ -1,129 +0,0 @@ -package org.nintynine.problems; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -public class BTreeP60 { - private final T value; - protected BTreeP60 left; - protected BTreeP60 right; - - public BTreeP60(T value) { - this.value = value; - this.left = null; - this.right = null; - } - - public static int minNodes(int h) { - if (h <= 0) return 0; - if (h == 1) return 1; - return 1 + minNodes(h - 1) + minNodes(h - 2); - } - - public static int maxHeight(int n) { - if (n <= 0) return 0; - int h = 0; - while (minNodes(h) <= n) h++; - return h - 1; - } - - public static List> hbalTreeNodes(int n) { - if (n <= 0) return Collections.emptyList(); - if (n == 1) { - List> result = new ArrayList<>(); - result.add(new BTreeP60<>("x")); - return result; - } - - // Special case for 2 nodes - if (n == 2) { - List> result = new ArrayList<>(); - // Create left-child tree - BTreeP60 leftTree = new BTreeP60<>("x"); - leftTree.left = new BTreeP60<>("x"); - result.add(leftTree); - - // Create right-child tree - BTreeP60 rightTree = new BTreeP60<>("x"); - rightTree.right = new BTreeP60<>("x"); - result.add(rightTree); - - return result; - } - - List> result = new ArrayList<>(); - int maxH = maxHeight(n); - int minH = (int) Math.ceil(Math.log(n + (double) 1) / Math.log(2)); - - for (int h = minH; h <= maxH; h++) { - result.addAll(generateTreesWithHeight(h, n)); - } - - return result; - } - - private static List> generateTreesWithHeight(int height, int n) { - List> result = new ArrayList<>(); - - if (n == 0) { - return Collections.emptyList(); - } - if (n == 1) { - result.add(new BTreeP60<>("x")); - return result; - } - - for (int leftNodes = 0; leftNodes < n; leftNodes++) { - int rightNodes = n - 1 - leftNodes; - - List> leftSubtrees = hbalTreeNodes(leftNodes); - List> rightSubtrees = hbalTreeNodes(rightNodes); - - for (BTreeP60 left : leftSubtrees) { - for (BTreeP60 right : rightSubtrees) { - if (isHeightBalanced(left, right) - && getHeight(left) <= height - 1 - && getHeight(right) <= height - 1) { - BTreeP60 root = new BTreeP60<>("x"); - root.left = cloneTree(left); - root.right = cloneTree(right); - result.add(root); - } - } - } - } - - return result; - } - - private static boolean isHeightBalanced(BTreeP60 left, BTreeP60 right) { - return Math.abs(getHeight(left) - getHeight(right)) <= 1; - } - - public static int getHeight(BTreeP60 node) { - if (node == null) return 0; - return 1 + Math.max(getHeight(node.left), getHeight(node.right)); - } - - private static BTreeP60 cloneTree(BTreeP60 node) { - if (node == null) return null; - BTreeP60 clone = new BTreeP60<>(node.value); - clone.left = cloneTree(node.left); - clone.right = cloneTree(node.right); - return clone; - } - - // Getters for testing - public T getValue() { - return value; - } - - public BTreeP60 getLeft() { - return left; - } - - public BTreeP60 getRight() { - return right; - } -} diff --git a/src/main/java/org/nintynine/problems/BTreeP61.java b/src/main/java/org/nintynine/problems/BTreeP61.java deleted file mode 100644 index 1ce4864..0000000 --- a/src/main/java/org/nintynine/problems/BTreeP61.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.nintynine.problems; - -public class BTreeP61 extends BTreeP60 { - - public BTreeP61(T value) { - super(value); - } - - public static int countLeaves(BTreeP61 tree) { - if (tree == null) { - return 0; - } - - // A leaf is a node with no children - if (tree.getLeft() == null && tree.getRight() == null) { - return 1; - } - - // Recursively count leaves in left and right subtrees - return countLeaves((BTreeP61) tree.getLeft()) + countLeaves((BTreeP61) tree.getRight()); - } -} diff --git a/src/main/java/org/nintynine/problems/BTree54.java b/src/main/java/org/nintynine/problems/Btree54.java similarity index 90% rename from src/main/java/org/nintynine/problems/BTree54.java rename to src/main/java/org/nintynine/problems/Btree54.java index e5aa65c..982d1db 100644 --- a/src/main/java/org/nintynine/problems/BTree54.java +++ b/src/main/java/org/nintynine/problems/Btree54.java @@ -3,12 +3,12 @@ import java.util.Objects; /** P54A: Check whether a given expression represents a binary tree */ -public class BTree54 { +public class Btree54 { /** Represents a node in the binary tree expression */ - public static class BTree54Node { + public static class Btree54Node { private final String value; - private final BTree54Node left; - private final BTree54Node right; + private final Btree54Node left; + private final Btree54Node right; /** * Constructs a binary tree node @@ -17,7 +17,7 @@ public static class BTree54Node { * @param left Left child node or null * @param right Right child node or null */ - public BTree54Node(String value, BTree54Node left, BTree54Node right) { + public Btree54Node(String value, Btree54Node left, Btree54Node right) { this.value = Objects.requireNonNull(value, "Node value cannot be null"); this.left = left; this.right = right; @@ -28,14 +28,14 @@ public BTree54Node(String value, BTree54Node left, BTree54Node right) { * * @param value The value at this node */ - public BTree54Node(String value) { + public Btree54Node(String value) { this(value, null, null); } @Override public boolean equals(Object o) { if (this == o) return true; - if (!(o instanceof BTree54Node bTree54Node)) return false; + if (!(o instanceof Btree54Node bTree54Node)) return false; return Objects.equals(value, bTree54Node.value) && Objects.equals(left, bTree54Node.left) && Objects.equals(right, bTree54Node.right); @@ -60,7 +60,7 @@ public String toString() { } } - private BTree54() {} // Prevent instantiation + private Btree54() {} // Prevent instantiation private static boolean isValidValue(String value) { // Check for any special characters or improper formatting @@ -113,7 +113,7 @@ public static boolean isTree(String expression) { * @return The root node of the parsed tree * @throws IllegalArgumentException if the expression is invalid */ - public static BTree54Node parseTree(String expression) { + public static Btree54Node parseTree(String expression) { if (expression == null) { throw new IllegalArgumentException("Expression cannot be null"); } @@ -123,7 +123,7 @@ public static BTree54Node parseTree(String expression) { // Handle single value case if (!expression.startsWith("(")) { if (isValidValue(expression)) { - return new BTree54Node(expression); + return new Btree54Node(expression); } throw new IllegalArgumentException("Invalid value: " + expression); } @@ -148,10 +148,10 @@ public static BTree54Node parseTree(String expression) { throw new IllegalArgumentException("Invalid node value"); } - BTree54Node left = "nil".equals(leftExpr) ? null : parseTree(leftExpr); - BTree54Node right = "nil".equals(rightExpr) ? null : parseTree(rightExpr); + Btree54Node left = "nil".equals(leftExpr) ? null : parseTree(leftExpr); + Btree54Node right = "nil".equals(rightExpr) ? null : parseTree(rightExpr); - return new BTree54Node(value, left, right); + return new Btree54Node(value, left, right); } @SuppressWarnings("java:S5852") diff --git a/src/main/java/org/nintynine/problems/BTreeP56.java b/src/main/java/org/nintynine/problems/BtreeP56.java similarity index 64% rename from src/main/java/org/nintynine/problems/BTreeP56.java rename to src/main/java/org/nintynine/problems/BtreeP56.java index 6cfd7ca..d6a4735 100644 --- a/src/main/java/org/nintynine/problems/BTreeP56.java +++ b/src/main/java/org/nintynine/problems/BtreeP56.java @@ -1,6 +1,11 @@ package org.nintynine.problems; -public class BTreeP56 { +/** + * Simple binary tree used for symmetry checks in problem 56. + * + * @param node value type + */ +public class BtreeP56 { private Node root; private static class Node { @@ -15,7 +20,7 @@ private static class Node { } } - public BTreeP56() { + public BtreeP56() { this.root = null; } @@ -24,27 +29,37 @@ public void setRoot(T value) { } public void addLeft(T value) { - if (root == null) throw new IllegalStateException("Tree has no root"); + if (root == null) { + throw new IllegalStateException("Tree has no root"); + } root.left = new Node<>(value); } public void addRight(T value) { - if (root == null) throw new IllegalStateException("Tree has no root"); + if (root == null) { + throw new IllegalStateException("Tree has no root"); + } root.right = new Node<>(value); } public boolean isSymmetric() { - if (root == null) return true; + if (root == null) { + return true; + } return isMirror(root.left, root.right); } @SuppressWarnings("java:S2234") // or just "S2234" private boolean isMirror(Node left, Node right) { // If both nodes are null, they are mirror images - if (left == null && right == null) return true; + if (left == null && right == null) { + return true; + } // If only one node is null, they are not mirror images - if (left == null || right == null) return false; + if (left == null || right == null) { + return false; + } // Check if the structure is mirrored return isMirror(left.left, right.right) && isMirror(left.right, right.left); diff --git a/src/main/java/org/nintynine/problems/BTreeP57.java b/src/main/java/org/nintynine/problems/BtreeP57.java similarity index 77% rename from src/main/java/org/nintynine/problems/BTreeP57.java rename to src/main/java/org/nintynine/problems/BtreeP57.java index 7fa2e90..3dafff5 100644 --- a/src/main/java/org/nintynine/problems/BTreeP57.java +++ b/src/main/java/org/nintynine/problems/BtreeP57.java @@ -1,6 +1,12 @@ package org.nintynine.problems; -public class BTreeP57> { +/** + * Binary tree utilities for problem 57. + * + * @param type of node values + */ +@SuppressWarnings("checkstyle:AbbreviationAsWordInName") +public class BtreeP57> { private Node root; private static class Node { @@ -15,10 +21,15 @@ private static class Node { } } - public BTreeP57() { + public BtreeP57() { this.root = null; } + /** + * Constructs the tree by inserting all given values. + * + * @param values values to insert + */ public void construct(T[] values) { for (T value : values) { insert(value); @@ -44,6 +55,11 @@ private Node insertRec(Node node, T value) { return node; } + /** + * Checks if this tree is symmetric. + * + * @return {@code true} if the tree is symmetric, otherwise {@code false} + */ public boolean isSymmetric() { return root == null || isMirror(root.left, root.right); } diff --git a/src/main/java/org/nintynine/problems/BTreeP58.java b/src/main/java/org/nintynine/problems/BtreeP58.java similarity index 62% rename from src/main/java/org/nintynine/problems/BTreeP58.java rename to src/main/java/org/nintynine/problems/BtreeP58.java index 384bf7c..813c583 100644 --- a/src/main/java/org/nintynine/problems/BTreeP58.java +++ b/src/main/java/org/nintynine/problems/BtreeP58.java @@ -4,15 +4,16 @@ import java.util.List; import java.util.Objects; -public class BTreeP58 { - private BTreeP58() {} +/** Utilities for constructing symmetric binary trees. */ +public class BtreeP58 { + private BtreeP58() {} - public static class BTreeP58Node { + public static class BtreeP58Node { char value; - BTreeP58Node left; - BTreeP58Node right; + BtreeP58Node left; + BtreeP58Node right; - BTreeP58Node(char value) { + BtreeP58Node(char value) { this.value = value; left = null; right = null; @@ -27,7 +28,7 @@ public int hashCode() { public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - BTreeP58Node bTreeP58Node = (BTreeP58Node) o; + BtreeP58Node bTreeP58Node = (BtreeP58Node) o; return value == bTreeP58Node.value && Objects.equals(left, bTreeP58Node.left) && Objects.equals(right, bTreeP58Node.right); @@ -42,26 +43,26 @@ public String toString() { } } - public static List symCbalTrees(int nodes) { + public static List symCbalTrees(int nodes) { if (nodes % 2 == 0) return new ArrayList<>(); return generateSymCbalTrees(nodes); } - private static List generateSymCbalTrees(int nodes) { - List result = new ArrayList<>(); + private static List generateSymCbalTrees(int nodes) { + List result = new ArrayList<>(); if (nodes == 0) return result; if (nodes == 1) { - result.add(new BTreeP58Node('X')); + result.add(new BtreeP58Node('X')); return result; } int remainingNodes = nodes - 1; if (remainingNodes % 2 != 0) return result; - List subtrees = generateBalancedSubtrees(remainingNodes / 2); - for (BTreeP58Node leftSubtree : subtrees) { - BTreeP58Node root = new BTreeP58Node('X'); + List subtrees = generateBalancedSubtrees(remainingNodes / 2); + for (BtreeP58Node leftSubtree : subtrees) { + BtreeP58Node root = new BtreeP58Node('X'); root.left = cloneTree(leftSubtree); root.right = cloneTree(mirrorTree(leftSubtree)); result.add(root); @@ -70,27 +71,27 @@ private static List generateSymCbalTrees(int nodes) { return result; } - private static List generateBalancedSubtrees(int nodes) { - List result = new ArrayList<>(); + private static List generateBalancedSubtrees(int nodes) { + List result = new ArrayList<>(); if (nodes == 0) { result.add(null); return result; } if (nodes == 1) { - result.add(new BTreeP58Node('X')); + result.add(new BtreeP58Node('X')); return result; } int remainingNodes = nodes - 1; for (int leftNodes = remainingNodes / 2; leftNodes <= (remainingNodes + 1) / 2; leftNodes++) { int rightNodes = remainingNodes - leftNodes; - List leftSubtrees = generateBalancedSubtrees(leftNodes); - List rightSubtrees = generateBalancedSubtrees(rightNodes); + List leftSubtrees = generateBalancedSubtrees(leftNodes); + List rightSubtrees = generateBalancedSubtrees(rightNodes); - for (BTreeP58Node left : leftSubtrees) { - for (BTreeP58Node right : rightSubtrees) { - BTreeP58Node root = new BTreeP58Node('X'); + for (BtreeP58Node left : leftSubtrees) { + for (BtreeP58Node right : rightSubtrees) { + BtreeP58Node root = new BtreeP58Node('X'); root.left = cloneTree(left); root.right = cloneTree(right); result.add(root); @@ -100,17 +101,17 @@ private static List generateBalancedSubtrees(int nodes) { return result; } - private static BTreeP58Node mirrorTree(BTreeP58Node root) { + private static BtreeP58Node mirrorTree(BtreeP58Node root) { if (root == null) return null; - BTreeP58Node mirrored = new BTreeP58Node(root.value); + BtreeP58Node mirrored = new BtreeP58Node(root.value); mirrored.left = mirrorTree(root.right); mirrored.right = mirrorTree(root.left); return mirrored; } - private static BTreeP58Node cloneTree(BTreeP58Node root) { + private static BtreeP58Node cloneTree(BtreeP58Node root) { if (root == null) return null; - BTreeP58Node clone = new BTreeP58Node(root.value); + BtreeP58Node clone = new BtreeP58Node(root.value); clone.left = cloneTree(root.left); clone.right = cloneTree(root.right); return clone; diff --git a/src/main/java/org/nintynine/problems/BTreeP59.java b/src/main/java/org/nintynine/problems/BtreeP59.java similarity index 96% rename from src/main/java/org/nintynine/problems/BTreeP59.java rename to src/main/java/org/nintynine/problems/BtreeP59.java index 8ee4a3b..bb91d5c 100644 --- a/src/main/java/org/nintynine/problems/BTreeP59.java +++ b/src/main/java/org/nintynine/problems/BtreeP59.java @@ -5,8 +5,9 @@ import java.util.Objects; @SuppressWarnings("DuplicatedCode") -public class BTreeP59 { - private BTreeP59() {} +/** Utility class for generating completely balanced binary trees. */ +public class BtreeP59 { + private BtreeP59() {} public static class BTree59Node { char value; diff --git a/src/main/java/org/nintynine/problems/BtreeP60.java b/src/main/java/org/nintynine/problems/BtreeP60.java new file mode 100644 index 0000000..8fc9b60 --- /dev/null +++ b/src/main/java/org/nintynine/problems/BtreeP60.java @@ -0,0 +1,189 @@ +package org.nintynine.problems; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Height-balanced binary tree utilities for problem 60. + * + * @param node value type + */ +@SuppressWarnings("checkstyle:AbbreviationAsWordInName") +public class BtreeP60 { + private final T value; + protected BtreeP60 left; + protected BtreeP60 right; + + /** + * Creates a new tree node with the given value. + * + * @param value node value + */ + public BtreeP60(T value) { + this.value = value; + this.left = null; + this.right = null; + } + + /** + * Computes the minimum number of nodes of a height-balanced tree for a + * given height. + * + * @param h desired height + * @return minimum node count + */ + public static int minNodes(int h) { + if (h <= 0) { + return 0; + } + if (h == 1) { + return 1; + } + return 1 + minNodes(h - 1) + minNodes(h - 2); + } + + /** + * Computes the maximum possible height of a tree with the given number of + * nodes while remaining height balanced. + * + * @param n node count + * @return maximum height + */ + public static int maxHeight(int n) { + if (n <= 0) { + return 0; + } + int h = 0; + while (minNodes(h) <= n) { + h++; + } + return h - 1; + } + + /** + * Generates all height-balanced trees with the given number of nodes. + * + * @param n number of nodes + * @return list of trees + */ + public static List> hbalTreeNodes(int n) { + if (n <= 0) { + return Collections.emptyList(); + } + if (n == 1) { + List> result = new ArrayList<>(); + result.add(new BtreeP60<>("x")); + return result; + } + + // Special case for 2 nodes + if (n == 2) { + List> result = new ArrayList<>(); + // Create left-child tree + BtreeP60 leftTree = new BtreeP60<>("x"); + leftTree.left = new BtreeP60<>("x"); + result.add(leftTree); + + // Create right-child tree + BtreeP60 rightTree = new BtreeP60<>("x"); + rightTree.right = new BtreeP60<>("x"); + result.add(rightTree); + + return result; + } + + List> result = new ArrayList<>(); + int maxH = maxHeight(n); + int minH = (int) Math.ceil(Math.log(n + (double) 1) / Math.log(2)); + + for (int h = minH; h <= maxH; h++) { + result.addAll(generateTreesWithHeight(h, n)); + } + + return result; + } + + /** + * Generates trees of a specific height containing the given number of nodes. + */ + private static List> generateTreesWithHeight(int height, int n) { + List> result = new ArrayList<>(); + + if (n == 0) { + return Collections.emptyList(); + } + if (n == 1) { + result.add(new BtreeP60<>("x")); + return result; + } + + for (int leftNodes = 0; leftNodes < n; leftNodes++) { + int rightNodes = n - 1 - leftNodes; + + List> leftSubtrees = hbalTreeNodes(leftNodes); + List> rightSubtrees = hbalTreeNodes(rightNodes); + + for (BtreeP60 left : leftSubtrees) { + for (BtreeP60 right : rightSubtrees) { + if (isHeightBalanced(left, right) + && getHeight(left) <= height - 1 + && getHeight(right) <= height - 1) { + BtreeP60 root = new BtreeP60<>("x"); + root.left = cloneTree(left); + root.right = cloneTree(right); + result.add(root); + } + } + } + } + + return result; + } + + /** + * Checks if two subtrees are height balanced relative to each other. + */ + private static boolean isHeightBalanced(BtreeP60 left, BtreeP60 right) { + return Math.abs(getHeight(left) - getHeight(right)) <= 1; + } + + /** + * Returns the height of the given tree. + * + * @param node root node + * @return tree height + */ + public static int getHeight(BtreeP60 node) { + if (node == null) { + return 0; + } + return 1 + Math.max(getHeight(node.left), getHeight(node.right)); + } + + /** + * Creates a deep copy of the given tree. + */ + private static BtreeP60 cloneTree(BtreeP60 node) { + if (node == null) { + return null; + } + BtreeP60 clone = new BtreeP60<>(node.value); + clone.left = cloneTree(node.left); + clone.right = cloneTree(node.right); + return clone; + } + + // Getters for testing + public T getValue() { + return value; + } + + public BtreeP60 getLeft() { + return left; + } + + public BtreeP60 getRight() { + return right; + } +} diff --git a/src/main/java/org/nintynine/problems/BtreeP61.java b/src/main/java/org/nintynine/problems/BtreeP61.java new file mode 100644 index 0000000..f11810f --- /dev/null +++ b/src/main/java/org/nintynine/problems/BtreeP61.java @@ -0,0 +1,40 @@ +package org.nintynine.problems; + +/** + * Binary tree utilities for problem 61. + * + * @param node value type + */ +@SuppressWarnings("checkstyle:AbbreviationAsWordInName") +public class BtreeP61 extends BtreeP60 { + + /** + * Creates a new tree node with the given value. + * + * @param value node value + */ + public BtreeP61(T value) { + super(value); + } + + /** + * Counts the number of leaves in the given tree. + * + * @param tree tree to inspect + * @param element type + * @return leaf count + */ + public static int countLeaves(BtreeP61 tree) { + if (tree == null) { + return 0; + } + + // A leaf is a node with no children + if (tree.getLeft() == null && tree.getRight() == null) { + return 1; + } + + // Recursively count leaves in left and right subtrees + return countLeaves((BtreeP61) tree.getLeft()) + countLeaves((BtreeP61) tree.getRight()); + } +} diff --git a/src/main/java/org/nintynine/problems/BTreeP68.java b/src/main/java/org/nintynine/problems/BtreeP68.java similarity index 98% rename from src/main/java/org/nintynine/problems/BTreeP68.java rename to src/main/java/org/nintynine/problems/BtreeP68.java index ba0e377..75ac087 100644 --- a/src/main/java/org/nintynine/problems/BTreeP68.java +++ b/src/main/java/org/nintynine/problems/BtreeP68.java @@ -12,9 +12,9 @@ *

See issue #61. */ @SuppressWarnings("checkstyle:AbbreviationAsWordInName") -public class BTreeP68 { +public class BtreeP68 { - private BTreeP68() { + private BtreeP68() { // utility class } diff --git a/src/main/java/org/nintynine/problems/BTreeP69.java b/src/main/java/org/nintynine/problems/BtreeP69.java similarity index 98% rename from src/main/java/org/nintynine/problems/BTreeP69.java rename to src/main/java/org/nintynine/problems/BtreeP69.java index e1badfe..2026043 100644 --- a/src/main/java/org/nintynine/problems/BTreeP69.java +++ b/src/main/java/org/nintynine/problems/BtreeP69.java @@ -11,9 +11,9 @@ * representation. */ @SuppressWarnings("checkstyle:AbbreviationAsWordInName") -public class BTreeP69 { +public class BtreeP69 { - private BTreeP69() { + private BtreeP69() { // utility class } diff --git a/src/main/java/org/nintynine/problems/MathP37.java b/src/main/java/org/nintynine/problems/MathP37.java index aae2744..604a3ea 100644 --- a/src/main/java/org/nintynine/problems/MathP37.java +++ b/src/main/java/org/nintynine/problems/MathP37.java @@ -85,7 +85,7 @@ public static long[] comparePerformance(long m) { // Test primitive method (P34) startTime = System.nanoTime(); - long result1 = MathP34.totientPhi(m); + final long result1 = MathP34.totientPhi(m); endTime = System.nanoTime(); times[0] = endTime - startTime; diff --git a/src/main/java/org/nintynine/problems/MathP41.java b/src/main/java/org/nintynine/problems/MathP41.java index f188d24..4f36684 100644 --- a/src/main/java/org/nintynine/problems/MathP41.java +++ b/src/main/java/org/nintynine/problems/MathP41.java @@ -117,7 +117,7 @@ public static String formatGoldbachList(List compositions) { return compositions.stream().map(GoldbachListEntry::toString).collect(Collectors.joining("\n")); } - /** Represents a Goldbach composition list entry */ + /** Represents a Goldbach composition list entry. */ public record GoldbachListEntry(long number, MathP40.GoldbachPair pair) { @Override public String toString() { diff --git a/src/main/java/org/nintynine/problems/MyListP02.java b/src/main/java/org/nintynine/problems/MyListP02.java index 444ba32..88444c1 100644 --- a/src/main/java/org/nintynine/problems/MyListP02.java +++ b/src/main/java/org/nintynine/problems/MyListP02.java @@ -3,15 +3,25 @@ import java.util.Arrays; import java.util.NoSuchElementException; +/** + * Utility list that provides a method to get the penultimate element. + * + * @param element type + */ public class MyListP02 extends MyList { @SafeVarargs public MyListP02(T... elements) { super(elements); } + /** + * Returns the element just before the last one in the list. + * + * @return second-to-last element + */ public T lastButOne() { return Arrays.stream(items) - .reduce(Pair.empty(), Pair::shift, (_, b) -> b) + .reduce(Pair.empty(), Pair::shift, (ignore, b) -> b) .secondLastOrThrow(); } diff --git a/src/main/java/org/nintynine/problems/MyListP03.java b/src/main/java/org/nintynine/problems/MyListP03.java index 38f4de0..b75f0d2 100644 --- a/src/main/java/org/nintynine/problems/MyListP03.java +++ b/src/main/java/org/nintynine/problems/MyListP03.java @@ -2,12 +2,23 @@ import java.util.Arrays; +/** + * Provides a method to select the Kth element of a list. + * + * @param element type + */ public class MyListP03 extends MyListP02 { @SafeVarargs public MyListP03(T... elements) { super(elements); } + /** + * Returns the element at the given 1-based position. + * + * @param k position (1-based) + * @return element at that position + */ public T elementAt(long k) { if (k < 1) { throw new IllegalArgumentException("Position must be greater than 0"); diff --git a/src/main/java/org/nintynine/problems/MyListP05.java b/src/main/java/org/nintynine/problems/MyListP05.java index 6937532..217a586 100644 --- a/src/main/java/org/nintynine/problems/MyListP05.java +++ b/src/main/java/org/nintynine/problems/MyListP05.java @@ -3,12 +3,22 @@ import java.util.Arrays; import java.util.LinkedList; +/** + * Provides a reverse operation for lists. + * + * @param element type + */ public class MyListP05 extends MyListP04 { @SafeVarargs public MyListP05(T... elements) { super(elements); } + /** + * Returns a new list with the elements in reverse order. + * + * @return reversed list + */ public MyListP05 reverse() { return new MyListP05<>( Arrays.stream(items) diff --git a/src/main/java/org/nintynine/problems/MyListP07.java b/src/main/java/org/nintynine/problems/MyListP07.java index c2aa509..0df25ce 100644 --- a/src/main/java/org/nintynine/problems/MyListP07.java +++ b/src/main/java/org/nintynine/problems/MyListP07.java @@ -4,6 +4,11 @@ import java.util.List; import java.util.stream.Stream; +/** + * Utility class for flattening nested lists. + * + * @param type of elements in the list + */ public class MyListP07 extends MyListP06 { @SafeVarargs public MyListP07(T... elements) { diff --git a/src/main/java/org/nintynine/problems/MyListP08.java b/src/main/java/org/nintynine/problems/MyListP08.java index 9aca4f2..d4b06a9 100644 --- a/src/main/java/org/nintynine/problems/MyListP08.java +++ b/src/main/java/org/nintynine/problems/MyListP08.java @@ -4,12 +4,22 @@ import java.util.Objects; import java.util.stream.LongStream; +/** + * Removes consecutive duplicates from the list. + * + * @param element type + */ public class MyListP08 extends MyListP07 { @SafeVarargs public MyListP08(T... elements) { super(elements); } + /** + * Compresses consecutive duplicate elements. + * + * @return a new list without consecutive duplicates + */ public MyListP08 compress() { if (length() == 0) { return new MyListP08<>(); diff --git a/src/main/java/org/nintynine/problems/MyListP10.java b/src/main/java/org/nintynine/problems/MyListP10.java index 1a6f813..8510c7c 100644 --- a/src/main/java/org/nintynine/problems/MyListP10.java +++ b/src/main/java/org/nintynine/problems/MyListP10.java @@ -71,8 +71,12 @@ public EncodedElement(long count, T element) { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } EncodedElement that = (EncodedElement) o; return count == that.count && Objects.equals(element, that.element); } diff --git a/src/main/java/org/nintynine/problems/MyListP13.java b/src/main/java/org/nintynine/problems/MyListP13.java index 647ba1a..537f130 100644 --- a/src/main/java/org/nintynine/problems/MyListP13.java +++ b/src/main/java/org/nintynine/problems/MyListP13.java @@ -83,7 +83,7 @@ private void addEncodedElement(List result, long count, T element) { } } - /** Override of decode method to return MyListP13 instead of MyListP12 */ + /** Override of decode method to return MyListP13 instead of MyListP12. */ @Override @SuppressWarnings({"unchecked", "DuplicatedCode"}) public MyListP13 decode() { diff --git a/src/main/java/org/nintynine/problems/MyListP18.java b/src/main/java/org/nintynine/problems/MyListP18.java index e771b38..75d7254 100644 --- a/src/main/java/org/nintynine/problems/MyListP18.java +++ b/src/main/java/org/nintynine/problems/MyListP18.java @@ -37,8 +37,8 @@ public MyListP18(T... elements) { */ public MyListP18 slice(int startIndex, int endIndex) { // Convert to 0-based indices for internal use - int start = startIndex - 1; - int end = endIndex - 1; + final int start = startIndex - 1; + final int end = endIndex - 1; // Validate indices if (startIndex < 1) { diff --git a/src/main/java/org/nintynine/problems/MyListP26.java b/src/main/java/org/nintynine/problems/MyListP26.java index 1054560..470260e 100644 --- a/src/main/java/org/nintynine/problems/MyListP26.java +++ b/src/main/java/org/nintynine/problems/MyListP26.java @@ -28,8 +28,12 @@ public MyListP26(T... elements) { * @return number of possible combinations */ public static long binomialCoefficient(int n, int k) { - if (k < 0 || k > n) return 0; - if (k == 0 || k == n) return 1; + if (k < 0 || k > n) { + return 0; + } + if (k == 0 || k == n) { + return 1; + } // Use symmetry to optimize calculation if (k > n - k) { diff --git a/src/main/java/org/nintynine/problems/TruthP47.java b/src/main/java/org/nintynine/problems/TruthP47.java index fdfec57..a245a19 100644 --- a/src/main/java/org/nintynine/problems/TruthP47.java +++ b/src/main/java/org/nintynine/problems/TruthP47.java @@ -179,6 +179,9 @@ public static Optional fromString(String symbol) { return Arrays.stream(values()).filter(op -> op.symbol.equals(symbol)).findFirst(); } + /** + * Applies the binary logical operation. + */ public boolean apply(boolean a, boolean b) { if (isUnary) { throw new IllegalStateException("Cannot apply binary operation to unary operator"); @@ -186,6 +189,9 @@ public boolean apply(boolean a, boolean b) { return binaryOp.apply(a, b); } + /** + * Applies the unary logical operation. + */ public boolean apply(boolean a) { if (!isUnary) { throw new IllegalStateException("Cannot apply unary operation to binary operator"); diff --git a/src/test/java/org/nintynine/problems/AdditionalCoverageTest.java b/src/test/java/org/nintynine/problems/AdditionalCoverageTest.java index 13738fb..94f5bca 100644 --- a/src/test/java/org/nintynine/problems/AdditionalCoverageTest.java +++ b/src/test/java/org/nintynine/problems/AdditionalCoverageTest.java @@ -10,25 +10,25 @@ class AdditionalCoverageTest { @Test - @DisplayName("BTree54Node handles raw expression values") - void testBTree54NodeRawValue() { + @DisplayName("Btree54Node handles raw expression values") + void testBtree54NodeRawValue() { String raw = "(a nil nil)"; - BTree54.BTree54Node node = new BTree54.BTree54Node(raw); + Btree54.Btree54Node node = new Btree54.Btree54Node(raw); assertEquals(raw, node.toString()); } @Test - @DisplayName("BTreeP58Node equality and toString") - void testBTreeP58NodeEquality() { - BTreeP58.BTreeP58Node left1 = new BTreeP58.BTreeP58Node('A'); - BTreeP58.BTreeP58Node right1 = new BTreeP58.BTreeP58Node('B'); - BTreeP58.BTreeP58Node root1 = new BTreeP58.BTreeP58Node('X'); + @DisplayName("BtreeP58Node equality and toString") + void testBtreeP58NodeEquality() { + BtreeP58.BtreeP58Node left1 = new BtreeP58.BtreeP58Node('A'); + BtreeP58.BtreeP58Node right1 = new BtreeP58.BtreeP58Node('B'); + BtreeP58.BtreeP58Node root1 = new BtreeP58.BtreeP58Node('X'); root1.left = left1; root1.right = right1; - BTreeP58.BTreeP58Node left2 = new BTreeP58.BTreeP58Node('A'); - BTreeP58.BTreeP58Node right2 = new BTreeP58.BTreeP58Node('B'); - BTreeP58.BTreeP58Node root2 = new BTreeP58.BTreeP58Node('X'); + BtreeP58.BtreeP58Node left2 = new BtreeP58.BtreeP58Node('A'); + BtreeP58.BtreeP58Node right2 = new BtreeP58.BtreeP58Node('B'); + BtreeP58.BtreeP58Node root2 = new BtreeP58.BtreeP58Node('X'); root2.left = left2; root2.right = right2; @@ -38,17 +38,17 @@ void testBTreeP58NodeEquality() { } @Test - @DisplayName("BTreeP59Node equality and toString") - void testBTreeP59NodeEquality() { - BTreeP59.BTree59Node left1 = new BTreeP59.BTree59Node('L'); - BTreeP59.BTree59Node right1 = new BTreeP59.BTree59Node('R'); - BTreeP59.BTree59Node root1 = new BTreeP59.BTree59Node('X'); + @DisplayName("BtreeP59Node equality and toString") + void testBtreeP59NodeEquality() { + BtreeP59.BTree59Node left1 = new BtreeP59.BTree59Node('L'); + BtreeP59.BTree59Node right1 = new BtreeP59.BTree59Node('R'); + BtreeP59.BTree59Node root1 = new BtreeP59.BTree59Node('X'); root1.left = left1; root1.right = right1; - BTreeP59.BTree59Node left2 = new BTreeP59.BTree59Node('L'); - BTreeP59.BTree59Node right2 = new BTreeP59.BTree59Node('R'); - BTreeP59.BTree59Node root2 = new BTreeP59.BTree59Node('X'); + BtreeP59.BTree59Node left2 = new BtreeP59.BTree59Node('L'); + BtreeP59.BTree59Node right2 = new BtreeP59.BTree59Node('R'); + BtreeP59.BTree59Node root2 = new BtreeP59.BTree59Node('X'); root2.left = left2; root2.right = right2; diff --git a/src/test/java/org/nintynine/problems/BTreeP61Test.java b/src/test/java/org/nintynine/problems/BTreeP61Test.java deleted file mode 100644 index f6e5032..0000000 --- a/src/test/java/org/nintynine/problems/BTreeP61Test.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.nintynine.problems; - -import static org.junit.jupiter.api.Assertions.*; - -import org.junit.jupiter.api.Test; - -class BTreeP61Test { - - @Test - void testEmptyTree() { - assertNull(null); - assertEquals(0, BTreeP61.countLeaves(null)); - } - - @Test - void testSingleNode() { - BTreeP61 tree = new BTreeP61<>("a"); - assertEquals(1, BTreeP61.countLeaves(tree)); - } - - @Test - void testOneChild() { - BTreeP61 tree = new BTreeP61<>("a"); - tree.left = new BTreeP61<>("b"); - assertEquals(1, BTreeP61.countLeaves(tree)); - } - - @Test - void testTwoChildren() { - BTreeP61 tree = new BTreeP61<>("a"); - tree.left = new BTreeP61<>("b"); - tree.right = new BTreeP61<>("c"); - assertEquals(2, BTreeP61.countLeaves(tree)); - } - - @Test - void testComplexTree() { - BTreeP61 tree = new BTreeP61<>("a"); - tree.left = new BTreeP61<>("b"); - tree.right = new BTreeP61<>("c"); - tree.left.left = new BTreeP61<>("d"); - tree.left.right = new BTreeP61<>("e"); - tree.right.right = new BTreeP61<>("f"); - - assertEquals(3, BTreeP61.countLeaves(tree)); - } - - @Test - void testFullBinaryTree() { - BTreeP61 tree = new BTreeP61<>("a"); - tree.left = new BTreeP61<>("b"); - tree.right = new BTreeP61<>("c"); - tree.left.left = new BTreeP61<>("d"); - tree.left.right = new BTreeP61<>("e"); - tree.right.left = new BTreeP61<>("f"); - tree.right.right = new BTreeP61<>("g"); - - assertEquals(4, BTreeP61.countLeaves(tree)); - } -} diff --git a/src/test/java/org/nintynine/problems/BTreeP68Test.java b/src/test/java/org/nintynine/problems/BTreeP68Test.java deleted file mode 100644 index 4810fbf..0000000 --- a/src/test/java/org/nintynine/problems/BTreeP68Test.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.nintynine.problems; - -import static org.junit.jupiter.api.Assertions.*; - -import java.util.List; -import org.junit.jupiter.api.Test; - -class BTreeP68Test { - - private BTreeP68.Node exampleTree() { - BTreeP68.Node a = new BTreeP68.Node('A'); - BTreeP68.Node b = new BTreeP68.Node('B'); - BTreeP68.Node c = new BTreeP68.Node('C'); - BTreeP68.Node d = new BTreeP68.Node('D'); - BTreeP68.Node e = new BTreeP68.Node('E'); - BTreeP68.Node f = new BTreeP68.Node('F'); - BTreeP68.Node g = new BTreeP68.Node('G'); - a.left = b; - a.right = c; - b.left = d; - b.right = e; - c.right = f; - f.left = g; - return a; - } - - @Test - void testPreorderAndInorder() { - BTreeP68.Node root = exampleTree(); - List pre = BTreeP68.preorder(root); - List in = BTreeP68.inorder(root); - assertEquals(List.of('A', 'B', 'D', 'E', 'C', 'F', 'G'), pre); - assertEquals(List.of('D', 'B', 'E', 'A', 'C', 'G', 'F'), in); - } - - @Test - void testFromPreorder() { - List seq = List.of('F', 'C', 'A', 'E', 'H', 'G'); - BTreeP68.Node root = BTreeP68.fromPreorder(seq); - assertEquals(seq, BTreeP68.preorder(root)); - List inorder = BTreeP68.inorder(root); - assertEquals(List.of('A', 'C', 'E', 'F', 'G', 'H'), inorder); // inorder sorted - } - - @Test - void testPreInTree() { - BTreeP68.Node root = exampleTree(); - List pre = BTreeP68.preorder(root); - List in = BTreeP68.inorder(root); - BTreeP68.Node rebuilt = BTreeP68.preInTree(pre, in); - assertEquals(pre, BTreeP68.preorder(rebuilt)); - assertEquals(in, BTreeP68.inorder(rebuilt)); - assertEquals(root, rebuilt); - } - - @Test - void testPreInTreeInvalid() { - assertThrows( - IllegalArgumentException.class, () -> BTreeP68.preInTree(List.of('A'), List.of('A', 'B'))); - } - - @Test - void testNodeEqualityAndHash() { - BTreeP68.Node n1 = new BTreeP68.Node('A'); - n1.left = new BTreeP68.Node('B'); - BTreeP68.Node n2 = new BTreeP68.Node('A'); - n2.left = new BTreeP68.Node('B'); - assertEquals(n1, n2); // same structure - assertEquals(n1, n1); // self equality - assertNotEquals(n1, "other"); - assertNotEquals(n1, null); - assertEquals(n1.hashCode(), n2.hashCode()); - - assertNotEquals(n1, new BTreeP68.Node('X')); - BTreeP68.Node n3 = new BTreeP68.Node('A'); - n3.left = new BTreeP68.Node('B'); - n3.right = new BTreeP68.Node('C'); - assertNotEquals(n1, n3); - - n2.left.value = 'C'; - assertNotEquals(n1, n2); - } - - @Test - void testNodeToString() { - BTreeP68.Node leaf = new BTreeP68.Node('X'); - assertEquals("X", leaf.toString()); - - BTreeP68.Node root = new BTreeP68.Node('A'); - root.left = new BTreeP68.Node('B'); - root.right = new BTreeP68.Node('C'); - assertEquals("A(B,C)", root.toString()); - - BTreeP68.Node half = new BTreeP68.Node('A'); - half.left = new BTreeP68.Node('B'); - assertEquals("A(B,NIL)", half.toString()); - - BTreeP68.Node halfRight = new BTreeP68.Node('A'); - halfRight.right = new BTreeP68.Node('B'); - assertEquals("A(NIL,B)", halfRight.toString()); - } -} diff --git a/src/test/java/org/nintynine/problems/BTree54Test.java b/src/test/java/org/nintynine/problems/Btree54Test.java similarity index 59% rename from src/test/java/org/nintynine/problems/BTree54Test.java rename to src/test/java/org/nintynine/problems/Btree54Test.java index f11912a..9dbe228 100644 --- a/src/test/java/org/nintynine/problems/BTree54Test.java +++ b/src/test/java/org/nintynine/problems/Btree54Test.java @@ -7,23 +7,23 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; -class BTree54Test { +class Btree54Test { @Test @DisplayName("Test single node expressions") void testSingleNode() { - assertTrue(BTree54.isTree("a")); - assertTrue(BTree54.isTree("x")); - assertTrue(BTree54.isTree("(a nil nil)")); + assertTrue(Btree54.isTree("a")); + assertTrue(Btree54.isTree("x")); + assertTrue(Btree54.isTree("(a nil nil)")); } @Test @DisplayName("Test complex valid expressions") void testValidComplexExpressions() { - assertTrue(BTree54.isTree("(a (b nil nil) nil)")); - assertTrue(BTree54.isTree("(a nil (b nil nil))")); - assertTrue(BTree54.isTree("(a (b nil nil) (c nil nil))")); - assertTrue(BTree54.isTree("(a (b (c nil nil) nil) nil)")); + assertTrue(Btree54.isTree("(a (b nil nil) nil)")); + assertTrue(Btree54.isTree("(a nil (b nil nil))")); + assertTrue(Btree54.isTree("(a (b nil nil) (c nil nil))")); + assertTrue(Btree54.isTree("(a (b (c nil nil) nil) nil)")); } @ParameterizedTest @@ -42,32 +42,32 @@ void testValidComplexExpressions() { "(a (b) nil)" }) void testInvalidExpressions(String expression) { - assertFalse(BTree54.isTree(expression)); + assertFalse(Btree54.isTree(expression)); } @Test @DisplayName("Test tree parsing and reconstruction") void testTreeParsing() { String expr = "(a (b nil nil) (c nil nil))"; - BTree54.BTree54Node tree = BTree54.parseTree(expr); + Btree54.Btree54Node tree = Btree54.parseTree(expr); assertEquals(expr, tree.toString()); } @Test @DisplayName("Test null and empty inputs") void testNullAndEmpty() { - assertFalse(BTree54.isTree(null)); - assertFalse(BTree54.isTree("")); - assertFalse(BTree54.isTree(" ")); + assertFalse(Btree54.isTree(null)); + assertFalse(Btree54.isTree("")); + assertFalse(Btree54.isTree(" ")); } @Test @DisplayName("Test node creation and equality") void testNodeCreation() { - BTree54.BTree54Node leaf1 = new BTree54.BTree54Node("x"); - BTree54.BTree54Node leaf2 = new BTree54.BTree54Node("x"); - BTree54.BTree54Node bTree54Node1 = new BTree54.BTree54Node("a", leaf1, null); - BTree54.BTree54Node bTree54Node = new BTree54.BTree54Node("a", leaf2, null); + Btree54.Btree54Node leaf1 = new Btree54.Btree54Node("x"); + Btree54.Btree54Node leaf2 = new Btree54.Btree54Node("x"); + Btree54.Btree54Node bTree54Node1 = new Btree54.Btree54Node("a", leaf1, null); + Btree54.Btree54Node bTree54Node = new Btree54.Btree54Node("a", leaf2, null); assertEquals(leaf1, leaf2); assertEquals(bTree54Node1, bTree54Node); @@ -77,24 +77,24 @@ void testNodeCreation() { @Test @DisplayName("Test node construction with null value") void testNodeNullValue() { - assertThrows(NullPointerException.class, () -> new BTree54.BTree54Node(null)); + assertThrows(NullPointerException.class, () -> new Btree54.Btree54Node(null)); } @Test @DisplayName("Test complex tree structure") void testComplexTree() { String complexExpr = "(root (left (ll nil nil) (lr nil nil)) (right nil (rr nil nil)))"; - assertTrue(BTree54.isTree(complexExpr)); + assertTrue(Btree54.isTree(complexExpr)); - BTree54.BTree54Node tree = BTree54.parseTree(complexExpr); + Btree54.Btree54Node tree = Btree54.parseTree(complexExpr); assertEquals(complexExpr, tree.toString()); } @Test @DisplayName("Test invalid characters in values") void testInvalidCharacters() { - assertFalse(BTree54.isTree("(a(b nil nil) nil)")); - assertFalse(BTree54.isTree("(a) (b nil nil) nil)")); - assertFalse(BTree54.isTree("(a,b nil nil)")); + assertFalse(Btree54.isTree("(a(b nil nil) nil)")); + assertFalse(Btree54.isTree("(a) (b nil nil) nil)")); + assertFalse(Btree54.isTree("(a,b nil nil)")); } } diff --git a/src/test/java/org/nintynine/problems/BTreeP56Test.java b/src/test/java/org/nintynine/problems/BtreeP56Test.java similarity index 75% rename from src/test/java/org/nintynine/problems/BTreeP56Test.java rename to src/test/java/org/nintynine/problems/BtreeP56Test.java index d171643..f1b0af8 100644 --- a/src/test/java/org/nintynine/problems/BTreeP56Test.java +++ b/src/test/java/org/nintynine/problems/BtreeP56Test.java @@ -4,24 +4,24 @@ import org.junit.jupiter.api.Test; -class BTreeP56Test { +class BtreeP56Test { @Test void emptyTreeIsSymmetric() { - BTreeP56 tree = new BTreeP56<>(); + BtreeP56 tree = new BtreeP56<>(); assertTrue(tree.isSymmetric()); } @Test void singleNodeTreeIsSymmetric() { - BTreeP56 tree = new BTreeP56<>(); + BtreeP56 tree = new BtreeP56<>(); tree.setRoot(1); assertTrue(tree.isSymmetric()); } @Test void symmetricTreeWithTwoNodes() { - BTreeP56 tree = new BTreeP56<>(); + BtreeP56 tree = new BtreeP56<>(); tree.setRoot(1); tree.addLeft(2); tree.addRight(3); @@ -30,7 +30,7 @@ void symmetricTreeWithTwoNodes() { @Test void asymmetricTreeWithLeftNodeOnly() { - BTreeP56 tree = new BTreeP56<>(); + BtreeP56 tree = new BtreeP56<>(); tree.setRoot(1); tree.addLeft(2); assertFalse(tree.isSymmetric()); @@ -38,7 +38,7 @@ void asymmetricTreeWithLeftNodeOnly() { @Test void asymmetricTreeWithRightNodeOnly() { - BTreeP56 tree = new BTreeP56<>(); + BtreeP56 tree = new BtreeP56<>(); tree.setRoot(1); tree.addRight(2); assertFalse(tree.isSymmetric()); @@ -46,7 +46,7 @@ void asymmetricTreeWithRightNodeOnly() { @Test void throwsExceptionWhenAddingToEmptyTree() { - BTreeP56 tree = new BTreeP56<>(); + BtreeP56 tree = new BtreeP56<>(); assertThrows(IllegalStateException.class, () -> tree.addLeft(1)); assertThrows(IllegalStateException.class, () -> tree.addRight(1)); } diff --git a/src/test/java/org/nintynine/problems/BTreeP57Test.java b/src/test/java/org/nintynine/problems/BtreeP57Test.java similarity index 77% rename from src/test/java/org/nintynine/problems/BTreeP57Test.java rename to src/test/java/org/nintynine/problems/BtreeP57Test.java index 08ca470..62fe1db 100644 --- a/src/test/java/org/nintynine/problems/BTreeP57Test.java +++ b/src/test/java/org/nintynine/problems/BtreeP57Test.java @@ -4,17 +4,17 @@ import org.junit.jupiter.api.Test; -class BTreeP57Test { +class BtreeP57Test { @Test void constructEmptyTree() { - BTreeP57 tree = new BTreeP57<>(); + BtreeP57 tree = new BtreeP57<>(); assertTrue(tree.isSymmetric()); } @Test void constructSymmetricTree() { - BTreeP57 tree = new BTreeP57<>(); + BtreeP57 tree = new BtreeP57<>(); Integer[] values = {5, 3, 18, 1, 4, 12, 21}; tree.construct(values); assertTrue(tree.isSymmetric()); @@ -22,7 +22,7 @@ void constructSymmetricTree() { @Test void constructAnotherSymmetricTree() { - BTreeP57 tree = new BTreeP57<>(); + BtreeP57 tree = new BtreeP57<>(); Integer[] values = {3, 2, 5, 7, 1}; tree.construct(values); assertTrue(tree.isSymmetric()); @@ -30,7 +30,7 @@ void constructAnotherSymmetricTree() { @Test void constructAsymmetricTree() { - BTreeP57 tree = new BTreeP57<>(); + BtreeP57 tree = new BtreeP57<>(); Integer[] values = {3, 2, 5, 7}; tree.construct(values); assertFalse(tree.isSymmetric()); @@ -38,7 +38,7 @@ void constructAsymmetricTree() { @Test void verifyTreeStructure() { - BTreeP57 tree = new BTreeP57<>(); + BtreeP57 tree = new BtreeP57<>(); Integer[] values = {3, 2, 5, 7, 1}; tree.construct(values); String expected = "(3 (2 (1 nil nil) nil) (5 nil (7 nil nil)))"; @@ -47,14 +47,14 @@ void verifyTreeStructure() { @Test void insertSingleValue() { - BTreeP57 tree = new BTreeP57<>(); + BtreeP57 tree = new BtreeP57<>(); tree.insert(5); assertEquals("(5 nil nil)", tree.getStructure()); } @Test void insertDuplicateValues() { - BTreeP57 tree = new BTreeP57<>(); + BtreeP57 tree = new BtreeP57<>(); Integer[] values = {3, 3, 3}; tree.construct(values); assertEquals("(3 nil nil)", tree.getStructure()); @@ -62,7 +62,7 @@ void insertDuplicateValues() { @Test void constructLargerSymmetricTree() { - BTreeP57 tree = new BTreeP57<>(); + BtreeP57 tree = new BtreeP57<>(); Integer[] values = {10, 5, 15, 3, 7, 13, 17, 1, 4, 6, 8, 12, 14, 16, 18}; tree.construct(values); assertTrue(tree.isSymmetric()); diff --git a/src/test/java/org/nintynine/problems/BTreeP58Test.java b/src/test/java/org/nintynine/problems/BtreeP58Test.java similarity index 54% rename from src/test/java/org/nintynine/problems/BTreeP58Test.java rename to src/test/java/org/nintynine/problems/BtreeP58Test.java index 80c7fa5..bed9f83 100644 --- a/src/test/java/org/nintynine/problems/BTreeP58Test.java +++ b/src/test/java/org/nintynine/problems/BtreeP58Test.java @@ -5,18 +5,18 @@ import java.util.List; import org.junit.jupiter.api.Test; -class BTreeP58Test { +class BtreeP58Test { @Test void testSymCbalTreesWithOneNode() { - List trees = BTreeP58.symCbalTrees(1); + List trees = BtreeP58.symCbalTrees(1); assertEquals(1, trees.size()); assertEquals("X", trees.getFirst().toString()); } @Test void testSymCbalTreesWithFiveNodes() { - List trees = BTreeP58.symCbalTrees(5); + List trees = BtreeP58.symCbalTrees(5); assertEquals(2, trees.size()); assertTrue( trees.stream() @@ -26,18 +26,18 @@ void testSymCbalTreesWithFiveNodes() { @Test void testSymCbalTreesWithEvenNodes() { - List trees = BTreeP58.symCbalTrees(6); + List trees = BtreeP58.symCbalTrees(6); assertEquals(0, trees.size()); } @Test void testCountSymCbalTrees() { - assertEquals(1, BTreeP58.countSymCbalTrees(1)); - assertEquals(0, BTreeP58.countSymCbalTrees(2)); - assertEquals(1, BTreeP58.countSymCbalTrees(3)); - assertEquals(0, BTreeP58.countSymCbalTrees(4)); - assertEquals(2, BTreeP58.countSymCbalTrees(5)); - assertEquals(0, BTreeP58.countSymCbalTrees(6)); - assertEquals(1, BTreeP58.countSymCbalTrees(7)); + assertEquals(1, BtreeP58.countSymCbalTrees(1)); + assertEquals(0, BtreeP58.countSymCbalTrees(2)); + assertEquals(1, BtreeP58.countSymCbalTrees(3)); + assertEquals(0, BtreeP58.countSymCbalTrees(4)); + assertEquals(2, BtreeP58.countSymCbalTrees(5)); + assertEquals(0, BtreeP58.countSymCbalTrees(6)); + assertEquals(1, BtreeP58.countSymCbalTrees(7)); } } diff --git a/src/test/java/org/nintynine/problems/BTreeP59Test.java b/src/test/java/org/nintynine/problems/BtreeP59Test.java similarity index 66% rename from src/test/java/org/nintynine/problems/BTreeP59Test.java rename to src/test/java/org/nintynine/problems/BtreeP59Test.java index 7a3ea23..c6fdcd9 100644 --- a/src/test/java/org/nintynine/problems/BTreeP59Test.java +++ b/src/test/java/org/nintynine/problems/BtreeP59Test.java @@ -5,25 +5,25 @@ import java.util.List; import org.junit.jupiter.api.Test; -class BTreeP59Test { +class BtreeP59Test { @Test void testHbalTreesHeight0() { - List trees = BTreeP59.hbalTrees(0); + List trees = BtreeP59.hbalTrees(0); assertEquals(1, trees.size()); assertNull(trees.getFirst()); } @Test void testHbalTreesHeight1() { - List trees = BTreeP59.hbalTrees(1); + List trees = BtreeP59.hbalTrees(1); assertEquals(1, trees.size()); assertEquals("X", trees.getFirst().toString()); } @Test void testHbalTreesHeight2() { - List trees = BTreeP59.hbalTrees(2); + List trees = BtreeP59.hbalTrees(2); assertEquals(3, trees.size()); assertTrue( trees.stream() @@ -33,17 +33,17 @@ void testHbalTreesHeight2() { @Test void testHbalTreesHeight3() { - List trees = BTreeP59.hbalTrees(3); + List trees = BtreeP59.hbalTrees(3); assertFalse(trees.isEmpty()); // All trees should be height-balanced - assertTrue(trees.stream().allMatch(BTreeP59::isHeightBalanced)); + assertTrue(trees.stream().allMatch(BtreeP59::isHeightBalanced)); // All trees should have height exactly 3 - assertTrue(trees.stream().allMatch(tree -> BTreeP59.height(tree) == 3)); + assertTrue(trees.stream().allMatch(tree -> BtreeP59.height(tree) == 3)); } @Test void testHbalTreesNegativeHeight() { - List trees = BTreeP59.hbalTrees(-1); + List trees = BtreeP59.hbalTrees(-1); assertTrue(trees.isEmpty()); } } diff --git a/src/test/java/org/nintynine/problems/BTreeP60Test.java b/src/test/java/org/nintynine/problems/BtreeP60Test.java similarity index 51% rename from src/test/java/org/nintynine/problems/BTreeP60Test.java rename to src/test/java/org/nintynine/problems/BtreeP60Test.java index c1fad94..47ed725 100644 --- a/src/test/java/org/nintynine/problems/BTreeP60Test.java +++ b/src/test/java/org/nintynine/problems/BtreeP60Test.java @@ -5,35 +5,35 @@ import java.util.List; import org.junit.jupiter.api.Test; -class BTreeP60Test { +class BtreeP60Test { @Test void testMinNodes() { - assertEquals(0, BTreeP60.minNodes(0)); - assertEquals(1, BTreeP60.minNodes(1)); - assertEquals(2, BTreeP60.minNodes(2)); - assertEquals(4, BTreeP60.minNodes(3)); - assertEquals(7, BTreeP60.minNodes(4)); + assertEquals(0, BtreeP60.minNodes(0)); + assertEquals(1, BtreeP60.minNodes(1)); + assertEquals(2, BtreeP60.minNodes(2)); + assertEquals(4, BtreeP60.minNodes(3)); + assertEquals(7, BtreeP60.minNodes(4)); } @Test void testMaxHeight() { - assertEquals(0, BTreeP60.maxHeight(0)); - assertEquals(1, BTreeP60.maxHeight(1)); - assertEquals(2, BTreeP60.maxHeight(2)); - assertEquals(2, BTreeP60.maxHeight(3)); - assertEquals(3, BTreeP60.maxHeight(4)); + assertEquals(0, BtreeP60.maxHeight(0)); + assertEquals(1, BtreeP60.maxHeight(1)); + assertEquals(2, BtreeP60.maxHeight(2)); + assertEquals(2, BtreeP60.maxHeight(3)); + assertEquals(3, BtreeP60.maxHeight(4)); } @Test void testHbalTreeNodesEmpty() { - List> trees = BTreeP60.hbalTreeNodes(0); + List> trees = BtreeP60.hbalTreeNodes(0); assertTrue(trees.isEmpty()); } @Test void testHbalTreeNodesSingleNode() { - List> trees = BTreeP60.hbalTreeNodes(1); + List> trees = BtreeP60.hbalTreeNodes(1); assertEquals(1, trees.size()); assertEquals("x", trees.getFirst().getValue()); assertNull(trees.getFirst().getLeft()); @@ -42,60 +42,60 @@ void testHbalTreeNodesSingleNode() { @Test void testHbalTreeNodesTwoNodes() { - List> trees = BTreeP60.hbalTreeNodes(2); + List> trees = BtreeP60.hbalTreeNodes(2); assertEquals(2, trees.size()); // There should be 2 possible trees with 2 nodes } @Test void testHbalTreeNodesThreeNodes() { - List> trees = BTreeP60.hbalTreeNodes(3); + List> trees = BtreeP60.hbalTreeNodes(3); assertEquals(1, trees.size()); // There should be 1 possible tree with 3 nodes } @Test void testTreeHeight() { - BTreeP60 root = new BTreeP60<>("x"); - assertEquals(1, BTreeP60.getHeight(root)); + BtreeP60 root = new BtreeP60<>("x"); + assertEquals(1, BtreeP60.getHeight(root)); - root.left = new BTreeP60<>("x"); - assertEquals(2, BTreeP60.getHeight(root)); + root.left = new BtreeP60<>("x"); + assertEquals(2, BtreeP60.getHeight(root)); - root.right = new BTreeP60<>("x"); - assertEquals(2, BTreeP60.getHeight(root)); + root.right = new BtreeP60<>("x"); + assertEquals(2, BtreeP60.getHeight(root)); } @Test void testHeightBalancedProperty() { - List> trees = BTreeP60.hbalTreeNodes(4); - for (BTreeP60 tree : trees) { + List> trees = BtreeP60.hbalTreeNodes(4); + for (BtreeP60 tree : trees) { assertTrue(isBalanced(tree)); } } @Test void testFifteenNodes() { - List> trees = BTreeP60.hbalTreeNodes(15); + List> trees = BtreeP60.hbalTreeNodes(15); assertFalse(trees.isEmpty()); // All trees should be height-balanced and have exactly 15 nodes - for (BTreeP60 tree : trees) { + for (BtreeP60 tree : trees) { assertTrue(isBalanced(tree)); assertEquals(15, countNodes(tree)); } } // Helper methods for testing - private boolean isBalanced(BTreeP60 root) { + private boolean isBalanced(BtreeP60 root) { if (root == null) return true; - int leftHeight = BTreeP60.getHeight(root.getLeft()); - int rightHeight = BTreeP60.getHeight(root.getRight()); + int leftHeight = BtreeP60.getHeight(root.getLeft()); + int rightHeight = BtreeP60.getHeight(root.getRight()); return Math.abs(leftHeight - rightHeight) <= 1 && isBalanced(root.getLeft()) && isBalanced(root.getRight()); } - private int countNodes(BTreeP60 root) { + private int countNodes(BtreeP60 root) { if (root == null) return 0; return 1 + countNodes(root.getLeft()) + countNodes(root.getRight()); } diff --git a/src/test/java/org/nintynine/problems/BtreeP61Test.java b/src/test/java/org/nintynine/problems/BtreeP61Test.java new file mode 100644 index 0000000..4370ad5 --- /dev/null +++ b/src/test/java/org/nintynine/problems/BtreeP61Test.java @@ -0,0 +1,60 @@ +package org.nintynine.problems; + +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.Test; + +class BtreeP61Test { + + @Test + void testEmptyTree() { + assertNull(null); + assertEquals(0, BtreeP61.countLeaves(null)); + } + + @Test + void testSingleNode() { + BtreeP61 tree = new BtreeP61<>("a"); + assertEquals(1, BtreeP61.countLeaves(tree)); + } + + @Test + void testOneChild() { + BtreeP61 tree = new BtreeP61<>("a"); + tree.left = new BtreeP61<>("b"); + assertEquals(1, BtreeP61.countLeaves(tree)); + } + + @Test + void testTwoChildren() { + BtreeP61 tree = new BtreeP61<>("a"); + tree.left = new BtreeP61<>("b"); + tree.right = new BtreeP61<>("c"); + assertEquals(2, BtreeP61.countLeaves(tree)); + } + + @Test + void testComplexTree() { + BtreeP61 tree = new BtreeP61<>("a"); + tree.left = new BtreeP61<>("b"); + tree.right = new BtreeP61<>("c"); + tree.left.left = new BtreeP61<>("d"); + tree.left.right = new BtreeP61<>("e"); + tree.right.right = new BtreeP61<>("f"); + + assertEquals(3, BtreeP61.countLeaves(tree)); + } + + @Test + void testFullBinaryTree() { + BtreeP61 tree = new BtreeP61<>("a"); + tree.left = new BtreeP61<>("b"); + tree.right = new BtreeP61<>("c"); + tree.left.left = new BtreeP61<>("d"); + tree.left.right = new BtreeP61<>("e"); + tree.right.left = new BtreeP61<>("f"); + tree.right.right = new BtreeP61<>("g"); + + assertEquals(4, BtreeP61.countLeaves(tree)); + } +} diff --git a/src/test/java/org/nintynine/problems/BtreeP68Test.java b/src/test/java/org/nintynine/problems/BtreeP68Test.java new file mode 100644 index 0000000..37a240e --- /dev/null +++ b/src/test/java/org/nintynine/problems/BtreeP68Test.java @@ -0,0 +1,102 @@ +package org.nintynine.problems; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.List; +import org.junit.jupiter.api.Test; + +class BtreeP68Test { + + private BtreeP68.Node exampleTree() { + BtreeP68.Node a = new BtreeP68.Node('A'); + BtreeP68.Node b = new BtreeP68.Node('B'); + BtreeP68.Node c = new BtreeP68.Node('C'); + BtreeP68.Node d = new BtreeP68.Node('D'); + BtreeP68.Node e = new BtreeP68.Node('E'); + BtreeP68.Node f = new BtreeP68.Node('F'); + BtreeP68.Node g = new BtreeP68.Node('G'); + a.left = b; + a.right = c; + b.left = d; + b.right = e; + c.right = f; + f.left = g; + return a; + } + + @Test + void testPreorderAndInorder() { + BtreeP68.Node root = exampleTree(); + List pre = BtreeP68.preorder(root); + List in = BtreeP68.inorder(root); + assertEquals(List.of('A', 'B', 'D', 'E', 'C', 'F', 'G'), pre); + assertEquals(List.of('D', 'B', 'E', 'A', 'C', 'G', 'F'), in); + } + + @Test + void testFromPreorder() { + List seq = List.of('F', 'C', 'A', 'E', 'H', 'G'); + BtreeP68.Node root = BtreeP68.fromPreorder(seq); + assertEquals(seq, BtreeP68.preorder(root)); + List inorder = BtreeP68.inorder(root); + assertEquals(List.of('A', 'C', 'E', 'F', 'G', 'H'), inorder); // inorder sorted + } + + @Test + void testPreInTree() { + BtreeP68.Node root = exampleTree(); + List pre = BtreeP68.preorder(root); + List in = BtreeP68.inorder(root); + BtreeP68.Node rebuilt = BtreeP68.preInTree(pre, in); + assertEquals(pre, BtreeP68.preorder(rebuilt)); + assertEquals(in, BtreeP68.inorder(rebuilt)); + assertEquals(root, rebuilt); + } + + @Test + void testPreInTreeInvalid() { + assertThrows( + IllegalArgumentException.class, () -> BtreeP68.preInTree(List.of('A'), List.of('A', 'B'))); + } + + @Test + void testNodeEqualityAndHash() { + BtreeP68.Node n1 = new BtreeP68.Node('A'); + n1.left = new BtreeP68.Node('B'); + BtreeP68.Node n2 = new BtreeP68.Node('A'); + n2.left = new BtreeP68.Node('B'); + assertEquals(n1, n2); // same structure + assertEquals(n1, n1); // self equality + assertNotEquals(n1, "other"); + assertNotEquals(n1, null); + assertEquals(n1.hashCode(), n2.hashCode()); + + assertNotEquals(n1, new BtreeP68.Node('X')); + BtreeP68.Node n3 = new BtreeP68.Node('A'); + n3.left = new BtreeP68.Node('B'); + n3.right = new BtreeP68.Node('C'); + assertNotEquals(n1, n3); + + n2.left.value = 'C'; + assertNotEquals(n1, n2); + } + + @Test + void testNodeToString() { + BtreeP68.Node leaf = new BtreeP68.Node('X'); + assertEquals("X", leaf.toString()); + + BtreeP68.Node root = new BtreeP68.Node('A'); + root.left = new BtreeP68.Node('B'); + root.right = new BtreeP68.Node('C'); + assertEquals("A(B,C)", root.toString()); + + BtreeP68.Node half = new BtreeP68.Node('A'); + half.left = new BtreeP68.Node('B'); + assertEquals("A(B,NIL)", half.toString()); + + BtreeP68.Node halfRight = new BtreeP68.Node('A'); + halfRight.right = new BtreeP68.Node('B'); + assertEquals("A(NIL,B)", halfRight.toString()); + } +} diff --git a/src/test/java/org/nintynine/problems/BTreeP69Test.java b/src/test/java/org/nintynine/problems/BtreeP69Test.java similarity index 52% rename from src/test/java/org/nintynine/problems/BTreeP69Test.java rename to src/test/java/org/nintynine/problems/BtreeP69Test.java index 1dcb76c..84d2eba 100644 --- a/src/test/java/org/nintynine/problems/BTreeP69Test.java +++ b/src/test/java/org/nintynine/problems/BtreeP69Test.java @@ -4,55 +4,55 @@ import org.junit.jupiter.api.Test; -class BTreeP69Test { +class BtreeP69Test { @Test void testDotstringExample() { String ds = "ABD..E..C.FG..."; - BTreeP69.Node tree = BTreeP69.tree(ds); - assertEquals(ds, BTreeP69.dotstring(tree)); + BtreeP69.Node tree = BtreeP69.tree(ds); + assertEquals(ds, BtreeP69.dotstring(tree)); } @Test void testSingleNode() { String ds = "A.."; - BTreeP69.Node tree = BTreeP69.tree(ds); + BtreeP69.Node tree = BtreeP69.tree(ds); assertEquals('A', tree.value); assertNull(tree.left); assertNull(tree.right); - assertEquals(ds, BTreeP69.dotstring(tree)); + assertEquals(ds, BtreeP69.dotstring(tree)); } @Test void testNullTree() { - assertNull(BTreeP69.tree(".")); - assertEquals(".", BTreeP69.dotstring(null)); + assertNull(BtreeP69.tree(".")); + assertEquals(".", BtreeP69.dotstring(null)); } @Test void testInvalidDotstring() { - assertThrows(IllegalArgumentException.class, () -> BTreeP69.tree("A.")); - assertThrows(IllegalArgumentException.class, () -> BTreeP69.tree("A...")); + assertThrows(IllegalArgumentException.class, () -> BtreeP69.tree("A.")); + assertThrows(IllegalArgumentException.class, () -> BtreeP69.tree("A...")); } @Test void testNullInput() { - assertThrows(IllegalArgumentException.class, () -> BTreeP69.tree(null)); + assertThrows(IllegalArgumentException.class, () -> BtreeP69.tree(null)); } @Test void testIncompleteDotstring() { - assertThrows(IllegalArgumentException.class, () -> BTreeP69.tree("A")); + assertThrows(IllegalArgumentException.class, () -> BtreeP69.tree("A")); } @Test void testExtraCharacters() { - assertThrows(IllegalArgumentException.class, () -> BTreeP69.tree("A..B")); + assertThrows(IllegalArgumentException.class, () -> BtreeP69.tree("A..B")); } @Test void testToStringRepresentation() { - BTreeP69.Node tree = BTreeP69.tree("ABD..E..C.FG..."); + BtreeP69.Node tree = BtreeP69.tree("ABD..E..C.FG..."); assertEquals("A(B(D,E),C(NIL,F(G,NIL)))", tree.toString()); } }