From 2befeec377d0cd2b49db99fb7ad1e928261230d2 Mon Sep 17 00:00:00 2001
From: Mohan <777emohan@gmail.com>
Date: Fri, 20 Feb 2026 23:03:15 +0530
Subject: [PATCH] Add time and space complexity documentation to
LongestNonRepetitiveSubstring
---
.clang-format | 272 +-
.devcontainer/Dockerfile | 48 +-
.devcontainer/devcontainer.json | 94 +-
.github/CODEOWNERS | 2 +-
.github/ISSUE_TEMPLATE/bug_report.yml | 90 +-
.github/ISSUE_TEMPLATE/config.yml | 10 +-
.github/ISSUE_TEMPLATE/feature_request.yml | 68 +-
.github/ISSUE_TEMPLATE/other.yml | 38 +-
.github/dependabot.yml | 36 +-
.github/pull_request_template.md | 34 +-
.github/workflows/build.yml | 80 +-
.github/workflows/clang-format-lint.yml | 38 +-
.github/workflows/close-failed-prs.yml | 312 +-
.github/workflows/codeql.yml | 132 +-
.github/workflows/infer.yml | 128 +-
.github/workflows/project_structure.yml | 50 +-
.github/workflows/scripts/check_structure.py | 54 +-
.github/workflows/stale.yml | 46 +-
.github/workflows/update-directorymd.yml | 88 +-
.gitignore | 92 +-
.gitpod.dockerfile | 44 +-
.gitpod.yml | 26 +-
.inferconfig | 58 +-
CONTRIBUTING.md | 60 +-
DIRECTORY.md | 3210 +++++-----
LICENSE | 42 +-
README.md | 40 +-
checkstyle.xml | 396 +-
pmd-custom_ruleset.xml | 56 +-
pmd-exclude.properties | 222 +-
pom.xml | 314 +-
spotbugs-exclude.xml | 362 +-
.../thealgorithms/audiofilters/EMAFilter.java | 96 +-
.../thealgorithms/audiofilters/IIRFilter.java | 186 +-
.../AllPathsFromSourceToTarget.java | 252 +-
.../backtracking/ArrayCombination.java | 108 +-
.../backtracking/Combination.java | 132 +-
.../backtracking/CombinationSum.java | 96 +-
.../backtracking/CrosswordSolver.java | 250 +-
.../thealgorithms/backtracking/FloodFill.java | 124 +-
.../backtracking/KnightsTour.java | 312 +-
.../thealgorithms/backtracking/MColoring.java | 192 +-
.../backtracking/MazeRecursion.java | 250 +-
.../thealgorithms/backtracking/NQueens.java | 222 +-
.../backtracking/ParenthesesGenerator.java | 100 +-
.../backtracking/Permutation.java | 114 +-
.../thealgorithms/backtracking/PowerSum.java | 102 +-
.../backtracking/SubsequenceFinder.java | 108 +-
.../backtracking/SudokuSolver.java | 314 +-
.../backtracking/UniquePermutation.java | 124 +-
.../backtracking/WordPatternMatcher.java | 172 +-
.../backtracking/WordSearch.java | 218 +-
.../bitmanipulation/BcdConversion.java | 164 +-
.../BinaryPalindromeCheck.java | 86 +-
.../bitmanipulation/BitRotate.java | 166 +-
.../bitmanipulation/BitSwap.java | 66 +-
.../bitmanipulation/BitwiseGCD.java | 294 +-
.../bitmanipulation/BooleanAlgebraGates.java | 222 +-
.../bitmanipulation/ClearLeftmostSetBit.java | 78 +-
.../bitmanipulation/CountBitsFlip.java | 126 +-
.../bitmanipulation/CountLeadingZeros.java | 78 +-
.../bitmanipulation/CountSetBits.java | 158 +-
.../bitmanipulation/FindNthBit.java | 92 +-
.../bitmanipulation/FirstDifferentBit.java | 66 +-
.../bitmanipulation/GenerateSubsets.java | 88 +-
.../bitmanipulation/GrayCodeConversion.java | 88 +-
.../bitmanipulation/HammingDistance.java | 58 +-
.../HigherLowerPowerOfTwo.java | 108 +-
.../bitmanipulation/HighestSetBit.java | 108 +-
.../IndexOfRightMostSetBit.java | 88 +-
.../thealgorithms/bitmanipulation/IsEven.java | 28 +-
.../bitmanipulation/IsPowerTwo.java | 64 +-
.../bitmanipulation/LowestSetBit.java | 68 +-
.../bitmanipulation/ModuloPowerOfTwo.java | 56 +-
.../NextHigherSameBitCount.java | 60 +-
.../NonRepeatingNumberFinder.java | 70 +-
.../NumberAppearingOddTimes.java | 82 +-
.../NumbersDifferentSigns.java | 60 +-
.../bitmanipulation/OneBitDifference.java | 64 +-
.../bitmanipulation/OnesComplement.java | 74 +-
.../bitmanipulation/ParityCheck.java | 68 +-
.../bitmanipulation/ReverseBits.java | 82 +-
.../bitmanipulation/SingleElement.java | 78 +-
.../bitmanipulation/SwapAdjacentBits.java | 114 +-
.../bitmanipulation/TwosComplement.java | 124 +-
.../bitmanipulation/Xs3Conversion.java | 116 +-
.../thealgorithms/ciphers/ADFGVXCipher.java | 334 +-
.../java/com/thealgorithms/ciphers/AES.java | 5562 ++++++++---------
.../thealgorithms/ciphers/AESEncryption.java | 208 +-
.../thealgorithms/ciphers/AffineCipher.java | 174 +-
.../com/thealgorithms/ciphers/Autokey.java | 110 +-
.../thealgorithms/ciphers/BaconianCipher.java | 142 +-
.../com/thealgorithms/ciphers/Blowfish.java | 2488 ++++----
.../com/thealgorithms/ciphers/Caesar.java | 198 +-
.../ciphers/ColumnarTranspositionCipher.java | 372 +-
.../java/com/thealgorithms/ciphers/DES.java | 500 +-
.../thealgorithms/ciphers/DiffieHellman.java | 72 +-
.../java/com/thealgorithms/ciphers/ECC.java | 472 +-
.../thealgorithms/ciphers/ElGamalCipher.java | 348 +-
.../com/thealgorithms/ciphers/HillCipher.java | 206 +-
.../thealgorithms/ciphers/MonoAlphabetic.java | 96 +-
.../ciphers/OneTimePadCipher.java | 178 +-
.../thealgorithms/ciphers/PlayfairCipher.java | 256 +-
.../com/thealgorithms/ciphers/Polybius.java | 124 +-
.../thealgorithms/ciphers/ProductCipher.java | 146 +-
.../java/com/thealgorithms/ciphers/RSA.java | 238 +-
.../ciphers/SimpleSubCipher.java | 170 +-
.../com/thealgorithms/ciphers/Vigenere.java | 212 +-
.../com/thealgorithms/ciphers/XORCipher.java | 190 +-
.../thealgorithms/ciphers/a5/A5Cipher.java | 126 +-
.../ciphers/a5/A5KeyStreamGenerator.java | 242 +-
.../thealgorithms/ciphers/a5/BaseLFSR.java | 20 +-
.../ciphers/a5/CompositeLFSR.java | 138 +-
.../com/thealgorithms/ciphers/a5/LFSR.java | 158 +-
.../com/thealgorithms/ciphers/a5/Utils.java | 50 +-
.../compression/ArithmeticCoding.java | 314 +-
.../compression/BurrowsWheelerTransform.java | 440 +-
.../com/thealgorithms/compression/LZ77.java | 336 +-
.../com/thealgorithms/compression/LZ78.java | 272 +-
.../com/thealgorithms/compression/LZW.java | 272 +-
.../compression/MoveToFront.java | 328 +-
.../compression/RunLengthEncoding.java | 174 +-
.../compression/ShannonFano.java | 318 +-
.../conversions/AffineConverter.java | 128 +-
.../conversions/AnyBaseToAnyBase.java | 362 +-
.../conversions/AnyBaseToDecimal.java | 104 +-
.../thealgorithms/conversions/AnytoAny.java | 136 +-
.../com/thealgorithms/conversions/Base64.java | 392 +-
.../conversions/BinaryToDecimal.java | 118 +-
.../conversions/BinaryToHexadecimal.java | 126 +-
.../conversions/BinaryToOctal.java | 90 +-
.../conversions/CoordinateConverter.java | 114 +-
.../conversions/DecimalToAnyBase.java | 138 +-
.../conversions/DecimalToBinary.java | 98 +-
.../conversions/DecimalToHexadecimal.java | 84 +-
.../conversions/DecimalToOctal.java | 76 +-
.../conversions/EndianConverter.java | 94 +-
.../thealgorithms/conversions/HexToOct.java | 124 +-
.../conversions/HexaDecimalToBinary.java | 124 +-
.../conversions/HexaDecimalToDecimal.java | 90 +-
.../conversions/IPConverter.java | 116 +-
.../conversions/IPv6Converter.java | 196 +-
.../conversions/IntegerToEnglish.java | 216 +-
.../conversions/IntegerToRoman.java | 136 +-
.../conversions/MorseCodeConverter.java | 196 +-
.../conversions/NumberToWords.java | 200 +-
.../conversions/OctalToBinary.java | 164 +-
.../conversions/OctalToDecimal.java | 84 +-
.../conversions/OctalToHexadecimal.java | 122 +-
.../PhoneticAlphabetConverter.java | 168 +-
.../conversions/RgbHsvConversion.java | 336 +-
.../conversions/RomanToInteger.java | 182 +-
.../conversions/TemperatureConverter.java | 92 +-
.../conversions/TimeConverter.java | 194 +-
.../conversions/TurkishToLatinConversion.java | 112 +-
.../conversions/UnitConversions.java | 102 +-
.../conversions/UnitsConverter.java | 294 +-
.../conversions/WordsToNumber.java | 686 +-
.../thealgorithms/datastructures/Node.java | 64 +-
.../datastructures/bags/Bag.java | 276 +-
.../bloomfilter/BloomFilter.java | 354 +-
.../buffers/CircularBuffer.java | 266 +-
.../datastructures/caches/FIFOCache.java | 1098 ++--
.../datastructures/caches/LFUCache.java | 370 +-
.../datastructures/caches/LIFOCache.java | 1126 ++--
.../datastructures/caches/LRUCache.java | 470 +-
.../datastructures/caches/MRUCache.java | 460 +-
.../datastructures/caches/RRCache.java | 1010 +--
.../datastructures/crdt/GCounter.java | 168 +-
.../datastructures/crdt/GSet.java | 130 +-
.../datastructures/crdt/LWWElementSet.java | 252 +-
.../datastructures/crdt/ORSet.java | 382 +-
.../datastructures/crdt/PNCounter.java | 200 +-
.../datastructures/crdt/TwoPSet.java | 168 +-
.../disjointsetunion/DisjointSetUnion.java | 130 +-
.../datastructures/disjointsetunion/Node.java | 50 +-
.../dynamicarray/DynamicArray.java | 584 +-
.../datastructures/graphs/AStar.java | 288 +-
.../datastructures/graphs/BellmanFord.java | 368 +-
.../graphs/BipartiteGraphDFS.java | 166 +-
.../graphs/BoruvkaAlgorithm.java | 434 +-
.../graphs/ConnectedComponent.java | 292 +-
.../datastructures/graphs/Cycles.java | 182 +-
.../datastructures/graphs/DialsAlgorithm.java | 228 +-
.../graphs/DijkstraAlgorithm.java | 182 +-
.../graphs/DijkstraOptimizedAlgorithm.java | 132 +-
.../graphs/EdmondsBlossomAlgorithm.java | 502 +-
.../datastructures/graphs/FloydWarshall.java | 170 +-
.../datastructures/graphs/FordFulkerson.java | 150 +-
.../datastructures/graphs/Graphs.java | 280 +-
.../graphs/HamiltonianCycle.java | 212 +-
.../graphs/JohnsonsAlgorithm.java | 400 +-
.../datastructures/graphs/KahnsAlgorithm.java | 332 +-
.../datastructures/graphs/Kosaraju.java | 338 +-
.../datastructures/graphs/Kruskal.java | 186 +-
.../datastructures/graphs/MatrixGraphs.java | 690 +-
.../datastructures/graphs/PrimMST.java | 122 +-
.../datastructures/graphs/README.md | 252 +-
.../graphs/TarjansAlgorithm.java | 286 +-
.../datastructures/graphs/TwoSat.java | 530 +-
.../graphs/UndirectedAdjacencyListGraph.java | 138 +-
.../datastructures/graphs/WelshPowell.java | 424 +-
.../datastructures/hashmap/Readme.md | 134 +-
.../hashing/GenericHashMapUsingArray.java | 408 +-
.../hashing/GenericHashMapUsingArrayList.java | 376 +-
.../hashmap/hashing/HashMap.java | 598 +-
.../hashmap/hashing/HashMapCuckooHashing.java | 538 +-
.../hashmap/hashing/ImmutableHashMap.java | 230 +-
.../hashmap/hashing/Intersection.java | 146 +-
.../hashmap/hashing/LinearProbingHashMap.java | 338 +-
.../hashmap/hashing/MainCuckooHashing.java | 140 +-
.../hashmap/hashing/MajorityElement.java | 86 +-
.../datastructures/hashmap/hashing/Map.java | 44 +-
.../heaps/EmptyHeapException.java | 34 +-
.../datastructures/heaps/FibonacciHeap.java | 908 +--
.../datastructures/heaps/GenericHeap.java | 298 +-
.../datastructures/heaps/Heap.java | 88 +-
.../datastructures/heaps/HeapElement.java | 346 +-
.../heaps/IndexedPriorityQueue.java | 654 +-
.../heaps/KthElementFinder.java | 120 +-
.../datastructures/heaps/LeftistHeap.java | 328 +-
.../datastructures/heaps/MaxHeap.java | 496 +-
.../datastructures/heaps/MedianFinder.java | 118 +-
.../heaps/MergeKSortedArrays.java | 120 +-
.../datastructures/heaps/MinHeap.java | 542 +-
.../heaps/MinPriorityQueue.java | 310 +-
.../datastructures/heaps/Readme.md | 256 +-
.../lists/CircleLinkedList.java | 254 +-
.../lists/CircularDoublyLinkedList.java | 236 +-
.../lists/CountSinglyLinkedListRecursion.java | 58 +-
.../lists/CreateAndDetectLoop.java | 184 +-
.../lists/CursorLinkedList.java | 418 +-
.../lists/DoublyLinkedList.java | 820 +--
.../lists/FlattenMultilevelLinkedList.java | 184 +-
.../lists/MergeKSortedLinkedList.java | 188 +-
.../lists/MergeSortedArrayList.java | 142 +-
.../lists/MergeSortedSinglyLinkedList.java | 134 +-
.../lists/MiddleOfLinkedList.java | 92 +-
.../lists/QuickSortLinkedList.java | 366 +-
.../datastructures/lists/README.md | 66 +-
.../datastructures/lists/RandomNode.java | 178 +-
.../datastructures/lists/ReverseKGroup.java | 184 +-
.../lists/RotateSinglyLinkedLists.java | 130 +-
.../SearchSinglyLinkedListRecursion.java | 94 +-
.../lists/SinglyLinkedList.java | 952 +--
.../lists/SinglyLinkedListNode.java | 68 +-
.../datastructures/lists/SkipList.java | 660 +-
.../lists/SortedLinkedList.java | 318 +-
.../lists/TortoiseHareAlgo.java | 126 +-
.../datastructures/queues/CircularQueue.java | 276 +-
.../datastructures/queues/Deque.java | 424 +-
.../queues/GenericArrayListQueue.java | 120 +-
.../datastructures/queues/LinkedQueue.java | 402 +-
.../datastructures/queues/PriorityQueues.java | 358 +-
.../datastructures/queues/Queue.java | 306 +-
.../queues/QueueByTwoStacks.java | 176 +-
.../datastructures/queues/README.md | 178 +-
.../queues/SlidingWindowMaximum.java | 126 +-
.../datastructures/queues/TokenBucket.java | 122 +-
.../datastructures/stacks/NodeStack.java | 196 +-
.../datastructures/stacks/README.md | 90 +-
.../datastructures/stacks/ReverseStack.java | 154 +-
.../datastructures/stacks/Stack.java | 102 +-
.../datastructures/stacks/StackArray.java | 320 +-
.../datastructures/stacks/StackArrayList.java | 182 +-
.../stacks/StackOfLinkedList.java | 270 +-
.../datastructures/trees/AVLSimple.java | 292 +-
.../datastructures/trees/AVLTree.java | 538 +-
.../trees/BSTFromSortedArray.java | 70 +-
.../datastructures/trees/BSTIterative.java | 382 +-
.../datastructures/trees/BSTRecursive.java | 296 +-
.../trees/BSTRecursiveGeneric.java | 732 +--
.../datastructures/trees/BTree.java | 646 +-
.../datastructures/trees/BinaryTree.java | 660 +-
.../trees/BinaryTreeToString.java | 200 +-
.../trees/BoundaryTraversal.java | 336 +-
.../trees/CeilInBinarySearchTree.java | 140 +-
.../trees/CentroidDecomposition.java | 434 +-
.../trees/CheckBinaryTreeIsValidBST.java | 60 +-
.../trees/CheckIfBinaryTreeBalanced.java | 314 +-
.../trees/CheckTreeIsSymmetric.java | 118 +-
.../CreateBinaryTreeFromInorderPreorder.java | 142 +-
.../datastructures/trees/FenwickTree.java | 70 +-
.../datastructures/trees/GenericTree.java | 474 +-
.../trees/InorderTraversal.java | 128 +-
.../datastructures/trees/KDTree.java | 912 +--
.../datastructures/trees/LCA.java | 228 +-
.../datastructures/trees/LazySegmentTree.java | 348 +-
.../trees/LevelOrderTraversal.java | 108 +-
.../trees/PostOrderTraversal.java | 136 +-
.../trees/PreOrderTraversal.java | 134 +-
.../trees/PrintTopViewofTree.java | 234 +-
.../datastructures/trees/QuadTree.java | 352 +-
.../datastructures/trees/README.md | 58 +-
.../datastructures/trees/RedBlackBST.java | 678 +-
.../datastructures/trees/SameTreesCheck.java | 178 +-
.../datastructures/trees/SegmentTree.java | 162 +-
.../datastructures/trees/SplayTree.java | 648 +-
.../trees/ThreadedBinaryTree.java | 290 +-
.../datastructures/trees/Treap.java | 714 +--
.../datastructures/trees/TreeRandomNode.java | 174 +-
.../datastructures/trees/Trie.java | 404 +-
.../trees/VerticalOrderTraversal.java | 192 +-
.../datastructures/trees/ZigzagTraversal.java | 154 +-
.../datastructures/trees/nearestRightKey.java | 166 +-
.../devutils/entities/ProcessDetails.java | 134 +-
.../devutils/nodes/LargeTreeNode.java | 154 +-
.../thealgorithms/devutils/nodes/Node.java | 84 +-
.../devutils/nodes/SimpleNode.java | 118 +-
.../devutils/nodes/SimpleTreeNode.java | 180 +-
.../devutils/nodes/TreeNode.java | 156 +-
.../searches/MatrixSearchAlgorithm.java | 32 +-
.../devutils/searches/SearchAlgorithm.java | 32 +-
.../BinaryExponentiation.java | 84 +-
.../divideandconquer/ClosestPair.java | 684 +-
.../divideandconquer/CountingInversions.java | 202 +-
.../MedianOfTwoSortedArrays.java | 106 +-
.../divideandconquer/SkylineAlgorithm.java | 368 +-
.../StrassenMatrixMultiplication.java | 284 +-
.../divideandconquer/TilingProblem.java | 198 +-
.../dynamicprogramming/Abbreviation.java | 112 +-
.../dynamicprogramming/AllConstruct.java | 122 +-
.../AssignmentUsingBitmask.java | 182 +-
.../dynamicprogramming/BoardPath.java | 142 +-
.../dynamicprogramming/BoundaryFill.java | 110 +-
.../BruteForceKnapsack.java | 134 +-
.../dynamicprogramming/CatalanNumber.java | 114 +-
.../dynamicprogramming/ClimbingStairs.java | 110 +-
.../dynamicprogramming/CoinChange.java | 120 +-
.../CountFriendsPairing.java | 68 +-
.../DamerauLevenshteinDistance.java | 370 +-
.../dynamicprogramming/DiceThrow.java | 94 +-
.../dynamicprogramming/EditDistance.java | 200 +-
.../dynamicprogramming/EggDropping.java | 102 +-
.../dynamicprogramming/Fibonacci.java | 238 +-
.../dynamicprogramming/KadaneAlgorithm.java | 104 +-
.../dynamicprogramming/Knapsack.java | 156 +-
.../KnapsackMemoization.java | 106 +-
.../dynamicprogramming/KnapsackZeroOne.java | 106 +-
.../KnapsackZeroOneTabulation.java | 138 +-
.../LevenshteinDistance.java | 168 +-
.../LongestAlternatingSubsequence.java | 146 +-
.../LongestArithmeticSubsequence.java | 86 +-
.../LongestCommonSubsequence.java | 196 +-
.../LongestIncreasingSubsequence.java | 196 +-
.../LongestIncreasingSubsequenceNLogN.java | 150 +-
.../LongestPalindromicSubsequence.java | 116 +-
.../LongestPalindromicSubstring.java | 78 +-
.../LongestValidParentheses.java | 86 +-
.../MatrixChainMultiplication.java | 326 +-
...atrixChainRecursiveTopDownMemoisation.java | 136 +-
.../MaximumProductSubarray.java | 116 +-
.../MaximumSumOfNonAdjacentElements.java | 190 +-
.../dynamicprogramming/MinimumPathSum.java | 128 +-
.../MinimumSumPartition.java | 114 +-
.../dynamicprogramming/NeedlemanWunsch.java | 120 +-
.../dynamicprogramming/NewManShanksPrime.java | 96 +-
.../OptimalJobScheduling.java | 262 +-
.../PalindromicPartitioning.java | 166 +-
.../dynamicprogramming/PartitionProblem.java | 78 +-
.../dynamicprogramming/RegexMatching.java | 400 +-
.../dynamicprogramming/RodCutting.java | 94 +-
.../ShortestCommonSupersequenceLength.java | 138 +-
.../dynamicprogramming/SmithWaterman.java | 112 +-
.../dynamicprogramming/SubsetCount.java | 154 +-
.../dynamicprogramming/SubsetSum.java | 66 +-
.../SubsetSumSpaceOptimized.java | 78 +-
.../dynamicprogramming/SumOfSubset.java | 90 +-
.../dynamicprogramming/TreeMatching.java | 156 +-
.../dynamicprogramming/Tribonacci.java | 76 +-
.../dynamicprogramming/UniquePaths.java | 142 +-
.../dynamicprogramming/WildcardMatching.java | 112 +-
.../dynamicprogramming/WineProblem.java | 218 +-
.../geometry/BentleyOttmann.java | 846 +--
.../thealgorithms/geometry/BresenhamLine.java | 138 +-
.../thealgorithms/geometry/ConvexHull.java | 414 +-
.../com/thealgorithms/geometry/DDALine.java | 108 +-
.../thealgorithms/geometry/GrahamScan.java | 136 +-
.../com/thealgorithms/geometry/Haversine.java | 98 +-
.../geometry/MidpointCircle.java | 170 +-
.../geometry/MidpointEllipse.java | 262 +-
.../com/thealgorithms/geometry/Point.java | 90 +-
.../com/thealgorithms/geometry/WusLine.java | 470 +-
.../com/thealgorithms/graph/BronKerbosch.java | 228 +-
.../graph/ConstrainedShortestPath.java | 246 +-
.../java/com/thealgorithms/graph/Dinic.java | 238 +-
.../java/com/thealgorithms/graph/Edmonds.java | 402 +-
.../com/thealgorithms/graph/EdmondsKarp.java | 214 +-
.../com/thealgorithms/graph/GomoryHuTree.java | 288 +-
.../graph/HierholzerAlgorithm.java | 280 +-
.../graph/HierholzerEulerianPath.java | 606 +-
.../com/thealgorithms/graph/HopcroftKarp.java | 206 +-
.../graph/HungarianAlgorithm.java | 300 +-
.../graph/PredecessorConstrainedDfs.java | 326 +-
.../com/thealgorithms/graph/PushRelabel.java | 324 +-
.../com/thealgorithms/graph/StoerWagner.java | 156 +-
.../StronglyConnectedComponentOptimized.java | 172 +-
.../graph/TravelingSalesman.java | 310 +-
.../graph/YensKShortestPaths.java | 526 +-
.../com/thealgorithms/graph/ZeroOneBfs.java | 154 +-
.../greedyalgorithms/ActivitySelection.java | 136 +-
.../greedyalgorithms/BandwidthAllocation.java | 116 +-
.../greedyalgorithms/BinaryAddition.java | 150 +-
.../greedyalgorithms/CoinChange.java | 70 +-
.../greedyalgorithms/DigitSeparation.java | 80 +-
.../greedyalgorithms/EgyptianFraction.java | 70 +-
.../greedyalgorithms/FractionalKnapsack.java | 108 +-
.../greedyalgorithms/GaleShapley.java | 130 +-
.../greedyalgorithms/JobSequencing.java | 132 +-
.../greedyalgorithms/KCenters.java | 124 +-
.../greedyalgorithms/MergeIntervals.java | 128 +-
.../greedyalgorithms/MinimizingLateness.java | 90 +-
.../greedyalgorithms/MinimumWaitingTime.java | 74 +-
.../greedyalgorithms/OptimalFileMerging.java | 104 +-
.../StockProfitCalculator.java | 68 +-
.../com/thealgorithms/io/BufferedReader.java | 394 +-
.../lineclipping/CohenSutherland.java | 266 +-
.../lineclipping/LiangBarsky.java | 186 +-
.../lineclipping/utils/Line.java | 86 +-
.../lineclipping/utils/Point.java | 86 +-
.../com/thealgorithms/maths/ADTFraction.java | 160 +-
.../com/thealgorithms/maths/AbsoluteMax.java | 52 +-
.../com/thealgorithms/maths/AbsoluteMin.java | 52 +-
.../thealgorithms/maths/AbsoluteValue.java | 32 +-
.../thealgorithms/maths/AbundantNumber.java | 116 +-
.../com/thealgorithms/maths/AliquotSum.java | 126 +-
.../thealgorithms/maths/AmicableNumber.java | 142 +-
.../java/com/thealgorithms/maths/Area.java | 428 +-
.../com/thealgorithms/maths/Armstrong.java | 78 +-
.../thealgorithms/maths/AutoCorrelation.java | 114 +-
.../maths/AutomorphicNumber.java | 134 +-
.../java/com/thealgorithms/maths/Average.java | 100 +-
.../com/thealgorithms/maths/BellNumbers.java | 118 +-
.../com/thealgorithms/maths/BinaryPow.java | 52 +-
.../maths/BinomialCoefficient.java | 80 +-
.../thealgorithms/maths/CatalanNumbers.java | 78 +-
.../java/com/thealgorithms/maths/Ceil.java | 68 +-
.../maths/ChebyshevIteration.java | 362 +-
.../maths/ChineseRemainderTheorem.java | 168 +-
.../maths/CircularConvolutionFFT.java | 124 +-
.../maths/CollatzConjecture.java | 84 +-
.../com/thealgorithms/maths/Combinations.java | 122 +-
.../maths/ComplexNumberMultiply.java | 64 +-
.../com/thealgorithms/maths/Convolution.java | 90 +-
.../thealgorithms/maths/ConvolutionFFT.java | 138 +-
.../thealgorithms/maths/CrossCorrelation.java | 178 +-
.../maths/DeterminantOfMatrix.java | 94 +-
.../com/thealgorithms/maths/DigitalRoot.java | 130 +-
.../maths/DistanceBetweenTwoPoints.java | 66 +-
.../thealgorithms/maths/DistanceFormula.java | 94 +-
.../thealgorithms/maths/DudeneyNumber.java | 56 +-
.../com/thealgorithms/maths/EulerMethod.java | 202 +-
.../thealgorithms/maths/EulerPseudoprime.java | 216 +-
.../thealgorithms/maths/EulersFunction.java | 94 +-
.../com/thealgorithms/maths/EvilNumber.java | 78 +-
.../maths/ExtendedEuclideanAlgorithm.java | 96 +-
.../java/com/thealgorithms/maths/FFT.java | 592 +-
.../com/thealgorithms/maths/FFTBluestein.java | 142 +-
.../com/thealgorithms/maths/Factorial.java | 46 +-
.../maths/FastExponentiation.java | 134 +-
.../thealgorithms/maths/FastInverseSqrt.java | 102 +-
.../maths/FibonacciJavaStreams.java | 68 +-
.../thealgorithms/maths/FibonacciLoop.java | 82 +-
.../maths/FibonacciNumberCheck.java | 74 +-
.../maths/FibonacciNumberGoldenRation.java | 100 +-
.../thealgorithms/maths/FindKthNumber.java | 164 +-
.../java/com/thealgorithms/maths/FindMax.java | 54 +-
.../thealgorithms/maths/FindMaxRecursion.java | 80 +-
.../java/com/thealgorithms/maths/FindMin.java | 52 +-
.../thealgorithms/maths/FindMinRecursion.java | 84 +-
.../java/com/thealgorithms/maths/Floor.java | 48 +-
.../com/thealgorithms/maths/FrizzyNumber.java | 62 +-
.../java/com/thealgorithms/maths/GCD.java | 130 +-
.../com/thealgorithms/maths/GCDRecursion.java | 82 +-
.../com/thealgorithms/maths/Gaussian.java | 140 +-
.../com/thealgorithms/maths/GenericRoot.java | 96 +-
.../maths/GermainPrimeAndSafePrime.java | 126 +-
.../maths/GoldbachConjecture.java | 60 +-
.../com/thealgorithms/maths/HappyNumber.java | 114 +-
.../thealgorithms/maths/HarshadNumber.java | 160 +-
.../thealgorithms/maths/HeronsFormula.java | 156 +-
.../thealgorithms/maths/JosephusProblem.java | 82 +-
.../thealgorithms/maths/JugglerSequence.java | 108 +-
.../thealgorithms/maths/KaprekarNumbers.java | 234 +-
.../maths/KaratsubaMultiplication.java | 186 +-
.../com/thealgorithms/maths/KeithNumber.java | 202 +-
.../maths/KrishnamurthyNumber.java | 142 +-
.../maths/LeastCommonMultiple.java | 84 +-
.../thealgorithms/maths/LeonardoNumber.java | 158 +-
.../LinearDiophantineEquationsSolver.java | 612 +-
.../com/thealgorithms/maths/LongDivision.java | 166 +-
.../com/thealgorithms/maths/LucasSeries.java | 138 +-
.../com/thealgorithms/maths/LuckyNumber.java | 156 +-
.../com/thealgorithms/maths/MagicSquare.java | 104 +-
.../com/thealgorithms/maths/MathBuilder.java | 1006 +--
.../com/thealgorithms/maths/MaxValue.java | 36 +-
.../java/com/thealgorithms/maths/Means.java | 242 +-
.../java/com/thealgorithms/maths/Median.java | 98 +-
.../com/thealgorithms/maths/MinValue.java | 36 +-
.../java/com/thealgorithms/maths/Mode.java | 102 +-
.../java/com/thealgorithms/maths/Neville.java | 122 +-
.../maths/NonRepeatingElement.java | 122 +-
.../thealgorithms/maths/NthUglyNumber.java | 160 +-
.../thealgorithms/maths/NumberOfDigits.java | 106 +-
.../maths/NumberPersistence.java | 158 +-
.../thealgorithms/maths/PalindromeNumber.java | 52 +-
.../com/thealgorithms/maths/ParseInteger.java | 92 +-
.../thealgorithms/maths/PascalTriangle.java | 130 +-
.../com/thealgorithms/maths/PerfectCube.java | 68 +-
.../thealgorithms/maths/PerfectNumber.java | 142 +-
.../thealgorithms/maths/PerfectSquare.java | 78 +-
.../com/thealgorithms/maths/Perimeter.java | 120 +-
.../thealgorithms/maths/PiApproximation.java | 148 +-
.../com/thealgorithms/maths/PiNilakantha.java | 88 +-
.../com/thealgorithms/maths/PollardRho.java | 160 +-
.../java/com/thealgorithms/maths/Pow.java | 72 +-
.../com/thealgorithms/maths/PowerOfFour.java | 72 +-
.../thealgorithms/maths/PowerOfTwoOrNot.java | 42 +-
.../maths/PowerUsingRecursion.java | 44 +-
.../maths/Prime/LiouvilleLambdaFunction.java | 72 +-
.../Prime/MillerRabinPrimalityCheck.java | 242 +-
.../maths/Prime/MobiusFunction.java | 114 +-
.../thealgorithms/maths/Prime/PrimeCheck.java | 170 +-
.../maths/Prime/PrimeFactorization.java | 80 +-
.../maths/Prime/SquareFreeInteger.java | 90 +-
.../com/thealgorithms/maths/PronicNumber.java | 102 +-
.../maths/PythagoreanTriple.java | 86 +-
.../maths/QuadraticEquationSolver.java | 120 +-
.../thealgorithms/maths/ReverseNumber.java | 58 +-
.../thealgorithms/maths/RomanNumeralUtil.java | 146 +-
.../com/thealgorithms/maths/SecondMinMax.java | 120 +-
.../com/thealgorithms/maths/SieveOfAtkin.java | 286 +-
.../maths/SieveOfEratosthenes.java | 164 +-
.../maths/SimpsonIntegration.java | 176 +-
.../com/thealgorithms/maths/SmithNumber.java | 104 +-
.../maths/SolovayStrassenPrimalityTest.java | 266 +-
.../maths/SquareRootWithBabylonianMethod.java | 46 +-
.../SquareRootWithNewtonRaphsonMethod.java | 66 +-
.../maths/StandardDeviation.java | 40 +-
.../thealgorithms/maths/StandardScore.java | 20 +-
.../maths/StrobogrammaticNumber.java | 86 +-
.../maths/SumOfArithmeticSeries.java | 62 +-
.../com/thealgorithms/maths/SumOfDigits.java | 90 +-
.../thealgorithms/maths/SumOfOddNumbers.java | 50 +-
.../com/thealgorithms/maths/SumOfSquares.java | 106 +-
.../maths/SumWithoutArithmeticOperators.java | 44 +-
.../maths/TrinomialTriangle.java | 88 +-
.../com/thealgorithms/maths/TwinPrime.java | 70 +-
.../thealgorithms/maths/UniformNumbers.java | 100 +-
.../thealgorithms/maths/VampireNumber.java | 96 +-
.../maths/VectorCrossProduct.java | 250 +-
.../java/com/thealgorithms/maths/Volume.java | 210 +-
.../maths/ZellersCongruence.java | 214 +-
.../thealgorithms/matrix/InverseOfMatrix.java | 206 +-
.../thealgorithms/matrix/LUDecomposition.java | 176 +-
.../matrix/MatrixMultiplication.java | 138 +-
.../com/thealgorithms/matrix/MatrixRank.java | 250 +-
.../thealgorithms/matrix/MatrixTranspose.java | 92 +-
.../thealgorithms/matrix/MedianOfMatrix.java | 64 +-
.../thealgorithms/matrix/MirrorOfMatrix.java | 72 +-
.../matrix/PrintAMatrixInSpiralOrder.java | 154 +-
.../matrix/RotateMatrixBy90Degrees.java | 146 +-
.../com/thealgorithms/matrix/SolveSystem.java | 142 +-
.../matrix/StochasticMatrix.java | 148 +-
.../matrixexponentiation/Fibonacci.java | 84 +-
.../matrix/utils/MatrixUtil.java | 266 +-
.../misc/ColorContrastRatio.java | 128 +-
.../com/thealgorithms/misc/MapReduce.java | 80 +-
.../misc/MedianOfRunningArray.java | 154 +-
.../misc/MedianOfRunningArrayByte.java | 16 +-
.../misc/MedianOfRunningArrayDouble.java | 16 +-
.../misc/MedianOfRunningArrayFloat.java | 16 +-
.../misc/MedianOfRunningArrayInteger.java | 16 +-
.../misc/MedianOfRunningArrayLong.java | 16 +-
.../thealgorithms/misc/PalindromePrime.java | 114 +-
.../misc/PalindromeSinglyLinkedList.java | 152 +-
.../misc/RangeInSortedArray.java | 268 +-
.../com/thealgorithms/misc/ShuffleArray.java | 112 +-
.../java/com/thealgorithms/misc/Sparsity.java | 92 +-
.../thealgorithms/misc/ThreeSumProblem.java | 176 +-
.../com/thealgorithms/misc/TwoSumProblem.java | 66 +-
.../others/ArrayLeftRotation.java | 88 +-
.../others/ArrayRightRotation.java | 102 +-
.../java/com/thealgorithms/others/BFPRT.java | 356 +-
.../others/BankersAlgorithm.java | 358 +-
.../com/thealgorithms/others/BoyerMoore.java | 162 +-
.../others/BrianKernighanAlgorithm.java | 100 +-
.../java/com/thealgorithms/others/CRC16.java | 64 +-
.../java/com/thealgorithms/others/CRC32.java | 66 +-
.../thealgorithms/others/CRCAlgorithm.java | 396 +-
.../java/com/thealgorithms/others/Conway.java | 74 +-
.../java/com/thealgorithms/others/Damm.java | 232 +-
.../com/thealgorithms/others/Dijkstra.java | 496 +-
.../thealgorithms/others/FloydTriangle.java | 60 +-
.../thealgorithms/others/GaussLegendre.java | 96 +-
.../com/thealgorithms/others/Huffman.java | 422 +-
...g_auto_completing_features_using_trie.java | 340 +-
.../others/InsertDeleteInArray.java | 346 +-
.../thealgorithms/others/KochSnowflake.java | 492 +-
.../com/thealgorithms/others/LineSweep.java | 124 +-
.../others/LinearCongruentialGenerator.java | 136 +-
.../others/LowestBasePalindrome.java | 360 +-
.../java/com/thealgorithms/others/Luhn.java | 320 +-
.../com/thealgorithms/others/Mandelbrot.java | 376 +-
...imumSumOfDistinctSubarraysWithLengthK.java | 178 +-
.../others/MemoryManagementAlgorithms.java | 564 +-
.../others/MiniMaxAlgorithm.java | 410 +-
.../thealgorithms/others/MosAlgorithm.java | 520 +-
.../com/thealgorithms/others/PageRank.java | 614 +-
.../com/thealgorithms/others/PasswordGen.java | 110 +-
.../com/thealgorithms/others/PerlinNoise.java | 466 +-
.../others/QueueUsingTwoStacks.java | 210 +-
.../thealgorithms/others/SkylineProblem.java | 306 +-
.../com/thealgorithms/others/TwoPointers.java | 90 +-
.../com/thealgorithms/others/Verhoeff.java | 342 +-
.../thealgorithms/physics/CoulombsLaw.java | 160 +-
.../physics/DampedOscillator.java | 218 +-
.../physics/ElasticCollision2D.java | 146 +-
.../thealgorithms/physics/Gravitation.java | 132 +-
.../GroundToGroundProjectileMotion.java | 180 +-
.../com/thealgorithms/physics/Kinematics.java | 138 +-
.../physics/ProjectileMotion.java | 192 +-
.../physics/SimplePendulumRK4.java | 252 +-
.../com/thealgorithms/physics/SnellLaw.java | 66 +-
.../com/thealgorithms/physics/ThinLens.java | 148 +-
.../prefixsum/DifferenceArray.java | 174 +-
.../thealgorithms/prefixsum/PrefixSum.java | 108 +-
.../thealgorithms/prefixsum/PrefixSum2D.java | 128 +-
.../prefixsum/RangeSumQuery.java | 146 +-
.../prefixsum/SubarraySumEqualsK.java | 144 +-
.../puzzlesandgames/TowerOfHanoi.java | 152 +-
.../puzzlesandgames/WordBoggle.java | 250 +-
.../randomized/KargerMinCut.java | 390 +-
.../randomized/MonteCarloIntegration.java | 180 +-
.../randomized/RandomizedClosestPair.java | 226 +-
...mizedMatrixMultiplicationVerification.java | 128 +-
.../randomized/RandomizedQuickSort.java | 136 +-
.../randomized/ReservoirSampling.java | 110 +-
.../thealgorithms/recursion/DiceThrower.java | 226 +-
.../recursion/FactorialRecursion.java | 36 +-
.../recursion/FibonacciSeries.java | 66 +-
.../recursion/GenerateSubsets.java | 104 +-
.../recursion/SylvesterSequence.java | 100 +-
.../scheduling/AgingScheduling.java | 124 +-
.../scheduling/EDFScheduling.java | 198 +-
.../scheduling/FCFSScheduling.java | 94 +-
.../scheduling/FairShareScheduling.java | 130 +-
.../scheduling/GangScheduling.java | 122 +-
.../HighestResponseRatioNextScheduling.java | 316 +-
.../scheduling/JobSchedulingWithDeadline.java | 176 +-
.../scheduling/LotteryScheduling.java | 282 +-
.../scheduling/MLFQScheduler.java | 296 +-
.../scheduling/MultiAgentScheduling.java | 144 +-
.../NonPreemptivePriorityScheduling.java | 266 +-
.../PreemptivePriorityScheduling.java | 120 +-
.../ProportionalFairScheduling.java | 108 +-
.../scheduling/RRScheduling.java | 202 +-
.../scheduling/RandomScheduling.java | 90 +-
.../scheduling/SJFScheduling.java | 176 +-
.../scheduling/SRTFScheduling.java | 140 +-
.../scheduling/SelfAdjustingScheduling.java | 126 +-
.../scheduling/SlackTimeScheduling.java | 128 +-
.../CircularLookScheduling.java | 160 +-
.../CircularScanScheduling.java | 166 +-
.../diskscheduling/LookScheduling.java | 190 +-
.../diskscheduling/SSFScheduling.java | 114 +-
.../diskscheduling/ScanScheduling.java | 164 +-
.../searches/BM25InvertedIndex.java | 440 +-
.../thealgorithms/searches/BinarySearch.java | 254 +-
.../searches/BinarySearch2dArray.java | 254 +-
.../thealgorithms/searches/BoyerMoore.java | 116 +-
.../searches/BreadthFirstSearch.java | 142 +-
.../searches/DepthFirstSearch.java | 64 +-
.../searches/ExponentialSearch.java | 102 +-
.../searches/FibonacciSearch.java | 174 +-
.../searches/HowManyTimesRotated.java | 126 +-
.../searches/InterpolationSearch.java | 114 +-
.../searches/IterativeBinarySearch.java | 110 +-
.../searches/IterativeTernarySearch.java | 128 +-
.../thealgorithms/searches/JumpSearch.java | 112 +-
.../com/thealgorithms/searches/KMPSearch.java | 148 +-
.../thealgorithms/searches/LinearSearch.java | 84 +-
.../searches/LinearSearchThread.java | 148 +-
.../thealgorithms/searches/LowerBound.java | 128 +-
.../searches/MonteCarloTreeSearch.java | 346 +-
.../searches/OrderAgnosticBinarySearch.java | 98 +-
.../thealgorithms/searches/QuickSelect.java | 250 +-
.../searches/RabinKarpAlgorithm.java | 136 +-
.../thealgorithms/searches/RandomSearch.java | 90 +-
.../searches/RecursiveBinarySearch.java | 152 +-
.../searches/RotatedBinarySearch.java | 120 +-
...owColumnWiseSorted2dArrayBinarySearch.java | 94 +-
.../searches/SaddlebackSearch.java | 106 +-
.../searches/SentinelLinearSearch.java | 198 +-
.../searches/SquareRootBinarySearch.java | 94 +-
.../thealgorithms/searches/TernarySearch.java | 120 +-
.../com/thealgorithms/searches/UnionFind.java | 208 +-
.../thealgorithms/searches/UpperBound.java | 124 +-
.../slidingwindow/CountNiceSubarrays.java | 198 +-
.../LongestSubarrayWithSumLessOrEqualToK.java | 96 +-
...stSubstringWithoutRepeatingCharacters.java | 92 +-
.../slidingwindow/MaxSumKSizeSubarray.java | 100 +-
.../slidingwindow/MaximumSlidingWindow.java | 112 +-
.../slidingwindow/MinSumKSizeSubarray.java | 102 +-
.../slidingwindow/MinimumWindowSubstring.java | 138 +-
.../slidingwindow/ShortestCoprimeSegment.java | 270 +-
.../sorts/AdaptiveMergeSort.java | 80 +-
.../com/thealgorithms/sorts/BeadSort.java | 126 +-
.../sorts/BinaryInsertionSort.java | 80 +-
.../com/thealgorithms/sorts/BitonicSort.java | 224 +-
.../com/thealgorithms/sorts/BogoSort.java | 108 +-
.../com/thealgorithms/sorts/BubbleSort.java | 80 +-
.../sorts/BubbleSortRecursive.java | 70 +-
.../com/thealgorithms/sorts/BucketSort.java | 260 +-
.../com/thealgorithms/sorts/CircleSort.java | 116 +-
.../sorts/CocktailShakerSort.java | 162 +-
.../com/thealgorithms/sorts/CombSort.java | 144 +-
.../com/thealgorithms/sorts/CountingSort.java | 120 +-
.../com/thealgorithms/sorts/CycleSort.java | 176 +-
.../com/thealgorithms/sorts/DarkSort.java | 118 +-
.../sorts/DualPivotQuickSort.java | 192 +-
.../sorts/DutchNationalFlagSort.java | 84 +-
.../com/thealgorithms/sorts/ExchangeSort.java | 82 +-
.../com/thealgorithms/sorts/FlashSort.java | 412 +-
.../com/thealgorithms/sorts/GnomeSort.java | 56 +-
.../com/thealgorithms/sorts/HeapSort.java | 116 +-
.../thealgorithms/sorts/InsertionSort.java | 218 +-
.../sorts/IntrospectiveSort.java | 278 +-
.../com/thealgorithms/sorts/LinkListSort.java | 652 +-
.../com/thealgorithms/sorts/MergeSort.java | 150 +-
.../sorts/MergeSortNoExtraSpace.java | 176 +-
.../sorts/MergeSortRecursive.java | 120 +-
.../com/thealgorithms/sorts/OddEvenSort.java | 102 +-
.../com/thealgorithms/sorts/PancakeSort.java | 88 +-
.../com/thealgorithms/sorts/PatienceSort.java | 224 +-
.../thealgorithms/sorts/PigeonholeSort.java | 178 +-
.../sorts/PriorityQueueSort.java | 98 +-
.../com/thealgorithms/sorts/QuickSort.java | 214 +-
.../com/thealgorithms/sorts/RadixSort.java | 196 +-
.../thealgorithms/sorts/SelectionSort.java | 70 +-
.../sorts/SelectionSortRecursive.java | 122 +-
.../com/thealgorithms/sorts/ShellSort.java | 138 +-
.../com/thealgorithms/sorts/SlowSort.java | 54 +-
.../com/thealgorithms/sorts/SmoothSort.java | 336 +-
.../thealgorithms/sorts/SortAlgorithm.java | 62 +-
.../com/thealgorithms/sorts/SortUtils.java | 242 +-
.../sorts/SortUtilsRandomGenerator.java | 96 +-
.../com/thealgorithms/sorts/SpreadSort.java | 548 +-
.../com/thealgorithms/sorts/StalinSort.java | 42 +-
.../com/thealgorithms/sorts/StoogeSort.java | 68 +-
.../com/thealgorithms/sorts/StrandSort.java | 158 +-
.../com/thealgorithms/sorts/SwapSort.java | 78 +-
.../java/com/thealgorithms/sorts/TimSort.java | 102 +-
.../thealgorithms/sorts/TopologicalSort.java | 284 +-
.../thealgorithms/sorts/TournamentSort.java | 168 +-
.../com/thealgorithms/sorts/TreeSort.java | 236 +-
.../com/thealgorithms/sorts/WaveSort.java | 92 +-
.../com/thealgorithms/sorts/WiggleSort.java | 170 +-
.../stacks/BalancedBrackets.java | 160 +-
.../thealgorithms/stacks/CelebrityFinder.java | 104 +-
.../stacks/DecimalToAnyUsingStack.java | 108 +-
.../stacks/DuplicateBrackets.java | 88 +-
.../stacks/GreatestElementConstantTime.java | 148 +-
.../thealgorithms/stacks/InfixToPostfix.java | 204 +-
.../thealgorithms/stacks/InfixToPrefix.java | 232 +-
.../stacks/LargestRectangle.java | 104 +-
.../stacks/MaximumMinimumWindow.java | 214 +-
.../stacks/MinStackUsingSingleStack.java | 130 +-
.../stacks/MinStackUsingTwoStacks.java | 114 +-
.../stacks/NextGreaterElement.java | 92 +-
.../stacks/NextSmallerElement.java | 118 +-
.../stacks/PalindromeWithStack.java | 114 +-
.../stacks/PostfixEvaluator.java | 148 +-
.../thealgorithms/stacks/PostfixToInfix.java | 204 +-
.../thealgorithms/stacks/PrefixEvaluator.java | 152 +-
.../thealgorithms/stacks/PrefixToInfix.java | 138 +-
.../stacks/SmallestElementConstantTime.java | 148 +-
.../com/thealgorithms/stacks/SortStack.java | 120 +-
.../stacks/StackPostfixNotation.java | 144 +-
.../stacks/StackUsingTwoQueues.java | 182 +-
.../stacks/TrappingRainwater.java | 96 +-
.../stacks/ValidParentheses.java | 148 +-
.../thealgorithms/strings/Alphabetical.java | 64 +-
.../strings/AlternativeStringArrange.java | 96 +-
.../com/thealgorithms/strings/Anagrams.java | 302 +-
.../thealgorithms/strings/CharactersSame.java | 52 +-
.../thealgorithms/strings/CheckVowels.java | 68 +-
.../com/thealgorithms/strings/CountChar.java | 40 +-
.../com/thealgorithms/strings/CountWords.java | 110 +-
.../strings/HammingDistance.java | 90 +-
.../thealgorithms/strings/HorspoolSearch.java | 370 +-
.../com/thealgorithms/strings/Isogram.java | 184 +-
.../com/thealgorithms/strings/Isomorphic.java | 116 +-
.../java/com/thealgorithms/strings/KMP.java | 134 +-
.../strings/LengthOfLastWord.java | 102 +-
.../LetterCombinationsOfPhoneNumber.java | 130 +-
.../strings/LongestCommonPrefix.java | 84 +-
.../LongestNonRepetitiveSubstring.java | 16 +-
.../java/com/thealgorithms/strings/Lower.java | 64 +-
.../com/thealgorithms/strings/Manacher.java | 138 +-
.../com/thealgorithms/strings/MyAtoi.java | 134 +-
.../com/thealgorithms/strings/Palindrome.java | 116 +-
.../com/thealgorithms/strings/Pangram.java | 160 +-
.../thealgorithms/strings/PermuteString.java | 178 +-
.../com/thealgorithms/strings/RabinKarp.java | 148 +-
.../strings/RemoveDuplicateFromString.java | 60 +-
.../thealgorithms/strings/RemoveStars.java | 62 +-
.../strings/ReturnSubsequence.java | 74 +-
.../thealgorithms/strings/ReverseString.java | 204 +-
.../strings/ReverseWordsInString.java | 42 +-
.../com/thealgorithms/strings/Rotation.java | 124 +-
.../strings/StringCompression.java | 120 +-
.../strings/StringMatchFiniteAutomata.java | 250 +-
.../thealgorithms/strings/SuffixArray.java | 120 +-
.../java/com/thealgorithms/strings/Upper.java | 86 +-
.../com/thealgorithms/strings/WordLadder.java | 128 +-
.../com/thealgorithms/strings/ZAlgorithm.java | 96 +-
.../strings/zigZagPattern/README.md | 70 +-
.../strings/zigZagPattern/ZigZagPattern.java | 76 +-
.../tree/HeavyLightDecomposition.java | 314 +-
.../audiofilters/EMAFilterTest.java | 82 +-
.../audiofilters/IIRFilterTest.java | 166 +-
.../AllPathsFromSourceToTargetTest.java | 114 +-
.../backtracking/ArrayCombinationTest.java | 80 +-
.../backtracking/CombinationSumTest.java | 58 +-
.../backtracking/CombinationTest.java | 102 +-
.../backtracking/CrosswordSolverTest.java | 132 +-
.../backtracking/FloodFillTest.java | 212 +-
.../backtracking/KnightsTourTest.java | 118 +-
.../backtracking/MColoringTest.java | 116 +-
.../backtracking/MazeRecursionTest.java | 134 +-
.../backtracking/NQueensTest.java | 98 +-
.../ParenthesesGeneratorTest.java | 66 +-
.../backtracking/PermutationTest.java | 60 +-
.../backtracking/PowerSumTest.java | 56 +-
.../backtracking/SubsequenceFinderTest.java | 56 +-
.../backtracking/SudokuSolverTest.java | 106 +-
.../backtracking/UniquePermutationTest.java | 62 +-
.../backtracking/WordPatternMatcherTest.java | 80 +-
.../backtracking/WordSearchTest.java | 64 +-
.../bitmanipulation/BcdConversionTest.java | 170 +-
.../BinaryPalindromeCheckTest.java | 36 +-
.../bitmanipulation/BitRotateTest.java | 410 +-
.../bitmanipulation/BitSwapTest.java | 124 +-
.../bitmanipulation/BitwiseGCDTest.java | 220 +-
.../BooleanAlgebraGatesTest.java | 202 +-
.../ClearLeftmostSetBitTest.java | 32 +-
.../bitmanipulation/CountBitsFlipTest.java | 188 +-
.../CountLeadingZerosTest.java | 32 +-
.../bitmanipulation/CountSetBitsTest.java | 112 +-
.../bitmanipulation/FindNthBitTest.java | 78 +-
.../FirstDifferentBitTest.java | 30 +-
.../bitmanipulation/GenerateSubsetsTest.java | 106 +-
.../GrayCodeConversionTest.java | 58 +-
.../bitmanipulation/HammingDistanceTest.java | 34 +-
.../HigherLowerPowerOfTwoTest.java | 52 +-
.../bitmanipulation/HighestSetBitTest.java | 78 +-
.../IndexOfRightMostSetBitTest.java | 40 +-
.../bitmanipulation/IsEvenTest.java | 34 +-
.../bitmanipulation/IsPowerTwoTest.java | 102 +-
.../bitmanipulation/LowestSetBitTest.java | 172 +-
.../bitmanipulation/ModuloPowerOfTwoTest.java | 76 +-
.../NextHigherSameBitCountTest.java | 44 +-
.../NonRepeatingNumberFinderTest.java | 72 +-
.../NumberAppearingOddTimesTest.java | 98 +-
.../NumbersDifferentSignsTest.java | 92 +-
.../bitmanipulation/OneBitDifferenceTest.java | 30 +-
.../bitmanipulation/OnesComplementTest.java | 116 +-
.../bitmanipulation/ParityCheckTest.java | 70 +-
.../bitmanipulation/ReverseBitsTest.java | 82 +-
.../SingleBitOperationsTest.java | 122 +-
.../bitmanipulation/SingleElementTest.java | 66 +-
.../bitmanipulation/SwapAdjacentBitsTest.java | 58 +-
.../bitmanipulation/TwosComplementTest.java | 128 +-
.../bitmanipulation/Xs3ConversionTest.java | 130 +-
.../ciphers/ADFGVXCipherTest.java | 92 +-
.../ciphers/AESEncryptionTest.java | 124 +-
.../ciphers/AffineCipherTest.java | 78 +-
.../thealgorithms/ciphers/AutokeyTest.java | 72 +-
.../ciphers/BaconianCipherTest.java | 68 +-
.../thealgorithms/ciphers/BlowfishTest.java | 76 +-
.../com/thealgorithms/ciphers/CaesarTest.java | 92 +-
.../ColumnarTranspositionCipherTest.java | 94 +-
.../com/thealgorithms/ciphers/DESTest.java | 110 +-
.../ciphers/DiffieHellmanTest.java | 76 +-
.../com/thealgorithms/ciphers/ECCTest.java | 212 +-
.../ciphers/ElGamalCipherTest.java | 290 +-
.../thealgorithms/ciphers/HillCipherTest.java | 72 +-
.../ciphers/MonoAlphabeticTest.java | 58 +-
.../ciphers/OneTimePadCipherTest.java | 98 +-
.../thealgorithms/ciphers/PlayfairTest.java | 74 +-
.../thealgorithms/ciphers/PolybiusTest.java | 90 +-
.../com/thealgorithms/ciphers/RSATest.java | 128 +-
.../ciphers/SimpleSubCipherTest.java | 72 +-
.../thealgorithms/ciphers/VigenereTest.java | 160 +-
.../thealgorithms/ciphers/XORCipherTest.java | 170 +-
.../ciphers/a5/A5CipherTest.java | 98 +-
.../ciphers/a5/A5KeyStreamGeneratorTest.java | 118 +-
.../thealgorithms/ciphers/a5/LFSRTest.java | 192 +-
.../compression/ArithmeticCodingTest.java | 308 +-
.../BurrowsWheelerTransformTest.java | 248 +-
.../thealgorithms/compression/LZ77Test.java | 446 +-
.../thealgorithms/compression/LZ78Test.java | 586 +-
.../thealgorithms/compression/LZWTest.java | 208 +-
.../compression/MoveToFrontTest.java | 184 +-
.../compression/RunLengthEncodingTest.java | 180 +-
.../compression/ShannonFanoTest.java | 142 +-
.../conversions/AffineConverterTest.java | 174 +-
.../conversions/AnyBaseToDecimalTest.java | 44 +-
.../conversions/AnytoAnyTest.java | 96 +-
.../thealgorithms/conversions/Base64Test.java | 366 +-
.../conversions/BinaryToDecimalTest.java | 112 +-
.../conversions/BinaryToHexadecimalTest.java | 44 +-
.../conversions/BinaryToOctalTest.java | 48 +-
.../conversions/CoordinateConverterTest.java | 68 +-
.../conversions/DecimalToAnyBaseTest.java | 46 +-
.../conversions/DecimalToBinaryTest.java | 42 +-
.../conversions/DecimalToHexadecimalTest.java | 28 +-
.../conversions/DecimalToOctalTest.java | 42 +-
.../conversions/EndianConverterTest.java | 70 +-
.../conversions/HexToOctTest.java | 66 +-
.../conversions/HexaDecimalToBinaryTest.java | 90 +-
.../conversions/HexaDecimalToDecimalTest.java | 74 +-
.../conversions/IPConverterTest.java | 60 +-
.../conversions/IPv6ConverterTest.java | 128 +-
.../conversions/IntegerToEnglishTest.java | 92 +-
.../conversions/IntegerToRomanTest.java | 78 +-
.../conversions/MorseCodeConverterTest.java | 38 +-
.../conversions/NumberToWordsTest.java | 120 +-
.../conversions/OctalToBinaryTest.java | 70 +-
.../conversions/OctalToDecimalTest.java | 42 +-
.../conversions/OctalToHexadecimalTest.java | 46 +-
.../PhoneticAlphabetConverterTest.java | 54 +-
.../conversions/RomanToIntegerTest.java | 76 +-
.../conversions/TemperatureConverterTest.java | 108 +-
.../conversions/TimeConverterTest.java | 138 +-
.../TurkishToLatinConversionTest.java | 62 +-
.../conversions/UnitConversionsTest.java | 96 +-
.../conversions/UnitsConverterTest.java | 88 +-
.../conversions/WordsToNumberTest.java | 228 +-
.../datastructures/bag/BagTest.java | 548 +-
.../bloomfilter/BloomFilterTest.java | 518 +-
.../buffers/CircularBufferTest.java | 464 +-
.../datastructures/caches/FIFOCacheTest.java | 660 +-
.../datastructures/caches/LFUCacheTest.java | 276 +-
.../datastructures/caches/LIFOCacheTest.java | 682 +-
.../datastructures/caches/LRUCacheTest.java | 298 +-
.../datastructures/caches/MRUCacheTest.java | 250 +-
.../datastructures/caches/RRCacheTest.java | 444 +-
.../datastructures/crdt/GCounterTest.java | 112 +-
.../datastructures/crdt/GSetTest.java | 132 +-
.../crdt/LWWElementSetTest.java | 196 +-
.../datastructures/crdt/ORSetTest.java | 176 +-
.../datastructures/crdt/PNCounterTest.java | 112 +-
.../datastructures/crdt/TwoPSetTest.java | 138 +-
.../DisjointSetUnionTest.java | 460 +-
.../dynamicarray/DynamicArrayTest.java | 554 +-
.../datastructures/graphs/AStarTest.java | 94 +-
.../graphs/BellmanFordTest.java | 316 +-
.../graphs/BipartiteGraphDFSTest.java | 146 +-
.../graphs/BoruvkaAlgorithmTest.java | 386 +-
.../graphs/ConnectedComponentTest.java | 408 +-
.../graphs/DialsAlgorithmTest.java | 176 +-
.../graphs/DijkstraAlgorithmTest.java | 362 +-
.../DijkstraOptimizedAlgorithmTest.java | 128 +-
.../graphs/EdmondsBlossomAlgorithmTest.java | 240 +-
.../graphs/FloydWarshallTest.java | 66 +-
.../graphs/FordFulkersonTest.java | 432 +-
.../graphs/HamiltonianCycleTest.java | 196 +-
.../graphs/JohnsonsAlgorithmTest.java | 284 +-
.../graphs/KahnsAlgorithmTest.java | 154 +-
.../datastructures/graphs/KosarajuTest.java | 222 +-
.../datastructures/graphs/KruskalTest.java | 226 +-
.../graphs/MatrixGraphsTest.java | 702 +--
.../datastructures/graphs/PrimMSTTest.java | 108 +-
.../graphs/TarjansAlgorithmTest.java | 264 +-
.../datastructures/graphs/TwoSatTest.java | 250 +-
.../graphs/WelshPowellTest.java | 268 +-
.../GenericHashMapUsingArrayListTest.java | 192 +-
.../hashing/GenericHashMapUsingArrayTest.java | 192 +-
.../hashing/HashMapCuckooHashingTest.java | 280 +-
.../hashmap/hashing/HashMapTest.java | 368 +-
.../hashmap/hashing/ImmutableHashMapTest.java | 110 +-
.../hashmap/hashing/IntersectionTest.java | 152 +-
.../hashing/LinearProbingHashMapTest.java | 182 +-
.../hashmap/hashing/MajorityElementTest.java | 160 +-
.../hashmap/hashing/MapTest.java | 262 +-
.../heaps/FibonacciHeapTest.java | 216 +-
.../datastructures/heaps/GenericHeapTest.java | 170 +-
.../datastructures/heaps/HeapElementTest.java | 112 +-
.../heaps/IndexedPriorityQueueTest.java | 700 +--
.../heaps/KthElementFinderTest.java | 38 +-
.../datastructures/heaps/LeftistHeapTest.java | 170 +-
.../datastructures/heaps/MaxHeapTest.java | 288 +-
.../heaps/MedianFinderTest.java | 34 +-
.../heaps/MergeKSortedArraysTest.java | 82 +-
.../datastructures/heaps/MinHeapTest.java | 282 +-
.../heaps/MinPriorityQueueTest.java | 174 +-
.../lists/CircleLinkedListTest.java | 230 +-
.../CountSinglyLinkedListRecursionTest.java | 256 +-
.../lists/CreateAndDetectLoopTest.java | 172 +-
.../lists/CursorLinkedListTest.java | 594 +-
.../FlattenMultilevelLinkedListTest.java | 224 +-
.../lists/MergeKSortedLinkedListTest.java | 354 +-
.../lists/MergeSortedArrayListTest.java | 198 +-
.../MergeSortedSinglyLinkedListTest.java | 180 +-
.../lists/MiddleOfLinkedListTest.java | 148 +-
.../lists/QuickSortLinkedListTest.java | 190 +-
.../lists/ReverseKGroupTest.java | 144 +-
.../lists/RotateSinglyLinkedListsTest.java | 210 +-
.../SearchSinglyLinkedListRecursionTest.java | 178 +-
.../lists/SinglyLinkedListTest.java | 520 +-
.../datastructures/lists/SkipListTest.java | 230 +-
.../lists/SortedLinkedListTest.java | 416 +-
.../lists/TortoiseHareAlgoTest.java | 92 +-
.../queues/CircularQueueTest.java | 344 +-
.../datastructures/queues/DequeTest.java | 394 +-
.../queues/GenericArrayListQueueTest.java | 200 +-
.../queues/LinkedQueueTest.java | 418 +-
.../queues/PriorityQueuesTest.java | 228 +-
.../queues/QueueByTwoStacksTest.java | 274 +-
.../datastructures/queues/QueueTest.java | 654 +-
.../queues/SlidingWindowMaximumTest.java | 100 +-
.../queues/TokenBucketTest.java | 180 +-
.../datastructures/stacks/NodeStackTest.java | 500 +-
.../stacks/ReverseStackTest.java | 152 +-
.../stacks/StackArrayListTest.java | 214 +-
.../datastructures/stacks/StackArrayTest.java | 374 +-
.../stacks/StackOfLinkedListTest.java | 442 +-
.../datastructures/trees/AVLTreeTest.java | 202 +-
.../trees/BSTFromSortedArrayTest.java | 94 +-
.../trees/BSTIterativeTest.java | 122 +-
.../trees/BSTRecursiveGenericTest.java | 338 +-
.../trees/BSTRecursiveTest.java | 122 +-
.../datastructures/trees/BTreeTest.java | 188 +-
.../datastructures/trees/BinaryTreeTest.java | 156 +-
.../trees/BinaryTreeToStringTest.java | 114 +-
.../trees/BoundaryTraversalTest.java | 216 +-
.../trees/CeilInBinarySearchTreeTest.java | 102 +-
.../trees/CentroidDecompositionTest.java | 472 +-
.../trees/CheckBinaryTreeIsValidBSTTest.java | 122 +-
.../trees/CheckIfBinaryTreeBalancedTest.java | 168 +-
.../trees/CheckTreeIsSymmetricTest.java | 70 +-
...eateBinaryTreeFromInorderPreorderTest.java | 204 +-
.../trees/InorderTraversalTest.java | 104 +-
.../datastructures/trees/KDTreeTest.java | 126 +-
.../trees/LazySegmentTreeTest.java | 122 +-
.../trees/LevelOrderTraversalTest.java | 102 +-
.../trees/PostOrderTraversalTest.java | 108 +-
.../trees/PreOrderTraversalTest.java | 104 +-
.../datastructures/trees/QuadTreeTest.java | 116 +-
.../trees/SameTreesCheckTest.java | 138 +-
.../datastructures/trees/SplayTreeTest.java | 226 +-
.../trees/ThreadedBinaryTreeTest.java | 100 +-
.../datastructures/trees/TreapTest.java | 126 +-
.../datastructures/trees/TreeTestUtils.java | 92 +-
.../datastructures/trees/TrieTest.java | 190 +-
.../trees/VerticalOrderTraversalTest.java | 102 +-
.../trees/ZigzagTraversalTest.java | 102 +-
.../devutils/entities/ProcessDetailsTest.java | 576 +-
.../BinaryExponentiationTest.java | 76 +-
.../divideandconquer/ClosestPairTest.java | 150 +-
.../CountingInversionsTest.java | 126 +-
.../MedianOfTwoSortedArraysTest.java | 82 +-
.../SkylineAlgorithmTest.java | 204 +-
.../StrassenMatrixMultiplicationTest.java | 82 +-
.../divideandconquer/TilingProblemTest.java | 30 +-
.../dynamicprogramming/AbbreviationTest.java | 88 +-
.../dynamicprogramming/AllConstructTest.java | 80 +-
.../AssignmentUsingBitmaskTest.java | 110 +-
.../dynamicprogramming/BoardPathTest.java | 66 +-
.../dynamicprogramming/BoundaryFillTest.java | 132 +-
.../BruteForceKnapsackTest.java | 192 +-
.../dynamicprogramming/CatalanNumberTest.java | 28 +-
.../dynamicprogramming/ClimbStairsTest.java | 66 +-
.../dynamicprogramming/CoinChangeTest.java | 160 +-
.../CountFriendsPairingTest.java | 100 +-
.../dynamicprogramming/DPTest.java | 112 +-
.../DamerauLevenshteinDistanceTest.java | 388 +-
.../dynamicprogramming/EditDistanceTest.java | 208 +-
.../dynamicprogramming/EggDroppingTest.java | 56 +-
.../dynamicprogramming/FibonacciTest.java | 178 +-
.../KadaneAlgorithmTest.java | 122 +-
.../KnapsackMemoizationTest.java | 98 +-
.../dynamicprogramming/KnapsackTest.java | 162 +-
.../KnapsackZeroOneTabulationTest.java | 156 +-
.../KnapsackZeroOneTest.java | 136 +-
.../LevenshteinDistanceTests.java | 90 +-
.../LongestAlternatingSubsequenceTest.java | 44 +-
.../LongestArithmeticSubsequenceTest.java | 70 +-
.../LongestCommonSubsequenceTest.java | 174 +-
...LongestIncreasingSubsequenceNLogNTest.java | 44 +-
.../LongestIncreasingSubsequenceTests.java | 98 +-
.../LongestPalindromicSubstringTest.java | 44 +-
.../LongestValidParenthesesTest.java | 44 +-
.../MatrixChainMultiplicationTest.java | 108 +-
...xChainRecursiveTopDownMemoisationTest.java | 136 +-
.../MaximumProductSubarrayTest.java | 304 +-
.../MaximumSumOfNonAdjacentElementsTest.java | 104 +-
.../MinimumPathSumTest.java | 100 +-
.../MinimumSumPartitionTest.java | 88 +-
.../NeedlemanWunschTest.java | 120 +-
.../NewManShanksPrimeTest.java | 160 +-
.../OptimalJobSchedulingTest.java | 196 +-
.../PalindromicPartitioningTest.java | 42 +-
.../PartitionProblemTest.java | 50 +-
.../dynamicprogramming/RegexMatchingTest.java | 86 +-
.../dynamicprogramming/RodCuttingTest.java | 204 +-
...ShortestCommonSupersequenceLengthTest.java | 28 +-
.../dynamicprogramming/SmithWatermanTest.java | 106 +-
.../dynamicprogramming/SubsetCountTest.java | 58 +-
.../SubsetSumSpaceOptimizedTest.java | 36 +-
.../dynamicprogramming/SubsetSumTest.java | 48 +-
.../dynamicprogramming/SumOfSubsetTest.java | 36 +-
.../dynamicprogramming/TreeMatchingTest.java | 240 +-
.../dynamicprogramming/TribonacciTest.java | 48 +-
.../dynamicprogramming/UniquePathsTests.java | 118 +-
.../WildcardMatchingTest.java | 54 +-
.../dynamicprogramming/WineProblemTest.java | 144 +-
.../geometry/BentleyOttmannTest.java | 648 +-
.../geometry/BresenhamLineTest.java | 114 +-
.../geometry/ConvexHullTest.java | 276 +-
.../thealgorithms/geometry/DDALineTest.java | 58 +-
.../geometry/GrahamScanTest.java | 32 +-
.../thealgorithms/geometry/HaversineTest.java | 120 +-
.../geometry/MidpointCircleTest.java | 110 +-
.../geometry/MidpointEllipseTest.java | 198 +-
.../com/thealgorithms/geometry/PointTest.java | 234 +-
.../thealgorithms/geometry/WusLineTest.java | 180 +-
.../thealgorithms/graph/BronKerboschTest.java | 158 +-
.../graph/ConstrainedShortestPathTest.java | 436 +-
.../com/thealgorithms/graph/DinicTest.java | 142 +-
.../thealgorithms/graph/EdmondsKarpTest.java | 96 +-
.../com/thealgorithms/graph/EdmondsTest.java | 344 +-
.../thealgorithms/graph/GomoryHuTreeTest.java | 264 +-
.../graph/HierholzerAlgorithmTest.java | 120 +-
.../graph/HierholzerEulerianPathTest.java | 338 +-
.../thealgorithms/graph/HopcroftKarpTest.java | 266 +-
.../graph/HungarianAlgorithmTest.java | 88 +-
.../graph/PredecessorConstrainedDfsTest.java | 180 +-
.../thealgorithms/graph/PushRelabelTest.java | 132 +-
.../thealgorithms/graph/StoerWagnerTest.java | 128 +-
...ronglyConnectedComponentOptimizedTest.java | 160 +-
.../graph/TravelingSalesmanTest.java | 254 +-
.../graph/YensKShortestPathsTest.java | 152 +-
.../thealgorithms/graph/ZeroOneBfsTest.java | 136 +-
.../ActivitySelectionTest.java | 88 +-
.../BandwidthAllocationTest.java | 44 +-
.../greedyalgorithms/BinaryAdditionTest.java | 192 +-
.../greedyalgorithms/CoinChangeTest.java | 120 +-
.../greedyalgorithms/DigitSeparationTest.java | 156 +-
.../EgyptianFractionTest.java | 44 +-
.../FractionalKnapsackTest.java | 64 +-
.../greedyalgorithms/GaleShapleyTest.java | 144 +-
.../greedyalgorithms/JobSequencingTest.java | 46 +-
.../greedyalgorithms/KCentersTest.java | 30 +-
.../greedyalgorithms/MergeIntervalsTest.java | 142 +-
.../MinimizingLatenessTest.java | 86 +-
.../MinimumWaitingTimeTest.java | 42 +-
.../OptimalFileMergingTest.java | 44 +-
.../StockProfitCalculatorTest.java | 42 +-
.../thealgorithms/io/BufferedReaderTest.java | 198 +-
.../lineclipping/CohenSutherlandTest.java | 162 +-
.../lineclipping/LiangBarskyTest.java | 130 +-
.../thealgorithms/maths/ADTFractionTest.java | 104 +-
.../thealgorithms/maths/AbsoluteMaxTest.java | 60 +-
.../thealgorithms/maths/AbsoluteMinTest.java | 54 +-
.../maths/AbsoluteValueTest.java | 78 +-
.../maths/AbundantNumberTest.java | 62 +-
.../thealgorithms/maths/AliquotSumTest.java | 40 +-
.../maths/AmicableNumberTest.java | 116 +-
.../com/thealgorithms/maths/AreaTest.java | 206 +-
.../thealgorithms/maths/ArmstrongTest.java | 50 +-
.../maths/AutoCorrelationTest.java | 74 +-
.../maths/AutomorphicNumberTest.java | 54 +-
.../com/thealgorithms/maths/AverageTest.java | 96 +-
.../thealgorithms/maths/BellNumbersTest.java | 106 +-
.../thealgorithms/maths/BinaryPowTest.java | 92 +-
.../maths/BinomialCoefficientTest.java | 32 +-
.../maths/CatalanNumbersTest.java | 86 +-
.../com/thealgorithms/maths/CeilTest.java | 62 +-
.../maths/ChebyshevIterationTest.java | 210 +-
.../maths/ChineseRemainderTheoremTest.java | 110 +-
.../maths/CollatzConjectureTest.java | 82 +-
.../thealgorithms/maths/CombinationsTest.java | 52 +-
.../maths/ComplexNumberMultiplyTest.java | 68 +-
.../maths/ConvolutionFFTTest.java | 110 +-
.../thealgorithms/maths/ConvolutionTest.java | 54 +-
.../maths/CrossCorrelationTest.java | 74 +-
.../maths/DeterminantOfMatrixTest.java | 100 +-
.../thealgorithms/maths/DigitalRootTest.java | 36 +-
.../maths/DistanceBetweenTwoPointsTest.java | 46 +-
.../maths/DistanceFormulaTest.java | 172 +-
.../maths/DudeneyNumberTest.java | 56 +-
.../thealgorithms/maths/EulerMethodTest.java | 158 +-
.../maths/EulerPseudoprimeTest.java | 186 +-
.../maths/EulersFunctionTest.java | 66 +-
.../thealgorithms/maths/EvilNumberTest.java | 56 +-
.../maths/ExtendedEuclideanAlgorithmTest.java | 94 +-
.../java/com/thealgorithms/maths/FFTTest.java | 276 +-
.../thealgorithms/maths/FactorialTest.java | 48 +-
.../maths/FastExponentiationTest.java | 134 +-
.../maths/FastInverseSqrtTests.java | 100 +-
.../maths/FibonacciJavaStreamsTest.java | 142 +-
.../maths/FibonacciLoopTest.java | 72 +-
.../maths/FibonacciNumberCheckTest.java | 60 +-
.../FibonacciNumberGoldenRationTest.java | 58 +-
.../maths/FindKthNumberTest.java | 144 +-
.../maths/FindMaxRecursionTest.java | 56 +-
.../com/thealgorithms/maths/FindMaxTest.java | 56 +-
.../maths/FindMinRecursionTest.java | 56 +-
.../com/thealgorithms/maths/FindMinTest.java | 58 +-
.../com/thealgorithms/maths/FloorTest.java | 56 +-
.../thealgorithms/maths/FrizzyNumberTest.java | 56 +-
.../thealgorithms/maths/GCDRecursionTest.java | 96 +-
.../java/com/thealgorithms/maths/GCDTest.java | 164 +-
.../com/thealgorithms/maths/GaussianTest.java | 58 +-
.../thealgorithms/maths/GenericRootTest.java | 52 +-
.../maths/GermainPrimeAndSafePrimeTest.java | 98 +-
.../maths/GoldbachConjectureTest.java | 58 +-
.../thealgorithms/maths/HappyNumberTest.java | 64 +-
.../maths/HarshadNumberTest.java | 270 +-
.../maths/HeronsFormulaTest.java | 286 +-
.../maths/JosephusProblemTest.java | 28 +-
.../maths/JugglerSequenceTest.java | 84 +-
.../maths/KaprekarNumbersTest.java | 376 +-
.../maths/KaratsubaMultiplicationTest.java | 116 +-
.../thealgorithms/maths/KeithNumberTest.java | 306 +-
.../maths/KrishnamurthyNumberTest.java | 240 +-
.../maths/LeastCommonMultipleTest.java | 42 +-
.../maths/LeonardoNumberTest.java | 342 +-
.../LinearDiophantineEquationsSolverTest.java | 660 +-
.../thealgorithms/maths/LongDivisionTest.java | 116 +-
.../thealgorithms/maths/LucasSeriesTest.java | 316 +-
.../thealgorithms/maths/LuckyNumberTest.java | 64 +-
.../thealgorithms/maths/MathBuilderTest.java | 104 +-
.../com/thealgorithms/maths/MaxValueTest.java | 28 +-
.../com/thealgorithms/maths/MeansTest.java | 436 +-
.../com/thealgorithms/maths/MedianTest.java | 314 +-
.../com/thealgorithms/maths/MinValueTest.java | 28 +-
.../com/thealgorithms/maths/ModeTest.java | 42 +-
.../com/thealgorithms/maths/NevilleTest.java | 138 +-
.../maths/NonRepeatingElementTest.java | 60 +-
.../maths/NthUglyNumberTest.java | 158 +-
.../maths/NumberOfDigitsTest.java | 80 +-
.../maths/NumberPersistenceTest.java | 84 +-
.../maths/PalindromeNumberTest.java | 60 +-
.../thealgorithms/maths/ParseIntegerTest.java | 102 +-
.../maths/PascalTriangleTest.java | 102 +-
.../thealgorithms/maths/PerfectCubeTest.java | 66 +-
.../maths/PerfectNumberTest.java | 46 +-
.../maths/PerfectSquareTest.java | 42 +-
.../thealgorithms/maths/PerimeterTest.java | 102 +-
.../maths/PiApproximationTest.java | 338 +-
.../thealgorithms/maths/PollardRhoTest.java | 98 +-
.../java/com/thealgorithms/maths/PowTest.java | 72 +-
.../thealgorithms/maths/PowerOfFourTest.java | 72 +-
.../maths/PowerOfTwoOrNotTest.java | 48 +-
.../maths/PowerUsingRecursionTest.java | 40 +-
.../thealgorithms/maths/PronicNumberTest.java | 44 +-
.../maths/PythagoreanTripleTest.java | 48 +-
.../maths/QuadraticEquationSolverTest.java | 100 +-
.../maths/ReverseNumberTest.java | 46 +-
.../thealgorithms/maths/SecondMinMaxTest.java | 116 +-
.../thealgorithms/maths/SieveOfAtkinTest.java | 94 +-
.../maths/SieveOfEratosthenesTest.java | 128 +-
.../thealgorithms/maths/SmithNumberTest.java | 44 +-
.../SolovayStrassenPrimalityTestTest.java | 244 +-
.../maths/SquareFreeIntegerTest.java | 168 +-
...SquareRootWithNewtonRaphsonTestMethod.java | 44 +-
.../SquareRootwithBabylonianMethodTest.java | 54 +-
.../maths/StandardDeviationTest.java | 74 +-
.../maths/StandardScoreTest.java | 54 +-
.../maths/StrobogrammaticNumberTest.java | 38 +-
.../maths/SumOfArithmeticSeriesTest.java | 106 +-
.../thealgorithms/maths/SumOfDigitsTest.java | 62 +-
.../maths/SumOfOddNumbersTest.java | 56 +-
.../thealgorithms/maths/SumOfSquaresTest.java | 136 +-
.../SumWithoutArithmeticOperatorsTest.java | 80 +-
.../thealgorithms/maths/TestArmstrong.java | 30 +-
.../thealgorithms/maths/TwinPrimeTest.java | 120 +-
.../maths/UniformNumbersTest.java | 112 +-
.../com/thealgorithms/maths/VolumeTest.java | 78 +-
.../maths/ZellersCongruenceTest.java | 72 +-
.../prime/LiouvilleLambdaFunctionTest.java | 128 +-
.../prime/MillerRabinPrimalityCheckTest.java | 62 +-
.../maths/prime/MobiusFunctionTest.java | 310 +-
.../maths/prime/PrimeCheckTest.java | 86 +-
.../maths/prime/PrimeFactorizationTest.java | 66 +-
.../matrix/InverseOfMatrixTest.java | 54 +-
.../matrix/LUDecompositionTest.java | 80 +-
.../matrix/MatrixMultiplicationTest.java | 202 +-
.../thealgorithms/matrix/MatrixRankTest.java | 90 +-
.../matrix/MatrixTransposeTest.java | 66 +-
.../thealgorithms/matrix/MatrixUtilTest.java | 160 +-
.../matrix/MedianOfMatrixTest.java | 100 +-
.../matrix/MirrorOfMatrixTest.java | 106 +-
.../matrix/PrintAMatrixInSpiralOrderTest.java | 166 +-
.../thealgorithms/matrix/SolveSystemTest.java | 42 +-
.../matrix/StochasticMatrixTest.java | 56 +-
.../misc/ColorContrastRatioTest.java | 66 +-
.../com/thealgorithms/misc/MapReduceTest.java | 30 +-
.../misc/MedianOfRunningArrayTest.java | 402 +-
.../misc/PalindromePrimeTest.java | 106 +-
.../misc/PalindromeSinglyLinkedListTest.java | 284 +-
.../misc/RangeInSortedArrayTest.java | 114 +-
.../thealgorithms/misc/ShuffleArrayTest.java | 170 +-
.../com/thealgorithms/misc/SparsityTest.java | 72 +-
.../misc/ThreeSumProblemTest.java | 104 +-
.../thealgorithms/misc/TwoSumProblemTest.java | 122 +-
.../others/ArrayLeftRotationTest.java | 108 +-
.../others/ArrayRightRotationTest.java | 106 +-
.../com/thealgorithms/others/BFPRTTest.java | 68 +-
.../thealgorithms/others/BestFitCPUTest.java | 138 +-
.../thealgorithms/others/BoyerMooreTest.java | 60 +-
.../com/thealgorithms/others/CRC16Test.java | 38 +-
.../others/CRCAlgorithmTest.java | 326 +-
.../com/thealgorithms/others/ConwayTest.java | 82 +-
.../others/CountFriendsPairingTest.java | 114 +-
.../thealgorithms/others/FirstFitCPUTest.java | 138 +-
.../others/FloydTriangleTest.java | 96 +-
.../com/thealgorithms/others/HuffmanTest.java | 446 +-
.../others/InsertDeleteInArrayTest.java | 440 +-
.../others/KadaneAlogrithmTest.java | 114 +-
.../thealgorithms/others/LineSweepTest.java | 74 +-
.../others/LinkListSortTest.java | 114 +-
.../others/LowestBasePalindromeTest.java | 242 +-
...SumOfDistinctSubarraysWithLengthKTest.java | 318 +-
.../others/MiniMaxAlgorithmTest.java | 688 +-
.../others/MosAlgorithmTest.java | 404 +-
.../com/thealgorithms/others/NextFitTest.java | 138 +-
.../thealgorithms/others/PageRankTest.java | 638 +-
.../thealgorithms/others/PasswordGenTest.java | 106 +-
.../thealgorithms/others/PerlinNoiseTest.java | 206 +-
.../others/QueueUsingTwoStacksTest.java | 290 +-
.../others/SkylineProblemTest.java | 172 +-
.../thealgorithms/others/TwoPointersTest.java | 160 +-
.../thealgorithms/others/WorstFitCPUTest.java | 158 +-
.../physics/CoulombsLawTest.java | 200 +-
.../physics/DampedOscillatorTest.java | 286 +-
.../physics/ElasticCollision2DTest.java | 182 +-
.../physics/GravitationTest.java | 166 +-
.../GroundToGroundProjectileMotionTest.java | 298 +-
.../thealgorithms/physics/KinematicsTest.java | 96 +-
.../physics/ProjectileMotionTest.java | 138 +-
.../physics/SimplePendulumRK4Test.java | 522 +-
.../thealgorithms/physics/SnellLawTest.java | 82 +-
.../thealgorithms/physics/ThinLensTest.java | 38 +-
.../prefixsum/DifferenceArrayTest.java | 220 +-
.../prefixsum/PrefixSum2DTest.java | 184 +-
.../prefixsum/PrefixSumTest.java | 160 +-
.../prefixsum/RangeSumQueryTest.java | 146 +-
.../prefixsum/SubarraySumEqualskTest.java | 118 +-
.../puzzlesandgames/TowerOfHanoiTest.java | 164 +-
.../puzzlesandgames/WordBoggleTest.java | 114 +-
.../randomized/KargerMinCutTest.java | 228 +-
.../randomized/MonteCarloIntegrationTest.java | 182 +-
.../randomized/RandomizedClosestPairTest.java | 60 +-
...dMatrixMultiplicationVerificationTest.java | 82 +-
.../randomized/RandomizedQuickSortTest.java | 88 +-
.../randomized/ReservoirSamplingTest.java | 90 +-
.../recursion/DiceThrowerTest.java | 446 +-
.../recursion/FactorialRecursionTest.java | 54 +-
.../recursion/FibonacciSeriesTest.java | 54 +-
.../recursion/GenerateSubsetsTest.java | 80 +-
.../recursion/SylvesterSequenceTest.java | 102 +-
.../scheduling/AgingSchedulingTest.java | 108 +-
.../scheduling/EDFSchedulingTest.java | 138 +-
.../scheduling/FCFSSchedulingTest.java | 92 +-
.../scheduling/FairShareSchedulingTest.java | 120 +-
.../scheduling/GangSchedulingTest.java | 104 +-
...ighestResponseRatioNextSchedulingTest.java | 224 +-
.../JobSchedulingWithDeadlineTest.java | 86 +-
.../scheduling/LotterySchedulingTest.java | 128 +-
.../scheduling/MLFQSchedulerTest.java | 92 +-
.../scheduling/MultiAgentSchedulingTest.java | 104 +-
.../NonPreemptivePrioritySchedulingTest.java | 140 +-
.../PreemptivePrioritySchedulingTest.java | 62 +-
.../ProportionalFairSchedulingTest.java | 106 +-
.../scheduling/RRSchedulingTest.java | 126 +-
.../scheduling/RandomSchedulingTest.java | 186 +-
.../scheduling/SJFSchedulingTest.java | 98 +-
.../scheduling/SRTFSchedulingTest.java | 122 +-
.../SelfAdjustingSchedulingTest.java | 114 +-
.../scheduling/SlackTimeSchedulingTest.java | 96 +-
.../CircularLookSchedulingTest.java | 110 +-
.../CircularScanSchedulingTest.java | 98 +-
.../diskscheduling/LookSchedulingTest.java | 136 +-
.../diskscheduling/SSFSchedulingTest.java | 110 +-
.../diskscheduling/ScanSchedulingTest.java | 110 +-
.../searches/BM25InvertedIndexTest.java | 190 +-
.../searches/BinarySearch2dArrayTest.java | 314 +-
.../searches/BinarySearchTest.java | 216 +-
.../searches/BoyerMooreTest.java | 110 +-
.../searches/BreadthFirstSearchTest.java | 208 +-
.../searches/DepthFirstSearchTest.java | 186 +-
.../searches/ExponentialSearchTest.java | 168 +-
.../searches/FibonacciSearchTest.java | 248 +-
.../searches/HowManyTimesRotatedTest.java | 32 +-
.../searches/InterpolationSearchTest.java | 180 +-
.../searches/IterativeBinarySearchTest.java | 234 +-
.../searches/IterativeTernarySearchTest.java | 234 +-
.../searches/JumpSearchTest.java | 188 +-
.../thealgorithms/searches/KMPSearchTest.java | 126 +-
.../searches/LinearSearchTest.java | 236 +-
.../searches/LinearSearchThreadTest.java | 148 +-
.../searches/LowerBoundTest.java | 118 +-
.../searches/MonteCarloTreeSearchTest.java | 252 +-
.../OrderAgnosticBinarySearchTest.java | 134 +-
.../searches/QuickSelectTest.java | 464 +-
.../searches/RabinKarpAlgorithmTest.java | 34 +-
.../searches/RandomSearchTest.java | 174 +-
.../searches/RecursiveBinarySearchTest.java | 82 +-
.../searches/RotatedBinarySearchTest.java | 106 +-
...lumnWiseSorted2dArrayBinarySearchTest.java | 480 +-
.../searches/SaddlebackSearchTest.java | 170 +-
...earchInARowAndColWiseSortedMatrixTest.java | 132 +-
.../searches/SentinelLinearSearchTest.java | 450 +-
.../searches/SquareRootBinarySearchTest.java | 114 +-
.../searches/TernarySearchTest.java | 162 +-
.../thealgorithms/searches/UnionFindTest.java | 162 +-
.../searches/UpperBoundTest.java | 198 +-
.../slidingwindow/CountNiceSubarraysTest.java | 110 +-
...gestSubarrayWithSumLessOrEqualToKTest.java | 44 +-
...bstringWithoutRepeatingCharactersTest.java | 46 +-
.../MaxSumKSizeSubarrayTest.java | 158 +-
.../MaximumSlidingWindowTest.java | 126 +-
.../MinSumKSizeSubarrayTest.java | 158 +-
.../MinimumWindowSubstringTest.java | 70 +-
.../ShortestCoprimeSegmentTest.java | 130 +-
.../sorts/AdaptiveMergeSortTest.java | 284 +-
.../com/thealgorithms/sorts/BeadSortTest.java | 58 +-
.../sorts/BinaryInsertionSortTest.java | 20 +-
.../thealgorithms/sorts/BitonicSortTest.java | 16 +-
.../com/thealgorithms/sorts/BogoSortTest.java | 300 +-
.../sorts/BubbleSortRecursiveTest.java | 16 +-
.../thealgorithms/sorts/BubbleSortTest.java | 356 +-
.../thealgorithms/sorts/BucketSortTest.java | 16 +-
.../thealgorithms/sorts/CircleSortTest.java | 16 +-
.../sorts/CocktailShakerSortTest.java | 16 +-
.../com/thealgorithms/sorts/CombSortTest.java | 16 +-
.../thealgorithms/sorts/CountingSortTest.java | 54 +-
.../thealgorithms/sorts/CycleSortTest.java | 16 +-
.../com/thealgorithms/sorts/DarkSortTest.java | 148 +-
.../sorts/DualPivotQuickSortTest.java | 16 +-
.../sorts/DutchNationalFlagSortTest.java | 224 +-
.../thealgorithms/sorts/ExchangeSortTest.java | 16 +-
.../thealgorithms/sorts/FlashSortTest.java | 178 +-
.../thealgorithms/sorts/GnomeSortTest.java | 344 +-
.../com/thealgorithms/sorts/HeapSortTest.java | 16 +-
.../sorts/InsertionSortTest.java | 396 +-
.../sorts/IntrospectiveSortTest.java | 16 +-
.../sorts/MergeSortNoExtraSpaceTest.java | 68 +-
.../sorts/MergeSortRecursiveTest.java | 64 +-
.../thealgorithms/sorts/MergeSortTest.java | 16 +-
.../thealgorithms/sorts/OddEvenSortTest.java | 30 +-
.../thealgorithms/sorts/PancakeSortTest.java | 16 +-
.../thealgorithms/sorts/PatienceSortTest.java | 16 +-
.../sorts/PigeonholeSortTest.java | 62 +-
.../sorts/PriorityQueueSortTest.java | 112 +-
.../thealgorithms/sorts/QuickSortTest.java | 24 +-
.../thealgorithms/sorts/RadixSortTest.java | 60 +-
.../sorts/SelectionSortRecursiveTest.java | 24 +-
.../sorts/SelectionSortTest.java | 16 +-
.../thealgorithms/sorts/ShellSortTest.java | 16 +-
.../com/thealgorithms/sorts/SlowSortTest.java | 326 +-
.../thealgorithms/sorts/SmoothSortTest.java | 16 +-
.../sorts/SortUtilsRandomGeneratorTest.java | 62 +-
.../thealgorithms/sorts/SortUtilsTest.java | 188 +-
.../sorts/SortingAlgorithmTest.java | 730 +--
.../thealgorithms/sorts/SpreadSortTest.java | 66 +-
.../thealgorithms/sorts/StalinSortTest.java | 106 +-
.../thealgorithms/sorts/StoogeSortTest.java | 24 +-
.../thealgorithms/sorts/StrandSortTest.java | 16 +-
.../com/thealgorithms/sorts/SwapSortTest.java | 16 +-
.../com/thealgorithms/sorts/TimSortTest.java | 16 +-
.../sorts/TopologicalSortTest.java | 154 +-
.../sorts/TournamentSortTest.java | 38 +-
.../com/thealgorithms/sorts/TreeSortTest.java | 108 +-
.../com/thealgorithms/sorts/WaveSortTest.java | 96 +-
.../thealgorithms/sorts/WiggleSortTest.java | 146 +-
.../stacks/BalancedBracketsTest.java | 72 +-
.../stacks/CelebrityFinderTest.java | 82 +-
.../stacks/DecimalToAnyUsingStackTest.java | 90 +-
.../stacks/DuplicateBracketsTest.java | 110 +-
.../GreatestElementConstantTimeTest.java | 140 +-
.../stacks/InfixToPostfixTest.java | 66 +-
.../stacks/InfixToPrefixTest.java | 88 +-
.../stacks/LargestRectangleTest.java | 56 +-
.../stacks/MinStackUsingSingleStackTest.java | 132 +-
.../stacks/MinStackUsingTwoStacksTest.java | 224 +-
.../stacks/NextGreaterElementTest.java | 58 +-
.../stacks/NextSmallerElementTest.java | 58 +-
.../stacks/PalindromeWithStackTest.java | 154 +-
.../stacks/PostfixEvaluatorTest.java | 88 +-
.../stacks/PostfixToInfixTest.java | 66 +-
.../stacks/PrefixEvaluatorTest.java | 62 +-
.../stacks/PrefixToInfixTest.java | 88 +-
.../SmallestElementConstantTimeTest.java | 138 +-
.../thealgorithms/stacks/SortStackTest.java | 520 +-
.../stacks/StackPostfixNotationTest.java | 64 +-
.../stacks/StackUsingTwoQueuesTest.java | 140 +-
.../stacks/TrappingRainwaterTest.java | 76 +-
.../stacks/ValidParenthesesTest.java | 64 +-
.../strings/AhoCorasickTest.java | 242 +-
.../strings/AlphabeticalTest.java | 30 +-
.../strings/AlternativeStringArrangeTest.java | 46 +-
.../thealgorithms/strings/AnagramsTest.java | 98 +-
.../strings/CharactersSameTest.java | 30 +-
.../strings/CheckVowelsTest.java | 30 +-
.../thealgorithms/strings/CountCharTest.java | 48 +-
.../thealgorithms/strings/CountWordsTest.java | 62 +-
.../strings/HammingDistanceTest.java | 72 +-
.../strings/HorspoolSearchTest.java | 174 +-
.../thealgorithms/strings/IsogramTest.java | 234 +-
.../thealgorithms/strings/IsomorphicTest.java | 46 +-
.../com/thealgorithms/strings/KMPTest.java | 58 +-
.../strings/LengthOfLastWordTest.java | 36 +-
.../LetterCombinationsOfPhoneNumberTest.java | 74 +-
.../strings/LongestCommonPrefixTest.java | 48 +-
.../LongestNonRepetitiveSubstringTest.java | 44 +-
.../com/thealgorithms/strings/LowerTest.java | 36 +-
.../thealgorithms/strings/ManacherTest.java | 106 +-
.../com/thealgorithms/strings/MyAtoiTest.java | 86 +-
.../thealgorithms/strings/PalindromeTest.java | 42 +-
.../thealgorithms/strings/PangramTest.java | 54 +-
.../strings/PermuteStringTest.java | 58 +-
.../thealgorithms/strings/RabinKarpTest.java | 92 +-
.../RemoveDuplicateFromStringTest.java | 88 +-
.../strings/RemoveStarsTest.java | 56 +-
.../strings/ReturnSubsequenceTest.java | 46 +-
.../strings/ReverseStringTest.java | 112 +-
.../strings/ReverseWordsInStringTest.java | 38 +-
.../thealgorithms/strings/RotationTest.java | 30 +-
.../strings/StringCompressionTest.java | 30 +-
.../StringMatchFiniteAutomataTest.java | 46 +-
.../strings/SuffixArrayTest.java | 88 +-
.../com/thealgorithms/strings/UpperTest.java | 36 +-
.../thealgorithms/strings/WordLadderTest.java | 134 +-
.../thealgorithms/strings/ZAlgorithmTest.java | 50 +-
.../zigZagPattern/ZigZagPatternTest.java | 38 +-
.../tree/HeavyLightDecompositionTest.java | 138 +-
1542 files changed, 132834 insertions(+), 132828 deletions(-)
diff --git a/.clang-format b/.clang-format
index 3d685994a1aa..73fd2dd73af7 100644
--- a/.clang-format
+++ b/.clang-format
@@ -1,136 +1,136 @@
----
-Language: Java
-AccessModifierOffset: -4
-AlignAfterOpenBracket: DontAlign
-AlignConsecutiveMacros: false
-AlignConsecutiveAssignments: false
-AlignConsecutiveDeclarations: false
-AlignEscapedNewlines: Right
-AlignOperands: false
-AlignTrailingComments: false
-AllowAllArgumentsOnNextLine: true
-AllowAllConstructorInitializersOnNextLine: true
-AllowAllParametersOfDeclarationOnNextLine: true
-AllowShortBlocksOnASingleLine: Never
-AllowShortCaseLabelsOnASingleLine: false
-AllowShortFunctionsOnASingleLine: false
-AllowShortLambdasOnASingleLine: All
-AllowShortIfStatementsOnASingleLine: true
-AllowShortLoopsOnASingleLine: true
-AlwaysBreakAfterDefinitionReturnType: None
-AlwaysBreakAfterReturnType: None
-AlwaysBreakBeforeMultilineStrings: false
-AlwaysBreakTemplateDeclarations: MultiLine
-BinPackArguments: true
-BinPackParameters: true
-BraceWrapping:
- AfterCaseLabel: false
- AfterClass: false
- AfterControlStatement: false
- AfterEnum: false
- AfterFunction: false
- AfterNamespace: false
- AfterObjCDeclaration: false
- AfterStruct: false
- AfterUnion: false
- AfterExternBlock: false
- BeforeCatch: false
- BeforeElse: false
- IndentBraces: false
- SplitEmptyFunction: true
- SplitEmptyRecord: true
- SplitEmptyNamespace: true
-BreakBeforeBinaryOperators: All
-BreakBeforeBraces: Custom
-BreakBeforeInheritanceComma: false
-BreakInheritanceList: BeforeColon
-BreakBeforeTernaryOperators: true
-BreakConstructorInitializersBeforeComma: false
-BreakConstructorInitializers: BeforeComma
-BreakAfterJavaFieldAnnotations: false
-BreakStringLiterals: true
-ColumnLimit: 300
-CommentPragmas: '^ IWYU pragma:'
-CompactNamespaces: false
-ConstructorInitializerAllOnOneLineOrOnePerLine: false
-ConstructorInitializerIndentWidth: 4
-ContinuationIndentWidth: 4
-Cpp11BracedListStyle: true
-DeriveLineEnding: true
-DerivePointerAlignment: false
-DisableFormat: false
-ExperimentalAutoDetectBinPacking: false
-FixNamespaceComments: false
-ForEachMacros:
- - foreach
- - Q_FOREACH
- - BOOST_FOREACH
-IncludeBlocks: Preserve
-IncludeCategories:
- - Regex: '^"(llvm|llvm-c|clang|clang-c)/'
- Priority: 2
- SortPriority: 0
- - Regex: '^(<|"(gtest|gmock|isl|json)/)'
- Priority: 3
- SortPriority: 0
- - Regex: '.*'
- Priority: 1
- SortPriority: 0
-IncludeIsMainRegex: '(Test)?$'
-IncludeIsMainSourceRegex: ''
-IndentCaseLabels: false
-IndentGotoLabels: true
-IndentPPDirectives: None
-IndentWidth: 4
-IndentWrappedFunctionNames: false
-InsertNewlineAtEOF: true
-JavaScriptQuotes: Leave
-JavaScriptWrapImports: true
-KeepEmptyLinesAtTheStartOfBlocks: true
-MacroBlockBegin: ''
-MacroBlockEnd: ''
-MaxEmptyLinesToKeep: 1
-NamespaceIndentation: Inner
-ObjCBinPackProtocolList: Auto
-ObjCBlockIndentWidth: 4
-ObjCSpaceAfterProperty: true
-ObjCSpaceBeforeProtocolList: true
-PenaltyBreakAssignment: 2
-PenaltyBreakBeforeFirstCallParameter: 19
-PenaltyBreakComment: 300
-PenaltyBreakFirstLessLess: 120
-PenaltyBreakString: 1000
-PenaltyBreakTemplateDeclaration: 10
-PenaltyExcessCharacter: 1000000
-PenaltyReturnTypeOnItsOwnLine: 60
-PointerAlignment: Left
-ReflowComments: true
-SortIncludes: true
-SortUsingDeclarations: true
-SpaceAfterCStyleCast: true
-SpaceAfterLogicalNot: false
-SpaceAfterTemplateKeyword: true
-SpaceBeforeAssignmentOperators: true
-SpaceBeforeCpp11BracedList: false
-SpaceBeforeCtorInitializerColon: true
-SpaceBeforeInheritanceColon: true
-SpaceBeforeParens: ControlStatements
-SpaceBeforeRangeBasedForLoopColon: true
-SpaceInEmptyBlock: false
-SpaceInEmptyParentheses: false
-SpacesBeforeTrailingComments: 1
-SpacesInAngles: false
-SpacesInConditionalStatement: false
-SpacesInContainerLiterals: false
-SpacesInCStyleCastParentheses: false
-SpacesInParentheses: false
-SpacesInSquareBrackets: false
-SpaceBeforeSquareBrackets: false
-Standard: Latest
-StatementMacros:
- - Q_UNUSED
- - QT_REQUIRE_VERSION
-TabWidth: 8
-UseCRLF: false
-UseTab: Never
-...
+---
+Language: Java
+AccessModifierOffset: -4
+AlignAfterOpenBracket: DontAlign
+AlignConsecutiveMacros: false
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlines: Right
+AlignOperands: false
+AlignTrailingComments: false
+AllowAllArgumentsOnNextLine: true
+AllowAllConstructorInitializersOnNextLine: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: Never
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: false
+AllowShortLambdasOnASingleLine: All
+AllowShortIfStatementsOnASingleLine: true
+AllowShortLoopsOnASingleLine: true
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: MultiLine
+BinPackArguments: true
+BinPackParameters: true
+BraceWrapping:
+ AfterCaseLabel: false
+ AfterClass: false
+ AfterControlStatement: false
+ AfterEnum: false
+ AfterFunction: false
+ AfterNamespace: false
+ AfterObjCDeclaration: false
+ AfterStruct: false
+ AfterUnion: false
+ AfterExternBlock: false
+ BeforeCatch: false
+ BeforeElse: false
+ IndentBraces: false
+ SplitEmptyFunction: true
+ SplitEmptyRecord: true
+ SplitEmptyNamespace: true
+BreakBeforeBinaryOperators: All
+BreakBeforeBraces: Custom
+BreakBeforeInheritanceComma: false
+BreakInheritanceList: BeforeColon
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializersBeforeComma: false
+BreakConstructorInitializers: BeforeComma
+BreakAfterJavaFieldAnnotations: false
+BreakStringLiterals: true
+ColumnLimit: 300
+CommentPragmas: '^ IWYU pragma:'
+CompactNamespaces: false
+ConstructorInitializerAllOnOneLineOrOnePerLine: false
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DeriveLineEnding: true
+DerivePointerAlignment: false
+DisableFormat: false
+ExperimentalAutoDetectBinPacking: false
+FixNamespaceComments: false
+ForEachMacros:
+ - foreach
+ - Q_FOREACH
+ - BOOST_FOREACH
+IncludeBlocks: Preserve
+IncludeCategories:
+ - Regex: '^"(llvm|llvm-c|clang|clang-c)/'
+ Priority: 2
+ SortPriority: 0
+ - Regex: '^(<|"(gtest|gmock|isl|json)/)'
+ Priority: 3
+ SortPriority: 0
+ - Regex: '.*'
+ Priority: 1
+ SortPriority: 0
+IncludeIsMainRegex: '(Test)?$'
+IncludeIsMainSourceRegex: ''
+IndentCaseLabels: false
+IndentGotoLabels: true
+IndentPPDirectives: None
+IndentWidth: 4
+IndentWrappedFunctionNames: false
+InsertNewlineAtEOF: true
+JavaScriptQuotes: Leave
+JavaScriptWrapImports: true
+KeepEmptyLinesAtTheStartOfBlocks: true
+MacroBlockBegin: ''
+MacroBlockEnd: ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: Inner
+ObjCBinPackProtocolList: Auto
+ObjCBlockIndentWidth: 4
+ObjCSpaceAfterProperty: true
+ObjCSpaceBeforeProtocolList: true
+PenaltyBreakAssignment: 2
+PenaltyBreakBeforeFirstCallParameter: 19
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyBreakTemplateDeclaration: 10
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 60
+PointerAlignment: Left
+ReflowComments: true
+SortIncludes: true
+SortUsingDeclarations: true
+SpaceAfterCStyleCast: true
+SpaceAfterLogicalNot: false
+SpaceAfterTemplateKeyword: true
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeCpp11BracedList: false
+SpaceBeforeCtorInitializerColon: true
+SpaceBeforeInheritanceColon: true
+SpaceBeforeParens: ControlStatements
+SpaceBeforeRangeBasedForLoopColon: true
+SpaceInEmptyBlock: false
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles: false
+SpacesInConditionalStatement: false
+SpacesInContainerLiterals: false
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+SpaceBeforeSquareBrackets: false
+Standard: Latest
+StatementMacros:
+ - Q_UNUSED
+ - QT_REQUIRE_VERSION
+TabWidth: 8
+UseCRLF: false
+UseTab: Never
+...
diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
index bcea8e797ffb..6282a0f901e3 100644
--- a/.devcontainer/Dockerfile
+++ b/.devcontainer/Dockerfile
@@ -1,25 +1,25 @@
-# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.238.0/containers/java/.devcontainer/base.Dockerfile
-
-# [Choice] Java version (use -bullseye variants on local arm64/Apple Silicon): 11, 17, 11-bullseye, 17-bullseye, 11-buster, 17-buster
-ARG VARIANT="21-bullseye"
-FROM mcr.microsoft.com/vscode/devcontainers/java:1.1.0-${VARIANT}
-
-# [Option] Install Maven
-ARG INSTALL_MAVEN="false"
-ARG MAVEN_VERSION=""
-# [Option] Install Gradle
-ARG INSTALL_GRADLE="false"
-ARG GRADLE_VERSION=""
-RUN if [ "${INSTALL_MAVEN}" = "true" ]; then su vscode -c "umask 0002 && . /usr/local/sdkman/bin/sdkman-init.sh && sdk install maven \"${MAVEN_VERSION}\""; fi \
- && if [ "${INSTALL_GRADLE}" = "true" ]; then su vscode -c "umask 0002 && . /usr/local/sdkman/bin/sdkman-init.sh && sdk install gradle \"${GRADLE_VERSION}\""; fi
-
-# [Choice] Node.js version: none, lts/*, 16, 14, 12, 10
-ARG NODE_VERSION="none"
-RUN if [ "${NODE_VERSION}" != "none" ]; then su vscode -c "umask 0002 && . /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi
-
-# [Optional] Uncomment this section to install additional OS packages.
-# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
-# && apt-get -y install --no-install-recommends
-
-# [Optional] Uncomment this line to install global node packages.
+# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.238.0/containers/java/.devcontainer/base.Dockerfile
+
+# [Choice] Java version (use -bullseye variants on local arm64/Apple Silicon): 11, 17, 11-bullseye, 17-bullseye, 11-buster, 17-buster
+ARG VARIANT="21-bullseye"
+FROM mcr.microsoft.com/vscode/devcontainers/java:1.1.0-${VARIANT}
+
+# [Option] Install Maven
+ARG INSTALL_MAVEN="false"
+ARG MAVEN_VERSION=""
+# [Option] Install Gradle
+ARG INSTALL_GRADLE="false"
+ARG GRADLE_VERSION=""
+RUN if [ "${INSTALL_MAVEN}" = "true" ]; then su vscode -c "umask 0002 && . /usr/local/sdkman/bin/sdkman-init.sh && sdk install maven \"${MAVEN_VERSION}\""; fi \
+ && if [ "${INSTALL_GRADLE}" = "true" ]; then su vscode -c "umask 0002 && . /usr/local/sdkman/bin/sdkman-init.sh && sdk install gradle \"${GRADLE_VERSION}\""; fi
+
+# [Choice] Node.js version: none, lts/*, 16, 14, 12, 10
+ARG NODE_VERSION="none"
+RUN if [ "${NODE_VERSION}" != "none" ]; then su vscode -c "umask 0002 && . /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi
+
+# [Optional] Uncomment this section to install additional OS packages.
+# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
+# && apt-get -y install --no-install-recommends
+
+# [Optional] Uncomment this line to install global node packages.
# RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g " 2>&1
\ No newline at end of file
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index fdc7cdbd25f9..91342ffa80f6 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -1,47 +1,47 @@
-// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
-// https://github.com/microsoft/vscode-dev-containers/tree/v0.238.0/containers/java
-{
- "name": "Java",
- "build": {
- "dockerfile": "Dockerfile",
- "args": {
- // Update the VARIANT arg to pick a Java version: 11, 17
- // Append -bullseye or -buster to pin to an OS version.
- // Use the -bullseye variants on local arm64/Apple Silicon.
- "VARIANT": "21-bullseye",
- // Options
- "INSTALL_MAVEN": "true",
- "INSTALL_GRADLE": "true",
- "NODE_VERSION": "lts/*"
- }
- },
-
- // Configure tool-specific properties.
- "customizations": {
- // Configure properties specific to VS Code.
- "vscode": {
- // Set *default* container specific settings.json values on container create.
- "settings": {
- },
-
- // Add the IDs of extensions you want installed when the container is created.
- "extensions": [
- "vscjava.vscode-java-pack",
- "GitHub.copilot",
- ]
- }
- },
-
- // Use 'forwardPorts' to make a list of ports inside the container available locally.
- // "forwardPorts": [],
-
- // Use 'postCreateCommand' to run commands after the container is created.
- "postCreateCommand": "java -version",
-
- // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
- "remoteUser": "vscode",
- "features": {
- "git": "os-provided",
- "github-cli": "latest"
- }
-}
+// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
+// https://github.com/microsoft/vscode-dev-containers/tree/v0.238.0/containers/java
+{
+ "name": "Java",
+ "build": {
+ "dockerfile": "Dockerfile",
+ "args": {
+ // Update the VARIANT arg to pick a Java version: 11, 17
+ // Append -bullseye or -buster to pin to an OS version.
+ // Use the -bullseye variants on local arm64/Apple Silicon.
+ "VARIANT": "21-bullseye",
+ // Options
+ "INSTALL_MAVEN": "true",
+ "INSTALL_GRADLE": "true",
+ "NODE_VERSION": "lts/*"
+ }
+ },
+
+ // Configure tool-specific properties.
+ "customizations": {
+ // Configure properties specific to VS Code.
+ "vscode": {
+ // Set *default* container specific settings.json values on container create.
+ "settings": {
+ },
+
+ // Add the IDs of extensions you want installed when the container is created.
+ "extensions": [
+ "vscjava.vscode-java-pack",
+ "GitHub.copilot",
+ ]
+ }
+ },
+
+ // Use 'forwardPorts' to make a list of ports inside the container available locally.
+ // "forwardPorts": [],
+
+ // Use 'postCreateCommand' to run commands after the container is created.
+ "postCreateCommand": "java -version",
+
+ // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
+ "remoteUser": "vscode",
+ "features": {
+ "git": "os-provided",
+ "github-cli": "latest"
+ }
+}
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index f41af80a3459..faf8d48aba31 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1 +1 @@
-* @DenizAltunkapan @yanglbme @alxkm
+* @DenizAltunkapan @yanglbme @alxkm
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
index 9c906c381608..1a056ca8898f 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -1,45 +1,45 @@
-name: "Bug report"
-description: "Create a report to help us improve"
-title: "[BUG] "
-labels: ["bug"]
-body:
- - type: textarea
- id: description
- attributes:
- label: "Description"
- description: "A clear and concise description of what the bug is."
- validations:
- required: true
- - type: textarea
- id: steps
- attributes:
- label: "Steps to reproduce"
- description: "Steps to reproduce the behavior (if applicable)"
- placeholder: |
- 1. Go to '...'
- 2. Click on '....'
- 3. Scroll down to '....'
- 4. See error
- validations:
- required: false
- - type: textarea
- id: exceptedbhv
- attributes:
- label: "Excepted behavior"
- description: "A clear and concise description of what you expected to happen."
- validations:
- required: true
- - type: textarea
- id: screenshots
- attributes:
- label: "Screenshots"
- description: "If applicable, add screenshots to help explain your problem."
- validations:
- required: false
- - type: textarea
- id: context
- attributes:
- label: "Additional context"
- description: "Is there anything else we should know about this bug report?"
- validations:
- required: false
+name: "Bug report"
+description: "Create a report to help us improve"
+title: "[BUG] "
+labels: ["bug"]
+body:
+ - type: textarea
+ id: description
+ attributes:
+ label: "Description"
+ description: "A clear and concise description of what the bug is."
+ validations:
+ required: true
+ - type: textarea
+ id: steps
+ attributes:
+ label: "Steps to reproduce"
+ description: "Steps to reproduce the behavior (if applicable)"
+ placeholder: |
+ 1. Go to '...'
+ 2. Click on '....'
+ 3. Scroll down to '....'
+ 4. See error
+ validations:
+ required: false
+ - type: textarea
+ id: exceptedbhv
+ attributes:
+ label: "Excepted behavior"
+ description: "A clear and concise description of what you expected to happen."
+ validations:
+ required: true
+ - type: textarea
+ id: screenshots
+ attributes:
+ label: "Screenshots"
+ description: "If applicable, add screenshots to help explain your problem."
+ validations:
+ required: false
+ - type: textarea
+ id: context
+ attributes:
+ label: "Additional context"
+ description: "Is there anything else we should know about this bug report?"
+ validations:
+ required: false
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
index 875cc4efab00..69bdb64839ac 100644
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -1,5 +1,5 @@
-blank_issues_enabled: false
-contact_links:
- - name: Discord community
- url: https://the-algorithms.com/discord/
- about: Have any questions or found any bugs? Please contact us via Discord
+blank_issues_enabled: false
+contact_links:
+ - name: Discord community
+ url: https://the-algorithms.com/discord/
+ about: Have any questions or found any bugs? Please contact us via Discord
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml
index 98ff394158be..2bb31371e16c 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.yml
+++ b/.github/ISSUE_TEMPLATE/feature_request.yml
@@ -1,34 +1,34 @@
-name: "Feature Request"
-description: "Suggest an idea for this project"
-title: "[FEATURE REQUEST] "
-labels: ["enhancement"]
-body:
- - type: textarea
- id: description
- attributes:
- label: What would you like to Propose?
- description: Provide a clear and concise explanation of your Proposal.
- validations:
- required: true
- - type: markdown
- attributes:
- value: |
- For new implementations, please specify the name and problem statement for the algorithm.
- For algorithm enhancements, specify what needs to be changed and why. For example:
- - Adding tests.
- - Optimizing logic.
- - Refactoring the file and folders for better structure.
- - type: textarea
- id: needdetails
- attributes:
- label: "Issue details"
- description: "Write down all the issue/algorithm details description mentioned above."
- validations:
- required: true
- - type: textarea
- id: extrainfo
- attributes:
- label: "Additional Information"
- description: "Add any other information or screenshots about the request here."
- validations:
- required: false
+name: "Feature Request"
+description: "Suggest an idea for this project"
+title: "[FEATURE REQUEST] "
+labels: ["enhancement"]
+body:
+ - type: textarea
+ id: description
+ attributes:
+ label: What would you like to Propose?
+ description: Provide a clear and concise explanation of your Proposal.
+ validations:
+ required: true
+ - type: markdown
+ attributes:
+ value: |
+ For new implementations, please specify the name and problem statement for the algorithm.
+ For algorithm enhancements, specify what needs to be changed and why. For example:
+ - Adding tests.
+ - Optimizing logic.
+ - Refactoring the file and folders for better structure.
+ - type: textarea
+ id: needdetails
+ attributes:
+ label: "Issue details"
+ description: "Write down all the issue/algorithm details description mentioned above."
+ validations:
+ required: true
+ - type: textarea
+ id: extrainfo
+ attributes:
+ label: "Additional Information"
+ description: "Add any other information or screenshots about the request here."
+ validations:
+ required: false
diff --git a/.github/ISSUE_TEMPLATE/other.yml b/.github/ISSUE_TEMPLATE/other.yml
index bf8b29f481c8..3f568a39ac77 100644
--- a/.github/ISSUE_TEMPLATE/other.yml
+++ b/.github/ISSUE_TEMPLATE/other.yml
@@ -1,19 +1,19 @@
-name: Other
-description: Use this for any other issues. Do NOT create blank issues
-title: "[OTHER]"
-labels: ["awaiting triage"]
-body:
- - type: textarea
- id: issuedescription
- attributes:
- label: What would you like to share?
- description: Provide a clear and concise explanation of your issue.
- validations:
- required: true
- - type: textarea
- id: extrainfo
- attributes:
- label: Additional information
- description: Is there anything else we should know about this issue?
- validations:
- required: false
+name: Other
+description: Use this for any other issues. Do NOT create blank issues
+title: "[OTHER]"
+labels: ["awaiting triage"]
+body:
+ - type: textarea
+ id: issuedescription
+ attributes:
+ label: What would you like to share?
+ description: Provide a clear and concise explanation of your issue.
+ validations:
+ required: true
+ - type: textarea
+ id: extrainfo
+ attributes:
+ label: Additional information
+ description: Is there anything else we should know about this issue?
+ validations:
+ required: false
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 2e5622f7b51d..334b5191f31f 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -1,18 +1,18 @@
----
-version: 2
-updates:
- - package-ecosystem: "docker"
- directory: "/"
- schedule:
- interval: "weekly"
-
- - package-ecosystem: "github-actions"
- directory: "/.github/workflows/"
- schedule:
- interval: "daily"
-
- - package-ecosystem: "maven"
- directory: "/"
- schedule:
- interval: "daily"
-...
+---
+version: 2
+updates:
+ - package-ecosystem: "docker"
+ directory: "/"
+ schedule:
+ interval: "weekly"
+
+ - package-ecosystem: "github-actions"
+ directory: "/.github/workflows/"
+ schedule:
+ interval: "daily"
+
+ - package-ecosystem: "maven"
+ directory: "/"
+ schedule:
+ interval: "daily"
+...
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index 30b46bbf45b5..4875f83bb16b 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -1,17 +1,17 @@
-
-
-
-
-- [ ] I have read [CONTRIBUTING.md](https://github.com/TheAlgorithms/Java/blob/master/CONTRIBUTING.md).
-- [ ] This pull request is all my own work -- I have not plagiarized it.
-- [ ] All filenames are in PascalCase.
-- [ ] All functions and variable names follow Java naming conventions.
-- [ ] All new algorithms have a URL in their comments that points to Wikipedia or other similar explanations.
-- [ ] All new algorithms include a corresponding test class that validates their functionality.
-- [ ] All new code is formatted with `clang-format -i --style=file path/to/your/file.java`
+
+
+
+
+- [ ] I have read [CONTRIBUTING.md](https://github.com/TheAlgorithms/Java/blob/master/CONTRIBUTING.md).
+- [ ] This pull request is all my own work -- I have not plagiarized it.
+- [ ] All filenames are in PascalCase.
+- [ ] All functions and variable names follow Java naming conventions.
+- [ ] All new algorithms have a URL in their comments that points to Wikipedia or other similar explanations.
+- [ ] All new algorithms include a corresponding test class that validates their functionality.
+- [ ] All new code is formatted with `clang-format -i --style=file path/to/your/file.java`
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index c5f200c12836..5aea174001ad 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -1,40 +1,40 @@
-name: Build
-on: [push, pull_request]
-
-permissions:
- contents: read
-
-jobs:
- build:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v6
- - name: Set up JDK
- uses: actions/setup-java@v5
- with:
- java-version: 21
- distribution: 'temurin'
- - name: Build with Maven
- run: mvn --batch-mode --update-snapshots verify
- - name: Upload coverage to codecov (tokenless)
- if: >-
- github.event_name == 'pull_request' &&
- github.event.pull_request.head.repo.full_name != github.repository
- uses: codecov/codecov-action@v5
- with:
- fail_ci_if_error: true
- - name: Upload coverage to codecov (with token)
- if: >
- github.repository == 'TheAlgorithms/Java' &&
- (github.event_name != 'pull_request' ||
- github.event.pull_request.head.repo.full_name == github.repository)
- uses: codecov/codecov-action@v5
- with:
- token: ${{ secrets.CODECOV_TOKEN }}
- fail_ci_if_error: true
- - name: Checkstyle
- run: mvn checkstyle:check
- - name: SpotBugs
- run: mvn spotbugs:check
- - name: PMD
- run: mvn pmd:check
+name: Build
+on: [push, pull_request]
+
+permissions:
+ contents: read
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v6
+ - name: Set up JDK
+ uses: actions/setup-java@v5
+ with:
+ java-version: 21
+ distribution: 'temurin'
+ - name: Build with Maven
+ run: mvn --batch-mode --update-snapshots verify
+ - name: Upload coverage to codecov (tokenless)
+ if: >-
+ github.event_name == 'pull_request' &&
+ github.event.pull_request.head.repo.full_name != github.repository
+ uses: codecov/codecov-action@v5
+ with:
+ fail_ci_if_error: true
+ - name: Upload coverage to codecov (with token)
+ if: >
+ github.repository == 'TheAlgorithms/Java' &&
+ (github.event_name != 'pull_request' ||
+ github.event.pull_request.head.repo.full_name == github.repository)
+ uses: codecov/codecov-action@v5
+ with:
+ token: ${{ secrets.CODECOV_TOKEN }}
+ fail_ci_if_error: true
+ - name: Checkstyle
+ run: mvn checkstyle:check
+ - name: SpotBugs
+ run: mvn spotbugs:check
+ - name: PMD
+ run: mvn pmd:check
diff --git a/.github/workflows/clang-format-lint.yml b/.github/workflows/clang-format-lint.yml
index dc0c9754ed1b..4888d92e379b 100644
--- a/.github/workflows/clang-format-lint.yml
+++ b/.github/workflows/clang-format-lint.yml
@@ -1,19 +1,19 @@
-name: Clang format linter
-on:
- push: {}
- pull_request: {}
-
-permissions:
- contents: read
-
-jobs:
- build:
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@v6
- - uses: DoozyX/clang-format-lint-action@v0.20
- with:
- source: './src'
- extensions: 'java'
- clangFormatVersion: 16
+name: Clang format linter
+on:
+ push: {}
+ pull_request: {}
+
+permissions:
+ contents: read
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v6
+ - uses: DoozyX/clang-format-lint-action@v0.20
+ with:
+ source: './src'
+ extensions: 'java'
+ clangFormatVersion: 16
diff --git a/.github/workflows/close-failed-prs.yml b/.github/workflows/close-failed-prs.yml
index 6deea88f0daf..a75b532a7ad2 100644
--- a/.github/workflows/close-failed-prs.yml
+++ b/.github/workflows/close-failed-prs.yml
@@ -1,156 +1,156 @@
-name: Close stale PRs with failed workflows
-
-on:
- schedule:
- - cron: '0 3 * * *' # runs daily at 03:00 UTC
- workflow_dispatch:
-
-permissions:
- contents: read
- issues: write
- pull-requests: write
-
-jobs:
- close-stale:
- runs-on: ubuntu-latest
- steps:
- - name: Close stale PRs
- uses: actions/github-script@v8
- with:
- github-token: ${{ secrets.GITHUB_TOKEN }}
- script: |
- const mainBranches = ['main', 'master'];
- const cutoffDays = 14;
- const cutoff = new Date();
- cutoff.setDate(cutoff.getDate() - cutoffDays);
-
- console.log(`Checking PRs older than: ${cutoff.toISOString()}`);
-
- try {
- const { data: prs } = await github.rest.pulls.list({
- owner: context.repo.owner,
- repo: context.repo.repo,
- state: 'open',
- sort: 'updated',
- direction: 'asc',
- per_page: 100
- });
-
- console.log(`Found ${prs.length} open PRs to check`);
-
- for (const pr of prs) {
- try {
- const updated = new Date(pr.updated_at);
-
- if (updated > cutoff) {
- console.log(`⏩ Skipping PR #${pr.number} - updated recently`);
- continue;
- }
-
- console.log(`🔍 Checking PR #${pr.number}: "${pr.title}"`);
-
- // Get commits
- const commits = await github.paginate(github.rest.pulls.listCommits, {
- owner: context.repo.owner,
- repo: context.repo.repo,
- pull_number: pr.number,
- per_page: 100
- });
-
- const meaningfulCommits = commits.filter(c => {
- const msg = c.commit.message.toLowerCase();
- const date = new Date(c.commit.committer.date);
- const isMergeFromMain = mainBranches.some(branch =>
- msg.startsWith(`merge branch '${branch}'`) ||
- msg.includes(`merge remote-tracking branch '${branch}'`)
- );
-
- return !isMergeFromMain && date > cutoff;
- });
-
- // Get checks with error handling
- let hasFailedChecks = false;
- let allChecksCompleted = false;
- let hasChecks = false;
-
- try {
- const { data: checks } = await github.rest.checks.listForRef({
- owner: context.repo.owner,
- repo: context.repo.repo,
- ref: pr.head.sha
- });
-
- hasChecks = checks.check_runs.length > 0;
- hasFailedChecks = checks.check_runs.some(c => c.conclusion === 'failure');
- allChecksCompleted = checks.check_runs.every(c =>
- c.status === 'completed' || c.status === 'skipped'
- );
- } catch (error) {
- console.log(`⚠️ Could not fetch checks for PR #${pr.number}: ${error.message}`);
- }
-
- // Get workflow runs with error handling
- let hasFailedWorkflows = false;
- let allWorkflowsCompleted = false;
- let hasWorkflows = false;
-
- try {
- const { data: runs } = await github.rest.actions.listWorkflowRuns({
- owner: context.repo.owner,
- repo: context.repo.repo,
- head_sha: pr.head.sha,
- per_page: 50
- });
-
- hasWorkflows = runs.workflow_runs.length > 0;
- hasFailedWorkflows = runs.workflow_runs.some(r => r.conclusion === 'failure');
- allWorkflowsCompleted = runs.workflow_runs.every(r =>
- ['completed', 'skipped', 'cancelled'].includes(r.status)
- );
-
- console.log(`PR #${pr.number}: ${runs.workflow_runs.length} workflow runs found`);
-
- } catch (error) {
- console.log(`⚠️ Could not fetch workflow runs for PR #${pr.number}: ${error.message}`);
- }
-
- console.log(`PR #${pr.number}: ${meaningfulCommits.length} meaningful commits`);
- console.log(`Checks - has: ${hasChecks}, failed: ${hasFailedChecks}, completed: ${allChecksCompleted}`);
- console.log(`Workflows - has: ${hasWorkflows}, failed: ${hasFailedWorkflows}, completed: ${allWorkflowsCompleted}`);
-
- // Combine conditions - only consider if we actually have checks/workflows
- const hasAnyFailure = (hasChecks && hasFailedChecks) || (hasWorkflows && hasFailedWorkflows);
- const allCompleted = (!hasChecks || allChecksCompleted) && (!hasWorkflows || allWorkflowsCompleted);
-
- if (meaningfulCommits.length === 0 && hasAnyFailure && allCompleted) {
- console.log(`✅ Closing PR #${pr.number} (${pr.title})`);
-
- await github.rest.issues.createComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- issue_number: pr.number,
- body: `This pull request has been automatically closed because its workflows or checks failed and it has been inactive for more than ${cutoffDays} days. Please fix the workflows and reopen if you'd like to continue. Merging from main/master alone does not count as activity.`
- });
-
- await github.rest.pulls.update({
- owner: context.repo.owner,
- repo: context.repo.repo,
- pull_number: pr.number,
- state: 'closed'
- });
-
- console.log(`✅ Successfully closed PR #${pr.number}`);
- } else {
- console.log(`⏩ Not closing PR #${pr.number} - conditions not met`);
- }
-
- } catch (prError) {
- console.error(`❌ Error processing PR #${pr.number}: ${prError.message}`);
- continue;
- }
- }
-
- } catch (error) {
- console.error(`❌ Fatal error: ${error.message}`);
- throw error;
- }
+name: Close stale PRs with failed workflows
+
+on:
+ schedule:
+ - cron: '0 3 * * *' # runs daily at 03:00 UTC
+ workflow_dispatch:
+
+permissions:
+ contents: read
+ issues: write
+ pull-requests: write
+
+jobs:
+ close-stale:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Close stale PRs
+ uses: actions/github-script@v8
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const mainBranches = ['main', 'master'];
+ const cutoffDays = 14;
+ const cutoff = new Date();
+ cutoff.setDate(cutoff.getDate() - cutoffDays);
+
+ console.log(`Checking PRs older than: ${cutoff.toISOString()}`);
+
+ try {
+ const { data: prs } = await github.rest.pulls.list({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ state: 'open',
+ sort: 'updated',
+ direction: 'asc',
+ per_page: 100
+ });
+
+ console.log(`Found ${prs.length} open PRs to check`);
+
+ for (const pr of prs) {
+ try {
+ const updated = new Date(pr.updated_at);
+
+ if (updated > cutoff) {
+ console.log(`⏩ Skipping PR #${pr.number} - updated recently`);
+ continue;
+ }
+
+ console.log(`🔍 Checking PR #${pr.number}: "${pr.title}"`);
+
+ // Get commits
+ const commits = await github.paginate(github.rest.pulls.listCommits, {
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ pull_number: pr.number,
+ per_page: 100
+ });
+
+ const meaningfulCommits = commits.filter(c => {
+ const msg = c.commit.message.toLowerCase();
+ const date = new Date(c.commit.committer.date);
+ const isMergeFromMain = mainBranches.some(branch =>
+ msg.startsWith(`merge branch '${branch}'`) ||
+ msg.includes(`merge remote-tracking branch '${branch}'`)
+ );
+
+ return !isMergeFromMain && date > cutoff;
+ });
+
+ // Get checks with error handling
+ let hasFailedChecks = false;
+ let allChecksCompleted = false;
+ let hasChecks = false;
+
+ try {
+ const { data: checks } = await github.rest.checks.listForRef({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ ref: pr.head.sha
+ });
+
+ hasChecks = checks.check_runs.length > 0;
+ hasFailedChecks = checks.check_runs.some(c => c.conclusion === 'failure');
+ allChecksCompleted = checks.check_runs.every(c =>
+ c.status === 'completed' || c.status === 'skipped'
+ );
+ } catch (error) {
+ console.log(`⚠️ Could not fetch checks for PR #${pr.number}: ${error.message}`);
+ }
+
+ // Get workflow runs with error handling
+ let hasFailedWorkflows = false;
+ let allWorkflowsCompleted = false;
+ let hasWorkflows = false;
+
+ try {
+ const { data: runs } = await github.rest.actions.listWorkflowRuns({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ head_sha: pr.head.sha,
+ per_page: 50
+ });
+
+ hasWorkflows = runs.workflow_runs.length > 0;
+ hasFailedWorkflows = runs.workflow_runs.some(r => r.conclusion === 'failure');
+ allWorkflowsCompleted = runs.workflow_runs.every(r =>
+ ['completed', 'skipped', 'cancelled'].includes(r.status)
+ );
+
+ console.log(`PR #${pr.number}: ${runs.workflow_runs.length} workflow runs found`);
+
+ } catch (error) {
+ console.log(`⚠️ Could not fetch workflow runs for PR #${pr.number}: ${error.message}`);
+ }
+
+ console.log(`PR #${pr.number}: ${meaningfulCommits.length} meaningful commits`);
+ console.log(`Checks - has: ${hasChecks}, failed: ${hasFailedChecks}, completed: ${allChecksCompleted}`);
+ console.log(`Workflows - has: ${hasWorkflows}, failed: ${hasFailedWorkflows}, completed: ${allWorkflowsCompleted}`);
+
+ // Combine conditions - only consider if we actually have checks/workflows
+ const hasAnyFailure = (hasChecks && hasFailedChecks) || (hasWorkflows && hasFailedWorkflows);
+ const allCompleted = (!hasChecks || allChecksCompleted) && (!hasWorkflows || allWorkflowsCompleted);
+
+ if (meaningfulCommits.length === 0 && hasAnyFailure && allCompleted) {
+ console.log(`✅ Closing PR #${pr.number} (${pr.title})`);
+
+ await github.rest.issues.createComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number: pr.number,
+ body: `This pull request has been automatically closed because its workflows or checks failed and it has been inactive for more than ${cutoffDays} days. Please fix the workflows and reopen if you'd like to continue. Merging from main/master alone does not count as activity.`
+ });
+
+ await github.rest.pulls.update({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ pull_number: pr.number,
+ state: 'closed'
+ });
+
+ console.log(`✅ Successfully closed PR #${pr.number}`);
+ } else {
+ console.log(`⏩ Not closing PR #${pr.number} - conditions not met`);
+ }
+
+ } catch (prError) {
+ console.error(`❌ Error processing PR #${pr.number}: ${prError.message}`);
+ continue;
+ }
+ }
+
+ } catch (error) {
+ console.error(`❌ Fatal error: ${error.message}`);
+ throw error;
+ }
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index 152d0d766fd2..d8940ca29a3f 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -1,66 +1,66 @@
----
-name: "CodeQL"
-
-on:
- workflow_dispatch:
- push:
- branches:
- - master
- pull_request:
- schedule:
- - cron: '53 3 * * 0'
-
-jobs:
- analyzeJava:
- name: AnalyzeJava
- runs-on: 'ubuntu-latest'
- permissions:
- actions: read
- contents: read
- security-events: write
-
- steps:
- - name: Checkout repository
- uses: actions/checkout@v6
-
- - name: Set up JDK
- uses: actions/setup-java@v5
- with:
- java-version: 21
- distribution: 'temurin'
-
- - name: Initialize CodeQL
- uses: github/codeql-action/init@v4
- with:
- languages: 'java-kotlin'
-
- - name: Build
- run: mvn --batch-mode --update-snapshots verify
-
- - name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v4
- with:
- category: "/language:java-kotlin"
-
- analyzeActions:
- name: AnalyzeActions
- runs-on: 'ubuntu-latest'
- permissions:
- actions: read
- contents: read
- security-events: write
-
- steps:
- - name: Checkout repository
- uses: actions/checkout@v6
-
- - name: Initialize CodeQL
- uses: github/codeql-action/init@v4
- with:
- languages: 'actions'
-
- - name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v4
- with:
- category: "/language:actions"
-...
+---
+name: "CodeQL"
+
+on:
+ workflow_dispatch:
+ push:
+ branches:
+ - master
+ pull_request:
+ schedule:
+ - cron: '53 3 * * 0'
+
+jobs:
+ analyzeJava:
+ name: AnalyzeJava
+ runs-on: 'ubuntu-latest'
+ permissions:
+ actions: read
+ contents: read
+ security-events: write
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v6
+
+ - name: Set up JDK
+ uses: actions/setup-java@v5
+ with:
+ java-version: 21
+ distribution: 'temurin'
+
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@v4
+ with:
+ languages: 'java-kotlin'
+
+ - name: Build
+ run: mvn --batch-mode --update-snapshots verify
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@v4
+ with:
+ category: "/language:java-kotlin"
+
+ analyzeActions:
+ name: AnalyzeActions
+ runs-on: 'ubuntu-latest'
+ permissions:
+ actions: read
+ contents: read
+ security-events: write
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v6
+
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@v4
+ with:
+ languages: 'actions'
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@v4
+ with:
+ category: "/language:actions"
+...
diff --git a/.github/workflows/infer.yml b/.github/workflows/infer.yml
index 9d4dcf63000b..8089463b732d 100644
--- a/.github/workflows/infer.yml
+++ b/.github/workflows/infer.yml
@@ -1,64 +1,64 @@
----
-name: Infer
-
-'on':
- workflow_dispatch:
- push:
- branches:
- - master
- pull_request:
-
-permissions:
- contents: read
-
-jobs:
- run_infer:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v6
-
- - name: Set up JDK
- uses: actions/setup-java@v5
- with:
- java-version: 21
- distribution: 'temurin'
-
- - name: Set up OCaml
- uses: ocaml/setup-ocaml@v3
- with:
- ocaml-compiler: 5
-
- - name: Get current year/weak
- run: echo "year_week=$(date +'%Y_%U')" >> $GITHUB_ENV
-
- - name: Cache infer build
- id: cache-infer
- uses: actions/cache@v5
- with:
- path: infer
- key: ${{ runner.os }}-infer-${{ env.year_week }}
-
- - name: Build infer
- if: steps.cache-infer.outputs.cache-hit != 'true'
- run: |
- cd ..
- git clone https://github.com/facebook/infer.git
- cd infer
- git checkout 02c2c43b71e4c5110c0be841e66153942fda06c9
- ./build-infer.sh java
- cp -r infer ../Java
-
- - name: Add infer to PATH
- run: |
- echo "infer/bin" >> $GITHUB_PATH
-
- - name: Display infer version
- run: |
- which infer
- infer --version
-
- - name: Run infer
- run: |
- mvn clean
- infer --fail-on-issue --print-logs --no-progress-bar -- mvn test
-...
+---
+name: Infer
+
+'on':
+ workflow_dispatch:
+ push:
+ branches:
+ - master
+ pull_request:
+
+permissions:
+ contents: read
+
+jobs:
+ run_infer:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v6
+
+ - name: Set up JDK
+ uses: actions/setup-java@v5
+ with:
+ java-version: 21
+ distribution: 'temurin'
+
+ - name: Set up OCaml
+ uses: ocaml/setup-ocaml@v3
+ with:
+ ocaml-compiler: 5
+
+ - name: Get current year/weak
+ run: echo "year_week=$(date +'%Y_%U')" >> $GITHUB_ENV
+
+ - name: Cache infer build
+ id: cache-infer
+ uses: actions/cache@v5
+ with:
+ path: infer
+ key: ${{ runner.os }}-infer-${{ env.year_week }}
+
+ - name: Build infer
+ if: steps.cache-infer.outputs.cache-hit != 'true'
+ run: |
+ cd ..
+ git clone https://github.com/facebook/infer.git
+ cd infer
+ git checkout 02c2c43b71e4c5110c0be841e66153942fda06c9
+ ./build-infer.sh java
+ cp -r infer ../Java
+
+ - name: Add infer to PATH
+ run: |
+ echo "infer/bin" >> $GITHUB_PATH
+
+ - name: Display infer version
+ run: |
+ which infer
+ infer --version
+
+ - name: Run infer
+ run: |
+ mvn clean
+ infer --fail-on-issue --print-logs --no-progress-bar -- mvn test
+...
diff --git a/.github/workflows/project_structure.yml b/.github/workflows/project_structure.yml
index 5aadc6353791..80f26e7a0803 100644
--- a/.github/workflows/project_structure.yml
+++ b/.github/workflows/project_structure.yml
@@ -1,25 +1,25 @@
----
-name: ProjectStructure
-
-'on':
- workflow_dispatch:
- push:
- branches:
- - master
- pull_request:
-
-permissions:
- contents: read
-
-jobs:
- check_structure:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v6
- - uses: actions/setup-python@v6
- with:
- python-version: '3.13'
-
- - name: Check project structure
- run: python3 .github/workflows/scripts/check_structure.py
-...
+---
+name: ProjectStructure
+
+'on':
+ workflow_dispatch:
+ push:
+ branches:
+ - master
+ pull_request:
+
+permissions:
+ contents: read
+
+jobs:
+ check_structure:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v6
+ - uses: actions/setup-python@v6
+ with:
+ python-version: '3.13'
+
+ - name: Check project structure
+ run: python3 .github/workflows/scripts/check_structure.py
+...
diff --git a/.github/workflows/scripts/check_structure.py b/.github/workflows/scripts/check_structure.py
index 914f64369207..ef8fba6402c4 100644
--- a/.github/workflows/scripts/check_structure.py
+++ b/.github/workflows/scripts/check_structure.py
@@ -1,27 +1,27 @@
-import pathlib
-import sys
-
-
-def _is_java_file_properly_located(java_file: pathlib.Path) -> bool:
- main_parents = java_file.parent.parents
- return (
- pathlib.Path("src/main/java/com/thealgorithms/") in main_parents
- or pathlib.Path("src/test/java/com/thealgorithms/") in main_parents
- )
-
-
-def _find_misplaced_java_files() -> list[pathlib.Path]:
- return [
- java_file
- for java_file in pathlib.Path(".").rglob("*.java")
- if not _is_java_file_properly_located(java_file)
- ]
-
-
-if __name__ == "__main__":
- misplaced_files = _find_misplaced_java_files()
- if misplaced_files:
- print("The following java files are not located in the correct directory:")
- for _ in misplaced_files:
- print(_)
- sys.exit(1)
+import pathlib
+import sys
+
+
+def _is_java_file_properly_located(java_file: pathlib.Path) -> bool:
+ main_parents = java_file.parent.parents
+ return (
+ pathlib.Path("src/main/java/com/thealgorithms/") in main_parents
+ or pathlib.Path("src/test/java/com/thealgorithms/") in main_parents
+ )
+
+
+def _find_misplaced_java_files() -> list[pathlib.Path]:
+ return [
+ java_file
+ for java_file in pathlib.Path(".").rglob("*.java")
+ if not _is_java_file_properly_located(java_file)
+ ]
+
+
+if __name__ == "__main__":
+ misplaced_files = _find_misplaced_java_files()
+ if misplaced_files:
+ print("The following java files are not located in the correct directory:")
+ for _ in misplaced_files:
+ print(_)
+ sys.exit(1)
diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml
index bb613daf8f1d..3df7381ea0fc 100644
--- a/.github/workflows/stale.yml
+++ b/.github/workflows/stale.yml
@@ -1,23 +1,23 @@
-name: 'Close stale issues and PRs'
-on:
- schedule:
- - cron: '0 0 * * *'
-permissions:
- contents: read
-jobs:
- stale:
- permissions:
- issues: write
- pull-requests: write
- runs-on: ubuntu-latest
- steps:
- - uses: actions/stale@v10
- with:
- stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contribution!'
- close-issue-message: 'Please reopen this issue once you have made the required changes. If you need help, feel free to ask in our [Discord](https://the-algorithms.com/discord) server or ping one of the maintainers here. Thank you for your contribution!'
- stale-pr-message: 'This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contribution!'
- close-pr-message: 'Please reopen this pull request once you have made the required changes. If you need help, feel free to ask in our [Discord](https://the-algorithms.com/discord) server or ping one of the maintainers here. Thank you for your contribution!'
- exempt-issue-labels: 'dont-close'
- exempt-pr-labels: 'dont-close'
- days-before-stale: 30
- days-before-close: 7
+name: 'Close stale issues and PRs'
+on:
+ schedule:
+ - cron: '0 0 * * *'
+permissions:
+ contents: read
+jobs:
+ stale:
+ permissions:
+ issues: write
+ pull-requests: write
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/stale@v10
+ with:
+ stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contribution!'
+ close-issue-message: 'Please reopen this issue once you have made the required changes. If you need help, feel free to ask in our [Discord](https://the-algorithms.com/discord) server or ping one of the maintainers here. Thank you for your contribution!'
+ stale-pr-message: 'This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contribution!'
+ close-pr-message: 'Please reopen this pull request once you have made the required changes. If you need help, feel free to ask in our [Discord](https://the-algorithms.com/discord) server or ping one of the maintainers here. Thank you for your contribution!'
+ exempt-issue-labels: 'dont-close'
+ exempt-pr-labels: 'dont-close'
+ days-before-stale: 30
+ days-before-close: 7
diff --git a/.github/workflows/update-directorymd.yml b/.github/workflows/update-directorymd.yml
index 1cfee6e36e4e..baed744616e6 100644
--- a/.github/workflows/update-directorymd.yml
+++ b/.github/workflows/update-directorymd.yml
@@ -1,44 +1,44 @@
-name: Generate Directory Markdown
-
-on:
- push:
- branches: [master]
- workflow_dispatch:
-
-permissions:
- contents: write
- pull-requests: write
-
-jobs:
- generate-directory:
- runs-on: ubuntu-latest
- steps:
- - name: Checkout Repository
- uses: actions/checkout@v6
- with:
- persist-credentials: false
-
- - name: Run Directory Tree Generator
- uses: DenizAltunkapan/directory-tree-generator@v2
- with:
- path: src
- extensions: .java
- show-extensions: false
-
- - name: Commit changes
- run: |
- git config --global user.name "$GITHUB_ACTOR"
- git config --global user.email "$GITHUB_ACTOR@users.noreply.github.com"
- git add DIRECTORY.md
- git diff --cached --quiet || git commit -m "Update DIRECTORY.md"
-
- - name: Create Pull Request
- uses: peter-evans/create-pull-request@v8
- with:
- token: ${{ secrets.REPO_SCOPED_TOKEN }}
- branch: update-directory
- base: master
- title: "Update DIRECTORY.md"
- body: "Automatically generated update of the directory tree."
- commit-message: "Update DIRECTORY.md"
- draft: false
+name: Generate Directory Markdown
+
+on:
+ push:
+ branches: [master]
+ workflow_dispatch:
+
+permissions:
+ contents: write
+ pull-requests: write
+
+jobs:
+ generate-directory:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@v6
+ with:
+ persist-credentials: false
+
+ - name: Run Directory Tree Generator
+ uses: DenizAltunkapan/directory-tree-generator@v2
+ with:
+ path: src
+ extensions: .java
+ show-extensions: false
+
+ - name: Commit changes
+ run: |
+ git config --global user.name "$GITHUB_ACTOR"
+ git config --global user.email "$GITHUB_ACTOR@users.noreply.github.com"
+ git add DIRECTORY.md
+ git diff --cached --quiet || git commit -m "Update DIRECTORY.md"
+
+ - name: Create Pull Request
+ uses: peter-evans/create-pull-request@v8
+ with:
+ token: ${{ secrets.REPO_SCOPED_TOKEN }}
+ branch: update-directory
+ base: master
+ title: "Update DIRECTORY.md"
+ body: "Automatically generated update of the directory tree."
+ commit-message: "Update DIRECTORY.md"
+ draft: false
diff --git a/.gitignore b/.gitignore
index eb9d33c78a33..14c83839ebef 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,46 +1,46 @@
-/gradle/wrapper/gradle-wrapper.properties
-
-##----------Android----------
-*.apk
-*.ap_
-*.dex
-*.class
-bin/
-gen/
-build/
-out/
-
-# Ignoring Gradle build artifacts and project files
-##----------Gradle----------
-.gradle/
-gradle-app.setting
-!gradle-wrapper.jar
-build/
-
-# Ignoring Maven build artifacts and project files
-##----------Maven----------
-*.classpath
-*.project
-*.settings
-/target/
-local.properties
-
-# Ignoring IntelliJ IDEA project files and configurations
-##----------IDEA----------
-*.iml
-.idea/
-*.ipr
-*.iws
-
-# Ignoring Android Studio Navigation editor temporary files
-.navigation/
-
-# Ignoring common system and editor-generated files
-##----------Other----------
-*~
-.DS_Store
-gradle.properties
-.vscode
-*.log
-
-/infer-out/
+/gradle/wrapper/gradle-wrapper.properties
+
+##----------Android----------
+*.apk
+*.ap_
+*.dex
+*.class
+bin/
+gen/
+build/
+out/
+
+# Ignoring Gradle build artifacts and project files
+##----------Gradle----------
+.gradle/
+gradle-app.setting
+!gradle-wrapper.jar
+build/
+
+# Ignoring Maven build artifacts and project files
+##----------Maven----------
+*.classpath
+*.project
+*.settings
+/target/
+local.properties
+
+# Ignoring IntelliJ IDEA project files and configurations
+##----------IDEA----------
+*.iml
+.idea/
+*.ipr
+*.iws
+
+# Ignoring Android Studio Navigation editor temporary files
+.navigation/
+
+# Ignoring common system and editor-generated files
+##----------Other----------
+*~
+.DS_Store
+gradle.properties
+.vscode
+*.log
+
+/infer-out/
diff --git a/.gitpod.dockerfile b/.gitpod.dockerfile
index a8951da7de26..7eef241abddd 100644
--- a/.gitpod.dockerfile
+++ b/.gitpod.dockerfile
@@ -1,22 +1,22 @@
-FROM gitpod/workspace-java-21:2025-11-14-10-05-32
-
-ENV LLVM_SCRIPT="tmp_llvm.sh"
-
-RUN test ! -f "$LLVM_SCRIPT" \
- && wget https://apt.llvm.org/llvm.sh -O "$LLVM_SCRIPT" \
- && chmod +x "$LLVM_SCRIPT"
-
-USER root
-
-RUN ./"$LLVM_SCRIPT" 16 \
- && apt-get update \
- && apt-get install -y --no-install-recommends \
- clang-format-16=1:16.0.6~++20231112100510+7cbf1a259152-1~exp1~20231112100554.106 \
- && apt-get clean \
- && rm -rf /var/lib/apt/lists/*
-
-RUN ln -s "$(command -v clang-format-16)" "/usr/bin/clang-format"
-
-USER gitpod
-
-RUN rm "$LLVM_SCRIPT"
+FROM gitpod/workspace-java-21:2025-11-14-10-05-32
+
+ENV LLVM_SCRIPT="tmp_llvm.sh"
+
+RUN test ! -f "$LLVM_SCRIPT" \
+ && wget https://apt.llvm.org/llvm.sh -O "$LLVM_SCRIPT" \
+ && chmod +x "$LLVM_SCRIPT"
+
+USER root
+
+RUN ./"$LLVM_SCRIPT" 16 \
+ && apt-get update \
+ && apt-get install -y --no-install-recommends \
+ clang-format-16=1:16.0.6~++20231112100510+7cbf1a259152-1~exp1~20231112100554.106 \
+ && apt-get clean \
+ && rm -rf /var/lib/apt/lists/*
+
+RUN ln -s "$(command -v clang-format-16)" "/usr/bin/clang-format"
+
+USER gitpod
+
+RUN rm "$LLVM_SCRIPT"
diff --git a/.gitpod.yml b/.gitpod.yml
index 21d69f6e2122..48f92da25f6c 100644
--- a/.gitpod.yml
+++ b/.gitpod.yml
@@ -1,13 +1,13 @@
----
-image:
- file: .gitpod.dockerfile
-
-tasks:
- - init: |
- mvn dependency:resolve
- mvn compile
-
-vscode:
- extensions:
- - xaver.clang-format
-
+---
+image:
+ file: .gitpod.dockerfile
+
+tasks:
+ - init: |
+ mvn dependency:resolve
+ mvn compile
+
+vscode:
+ extensions:
+ - xaver.clang-format
+
diff --git a/.inferconfig b/.inferconfig
index 239172177b38..39d0f95ab109 100644
--- a/.inferconfig
+++ b/.inferconfig
@@ -1,29 +1,29 @@
-{
- "report-block-list-path-regex": [
- "src/main/java/com/thealgorithms/ciphers/a5/CompositeLFSR.java",
- "src/main/java/com/thealgorithms/compression/ArithmeticCoding.java",
- "src/main/java/com/thealgorithms/datastructures/caches/FIFOCache.java",
- "src/main/java/com/thealgorithms/datastructures/crdt/GCounter.java",
- "src/main/java/com/thealgorithms/datastructures/crdt/PNCounter.java",
- "src/main/java/com/thealgorithms/datastructures/graphs/KahnsAlgorithm.java",
- "src/main/java/com/thealgorithms/datastructures/heaps/GenericHeap.java",
- "src/main/java/com/thealgorithms/datastructures/lists/DoublyLinkedList.java",
- "src/main/java/com/thealgorithms/datastructures/trees/CreateBinaryTreeFromInorderPreorder.java",
- "src/main/java/com/thealgorithms/divideandconquer/ClosestPair.java",
- "src/main/java/com/thealgorithms/dynamicprogramming/DamerauLevenshteinDistance.java",
- "src/main/java/com/thealgorithms/dynamicprogramming/Fibonacci.java",
- "src/main/java/com/thealgorithms/maths/SimpsonIntegration.java",
- "src/main/java/com/thealgorithms/others/Dijkstra.java",
- "src/main/java/com/thealgorithms/sorts/TopologicalSort.java",
- "src/main/java/com/thealgorithms/strings/AhoCorasick.java",
- "src/test/java/com/thealgorithms/compression/ShannonFanoTest.java",
- "src/test/java/com/thealgorithms/datastructures/caches/LRUCacheTest.java",
- "src/test/java/com/thealgorithms/datastructures/lists/SkipListTest.java",
- "src/test/java/com/thealgorithms/datastructures/trees/KDTreeTest.java",
- "src/test/java/com/thealgorithms/datastructures/trees/LazySegmentTreeTest.java",
- "src/test/java/com/thealgorithms/others/HuffmanTest.java",
- "src/test/java/com/thealgorithms/searches/QuickSelectTest.java",
- "src/test/java/com/thealgorithms/stacks/PostfixToInfixTest.java",
- "src/test/java/com/thealgorithms/strings/HorspoolSearchTest.java"
- ]
-}
+{
+ "report-block-list-path-regex": [
+ "src/main/java/com/thealgorithms/ciphers/a5/CompositeLFSR.java",
+ "src/main/java/com/thealgorithms/compression/ArithmeticCoding.java",
+ "src/main/java/com/thealgorithms/datastructures/caches/FIFOCache.java",
+ "src/main/java/com/thealgorithms/datastructures/crdt/GCounter.java",
+ "src/main/java/com/thealgorithms/datastructures/crdt/PNCounter.java",
+ "src/main/java/com/thealgorithms/datastructures/graphs/KahnsAlgorithm.java",
+ "src/main/java/com/thealgorithms/datastructures/heaps/GenericHeap.java",
+ "src/main/java/com/thealgorithms/datastructures/lists/DoublyLinkedList.java",
+ "src/main/java/com/thealgorithms/datastructures/trees/CreateBinaryTreeFromInorderPreorder.java",
+ "src/main/java/com/thealgorithms/divideandconquer/ClosestPair.java",
+ "src/main/java/com/thealgorithms/dynamicprogramming/DamerauLevenshteinDistance.java",
+ "src/main/java/com/thealgorithms/dynamicprogramming/Fibonacci.java",
+ "src/main/java/com/thealgorithms/maths/SimpsonIntegration.java",
+ "src/main/java/com/thealgorithms/others/Dijkstra.java",
+ "src/main/java/com/thealgorithms/sorts/TopologicalSort.java",
+ "src/main/java/com/thealgorithms/strings/AhoCorasick.java",
+ "src/test/java/com/thealgorithms/compression/ShannonFanoTest.java",
+ "src/test/java/com/thealgorithms/datastructures/caches/LRUCacheTest.java",
+ "src/test/java/com/thealgorithms/datastructures/lists/SkipListTest.java",
+ "src/test/java/com/thealgorithms/datastructures/trees/KDTreeTest.java",
+ "src/test/java/com/thealgorithms/datastructures/trees/LazySegmentTreeTest.java",
+ "src/test/java/com/thealgorithms/others/HuffmanTest.java",
+ "src/test/java/com/thealgorithms/searches/QuickSelectTest.java",
+ "src/test/java/com/thealgorithms/stacks/PostfixToInfixTest.java",
+ "src/test/java/com/thealgorithms/strings/HorspoolSearchTest.java"
+ ]
+}
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index f2f8dd9ffdea..ddd2340ca67c 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,31 +1,31 @@
-## How to contribute?
-
-NOTE: *We DO NOT add leetcode problems. They are just applications of basic principles that can be found in other algorithms included in the repository.*
-
-### Did you find a bug?
-
-**Ensure the bug was not already reported** by searching on GitHub under [Project Issues](https://github.com/TheAlgorithms/Java/issues).
- - If it is mentioned in the issues and you want to fix it, [fork](https://github.com/TheAlgorithms/Java/fork) the repository and submit your implementation in a pull request. The project maintainers will evaluate it.
- - If the bug is **NOT** mentioned in the issues, [open a new issue](https://github.com/TheAlgorithms/Java/issues/new). Be sure to include a **title**, a clear **description** and a **test case** demonstrating the expected behavior that is not occurring.
-
-NOTE: *Please avoid opening issues asking to be "assigned" to a particular algorithm. This merely creates unnecessary noise for maintainers. Instead, please submit your implementation in a pull request and project maintainers will evaluate it.*
-
-
-
-### Do you want to contribute to the documentation?
- - [Fork](https://github.com/TheAlgorithms/Java/fork) the repository and make necessary changes.
- - Create a pull request.
- - It will be put under review for approval.
- - If approved, the requested changes will be merged to the repository.
-
-### Do you want to add a new feature?
-
-- [Open a new issue](https://github.com/TheAlgorithms/Java/issues/new).
-- Be sure to include a **title**, a clear **description** and a **test case** demonstrating the new feature you want to add to the project.
-
-
-### Do you have questions about the source code?
-
-- Ask any question about how to use the repository in the [TheAlgorithms room in GITTER](https://gitter.im/TheAlgorithms/community?source=orgpage#) or [open a new issue](https://github.com/TheAlgorithms/Java/issues/new)
-
+## How to contribute?
+
+NOTE: *We DO NOT add leetcode problems. They are just applications of basic principles that can be found in other algorithms included in the repository.*
+
+### Did you find a bug?
+
+**Ensure the bug was not already reported** by searching on GitHub under [Project Issues](https://github.com/TheAlgorithms/Java/issues).
+ - If it is mentioned in the issues and you want to fix it, [fork](https://github.com/TheAlgorithms/Java/fork) the repository and submit your implementation in a pull request. The project maintainers will evaluate it.
+ - If the bug is **NOT** mentioned in the issues, [open a new issue](https://github.com/TheAlgorithms/Java/issues/new). Be sure to include a **title**, a clear **description** and a **test case** demonstrating the expected behavior that is not occurring.
+
+NOTE: *Please avoid opening issues asking to be "assigned" to a particular algorithm. This merely creates unnecessary noise for maintainers. Instead, please submit your implementation in a pull request and project maintainers will evaluate it.*
+
+
+
+### Do you want to contribute to the documentation?
+ - [Fork](https://github.com/TheAlgorithms/Java/fork) the repository and make necessary changes.
+ - Create a pull request.
+ - It will be put under review for approval.
+ - If approved, the requested changes will be merged to the repository.
+
+### Do you want to add a new feature?
+
+- [Open a new issue](https://github.com/TheAlgorithms/Java/issues/new).
+- Be sure to include a **title**, a clear **description** and a **test case** demonstrating the new feature you want to add to the project.
+
+
+### Do you have questions about the source code?
+
+- Ask any question about how to use the repository in the [TheAlgorithms room in GITTER](https://gitter.im/TheAlgorithms/community?source=orgpage#) or [open a new issue](https://github.com/TheAlgorithms/Java/issues/new)
+
:+1::tada: That's all you need to know about the process now it's your turn to help us improve the repository, thank you again! :+1::tada:
\ No newline at end of file
diff --git a/DIRECTORY.md b/DIRECTORY.md
index 585c634c3429..1d1c73203fcf 100644
--- a/DIRECTORY.md
+++ b/DIRECTORY.md
@@ -1,1605 +1,1605 @@
-# Project Structure
-
-## src
-
-- 📁 **main**
- - 📁 **java**
- - 📁 **com**
- - 📁 **thealgorithms**
- - 📁 **audiofilters**
- - 📄 [EMAFilter](src/main/java/com/thealgorithms/audiofilters/EMAFilter.java)
- - 📄 [IIRFilter](src/main/java/com/thealgorithms/audiofilters/IIRFilter.java)
- - 📁 **backtracking**
- - 📄 [AllPathsFromSourceToTarget](src/main/java/com/thealgorithms/backtracking/AllPathsFromSourceToTarget.java)
- - 📄 [ArrayCombination](src/main/java/com/thealgorithms/backtracking/ArrayCombination.java)
- - 📄 [Combination](src/main/java/com/thealgorithms/backtracking/Combination.java)
- - 📄 [CombinationSum](src/main/java/com/thealgorithms/backtracking/CombinationSum.java)
- - 📄 [CrosswordSolver](src/main/java/com/thealgorithms/backtracking/CrosswordSolver.java)
- - 📄 [FloodFill](src/main/java/com/thealgorithms/backtracking/FloodFill.java)
- - 📄 [KnightsTour](src/main/java/com/thealgorithms/backtracking/KnightsTour.java)
- - 📄 [MColoring](src/main/java/com/thealgorithms/backtracking/MColoring.java)
- - 📄 [MazeRecursion](src/main/java/com/thealgorithms/backtracking/MazeRecursion.java)
- - 📄 [NQueens](src/main/java/com/thealgorithms/backtracking/NQueens.java)
- - 📄 [ParenthesesGenerator](src/main/java/com/thealgorithms/backtracking/ParenthesesGenerator.java)
- - 📄 [Permutation](src/main/java/com/thealgorithms/backtracking/Permutation.java)
- - 📄 [PowerSum](src/main/java/com/thealgorithms/backtracking/PowerSum.java)
- - 📄 [SubsequenceFinder](src/main/java/com/thealgorithms/backtracking/SubsequenceFinder.java)
- - 📄 [SudokuSolver](src/main/java/com/thealgorithms/backtracking/SudokuSolver.java)
- - 📄 [UniquePermutation](src/main/java/com/thealgorithms/backtracking/UniquePermutation.java)
- - 📄 [WordPatternMatcher](src/main/java/com/thealgorithms/backtracking/WordPatternMatcher.java)
- - 📄 [WordSearch](src/main/java/com/thealgorithms/backtracking/WordSearch.java)
- - 📁 **bitmanipulation**
- - 📄 [BcdConversion](src/main/java/com/thealgorithms/bitmanipulation/BcdConversion.java)
- - 📄 [BinaryPalindromeCheck](src/main/java/com/thealgorithms/bitmanipulation/BinaryPalindromeCheck.java)
- - 📄 [BitRotate](src/main/java/com/thealgorithms/bitmanipulation/BitRotate.java)
- - 📄 [BitSwap](src/main/java/com/thealgorithms/bitmanipulation/BitSwap.java)
- - 📄 [BitwiseGCD](src/main/java/com/thealgorithms/bitmanipulation/BitwiseGCD.java)
- - 📄 [BooleanAlgebraGates](src/main/java/com/thealgorithms/bitmanipulation/BooleanAlgebraGates.java)
- - 📄 [ClearLeftmostSetBit](src/main/java/com/thealgorithms/bitmanipulation/ClearLeftmostSetBit.java)
- - 📄 [CountBitsFlip](src/main/java/com/thealgorithms/bitmanipulation/CountBitsFlip.java)
- - 📄 [CountLeadingZeros](src/main/java/com/thealgorithms/bitmanipulation/CountLeadingZeros.java)
- - 📄 [CountSetBits](src/main/java/com/thealgorithms/bitmanipulation/CountSetBits.java)
- - 📄 [FindNthBit](src/main/java/com/thealgorithms/bitmanipulation/FindNthBit.java)
- - 📄 [FirstDifferentBit](src/main/java/com/thealgorithms/bitmanipulation/FirstDifferentBit.java)
- - 📄 [GenerateSubsets](src/main/java/com/thealgorithms/bitmanipulation/GenerateSubsets.java)
- - 📄 [GrayCodeConversion](src/main/java/com/thealgorithms/bitmanipulation/GrayCodeConversion.java)
- - 📄 [HammingDistance](src/main/java/com/thealgorithms/bitmanipulation/HammingDistance.java)
- - 📄 [HigherLowerPowerOfTwo](src/main/java/com/thealgorithms/bitmanipulation/HigherLowerPowerOfTwo.java)
- - 📄 [HighestSetBit](src/main/java/com/thealgorithms/bitmanipulation/HighestSetBit.java)
- - 📄 [IndexOfRightMostSetBit](src/main/java/com/thealgorithms/bitmanipulation/IndexOfRightMostSetBit.java)
- - 📄 [IsEven](src/main/java/com/thealgorithms/bitmanipulation/IsEven.java)
- - 📄 [IsPowerTwo](src/main/java/com/thealgorithms/bitmanipulation/IsPowerTwo.java)
- - 📄 [LowestSetBit](src/main/java/com/thealgorithms/bitmanipulation/LowestSetBit.java)
- - 📄 [ModuloPowerOfTwo](src/main/java/com/thealgorithms/bitmanipulation/ModuloPowerOfTwo.java)
- - 📄 [NextHigherSameBitCount](src/main/java/com/thealgorithms/bitmanipulation/NextHigherSameBitCount.java)
- - 📄 [NonRepeatingNumberFinder](src/main/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinder.java)
- - 📄 [NumberAppearingOddTimes](src/main/java/com/thealgorithms/bitmanipulation/NumberAppearingOddTimes.java)
- - 📄 [NumbersDifferentSigns](src/main/java/com/thealgorithms/bitmanipulation/NumbersDifferentSigns.java)
- - 📄 [OneBitDifference](src/main/java/com/thealgorithms/bitmanipulation/OneBitDifference.java)
- - 📄 [OnesComplement](src/main/java/com/thealgorithms/bitmanipulation/OnesComplement.java)
- - 📄 [ParityCheck](src/main/java/com/thealgorithms/bitmanipulation/ParityCheck.java)
- - 📄 [ReverseBits](src/main/java/com/thealgorithms/bitmanipulation/ReverseBits.java)
- - 📄 [SingleBitOperations](src/main/java/com/thealgorithms/bitmanipulation/SingleBitOperations.java)
- - 📄 [SingleElement](src/main/java/com/thealgorithms/bitmanipulation/SingleElement.java)
- - 📄 [SwapAdjacentBits](src/main/java/com/thealgorithms/bitmanipulation/SwapAdjacentBits.java)
- - 📄 [TwosComplement](src/main/java/com/thealgorithms/bitmanipulation/TwosComplement.java)
- - 📄 [Xs3Conversion](src/main/java/com/thealgorithms/bitmanipulation/Xs3Conversion.java)
- - 📁 **ciphers**
- - 📄 [ADFGVXCipher](src/main/java/com/thealgorithms/ciphers/ADFGVXCipher.java)
- - 📄 [AES](src/main/java/com/thealgorithms/ciphers/AES.java)
- - 📄 [AESEncryption](src/main/java/com/thealgorithms/ciphers/AESEncryption.java)
- - 📄 [AffineCipher](src/main/java/com/thealgorithms/ciphers/AffineCipher.java)
- - 📄 [AtbashCipher](src/main/java/com/thealgorithms/ciphers/AtbashCipher.java)
- - 📄 [Autokey](src/main/java/com/thealgorithms/ciphers/Autokey.java)
- - 📄 [BaconianCipher](src/main/java/com/thealgorithms/ciphers/BaconianCipher.java)
- - 📄 [Blowfish](src/main/java/com/thealgorithms/ciphers/Blowfish.java)
- - 📄 [Caesar](src/main/java/com/thealgorithms/ciphers/Caesar.java)
- - 📄 [ColumnarTranspositionCipher](src/main/java/com/thealgorithms/ciphers/ColumnarTranspositionCipher.java)
- - 📄 [DES](src/main/java/com/thealgorithms/ciphers/DES.java)
- - 📄 [DiffieHellman](src/main/java/com/thealgorithms/ciphers/DiffieHellman.java)
- - 📄 [ECC](src/main/java/com/thealgorithms/ciphers/ECC.java)
- - 📄 [HillCipher](src/main/java/com/thealgorithms/ciphers/HillCipher.java)
- - 📄 [MonoAlphabetic](src/main/java/com/thealgorithms/ciphers/MonoAlphabetic.java)
- - 📄 [OneTimePadCipher](src/main/java/com/thealgorithms/ciphers/OneTimePadCipher.java)
- - 📄 [PermutationCipher](src/main/java/com/thealgorithms/ciphers/PermutationCipher.java)
- - 📄 [PlayfairCipher](src/main/java/com/thealgorithms/ciphers/PlayfairCipher.java)
- - 📄 [Polybius](src/main/java/com/thealgorithms/ciphers/Polybius.java)
- - 📄 [ProductCipher](src/main/java/com/thealgorithms/ciphers/ProductCipher.java)
- - 📄 [RSA](src/main/java/com/thealgorithms/ciphers/RSA.java)
- - 📄 [RailFenceCipher](src/main/java/com/thealgorithms/ciphers/RailFenceCipher.java)
- - 📄 [SimpleSubCipher](src/main/java/com/thealgorithms/ciphers/SimpleSubCipher.java)
- - 📄 [Vigenere](src/main/java/com/thealgorithms/ciphers/Vigenere.java)
- - 📄 [XORCipher](src/main/java/com/thealgorithms/ciphers/XORCipher.java)
- - 📁 **a5**
- - 📄 [A5Cipher](src/main/java/com/thealgorithms/ciphers/a5/A5Cipher.java)
- - 📄 [A5KeyStreamGenerator](src/main/java/com/thealgorithms/ciphers/a5/A5KeyStreamGenerator.java)
- - 📄 [BaseLFSR](src/main/java/com/thealgorithms/ciphers/a5/BaseLFSR.java)
- - 📄 [CompositeLFSR](src/main/java/com/thealgorithms/ciphers/a5/CompositeLFSR.java)
- - 📄 [LFSR](src/main/java/com/thealgorithms/ciphers/a5/LFSR.java)
- - 📄 [Utils](src/main/java/com/thealgorithms/ciphers/a5/Utils.java)
- - 📁 **compression**
- - 📄 [ArithmeticCoding](src/main/java/com/thealgorithms/compression/ArithmeticCoding.java)
- - 📄 [BurrowsWheelerTransform](src/main/java/com/thealgorithms/compression/BurrowsWheelerTransform.java)
- - 📄 [LZ77](src/main/java/com/thealgorithms/compression/LZ77.java)
- - 📄 [LZ78](src/main/java/com/thealgorithms/compression/LZ78.java)
- - 📄 [LZW](src/main/java/com/thealgorithms/compression/LZW.java)
- - 📄 [MoveToFront](src/main/java/com/thealgorithms/compression/MoveToFront.java)
- - 📄 [RunLengthEncoding](src/main/java/com/thealgorithms/compression/RunLengthEncoding.java)
- - 📄 [ShannonFano](src/main/java/com/thealgorithms/compression/ShannonFano.java)
- - 📁 **conversions**
- - 📄 [AffineConverter](src/main/java/com/thealgorithms/conversions/AffineConverter.java)
- - 📄 [AnyBaseToAnyBase](src/main/java/com/thealgorithms/conversions/AnyBaseToAnyBase.java)
- - 📄 [AnyBaseToDecimal](src/main/java/com/thealgorithms/conversions/AnyBaseToDecimal.java)
- - 📄 [AnytoAny](src/main/java/com/thealgorithms/conversions/AnytoAny.java)
- - 📄 [Base64](src/main/java/com/thealgorithms/conversions/Base64.java)
- - 📄 [BinaryToDecimal](src/main/java/com/thealgorithms/conversions/BinaryToDecimal.java)
- - 📄 [BinaryToHexadecimal](src/main/java/com/thealgorithms/conversions/BinaryToHexadecimal.java)
- - 📄 [BinaryToOctal](src/main/java/com/thealgorithms/conversions/BinaryToOctal.java)
- - 📄 [CoordinateConverter](src/main/java/com/thealgorithms/conversions/CoordinateConverter.java)
- - 📄 [DecimalToAnyBase](src/main/java/com/thealgorithms/conversions/DecimalToAnyBase.java)
- - 📄 [DecimalToBinary](src/main/java/com/thealgorithms/conversions/DecimalToBinary.java)
- - 📄 [DecimalToHexadecimal](src/main/java/com/thealgorithms/conversions/DecimalToHexadecimal.java)
- - 📄 [DecimalToOctal](src/main/java/com/thealgorithms/conversions/DecimalToOctal.java)
- - 📄 [EndianConverter](src/main/java/com/thealgorithms/conversions/EndianConverter.java)
- - 📄 [HexToOct](src/main/java/com/thealgorithms/conversions/HexToOct.java)
- - 📄 [HexaDecimalToBinary](src/main/java/com/thealgorithms/conversions/HexaDecimalToBinary.java)
- - 📄 [HexaDecimalToDecimal](src/main/java/com/thealgorithms/conversions/HexaDecimalToDecimal.java)
- - 📄 [IPConverter](src/main/java/com/thealgorithms/conversions/IPConverter.java)
- - 📄 [IPv6Converter](src/main/java/com/thealgorithms/conversions/IPv6Converter.java)
- - 📄 [IntegerToEnglish](src/main/java/com/thealgorithms/conversions/IntegerToEnglish.java)
- - 📄 [IntegerToRoman](src/main/java/com/thealgorithms/conversions/IntegerToRoman.java)
- - 📄 [MorseCodeConverter](src/main/java/com/thealgorithms/conversions/MorseCodeConverter.java)
- - 📄 [NumberToWords](src/main/java/com/thealgorithms/conversions/NumberToWords.java)
- - 📄 [OctalToBinary](src/main/java/com/thealgorithms/conversions/OctalToBinary.java)
- - 📄 [OctalToDecimal](src/main/java/com/thealgorithms/conversions/OctalToDecimal.java)
- - 📄 [OctalToHexadecimal](src/main/java/com/thealgorithms/conversions/OctalToHexadecimal.java)
- - 📄 [PhoneticAlphabetConverter](src/main/java/com/thealgorithms/conversions/PhoneticAlphabetConverter.java)
- - 📄 [RgbHsvConversion](src/main/java/com/thealgorithms/conversions/RgbHsvConversion.java)
- - 📄 [RomanToInteger](src/main/java/com/thealgorithms/conversions/RomanToInteger.java)
- - 📄 [TemperatureConverter](src/main/java/com/thealgorithms/conversions/TemperatureConverter.java)
- - 📄 [TimeConverter](src/main/java/com/thealgorithms/conversions/TimeConverter.java)
- - 📄 [TurkishToLatinConversion](src/main/java/com/thealgorithms/conversions/TurkishToLatinConversion.java)
- - 📄 [UnitConversions](src/main/java/com/thealgorithms/conversions/UnitConversions.java)
- - 📄 [UnitsConverter](src/main/java/com/thealgorithms/conversions/UnitsConverter.java)
- - 📄 [WordsToNumber](src/main/java/com/thealgorithms/conversions/WordsToNumber.java)
- - 📁 **datastructures**
- - 📄 [Node](src/main/java/com/thealgorithms/datastructures/Node.java)
- - 📁 **bags**
- - 📄 [Bag](src/main/java/com/thealgorithms/datastructures/bags/Bag.java)
- - 📁 **bloomfilter**
- - 📄 [BloomFilter](src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java)
- - 📁 **buffers**
- - 📄 [CircularBuffer](src/main/java/com/thealgorithms/datastructures/buffers/CircularBuffer.java)
- - 📁 **caches**
- - 📄 [FIFOCache](src/main/java/com/thealgorithms/datastructures/caches/FIFOCache.java)
- - 📄 [LFUCache](src/main/java/com/thealgorithms/datastructures/caches/LFUCache.java)
- - 📄 [LIFOCache](src/main/java/com/thealgorithms/datastructures/caches/LIFOCache.java)
- - 📄 [LRUCache](src/main/java/com/thealgorithms/datastructures/caches/LRUCache.java)
- - 📄 [MRUCache](src/main/java/com/thealgorithms/datastructures/caches/MRUCache.java)
- - 📄 [RRCache](src/main/java/com/thealgorithms/datastructures/caches/RRCache.java)
- - 📁 **crdt**
- - 📄 [GCounter](src/main/java/com/thealgorithms/datastructures/crdt/GCounter.java)
- - 📄 [GSet](src/main/java/com/thealgorithms/datastructures/crdt/GSet.java)
- - 📄 [LWWElementSet](src/main/java/com/thealgorithms/datastructures/crdt/LWWElementSet.java)
- - 📄 [ORSet](src/main/java/com/thealgorithms/datastructures/crdt/ORSet.java)
- - 📄 [PNCounter](src/main/java/com/thealgorithms/datastructures/crdt/PNCounter.java)
- - 📄 [TwoPSet](src/main/java/com/thealgorithms/datastructures/crdt/TwoPSet.java)
- - 📁 **disjointsetunion**
- - 📄 [DisjointSetUnion](src/main/java/com/thealgorithms/datastructures/disjointsetunion/DisjointSetUnion.java)
- - 📄 [DisjointSetUnionBySize](src/main/java/com/thealgorithms/datastructures/disjointsetunion/DisjointSetUnionBySize.java)
- - 📄 [Node](src/main/java/com/thealgorithms/datastructures/disjointsetunion/Node.java)
- - 📁 **dynamicarray**
- - 📄 [DynamicArray](src/main/java/com/thealgorithms/datastructures/dynamicarray/DynamicArray.java)
- - 📁 **graphs**
- - 📄 [AStar](src/main/java/com/thealgorithms/datastructures/graphs/AStar.java)
- - 📄 [BellmanFord](src/main/java/com/thealgorithms/datastructures/graphs/BellmanFord.java)
- - 📄 [BipartiteGraphDFS](src/main/java/com/thealgorithms/datastructures/graphs/BipartiteGraphDFS.java)
- - 📄 [BoruvkaAlgorithm](src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithm.java)
- - 📄 [ConnectedComponent](src/main/java/com/thealgorithms/datastructures/graphs/ConnectedComponent.java)
- - 📄 [Cycles](src/main/java/com/thealgorithms/datastructures/graphs/Cycles.java)
- - 📄 [DialsAlgorithm](src/main/java/com/thealgorithms/datastructures/graphs/DialsAlgorithm.java)
- - 📄 [DijkstraAlgorithm](src/main/java/com/thealgorithms/datastructures/graphs/DijkstraAlgorithm.java)
- - 📄 [DijkstraOptimizedAlgorithm](src/main/java/com/thealgorithms/datastructures/graphs/DijkstraOptimizedAlgorithm.java)
- - 📄 [EdmondsBlossomAlgorithm](src/main/java/com/thealgorithms/datastructures/graphs/EdmondsBlossomAlgorithm.java)
- - 📄 [FloydWarshall](src/main/java/com/thealgorithms/datastructures/graphs/FloydWarshall.java)
- - 📄 [FordFulkerson](src/main/java/com/thealgorithms/datastructures/graphs/FordFulkerson.java)
- - 📄 [Graphs](src/main/java/com/thealgorithms/datastructures/graphs/Graphs.java)
- - 📄 [HamiltonianCycle](src/main/java/com/thealgorithms/datastructures/graphs/HamiltonianCycle.java)
- - 📄 [JohnsonsAlgorithm](src/main/java/com/thealgorithms/datastructures/graphs/JohnsonsAlgorithm.java)
- - 📄 [KahnsAlgorithm](src/main/java/com/thealgorithms/datastructures/graphs/KahnsAlgorithm.java)
- - 📄 [Kosaraju](src/main/java/com/thealgorithms/datastructures/graphs/Kosaraju.java)
- - 📄 [Kruskal](src/main/java/com/thealgorithms/datastructures/graphs/Kruskal.java)
- - 📄 [MatrixGraphs](src/main/java/com/thealgorithms/datastructures/graphs/MatrixGraphs.java)
- - 📄 [PrimMST](src/main/java/com/thealgorithms/datastructures/graphs/PrimMST.java)
- - 📄 [TarjansAlgorithm](src/main/java/com/thealgorithms/datastructures/graphs/TarjansAlgorithm.java)
- - 📄 [TwoSat](src/main/java/com/thealgorithms/datastructures/graphs/TwoSat.java)
- - 📄 [UndirectedAdjacencyListGraph](src/main/java/com/thealgorithms/datastructures/graphs/UndirectedAdjacencyListGraph.java)
- - 📄 [WelshPowell](src/main/java/com/thealgorithms/datastructures/graphs/WelshPowell.java)
- - 📁 **hashmap**
- - 📁 **hashing**
- - 📄 [GenericHashMapUsingArray](src/main/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArray.java)
- - 📄 [GenericHashMapUsingArrayList](src/main/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayList.java)
- - 📄 [HashMap](src/main/java/com/thealgorithms/datastructures/hashmap/hashing/HashMap.java)
- - 📄 [HashMapCuckooHashing](src/main/java/com/thealgorithms/datastructures/hashmap/hashing/HashMapCuckooHashing.java)
- - 📄 [ImmutableHashMap](src/main/java/com/thealgorithms/datastructures/hashmap/hashing/ImmutableHashMap.java)
- - 📄 [Intersection](src/main/java/com/thealgorithms/datastructures/hashmap/hashing/Intersection.java)
- - 📄 [LinearProbingHashMap](src/main/java/com/thealgorithms/datastructures/hashmap/hashing/LinearProbingHashMap.java)
- - 📄 [MainCuckooHashing](src/main/java/com/thealgorithms/datastructures/hashmap/hashing/MainCuckooHashing.java)
- - 📄 [MajorityElement](src/main/java/com/thealgorithms/datastructures/hashmap/hashing/MajorityElement.java)
- - 📄 [Map](src/main/java/com/thealgorithms/datastructures/hashmap/hashing/Map.java)
- - 📁 **heaps**
- - 📄 [EmptyHeapException](src/main/java/com/thealgorithms/datastructures/heaps/EmptyHeapException.java)
- - 📄 [FibonacciHeap](src/main/java/com/thealgorithms/datastructures/heaps/FibonacciHeap.java)
- - 📄 [GenericHeap](src/main/java/com/thealgorithms/datastructures/heaps/GenericHeap.java)
- - 📄 [Heap](src/main/java/com/thealgorithms/datastructures/heaps/Heap.java)
- - 📄 [HeapElement](src/main/java/com/thealgorithms/datastructures/heaps/HeapElement.java)
- - 📄 [IndexedPriorityQueue](src/main/java/com/thealgorithms/datastructures/heaps/IndexedPriorityQueue.java)
- - 📄 [KthElementFinder](src/main/java/com/thealgorithms/datastructures/heaps/KthElementFinder.java)
- - 📄 [LeftistHeap](src/main/java/com/thealgorithms/datastructures/heaps/LeftistHeap.java)
- - 📄 [MaxHeap](src/main/java/com/thealgorithms/datastructures/heaps/MaxHeap.java)
- - 📄 [MedianFinder](src/main/java/com/thealgorithms/datastructures/heaps/MedianFinder.java)
- - 📄 [MergeKSortedArrays](src/main/java/com/thealgorithms/datastructures/heaps/MergeKSortedArrays.java)
- - 📄 [MinHeap](src/main/java/com/thealgorithms/datastructures/heaps/MinHeap.java)
- - 📄 [MinPriorityQueue](src/main/java/com/thealgorithms/datastructures/heaps/MinPriorityQueue.java)
- - 📁 **lists**
- - 📄 [CircleLinkedList](src/main/java/com/thealgorithms/datastructures/lists/CircleLinkedList.java)
- - 📄 [CircularDoublyLinkedList](src/main/java/com/thealgorithms/datastructures/lists/CircularDoublyLinkedList.java)
- - 📄 [CountSinglyLinkedListRecursion](src/main/java/com/thealgorithms/datastructures/lists/CountSinglyLinkedListRecursion.java)
- - 📄 [CreateAndDetectLoop](src/main/java/com/thealgorithms/datastructures/lists/CreateAndDetectLoop.java)
- - 📄 [CursorLinkedList](src/main/java/com/thealgorithms/datastructures/lists/CursorLinkedList.java)
- - 📄 [DoublyLinkedList](src/main/java/com/thealgorithms/datastructures/lists/DoublyLinkedList.java)
- - 📄 [FlattenMultilevelLinkedList](src/main/java/com/thealgorithms/datastructures/lists/FlattenMultilevelLinkedList.java)
- - 📄 [MergeKSortedLinkedList](src/main/java/com/thealgorithms/datastructures/lists/MergeKSortedLinkedList.java)
- - 📄 [MergeSortedArrayList](src/main/java/com/thealgorithms/datastructures/lists/MergeSortedArrayList.java)
- - 📄 [MergeSortedSinglyLinkedList](src/main/java/com/thealgorithms/datastructures/lists/MergeSortedSinglyLinkedList.java)
- - 📄 [QuickSortLinkedList](src/main/java/com/thealgorithms/datastructures/lists/QuickSortLinkedList.java)
- - 📄 [RandomNode](src/main/java/com/thealgorithms/datastructures/lists/RandomNode.java)
- - 📄 [ReverseKGroup](src/main/java/com/thealgorithms/datastructures/lists/ReverseKGroup.java)
- - 📄 [RotateSinglyLinkedLists](src/main/java/com/thealgorithms/datastructures/lists/RotateSinglyLinkedLists.java)
- - 📄 [SearchSinglyLinkedListRecursion](src/main/java/com/thealgorithms/datastructures/lists/SearchSinglyLinkedListRecursion.java)
- - 📄 [SinglyLinkedList](src/main/java/com/thealgorithms/datastructures/lists/SinglyLinkedList.java)
- - 📄 [SinglyLinkedListNode](src/main/java/com/thealgorithms/datastructures/lists/SinglyLinkedListNode.java)
- - 📄 [SkipList](src/main/java/com/thealgorithms/datastructures/lists/SkipList.java)
- - 📄 [SortedLinkedList](src/main/java/com/thealgorithms/datastructures/lists/SortedLinkedList.java)
- - 📄 [TortoiseHareAlgo](src/main/java/com/thealgorithms/datastructures/lists/TortoiseHareAlgo.java)
- - 📁 **queues**
- - 📄 [CircularQueue](src/main/java/com/thealgorithms/datastructures/queues/CircularQueue.java)
- - 📄 [Deque](src/main/java/com/thealgorithms/datastructures/queues/Deque.java)
- - 📄 [GenericArrayListQueue](src/main/java/com/thealgorithms/datastructures/queues/GenericArrayListQueue.java)
- - 📄 [LinkedQueue](src/main/java/com/thealgorithms/datastructures/queues/LinkedQueue.java)
- - 📄 [PriorityQueues](src/main/java/com/thealgorithms/datastructures/queues/PriorityQueues.java)
- - 📄 [Queue](src/main/java/com/thealgorithms/datastructures/queues/Queue.java)
- - 📄 [QueueByTwoStacks](src/main/java/com/thealgorithms/datastructures/queues/QueueByTwoStacks.java)
- - 📄 [SlidingWindowMaximum](src/main/java/com/thealgorithms/datastructures/queues/SlidingWindowMaximum.java)
- - 📄 [TokenBucket](src/main/java/com/thealgorithms/datastructures/queues/TokenBucket.java)
- - 📁 **stacks**
- - 📄 [NodeStack](src/main/java/com/thealgorithms/datastructures/stacks/NodeStack.java)
- - 📄 [ReverseStack](src/main/java/com/thealgorithms/datastructures/stacks/ReverseStack.java)
- - 📄 [Stack](src/main/java/com/thealgorithms/datastructures/stacks/Stack.java)
- - 📄 [StackArray](src/main/java/com/thealgorithms/datastructures/stacks/StackArray.java)
- - 📄 [StackArrayList](src/main/java/com/thealgorithms/datastructures/stacks/StackArrayList.java)
- - 📄 [StackOfLinkedList](src/main/java/com/thealgorithms/datastructures/stacks/StackOfLinkedList.java)
- - 📁 **trees**
- - 📄 [AVLSimple](src/main/java/com/thealgorithms/datastructures/trees/AVLSimple.java)
- - 📄 [AVLTree](src/main/java/com/thealgorithms/datastructures/trees/AVLTree.java)
- - 📄 [BSTFromSortedArray](src/main/java/com/thealgorithms/datastructures/trees/BSTFromSortedArray.java)
- - 📄 [BSTIterative](src/main/java/com/thealgorithms/datastructures/trees/BSTIterative.java)
- - 📄 [BSTRecursive](src/main/java/com/thealgorithms/datastructures/trees/BSTRecursive.java)
- - 📄 [BSTRecursiveGeneric](src/main/java/com/thealgorithms/datastructures/trees/BSTRecursiveGeneric.java)
- - 📄 [BTree](src/main/java/com/thealgorithms/datastructures/trees/BTree.java)
- - 📄 [BinaryTree](src/main/java/com/thealgorithms/datastructures/trees/BinaryTree.java)
- - 📄 [BinaryTreeToString](src/main/java/com/thealgorithms/datastructures/trees/BinaryTreeToString.java)
- - 📄 [BoundaryTraversal](src/main/java/com/thealgorithms/datastructures/trees/BoundaryTraversal.java)
- - 📄 [CeilInBinarySearchTree](src/main/java/com/thealgorithms/datastructures/trees/CeilInBinarySearchTree.java)
- - 📄 [CentroidDecomposition](src/main/java/com/thealgorithms/datastructures/trees/CentroidDecomposition.java)
- - 📄 [CheckBinaryTreeIsValidBST](src/main/java/com/thealgorithms/datastructures/trees/CheckBinaryTreeIsValidBST.java)
- - 📄 [CheckIfBinaryTreeBalanced](src/main/java/com/thealgorithms/datastructures/trees/CheckIfBinaryTreeBalanced.java)
- - 📄 [CheckTreeIsSymmetric](src/main/java/com/thealgorithms/datastructures/trees/CheckTreeIsSymmetric.java)
- - 📄 [CreateBinaryTreeFromInorderPreorder](src/main/java/com/thealgorithms/datastructures/trees/CreateBinaryTreeFromInorderPreorder.java)
- - 📄 [FenwickTree](src/main/java/com/thealgorithms/datastructures/trees/FenwickTree.java)
- - 📄 [GenericTree](src/main/java/com/thealgorithms/datastructures/trees/GenericTree.java)
- - 📄 [InorderTraversal](src/main/java/com/thealgorithms/datastructures/trees/InorderTraversal.java)
- - 📄 [KDTree](src/main/java/com/thealgorithms/datastructures/trees/KDTree.java)
- - 📄 [LCA](src/main/java/com/thealgorithms/datastructures/trees/LCA.java)
- - 📄 [LazySegmentTree](src/main/java/com/thealgorithms/datastructures/trees/LazySegmentTree.java)
- - 📄 [LevelOrderTraversal](src/main/java/com/thealgorithms/datastructures/trees/LevelOrderTraversal.java)
- - 📄 [PostOrderTraversal](src/main/java/com/thealgorithms/datastructures/trees/PostOrderTraversal.java)
- - 📄 [PreOrderTraversal](src/main/java/com/thealgorithms/datastructures/trees/PreOrderTraversal.java)
- - 📄 [PrintTopViewofTree](src/main/java/com/thealgorithms/datastructures/trees/PrintTopViewofTree.java)
- - 📄 [QuadTree](src/main/java/com/thealgorithms/datastructures/trees/QuadTree.java)
- - 📄 [RedBlackBST](src/main/java/com/thealgorithms/datastructures/trees/RedBlackBST.java)
- - 📄 [SameTreesCheck](src/main/java/com/thealgorithms/datastructures/trees/SameTreesCheck.java)
- - 📄 [SegmentTree](src/main/java/com/thealgorithms/datastructures/trees/SegmentTree.java)
- - 📄 [SplayTree](src/main/java/com/thealgorithms/datastructures/trees/SplayTree.java)
- - 📄 [ThreadedBinaryTree](src/main/java/com/thealgorithms/datastructures/trees/ThreadedBinaryTree.java)
- - 📄 [Treap](src/main/java/com/thealgorithms/datastructures/trees/Treap.java)
- - 📄 [TreeRandomNode](src/main/java/com/thealgorithms/datastructures/trees/TreeRandomNode.java)
- - 📄 [Trie](src/main/java/com/thealgorithms/datastructures/trees/Trie.java)
- - 📄 [VerticalOrderTraversal](src/main/java/com/thealgorithms/datastructures/trees/VerticalOrderTraversal.java)
- - 📄 [ZigzagTraversal](src/main/java/com/thealgorithms/datastructures/trees/ZigzagTraversal.java)
- - 📄 [nearestRightKey](src/main/java/com/thealgorithms/datastructures/trees/nearestRightKey.java)
- - 📁 **devutils**
- - 📁 **entities**
- - 📄 [ProcessDetails](src/main/java/com/thealgorithms/devutils/entities/ProcessDetails.java)
- - 📁 **nodes**
- - 📄 [LargeTreeNode](src/main/java/com/thealgorithms/devutils/nodes/LargeTreeNode.java)
- - 📄 [Node](src/main/java/com/thealgorithms/devutils/nodes/Node.java)
- - 📄 [SimpleNode](src/main/java/com/thealgorithms/devutils/nodes/SimpleNode.java)
- - 📄 [SimpleTreeNode](src/main/java/com/thealgorithms/devutils/nodes/SimpleTreeNode.java)
- - 📄 [TreeNode](src/main/java/com/thealgorithms/devutils/nodes/TreeNode.java)
- - 📁 **searches**
- - 📄 [MatrixSearchAlgorithm](src/main/java/com/thealgorithms/devutils/searches/MatrixSearchAlgorithm.java)
- - 📄 [SearchAlgorithm](src/main/java/com/thealgorithms/devutils/searches/SearchAlgorithm.java)
- - 📁 **divideandconquer**
- - 📄 [BinaryExponentiation](src/main/java/com/thealgorithms/divideandconquer/BinaryExponentiation.java)
- - 📄 [ClosestPair](src/main/java/com/thealgorithms/divideandconquer/ClosestPair.java)
- - 📄 [CountingInversions](src/main/java/com/thealgorithms/divideandconquer/CountingInversions.java)
- - 📄 [MedianOfTwoSortedArrays](src/main/java/com/thealgorithms/divideandconquer/MedianOfTwoSortedArrays.java)
- - 📄 [SkylineAlgorithm](src/main/java/com/thealgorithms/divideandconquer/SkylineAlgorithm.java)
- - 📄 [StrassenMatrixMultiplication](src/main/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplication.java)
- - 📄 [TilingProblem](src/main/java/com/thealgorithms/divideandconquer/TilingProblem.java)
- - 📁 **dynamicprogramming**
- - 📄 [Abbreviation](src/main/java/com/thealgorithms/dynamicprogramming/Abbreviation.java)
- - 📄 [AllConstruct](src/main/java/com/thealgorithms/dynamicprogramming/AllConstruct.java)
- - 📄 [AssignmentUsingBitmask](src/main/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmask.java)
- - 📄 [BoardPath](src/main/java/com/thealgorithms/dynamicprogramming/BoardPath.java)
- - 📄 [BoundaryFill](src/main/java/com/thealgorithms/dynamicprogramming/BoundaryFill.java)
- - 📄 [BruteForceKnapsack](src/main/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsack.java)
- - 📄 [CatalanNumber](src/main/java/com/thealgorithms/dynamicprogramming/CatalanNumber.java)
- - 📄 [ClimbingStairs](src/main/java/com/thealgorithms/dynamicprogramming/ClimbingStairs.java)
- - 📄 [CoinChange](src/main/java/com/thealgorithms/dynamicprogramming/CoinChange.java)
- - 📄 [CountFriendsPairing](src/main/java/com/thealgorithms/dynamicprogramming/CountFriendsPairing.java)
- - 📄 [DamerauLevenshteinDistance](src/main/java/com/thealgorithms/dynamicprogramming/DamerauLevenshteinDistance.java)
- - 📄 [DiceThrow](src/main/java/com/thealgorithms/dynamicprogramming/DiceThrow.java)
- - 📄 [EditDistance](src/main/java/com/thealgorithms/dynamicprogramming/EditDistance.java)
- - 📄 [EggDropping](src/main/java/com/thealgorithms/dynamicprogramming/EggDropping.java)
- - 📄 [Fibonacci](src/main/java/com/thealgorithms/dynamicprogramming/Fibonacci.java)
- - 📄 [KadaneAlgorithm](src/main/java/com/thealgorithms/dynamicprogramming/KadaneAlgorithm.java)
- - 📄 [Knapsack](src/main/java/com/thealgorithms/dynamicprogramming/Knapsack.java)
- - 📄 [KnapsackMemoization](src/main/java/com/thealgorithms/dynamicprogramming/KnapsackMemoization.java)
- - 📄 [KnapsackZeroOne](src/main/java/com/thealgorithms/dynamicprogramming/KnapsackZeroOne.java)
- - 📄 [KnapsackZeroOneTabulation](src/main/java/com/thealgorithms/dynamicprogramming/KnapsackZeroOneTabulation.java)
- - 📄 [LevenshteinDistance](src/main/java/com/thealgorithms/dynamicprogramming/LevenshteinDistance.java)
- - 📄 [LongestAlternatingSubsequence](src/main/java/com/thealgorithms/dynamicprogramming/LongestAlternatingSubsequence.java)
- - 📄 [LongestArithmeticSubsequence](src/main/java/com/thealgorithms/dynamicprogramming/LongestArithmeticSubsequence.java)
- - 📄 [LongestCommonSubsequence](src/main/java/com/thealgorithms/dynamicprogramming/LongestCommonSubsequence.java)
- - 📄 [LongestIncreasingSubsequence](src/main/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequence.java)
- - 📄 [LongestIncreasingSubsequenceNLogN](src/main/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequenceNLogN.java)
- - 📄 [LongestPalindromicSubsequence](src/main/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubsequence.java)
- - 📄 [LongestPalindromicSubstring](src/main/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubstring.java)
- - 📄 [LongestValidParentheses](src/main/java/com/thealgorithms/dynamicprogramming/LongestValidParentheses.java)
- - 📄 [MatrixChainMultiplication](src/main/java/com/thealgorithms/dynamicprogramming/MatrixChainMultiplication.java)
- - 📄 [MatrixChainRecursiveTopDownMemoisation](src/main/java/com/thealgorithms/dynamicprogramming/MatrixChainRecursiveTopDownMemoisation.java)
- - 📄 [MaximumProductSubarray](src/main/java/com/thealgorithms/dynamicprogramming/MaximumProductSubarray.java)
- - 📄 [MaximumSumOfNonAdjacentElements](src/main/java/com/thealgorithms/dynamicprogramming/MaximumSumOfNonAdjacentElements.java)
- - 📄 [MinimumPathSum](src/main/java/com/thealgorithms/dynamicprogramming/MinimumPathSum.java)
- - 📄 [MinimumSumPartition](src/main/java/com/thealgorithms/dynamicprogramming/MinimumSumPartition.java)
- - 📄 [NeedlemanWunsch](src/main/java/com/thealgorithms/dynamicprogramming/NeedlemanWunsch.java)
- - 📄 [NewManShanksPrime](src/main/java/com/thealgorithms/dynamicprogramming/NewManShanksPrime.java)
- - 📄 [OptimalJobScheduling](src/main/java/com/thealgorithms/dynamicprogramming/OptimalJobScheduling.java)
- - 📄 [PalindromicPartitioning](src/main/java/com/thealgorithms/dynamicprogramming/PalindromicPartitioning.java)
- - 📄 [PartitionProblem](src/main/java/com/thealgorithms/dynamicprogramming/PartitionProblem.java)
- - 📄 [RegexMatching](src/main/java/com/thealgorithms/dynamicprogramming/RegexMatching.java)
- - 📄 [RodCutting](src/main/java/com/thealgorithms/dynamicprogramming/RodCutting.java)
- - 📄 [ShortestCommonSupersequenceLength](src/main/java/com/thealgorithms/dynamicprogramming/ShortestCommonSupersequenceLength.java)
- - 📄 [SmithWaterman](src/main/java/com/thealgorithms/dynamicprogramming/SmithWaterman.java)
- - 📄 [SubsetCount](src/main/java/com/thealgorithms/dynamicprogramming/SubsetCount.java)
- - 📄 [SubsetSum](src/main/java/com/thealgorithms/dynamicprogramming/SubsetSum.java)
- - 📄 [SubsetSumSpaceOptimized](src/main/java/com/thealgorithms/dynamicprogramming/SubsetSumSpaceOptimized.java)
- - 📄 [SumOfSubset](src/main/java/com/thealgorithms/dynamicprogramming/SumOfSubset.java)
- - 📄 [TreeMatching](src/main/java/com/thealgorithms/dynamicprogramming/TreeMatching.java)
- - 📄 [Tribonacci](src/main/java/com/thealgorithms/dynamicprogramming/Tribonacci.java)
- - 📄 [UniquePaths](src/main/java/com/thealgorithms/dynamicprogramming/UniquePaths.java)
- - 📄 [UniqueSubsequencesCount](src/main/java/com/thealgorithms/dynamicprogramming/UniqueSubsequencesCount.java)
- - 📄 [WildcardMatching](src/main/java/com/thealgorithms/dynamicprogramming/WildcardMatching.java)
- - 📄 [WineProblem](src/main/java/com/thealgorithms/dynamicprogramming/WineProblem.java)
- - 📁 **geometry**
- - 📄 [BentleyOttmann](src/main/java/com/thealgorithms/geometry/BentleyOttmann.java)
- - 📄 [BresenhamLine](src/main/java/com/thealgorithms/geometry/BresenhamLine.java)
- - 📄 [ConvexHull](src/main/java/com/thealgorithms/geometry/ConvexHull.java)
- - 📄 [DDALine](src/main/java/com/thealgorithms/geometry/DDALine.java)
- - 📄 [GrahamScan](src/main/java/com/thealgorithms/geometry/GrahamScan.java)
- - 📄 [Haversine](src/main/java/com/thealgorithms/geometry/Haversine.java)
- - 📄 [MidpointCircle](src/main/java/com/thealgorithms/geometry/MidpointCircle.java)
- - 📄 [MidpointEllipse](src/main/java/com/thealgorithms/geometry/MidpointEllipse.java)
- - 📄 [Point](src/main/java/com/thealgorithms/geometry/Point.java)
- - 📄 [WusLine](src/main/java/com/thealgorithms/geometry/WusLine.java)
- - 📁 **graph**
- - 📄 [BronKerbosch](src/main/java/com/thealgorithms/graph/BronKerbosch.java)
- - 📄 [ConstrainedShortestPath](src/main/java/com/thealgorithms/graph/ConstrainedShortestPath.java)
- - 📄 [Dinic](src/main/java/com/thealgorithms/graph/Dinic.java)
- - 📄 [Edmonds](src/main/java/com/thealgorithms/graph/Edmonds.java)
- - 📄 [EdmondsKarp](src/main/java/com/thealgorithms/graph/EdmondsKarp.java)
- - 📄 [GomoryHuTree](src/main/java/com/thealgorithms/graph/GomoryHuTree.java)
- - 📄 [HierholzerAlgorithm](src/main/java/com/thealgorithms/graph/HierholzerAlgorithm.java)
- - 📄 [HierholzerEulerianPath](src/main/java/com/thealgorithms/graph/HierholzerEulerianPath.java)
- - 📄 [HopcroftKarp](src/main/java/com/thealgorithms/graph/HopcroftKarp.java)
- - 📄 [HungarianAlgorithm](src/main/java/com/thealgorithms/graph/HungarianAlgorithm.java)
- - 📄 [PredecessorConstrainedDfs](src/main/java/com/thealgorithms/graph/PredecessorConstrainedDfs.java)
- - 📄 [PushRelabel](src/main/java/com/thealgorithms/graph/PushRelabel.java)
- - 📄 [StoerWagner](src/main/java/com/thealgorithms/graph/StoerWagner.java)
- - 📄 [StronglyConnectedComponentOptimized](src/main/java/com/thealgorithms/graph/StronglyConnectedComponentOptimized.java)
- - 📄 [TravelingSalesman](src/main/java/com/thealgorithms/graph/TravelingSalesman.java)
- - 📄 [YensKShortestPaths](src/main/java/com/thealgorithms/graph/YensKShortestPaths.java)
- - 📄 [ZeroOneBfs](src/main/java/com/thealgorithms/graph/ZeroOneBfs.java)
- - 📁 **greedyalgorithms**
- - 📄 [ActivitySelection](src/main/java/com/thealgorithms/greedyalgorithms/ActivitySelection.java)
- - 📄 [BandwidthAllocation](src/main/java/com/thealgorithms/greedyalgorithms/BandwidthAllocation.java)
- - 📄 [BinaryAddition](src/main/java/com/thealgorithms/greedyalgorithms/BinaryAddition.java)
- - 📄 [CoinChange](src/main/java/com/thealgorithms/greedyalgorithms/CoinChange.java)
- - 📄 [DigitSeparation](src/main/java/com/thealgorithms/greedyalgorithms/DigitSeparation.java)
- - 📄 [EgyptianFraction](src/main/java/com/thealgorithms/greedyalgorithms/EgyptianFraction.java)
- - 📄 [FractionalKnapsack](src/main/java/com/thealgorithms/greedyalgorithms/FractionalKnapsack.java)
- - 📄 [GaleShapley](src/main/java/com/thealgorithms/greedyalgorithms/GaleShapley.java)
- - 📄 [JobSequencing](src/main/java/com/thealgorithms/greedyalgorithms/JobSequencing.java)
- - 📄 [KCenters](src/main/java/com/thealgorithms/greedyalgorithms/KCenters.java)
- - 📄 [MergeIntervals](src/main/java/com/thealgorithms/greedyalgorithms/MergeIntervals.java)
- - 📄 [MinimizingLateness](src/main/java/com/thealgorithms/greedyalgorithms/MinimizingLateness.java)
- - 📄 [MinimumWaitingTime](src/main/java/com/thealgorithms/greedyalgorithms/MinimumWaitingTime.java)
- - 📄 [OptimalFileMerging](src/main/java/com/thealgorithms/greedyalgorithms/OptimalFileMerging.java)
- - 📄 [StockProfitCalculator](src/main/java/com/thealgorithms/greedyalgorithms/StockProfitCalculator.java)
- - 📁 **io**
- - 📄 [BufferedReader](src/main/java/com/thealgorithms/io/BufferedReader.java)
- - 📁 **lineclipping**
- - 📄 [CohenSutherland](src/main/java/com/thealgorithms/lineclipping/CohenSutherland.java)
- - 📄 [LiangBarsky](src/main/java/com/thealgorithms/lineclipping/LiangBarsky.java)
- - 📁 **utils**
- - 📄 [Line](src/main/java/com/thealgorithms/lineclipping/utils/Line.java)
- - 📄 [Point](src/main/java/com/thealgorithms/lineclipping/utils/Point.java)
- - 📁 **maths**
- - 📄 [ADTFraction](src/main/java/com/thealgorithms/maths/ADTFraction.java)
- - 📄 [AbsoluteMax](src/main/java/com/thealgorithms/maths/AbsoluteMax.java)
- - 📄 [AbsoluteMin](src/main/java/com/thealgorithms/maths/AbsoluteMin.java)
- - 📄 [AbsoluteValue](src/main/java/com/thealgorithms/maths/AbsoluteValue.java)
- - 📄 [AbundantNumber](src/main/java/com/thealgorithms/maths/AbundantNumber.java)
- - 📄 [AliquotSum](src/main/java/com/thealgorithms/maths/AliquotSum.java)
- - 📄 [AmicableNumber](src/main/java/com/thealgorithms/maths/AmicableNumber.java)
- - 📄 [Area](src/main/java/com/thealgorithms/maths/Area.java)
- - 📄 [Armstrong](src/main/java/com/thealgorithms/maths/Armstrong.java)
- - 📄 [AutoCorrelation](src/main/java/com/thealgorithms/maths/AutoCorrelation.java)
- - 📄 [AutomorphicNumber](src/main/java/com/thealgorithms/maths/AutomorphicNumber.java)
- - 📄 [Average](src/main/java/com/thealgorithms/maths/Average.java)
- - 📄 [BinaryPow](src/main/java/com/thealgorithms/maths/BinaryPow.java)
- - 📄 [BinomialCoefficient](src/main/java/com/thealgorithms/maths/BinomialCoefficient.java)
- - 📄 [CatalanNumbers](src/main/java/com/thealgorithms/maths/CatalanNumbers.java)
- - 📄 [Ceil](src/main/java/com/thealgorithms/maths/Ceil.java)
- - 📄 [ChebyshevIteration](src/main/java/com/thealgorithms/maths/ChebyshevIteration.java)
- - 📄 [ChineseRemainderTheorem](src/main/java/com/thealgorithms/maths/ChineseRemainderTheorem.java)
- - 📄 [CircularConvolutionFFT](src/main/java/com/thealgorithms/maths/CircularConvolutionFFT.java)
- - 📄 [CollatzConjecture](src/main/java/com/thealgorithms/maths/CollatzConjecture.java)
- - 📄 [Combinations](src/main/java/com/thealgorithms/maths/Combinations.java)
- - 📄 [Convolution](src/main/java/com/thealgorithms/maths/Convolution.java)
- - 📄 [ConvolutionFFT](src/main/java/com/thealgorithms/maths/ConvolutionFFT.java)
- - 📄 [CrossCorrelation](src/main/java/com/thealgorithms/maths/CrossCorrelation.java)
- - 📄 [DeterminantOfMatrix](src/main/java/com/thealgorithms/maths/DeterminantOfMatrix.java)
- - 📄 [DigitalRoot](src/main/java/com/thealgorithms/maths/DigitalRoot.java)
- - 📄 [DistanceFormula](src/main/java/com/thealgorithms/maths/DistanceFormula.java)
- - 📄 [DudeneyNumber](src/main/java/com/thealgorithms/maths/DudeneyNumber.java)
- - 📄 [EulerMethod](src/main/java/com/thealgorithms/maths/EulerMethod.java)
- - 📄 [EulerPseudoprime](src/main/java/com/thealgorithms/maths/EulerPseudoprime.java)
- - 📄 [EulersFunction](src/main/java/com/thealgorithms/maths/EulersFunction.java)
- - 📄 [EvilNumber](src/main/java/com/thealgorithms/maths/EvilNumber.java)
- - 📄 [ExtendedEuclideanAlgorithm](src/main/java/com/thealgorithms/maths/ExtendedEuclideanAlgorithm.java)
- - 📄 [FFT](src/main/java/com/thealgorithms/maths/FFT.java)
- - 📄 [FFTBluestein](src/main/java/com/thealgorithms/maths/FFTBluestein.java)
- - 📄 [Factorial](src/main/java/com/thealgorithms/maths/Factorial.java)
- - 📄 [FastExponentiation](src/main/java/com/thealgorithms/maths/FastExponentiation.java)
- - 📄 [FastInverseSqrt](src/main/java/com/thealgorithms/maths/FastInverseSqrt.java)
- - 📄 [FibonacciJavaStreams](src/main/java/com/thealgorithms/maths/FibonacciJavaStreams.java)
- - 📄 [FibonacciLoop](src/main/java/com/thealgorithms/maths/FibonacciLoop.java)
- - 📄 [FibonacciNumberCheck](src/main/java/com/thealgorithms/maths/FibonacciNumberCheck.java)
- - 📄 [FibonacciNumberGoldenRation](src/main/java/com/thealgorithms/maths/FibonacciNumberGoldenRation.java)
- - 📄 [FindKthNumber](src/main/java/com/thealgorithms/maths/FindKthNumber.java)
- - 📄 [FindMax](src/main/java/com/thealgorithms/maths/FindMax.java)
- - 📄 [FindMaxRecursion](src/main/java/com/thealgorithms/maths/FindMaxRecursion.java)
- - 📄 [FindMin](src/main/java/com/thealgorithms/maths/FindMin.java)
- - 📄 [FindMinRecursion](src/main/java/com/thealgorithms/maths/FindMinRecursion.java)
- - 📄 [Floor](src/main/java/com/thealgorithms/maths/Floor.java)
- - 📄 [FrizzyNumber](src/main/java/com/thealgorithms/maths/FrizzyNumber.java)
- - 📄 [GCD](src/main/java/com/thealgorithms/maths/GCD.java)
- - 📄 [GCDRecursion](src/main/java/com/thealgorithms/maths/GCDRecursion.java)
- - 📄 [Gaussian](src/main/java/com/thealgorithms/maths/Gaussian.java)
- - 📄 [GenericRoot](src/main/java/com/thealgorithms/maths/GenericRoot.java)
- - 📄 [GermainPrimeAndSafePrime](src/main/java/com/thealgorithms/maths/GermainPrimeAndSafePrime.java)
- - 📄 [GoldbachConjecture](src/main/java/com/thealgorithms/maths/GoldbachConjecture.java)
- - 📄 [HappyNumber](src/main/java/com/thealgorithms/maths/HappyNumber.java)
- - 📄 [HarshadNumber](src/main/java/com/thealgorithms/maths/HarshadNumber.java)
- - 📄 [HeronsFormula](src/main/java/com/thealgorithms/maths/HeronsFormula.java)
- - 📄 [JosephusProblem](src/main/java/com/thealgorithms/maths/JosephusProblem.java)
- - 📄 [JugglerSequence](src/main/java/com/thealgorithms/maths/JugglerSequence.java)
- - 📄 [KaprekarNumbers](src/main/java/com/thealgorithms/maths/KaprekarNumbers.java)
- - 📄 [KaratsubaMultiplication](src/main/java/com/thealgorithms/maths/KaratsubaMultiplication.java)
- - 📄 [KeithNumber](src/main/java/com/thealgorithms/maths/KeithNumber.java)
- - 📄 [KrishnamurthyNumber](src/main/java/com/thealgorithms/maths/KrishnamurthyNumber.java)
- - 📄 [LeastCommonMultiple](src/main/java/com/thealgorithms/maths/LeastCommonMultiple.java)
- - 📄 [LeonardoNumber](src/main/java/com/thealgorithms/maths/LeonardoNumber.java)
- - 📄 [LinearDiophantineEquationsSolver](src/main/java/com/thealgorithms/maths/LinearDiophantineEquationsSolver.java)
- - 📄 [LongDivision](src/main/java/com/thealgorithms/maths/LongDivision.java)
- - 📄 [LucasSeries](src/main/java/com/thealgorithms/maths/LucasSeries.java)
- - 📄 [LuckyNumber](src/main/java/com/thealgorithms/maths/LuckyNumber.java)
- - 📄 [MagicSquare](src/main/java/com/thealgorithms/maths/MagicSquare.java)
- - 📄 [MathBuilder](src/main/java/com/thealgorithms/maths/MathBuilder.java)
- - 📄 [MaxValue](src/main/java/com/thealgorithms/maths/MaxValue.java)
- - 📄 [Means](src/main/java/com/thealgorithms/maths/Means.java)
- - 📄 [Median](src/main/java/com/thealgorithms/maths/Median.java)
- - 📄 [MinValue](src/main/java/com/thealgorithms/maths/MinValue.java)
- - 📄 [Mode](src/main/java/com/thealgorithms/maths/Mode.java)
- - 📄 [Neville](src/main/java/com/thealgorithms/maths/Neville.java)
- - 📄 [NonRepeatingElement](src/main/java/com/thealgorithms/maths/NonRepeatingElement.java)
- - 📄 [NthUglyNumber](src/main/java/com/thealgorithms/maths/NthUglyNumber.java)
- - 📄 [NumberOfDigits](src/main/java/com/thealgorithms/maths/NumberOfDigits.java)
- - 📄 [NumberPersistence](src/main/java/com/thealgorithms/maths/NumberPersistence.java)
- - 📄 [PalindromeNumber](src/main/java/com/thealgorithms/maths/PalindromeNumber.java)
- - 📄 [ParseInteger](src/main/java/com/thealgorithms/maths/ParseInteger.java)
- - 📄 [PascalTriangle](src/main/java/com/thealgorithms/maths/PascalTriangle.java)
- - 📄 [PerfectCube](src/main/java/com/thealgorithms/maths/PerfectCube.java)
- - 📄 [PerfectNumber](src/main/java/com/thealgorithms/maths/PerfectNumber.java)
- - 📄 [PerfectSquare](src/main/java/com/thealgorithms/maths/PerfectSquare.java)
- - 📄 [Perimeter](src/main/java/com/thealgorithms/maths/Perimeter.java)
- - 📄 [PiApproximation](src/main/java/com/thealgorithms/maths/PiApproximation.java)
- - 📄 [PiNilakantha](src/main/java/com/thealgorithms/maths/PiNilakantha.java)
- - 📄 [PollardRho](src/main/java/com/thealgorithms/maths/PollardRho.java)
- - 📄 [Pow](src/main/java/com/thealgorithms/maths/Pow.java)
- - 📄 [PowerOfFour](src/main/java/com/thealgorithms/maths/PowerOfFour.java)
- - 📄 [PowerOfTwoOrNot](src/main/java/com/thealgorithms/maths/PowerOfTwoOrNot.java)
- - 📄 [PowerUsingRecursion](src/main/java/com/thealgorithms/maths/PowerUsingRecursion.java)
- - 📁 **Prime**
- - 📄 [LiouvilleLambdaFunction](src/main/java/com/thealgorithms/maths/Prime/LiouvilleLambdaFunction.java)
- - 📄 [MillerRabinPrimalityCheck](src/main/java/com/thealgorithms/maths/Prime/MillerRabinPrimalityCheck.java)
- - 📄 [MobiusFunction](src/main/java/com/thealgorithms/maths/Prime/MobiusFunction.java)
- - 📄 [PrimeCheck](src/main/java/com/thealgorithms/maths/Prime/PrimeCheck.java)
- - 📄 [PrimeFactorization](src/main/java/com/thealgorithms/maths/Prime/PrimeFactorization.java)
- - 📄 [SquareFreeInteger](src/main/java/com/thealgorithms/maths/Prime/SquareFreeInteger.java)
- - 📄 [PronicNumber](src/main/java/com/thealgorithms/maths/PronicNumber.java)
- - 📄 [PythagoreanTriple](src/main/java/com/thealgorithms/maths/PythagoreanTriple.java)
- - 📄 [QuadraticEquationSolver](src/main/java/com/thealgorithms/maths/QuadraticEquationSolver.java)
- - 📄 [ReverseNumber](src/main/java/com/thealgorithms/maths/ReverseNumber.java)
- - 📄 [RomanNumeralUtil](src/main/java/com/thealgorithms/maths/RomanNumeralUtil.java)
- - 📄 [SecondMinMax](src/main/java/com/thealgorithms/maths/SecondMinMax.java)
- - 📄 [SieveOfAtkin](src/main/java/com/thealgorithms/maths/SieveOfAtkin.java)
- - 📄 [SieveOfEratosthenes](src/main/java/com/thealgorithms/maths/SieveOfEratosthenes.java)
- - 📄 [SimpsonIntegration](src/main/java/com/thealgorithms/maths/SimpsonIntegration.java)
- - 📄 [SmithNumber](src/main/java/com/thealgorithms/maths/SmithNumber.java)
- - 📄 [SolovayStrassenPrimalityTest](src/main/java/com/thealgorithms/maths/SolovayStrassenPrimalityTest.java)
- - 📄 [SquareRootWithBabylonianMethod](src/main/java/com/thealgorithms/maths/SquareRootWithBabylonianMethod.java)
- - 📄 [SquareRootWithNewtonRaphsonMethod](src/main/java/com/thealgorithms/maths/SquareRootWithNewtonRaphsonMethod.java)
- - 📄 [StandardDeviation](src/main/java/com/thealgorithms/maths/StandardDeviation.java)
- - 📄 [StandardScore](src/main/java/com/thealgorithms/maths/StandardScore.java)
- - 📄 [StrobogrammaticNumber](src/main/java/com/thealgorithms/maths/StrobogrammaticNumber.java)
- - 📄 [SumOfArithmeticSeries](src/main/java/com/thealgorithms/maths/SumOfArithmeticSeries.java)
- - 📄 [SumOfDigits](src/main/java/com/thealgorithms/maths/SumOfDigits.java)
- - 📄 [SumOfOddNumbers](src/main/java/com/thealgorithms/maths/SumOfOddNumbers.java)
- - 📄 [SumOfSquares](src/main/java/com/thealgorithms/maths/SumOfSquares.java)
- - 📄 [SumWithoutArithmeticOperators](src/main/java/com/thealgorithms/maths/SumWithoutArithmeticOperators.java)
- - 📄 [TrinomialTriangle](src/main/java/com/thealgorithms/maths/TrinomialTriangle.java)
- - 📄 [TwinPrime](src/main/java/com/thealgorithms/maths/TwinPrime.java)
- - 📄 [UniformNumbers](src/main/java/com/thealgorithms/maths/UniformNumbers.java)
- - 📄 [VampireNumber](src/main/java/com/thealgorithms/maths/VampireNumber.java)
- - 📄 [VectorCrossProduct](src/main/java/com/thealgorithms/maths/VectorCrossProduct.java)
- - 📄 [Volume](src/main/java/com/thealgorithms/maths/Volume.java)
- - 📄 [ZellersCongruence](src/main/java/com/thealgorithms/maths/ZellersCongruence.java)
- - 📁 **matrix**
- - 📄 [InverseOfMatrix](src/main/java/com/thealgorithms/matrix/InverseOfMatrix.java)
- - 📄 [LUDecomposition](src/main/java/com/thealgorithms/matrix/LUDecomposition.java)
- - 📄 [MatrixMultiplication](src/main/java/com/thealgorithms/matrix/MatrixMultiplication.java)
- - 📄 [MatrixRank](src/main/java/com/thealgorithms/matrix/MatrixRank.java)
- - 📄 [MatrixTranspose](src/main/java/com/thealgorithms/matrix/MatrixTranspose.java)
- - 📄 [MedianOfMatrix](src/main/java/com/thealgorithms/matrix/MedianOfMatrix.java)
- - 📄 [MirrorOfMatrix](src/main/java/com/thealgorithms/matrix/MirrorOfMatrix.java)
- - 📄 [PrintAMatrixInSpiralOrder](src/main/java/com/thealgorithms/matrix/PrintAMatrixInSpiralOrder.java)
- - 📄 [RotateMatrixBy90Degrees](src/main/java/com/thealgorithms/matrix/RotateMatrixBy90Degrees.java)
- - 📄 [SolveSystem](src/main/java/com/thealgorithms/matrix/SolveSystem.java)
- - 📄 [StochasticMatrix](src/main/java/com/thealgorithms/matrix/StochasticMatrix.java)
- - 📁 **matrixexponentiation**
- - 📄 [Fibonacci](src/main/java/com/thealgorithms/matrix/matrixexponentiation/Fibonacci.java)
- - 📁 **utils**
- - 📄 [MatrixUtil](src/main/java/com/thealgorithms/matrix/utils/MatrixUtil.java)
- - 📁 **misc**
- - 📄 [ColorContrastRatio](src/main/java/com/thealgorithms/misc/ColorContrastRatio.java)
- - 📄 [MapReduce](src/main/java/com/thealgorithms/misc/MapReduce.java)
- - 📄 [MedianOfRunningArray](src/main/java/com/thealgorithms/misc/MedianOfRunningArray.java)
- - 📄 [MedianOfRunningArrayByte](src/main/java/com/thealgorithms/misc/MedianOfRunningArrayByte.java)
- - 📄 [MedianOfRunningArrayDouble](src/main/java/com/thealgorithms/misc/MedianOfRunningArrayDouble.java)
- - 📄 [MedianOfRunningArrayFloat](src/main/java/com/thealgorithms/misc/MedianOfRunningArrayFloat.java)
- - 📄 [MedianOfRunningArrayInteger](src/main/java/com/thealgorithms/misc/MedianOfRunningArrayInteger.java)
- - 📄 [MedianOfRunningArrayLong](src/main/java/com/thealgorithms/misc/MedianOfRunningArrayLong.java)
- - 📄 [PalindromePrime](src/main/java/com/thealgorithms/misc/PalindromePrime.java)
- - 📄 [PalindromeSinglyLinkedList](src/main/java/com/thealgorithms/misc/PalindromeSinglyLinkedList.java)
- - 📄 [RangeInSortedArray](src/main/java/com/thealgorithms/misc/RangeInSortedArray.java)
- - 📄 [ShuffleArray](src/main/java/com/thealgorithms/misc/ShuffleArray.java)
- - 📄 [Sparsity](src/main/java/com/thealgorithms/misc/Sparsity.java)
- - 📄 [ThreeSumProblem](src/main/java/com/thealgorithms/misc/ThreeSumProblem.java)
- - 📄 [TwoSumProblem](src/main/java/com/thealgorithms/misc/TwoSumProblem.java)
- - 📁 **others**
- - 📄 [ArrayLeftRotation](src/main/java/com/thealgorithms/others/ArrayLeftRotation.java)
- - 📄 [ArrayRightRotation](src/main/java/com/thealgorithms/others/ArrayRightRotation.java)
- - 📄 [BFPRT](src/main/java/com/thealgorithms/others/BFPRT.java)
- - 📄 [BankersAlgorithm](src/main/java/com/thealgorithms/others/BankersAlgorithm.java)
- - 📄 [BoyerMoore](src/main/java/com/thealgorithms/others/BoyerMoore.java)
- - 📄 [BrianKernighanAlgorithm](src/main/java/com/thealgorithms/others/BrianKernighanAlgorithm.java)
- - 📄 [CRC16](src/main/java/com/thealgorithms/others/CRC16.java)
- - 📄 [CRC32](src/main/java/com/thealgorithms/others/CRC32.java)
- - 📄 [CRCAlgorithm](src/main/java/com/thealgorithms/others/CRCAlgorithm.java)
- - 📄 [Conway](src/main/java/com/thealgorithms/others/Conway.java)
- - 📄 [Damm](src/main/java/com/thealgorithms/others/Damm.java)
- - 📄 [Dijkstra](src/main/java/com/thealgorithms/others/Dijkstra.java)
- - 📄 [FloydTriangle](src/main/java/com/thealgorithms/others/FloydTriangle.java)
- - 📄 [GaussLegendre](src/main/java/com/thealgorithms/others/GaussLegendre.java)
- - 📄 [Huffman](src/main/java/com/thealgorithms/others/Huffman.java)
- - 📄 [Implementing_auto_completing_features_using_trie](src/main/java/com/thealgorithms/others/Implementing_auto_completing_features_using_trie.java)
- - 📄 [InsertDeleteInArray](src/main/java/com/thealgorithms/others/InsertDeleteInArray.java)
- - 📄 [IterativeFloodFill](src/main/java/com/thealgorithms/others/IterativeFloodFill.java)
- - 📄 [KochSnowflake](src/main/java/com/thealgorithms/others/KochSnowflake.java)
- - 📄 [LineSweep](src/main/java/com/thealgorithms/others/LineSweep.java)
- - 📄 [LinearCongruentialGenerator](src/main/java/com/thealgorithms/others/LinearCongruentialGenerator.java)
- - 📄 [LowestBasePalindrome](src/main/java/com/thealgorithms/others/LowestBasePalindrome.java)
- - 📄 [Luhn](src/main/java/com/thealgorithms/others/Luhn.java)
- - 📄 [Mandelbrot](src/main/java/com/thealgorithms/others/Mandelbrot.java)
- - 📄 [MaximumSumOfDistinctSubarraysWithLengthK](src/main/java/com/thealgorithms/others/MaximumSumOfDistinctSubarraysWithLengthK.java)
- - 📄 [MemoryManagementAlgorithms](src/main/java/com/thealgorithms/others/MemoryManagementAlgorithms.java)
- - 📄 [MiniMaxAlgorithm](src/main/java/com/thealgorithms/others/MiniMaxAlgorithm.java)
- - 📄 [MosAlgorithm](src/main/java/com/thealgorithms/others/MosAlgorithm.java)
- - 📄 [PageRank](src/main/java/com/thealgorithms/others/PageRank.java)
- - 📄 [PasswordGen](src/main/java/com/thealgorithms/others/PasswordGen.java)
- - 📄 [PerlinNoise](src/main/java/com/thealgorithms/others/PerlinNoise.java)
- - 📄 [QueueUsingTwoStacks](src/main/java/com/thealgorithms/others/QueueUsingTwoStacks.java)
- - 📄 [SkylineProblem](src/main/java/com/thealgorithms/others/SkylineProblem.java)
- - 📄 [TwoPointers](src/main/java/com/thealgorithms/others/TwoPointers.java)
- - 📄 [Verhoeff](src/main/java/com/thealgorithms/others/Verhoeff.java)
- - 📁 **physics**
- - 📄 [CoulombsLaw](src/main/java/com/thealgorithms/physics/CoulombsLaw.java)
- - 📄 [DampedOscillator](src/main/java/com/thealgorithms/physics/DampedOscillator.java)
- - 📄 [ElasticCollision2D](src/main/java/com/thealgorithms/physics/ElasticCollision2D.java)
- - 📄 [Gravitation](src/main/java/com/thealgorithms/physics/Gravitation.java)
- - 📄 [GroundToGroundProjectileMotion](src/main/java/com/thealgorithms/physics/GroundToGroundProjectileMotion.java)
- - 📄 [Kinematics](src/main/java/com/thealgorithms/physics/Kinematics.java)
- - 📄 [ProjectileMotion](src/main/java/com/thealgorithms/physics/ProjectileMotion.java)
- - 📄 [SimplePendulumRK4](src/main/java/com/thealgorithms/physics/SimplePendulumRK4.java)
- - 📄 [SnellLaw](src/main/java/com/thealgorithms/physics/SnellLaw.java)
- - 📄 [ThinLens](src/main/java/com/thealgorithms/physics/ThinLens.java)
- - 📁 **puzzlesandgames**
- - 📄 [TowerOfHanoi](src/main/java/com/thealgorithms/puzzlesandgames/TowerOfHanoi.java)
- - 📄 [WordBoggle](src/main/java/com/thealgorithms/puzzlesandgames/WordBoggle.java)
- - 📁 **randomized**
- - 📄 [KargerMinCut](src/main/java/com/thealgorithms/randomized/KargerMinCut.java)
- - 📄 [MonteCarloIntegration](src/main/java/com/thealgorithms/randomized/MonteCarloIntegration.java)
- - 📄 [RandomizedClosestPair](src/main/java/com/thealgorithms/randomized/RandomizedClosestPair.java)
- - 📄 [RandomizedMatrixMultiplicationVerification](src/main/java/com/thealgorithms/randomized/RandomizedMatrixMultiplicationVerification.java)
- - 📄 [RandomizedQuickSort](src/main/java/com/thealgorithms/randomized/RandomizedQuickSort.java)
- - 📄 [ReservoirSampling](src/main/java/com/thealgorithms/randomized/ReservoirSampling.java)
- - 📁 **recursion**
- - 📄 [DiceThrower](src/main/java/com/thealgorithms/recursion/DiceThrower.java)
- - 📄 [FactorialRecursion](src/main/java/com/thealgorithms/recursion/FactorialRecursion.java)
- - 📄 [FibonacciSeries](src/main/java/com/thealgorithms/recursion/FibonacciSeries.java)
- - 📄 [GenerateSubsets](src/main/java/com/thealgorithms/recursion/GenerateSubsets.java)
- - 📄 [SylvesterSequence](src/main/java/com/thealgorithms/recursion/SylvesterSequence.java)
- - 📁 **scheduling**
- - 📄 [AgingScheduling](src/main/java/com/thealgorithms/scheduling/AgingScheduling.java)
- - 📄 [EDFScheduling](src/main/java/com/thealgorithms/scheduling/EDFScheduling.java)
- - 📄 [FCFSScheduling](src/main/java/com/thealgorithms/scheduling/FCFSScheduling.java)
- - 📄 [FairShareScheduling](src/main/java/com/thealgorithms/scheduling/FairShareScheduling.java)
- - 📄 [GangScheduling](src/main/java/com/thealgorithms/scheduling/GangScheduling.java)
- - 📄 [HighestResponseRatioNextScheduling](src/main/java/com/thealgorithms/scheduling/HighestResponseRatioNextScheduling.java)
- - 📄 [JobSchedulingWithDeadline](src/main/java/com/thealgorithms/scheduling/JobSchedulingWithDeadline.java)
- - 📄 [LotteryScheduling](src/main/java/com/thealgorithms/scheduling/LotteryScheduling.java)
- - 📄 [MLFQScheduler](src/main/java/com/thealgorithms/scheduling/MLFQScheduler.java)
- - 📄 [MultiAgentScheduling](src/main/java/com/thealgorithms/scheduling/MultiAgentScheduling.java)
- - 📄 [NonPreemptivePriorityScheduling](src/main/java/com/thealgorithms/scheduling/NonPreemptivePriorityScheduling.java)
- - 📄 [PreemptivePriorityScheduling](src/main/java/com/thealgorithms/scheduling/PreemptivePriorityScheduling.java)
- - 📄 [ProportionalFairScheduling](src/main/java/com/thealgorithms/scheduling/ProportionalFairScheduling.java)
- - 📄 [RRScheduling](src/main/java/com/thealgorithms/scheduling/RRScheduling.java)
- - 📄 [RandomScheduling](src/main/java/com/thealgorithms/scheduling/RandomScheduling.java)
- - 📄 [SJFScheduling](src/main/java/com/thealgorithms/scheduling/SJFScheduling.java)
- - 📄 [SRTFScheduling](src/main/java/com/thealgorithms/scheduling/SRTFScheduling.java)
- - 📄 [SelfAdjustingScheduling](src/main/java/com/thealgorithms/scheduling/SelfAdjustingScheduling.java)
- - 📄 [SlackTimeScheduling](src/main/java/com/thealgorithms/scheduling/SlackTimeScheduling.java)
- - 📁 **diskscheduling**
- - 📄 [CircularLookScheduling](src/main/java/com/thealgorithms/scheduling/diskscheduling/CircularLookScheduling.java)
- - 📄 [CircularScanScheduling](src/main/java/com/thealgorithms/scheduling/diskscheduling/CircularScanScheduling.java)
- - 📄 [LookScheduling](src/main/java/com/thealgorithms/scheduling/diskscheduling/LookScheduling.java)
- - 📄 [SSFScheduling](src/main/java/com/thealgorithms/scheduling/diskscheduling/SSFScheduling.java)
- - 📄 [ScanScheduling](src/main/java/com/thealgorithms/scheduling/diskscheduling/ScanScheduling.java)
- - 📁 **searches**
- - 📄 [BM25InvertedIndex](src/main/java/com/thealgorithms/searches/BM25InvertedIndex.java)
- - 📄 [BinarySearch](src/main/java/com/thealgorithms/searches/BinarySearch.java)
- - 📄 [BinarySearch2dArray](src/main/java/com/thealgorithms/searches/BinarySearch2dArray.java)
- - 📄 [BoyerMoore](src/main/java/com/thealgorithms/searches/BoyerMoore.java)
- - 📄 [BreadthFirstSearch](src/main/java/com/thealgorithms/searches/BreadthFirstSearch.java)
- - 📄 [DepthFirstSearch](src/main/java/com/thealgorithms/searches/DepthFirstSearch.java)
- - 📄 [ExponentialSearch](src/main/java/com/thealgorithms/searches/ExponentialSearch.java)
- - 📄 [FibonacciSearch](src/main/java/com/thealgorithms/searches/FibonacciSearch.java)
- - 📄 [HowManyTimesRotated](src/main/java/com/thealgorithms/searches/HowManyTimesRotated.java)
- - 📄 [InterpolationSearch](src/main/java/com/thealgorithms/searches/InterpolationSearch.java)
- - 📄 [IterativeBinarySearch](src/main/java/com/thealgorithms/searches/IterativeBinarySearch.java)
- - 📄 [IterativeTernarySearch](src/main/java/com/thealgorithms/searches/IterativeTernarySearch.java)
- - 📄 [JumpSearch](src/main/java/com/thealgorithms/searches/JumpSearch.java)
- - 📄 [KMPSearch](src/main/java/com/thealgorithms/searches/KMPSearch.java)
- - 📄 [LinearSearch](src/main/java/com/thealgorithms/searches/LinearSearch.java)
- - 📄 [LinearSearchThread](src/main/java/com/thealgorithms/searches/LinearSearchThread.java)
- - 📄 [LowerBound](src/main/java/com/thealgorithms/searches/LowerBound.java)
- - 📄 [MonteCarloTreeSearch](src/main/java/com/thealgorithms/searches/MonteCarloTreeSearch.java)
- - 📄 [OrderAgnosticBinarySearch](src/main/java/com/thealgorithms/searches/OrderAgnosticBinarySearch.java)
- - 📄 [QuickSelect](src/main/java/com/thealgorithms/searches/QuickSelect.java)
- - 📄 [RabinKarpAlgorithm](src/main/java/com/thealgorithms/searches/RabinKarpAlgorithm.java)
- - 📄 [RandomSearch](src/main/java/com/thealgorithms/searches/RandomSearch.java)
- - 📄 [RecursiveBinarySearch](src/main/java/com/thealgorithms/searches/RecursiveBinarySearch.java)
- - 📄 [RowColumnWiseSorted2dArrayBinarySearch](src/main/java/com/thealgorithms/searches/RowColumnWiseSorted2dArrayBinarySearch.java)
- - 📄 [SaddlebackSearch](src/main/java/com/thealgorithms/searches/SaddlebackSearch.java)
- - 📄 [SearchInARowAndColWiseSortedMatrix](src/main/java/com/thealgorithms/searches/SearchInARowAndColWiseSortedMatrix.java)
- - 📄 [SentinelLinearSearch](src/main/java/com/thealgorithms/searches/SentinelLinearSearch.java)
- - 📄 [SquareRootBinarySearch](src/main/java/com/thealgorithms/searches/SquareRootBinarySearch.java)
- - 📄 [TernarySearch](src/main/java/com/thealgorithms/searches/TernarySearch.java)
- - 📄 [UnionFind](src/main/java/com/thealgorithms/searches/UnionFind.java)
- - 📄 [UpperBound](src/main/java/com/thealgorithms/searches/UpperBound.java)
- - 📁 **slidingwindow**
- - 📄 [LongestSubarrayWithSumLessOrEqualToK](src/main/java/com/thealgorithms/slidingwindow/LongestSubarrayWithSumLessOrEqualToK.java)
- - 📄 [LongestSubstringWithoutRepeatingCharacters](src/main/java/com/thealgorithms/slidingwindow/LongestSubstringWithoutRepeatingCharacters.java)
- - 📄 [MaxSumKSizeSubarray](src/main/java/com/thealgorithms/slidingwindow/MaxSumKSizeSubarray.java)
- - 📄 [MaximumSlidingWindow](src/main/java/com/thealgorithms/slidingwindow/MaximumSlidingWindow.java)
- - 📄 [MinSumKSizeSubarray](src/main/java/com/thealgorithms/slidingwindow/MinSumKSizeSubarray.java)
- - 📄 [MinimumWindowSubstring](src/main/java/com/thealgorithms/slidingwindow/MinimumWindowSubstring.java)
- - 📄 [ShortestCoprimeSegment](src/main/java/com/thealgorithms/slidingwindow/ShortestCoprimeSegment.java)
- - 📁 **sorts**
- - 📄 [AdaptiveMergeSort](src/main/java/com/thealgorithms/sorts/AdaptiveMergeSort.java)
- - 📄 [BeadSort](src/main/java/com/thealgorithms/sorts/BeadSort.java)
- - 📄 [BinaryInsertionSort](src/main/java/com/thealgorithms/sorts/BinaryInsertionSort.java)
- - 📄 [BitonicSort](src/main/java/com/thealgorithms/sorts/BitonicSort.java)
- - 📄 [BogoSort](src/main/java/com/thealgorithms/sorts/BogoSort.java)
- - 📄 [BubbleSort](src/main/java/com/thealgorithms/sorts/BubbleSort.java)
- - 📄 [BubbleSortRecursive](src/main/java/com/thealgorithms/sorts/BubbleSortRecursive.java)
- - 📄 [BucketSort](src/main/java/com/thealgorithms/sorts/BucketSort.java)
- - 📄 [CircleSort](src/main/java/com/thealgorithms/sorts/CircleSort.java)
- - 📄 [CocktailShakerSort](src/main/java/com/thealgorithms/sorts/CocktailShakerSort.java)
- - 📄 [CombSort](src/main/java/com/thealgorithms/sorts/CombSort.java)
- - 📄 [CountingSort](src/main/java/com/thealgorithms/sorts/CountingSort.java)
- - 📄 [CycleSort](src/main/java/com/thealgorithms/sorts/CycleSort.java)
- - 📄 [DarkSort](src/main/java/com/thealgorithms/sorts/DarkSort.java)
- - 📄 [DualPivotQuickSort](src/main/java/com/thealgorithms/sorts/DualPivotQuickSort.java)
- - 📄 [DutchNationalFlagSort](src/main/java/com/thealgorithms/sorts/DutchNationalFlagSort.java)
- - 📄 [ExchangeSort](src/main/java/com/thealgorithms/sorts/ExchangeSort.java)
- - 📄 [FlashSort](src/main/java/com/thealgorithms/sorts/FlashSort.java)
- - 📄 [GnomeSort](src/main/java/com/thealgorithms/sorts/GnomeSort.java)
- - 📄 [HeapSort](src/main/java/com/thealgorithms/sorts/HeapSort.java)
- - 📄 [InsertionSort](src/main/java/com/thealgorithms/sorts/InsertionSort.java)
- - 📄 [IntrospectiveSort](src/main/java/com/thealgorithms/sorts/IntrospectiveSort.java)
- - 📄 [LinkListSort](src/main/java/com/thealgorithms/sorts/LinkListSort.java)
- - 📄 [MergeSort](src/main/java/com/thealgorithms/sorts/MergeSort.java)
- - 📄 [MergeSortNoExtraSpace](src/main/java/com/thealgorithms/sorts/MergeSortNoExtraSpace.java)
- - 📄 [MergeSortRecursive](src/main/java/com/thealgorithms/sorts/MergeSortRecursive.java)
- - 📄 [OddEvenSort](src/main/java/com/thealgorithms/sorts/OddEvenSort.java)
- - 📄 [PancakeSort](src/main/java/com/thealgorithms/sorts/PancakeSort.java)
- - 📄 [PatienceSort](src/main/java/com/thealgorithms/sorts/PatienceSort.java)
- - 📄 [PigeonholeSort](src/main/java/com/thealgorithms/sorts/PigeonholeSort.java)
- - 📄 [PriorityQueueSort](src/main/java/com/thealgorithms/sorts/PriorityQueueSort.java)
- - 📄 [QuickSort](src/main/java/com/thealgorithms/sorts/QuickSort.java)
- - 📄 [RadixSort](src/main/java/com/thealgorithms/sorts/RadixSort.java)
- - 📄 [SelectionSort](src/main/java/com/thealgorithms/sorts/SelectionSort.java)
- - 📄 [SelectionSortRecursive](src/main/java/com/thealgorithms/sorts/SelectionSortRecursive.java)
- - 📄 [ShellSort](src/main/java/com/thealgorithms/sorts/ShellSort.java)
- - 📄 [SlowSort](src/main/java/com/thealgorithms/sorts/SlowSort.java)
- - 📄 [SortAlgorithm](src/main/java/com/thealgorithms/sorts/SortAlgorithm.java)
- - 📄 [SortUtils](src/main/java/com/thealgorithms/sorts/SortUtils.java)
- - 📄 [SortUtilsRandomGenerator](src/main/java/com/thealgorithms/sorts/SortUtilsRandomGenerator.java)
- - 📄 [SpreadSort](src/main/java/com/thealgorithms/sorts/SpreadSort.java)
- - 📄 [StalinSort](src/main/java/com/thealgorithms/sorts/StalinSort.java)
- - 📄 [StoogeSort](src/main/java/com/thealgorithms/sorts/StoogeSort.java)
- - 📄 [StrandSort](src/main/java/com/thealgorithms/sorts/StrandSort.java)
- - 📄 [SwapSort](src/main/java/com/thealgorithms/sorts/SwapSort.java)
- - 📄 [TimSort](src/main/java/com/thealgorithms/sorts/TimSort.java)
- - 📄 [TopologicalSort](src/main/java/com/thealgorithms/sorts/TopologicalSort.java)
- - 📄 [TreeSort](src/main/java/com/thealgorithms/sorts/TreeSort.java)
- - 📄 [WaveSort](src/main/java/com/thealgorithms/sorts/WaveSort.java)
- - 📄 [WiggleSort](src/main/java/com/thealgorithms/sorts/WiggleSort.java)
- - 📁 **stacks**
- - 📄 [BalancedBrackets](src/main/java/com/thealgorithms/stacks/BalancedBrackets.java)
- - 📄 [CelebrityFinder](src/main/java/com/thealgorithms/stacks/CelebrityFinder.java)
- - 📄 [DecimalToAnyUsingStack](src/main/java/com/thealgorithms/stacks/DecimalToAnyUsingStack.java)
- - 📄 [DuplicateBrackets](src/main/java/com/thealgorithms/stacks/DuplicateBrackets.java)
- - 📄 [GreatestElementConstantTime](src/main/java/com/thealgorithms/stacks/GreatestElementConstantTime.java)
- - 📄 [InfixToPostfix](src/main/java/com/thealgorithms/stacks/InfixToPostfix.java)
- - 📄 [InfixToPrefix](src/main/java/com/thealgorithms/stacks/InfixToPrefix.java)
- - 📄 [LargestRectangle](src/main/java/com/thealgorithms/stacks/LargestRectangle.java)
- - 📄 [MaximumMinimumWindow](src/main/java/com/thealgorithms/stacks/MaximumMinimumWindow.java)
- - 📄 [MinStackUsingSingleStack](src/main/java/com/thealgorithms/stacks/MinStackUsingSingleStack.java)
- - 📄 [MinStackUsingTwoStacks](src/main/java/com/thealgorithms/stacks/MinStackUsingTwoStacks.java)
- - 📄 [NextGreaterElement](src/main/java/com/thealgorithms/stacks/NextGreaterElement.java)
- - 📄 [NextSmallerElement](src/main/java/com/thealgorithms/stacks/NextSmallerElement.java)
- - 📄 [PalindromeWithStack](src/main/java/com/thealgorithms/stacks/PalindromeWithStack.java)
- - 📄 [PostfixEvaluator](src/main/java/com/thealgorithms/stacks/PostfixEvaluator.java)
- - 📄 [PostfixToInfix](src/main/java/com/thealgorithms/stacks/PostfixToInfix.java)
- - 📄 [PrefixEvaluator](src/main/java/com/thealgorithms/stacks/PrefixEvaluator.java)
- - 📄 [PrefixToInfix](src/main/java/com/thealgorithms/stacks/PrefixToInfix.java)
- - 📄 [SmallestElementConstantTime](src/main/java/com/thealgorithms/stacks/SmallestElementConstantTime.java)
- - 📄 [SortStack](src/main/java/com/thealgorithms/stacks/SortStack.java)
- - 📄 [StackPostfixNotation](src/main/java/com/thealgorithms/stacks/StackPostfixNotation.java)
- - 📄 [StackUsingTwoQueues](src/main/java/com/thealgorithms/stacks/StackUsingTwoQueues.java)
- - 📄 [TrappingRainwater](src/main/java/com/thealgorithms/stacks/TrappingRainwater.java)
- - 📄 [ValidParentheses](src/main/java/com/thealgorithms/stacks/ValidParentheses.java)
- - 📁 **strings**
- - 📄 [AhoCorasick](src/main/java/com/thealgorithms/strings/AhoCorasick.java)
- - 📄 [Alphabetical](src/main/java/com/thealgorithms/strings/Alphabetical.java)
- - 📄 [AlternativeStringArrange](src/main/java/com/thealgorithms/strings/AlternativeStringArrange.java)
- - 📄 [Anagrams](src/main/java/com/thealgorithms/strings/Anagrams.java)
- - 📄 [CharactersSame](src/main/java/com/thealgorithms/strings/CharactersSame.java)
- - 📄 [CheckVowels](src/main/java/com/thealgorithms/strings/CheckVowels.java)
- - 📄 [CountChar](src/main/java/com/thealgorithms/strings/CountChar.java)
- - 📄 [CountWords](src/main/java/com/thealgorithms/strings/CountWords.java)
- - 📄 [HammingDistance](src/main/java/com/thealgorithms/strings/HammingDistance.java)
- - 📄 [HorspoolSearch](src/main/java/com/thealgorithms/strings/HorspoolSearch.java)
- - 📄 [Isogram](src/main/java/com/thealgorithms/strings/Isogram.java)
- - 📄 [Isomorphic](src/main/java/com/thealgorithms/strings/Isomorphic.java)
- - 📄 [KMP](src/main/java/com/thealgorithms/strings/KMP.java)
- - 📄 [LengthOfLastWord](src/main/java/com/thealgorithms/strings/LengthOfLastWord.java)
- - 📄 [LetterCombinationsOfPhoneNumber](src/main/java/com/thealgorithms/strings/LetterCombinationsOfPhoneNumber.java)
- - 📄 [LongestCommonPrefix](src/main/java/com/thealgorithms/strings/LongestCommonPrefix.java)
- - 📄 [LongestNonRepetitiveSubstring](src/main/java/com/thealgorithms/strings/LongestNonRepetitiveSubstring.java)
- - 📄 [Lower](src/main/java/com/thealgorithms/strings/Lower.java)
- - 📄 [Manacher](src/main/java/com/thealgorithms/strings/Manacher.java)
- - 📄 [MyAtoi](src/main/java/com/thealgorithms/strings/MyAtoi.java)
- - 📄 [Palindrome](src/main/java/com/thealgorithms/strings/Palindrome.java)
- - 📄 [Pangram](src/main/java/com/thealgorithms/strings/Pangram.java)
- - 📄 [PermuteString](src/main/java/com/thealgorithms/strings/PermuteString.java)
- - 📄 [RabinKarp](src/main/java/com/thealgorithms/strings/RabinKarp.java)
- - 📄 [RemoveDuplicateFromString](src/main/java/com/thealgorithms/strings/RemoveDuplicateFromString.java)
- - 📄 [ReturnSubsequence](src/main/java/com/thealgorithms/strings/ReturnSubsequence.java)
- - 📄 [ReverseString](src/main/java/com/thealgorithms/strings/ReverseString.java)
- - 📄 [ReverseWordsInString](src/main/java/com/thealgorithms/strings/ReverseWordsInString.java)
- - 📄 [Rotation](src/main/java/com/thealgorithms/strings/Rotation.java)
- - 📄 [StringCompression](src/main/java/com/thealgorithms/strings/StringCompression.java)
- - 📄 [StringMatchFiniteAutomata](src/main/java/com/thealgorithms/strings/StringMatchFiniteAutomata.java)
- - 📄 [SuffixArray](src/main/java/com/thealgorithms/strings/SuffixArray.java)
- - 📄 [Upper](src/main/java/com/thealgorithms/strings/Upper.java)
- - 📄 [WordLadder](src/main/java/com/thealgorithms/strings/WordLadder.java)
- - 📄 [ZAlgorithm](src/main/java/com/thealgorithms/strings/ZAlgorithm.java)
- - 📁 **zigZagPattern**
- - 📄 [ZigZagPattern](src/main/java/com/thealgorithms/strings/zigZagPattern/ZigZagPattern.java)
- - 📁 **tree**
- - 📄 [HeavyLightDecomposition](src/main/java/com/thealgorithms/tree/HeavyLightDecomposition.java)
-- 📁 **test**
- - 📁 **java**
- - 📁 **com**
- - 📁 **thealgorithms**
- - 📁 **audiofilters**
- - 📄 [EMAFilterTest](src/test/java/com/thealgorithms/audiofilters/EMAFilterTest.java)
- - 📄 [IIRFilterTest](src/test/java/com/thealgorithms/audiofilters/IIRFilterTest.java)
- - 📁 **backtracking**
- - 📄 [AllPathsFromSourceToTargetTest](src/test/java/com/thealgorithms/backtracking/AllPathsFromSourceToTargetTest.java)
- - 📄 [ArrayCombinationTest](src/test/java/com/thealgorithms/backtracking/ArrayCombinationTest.java)
- - 📄 [CombinationSumTest](src/test/java/com/thealgorithms/backtracking/CombinationSumTest.java)
- - 📄 [CombinationTest](src/test/java/com/thealgorithms/backtracking/CombinationTest.java)
- - 📄 [CrosswordSolverTest](src/test/java/com/thealgorithms/backtracking/CrosswordSolverTest.java)
- - 📄 [FloodFillTest](src/test/java/com/thealgorithms/backtracking/FloodFillTest.java)
- - 📄 [KnightsTourTest](src/test/java/com/thealgorithms/backtracking/KnightsTourTest.java)
- - 📄 [MColoringTest](src/test/java/com/thealgorithms/backtracking/MColoringTest.java)
- - 📄 [MazeRecursionTest](src/test/java/com/thealgorithms/backtracking/MazeRecursionTest.java)
- - 📄 [NQueensTest](src/test/java/com/thealgorithms/backtracking/NQueensTest.java)
- - 📄 [ParenthesesGeneratorTest](src/test/java/com/thealgorithms/backtracking/ParenthesesGeneratorTest.java)
- - 📄 [PermutationTest](src/test/java/com/thealgorithms/backtracking/PermutationTest.java)
- - 📄 [PowerSumTest](src/test/java/com/thealgorithms/backtracking/PowerSumTest.java)
- - 📄 [SubsequenceFinderTest](src/test/java/com/thealgorithms/backtracking/SubsequenceFinderTest.java)
- - 📄 [SudokuSolverTest](src/test/java/com/thealgorithms/backtracking/SudokuSolverTest.java)
- - 📄 [UniquePermutationTest](src/test/java/com/thealgorithms/backtracking/UniquePermutationTest.java)
- - 📄 [WordPatternMatcherTest](src/test/java/com/thealgorithms/backtracking/WordPatternMatcherTest.java)
- - 📄 [WordSearchTest](src/test/java/com/thealgorithms/backtracking/WordSearchTest.java)
- - 📁 **bitmanipulation**
- - 📄 [BcdConversionTest](src/test/java/com/thealgorithms/bitmanipulation/BcdConversionTest.java)
- - 📄 [BinaryPalindromeCheckTest](src/test/java/com/thealgorithms/bitmanipulation/BinaryPalindromeCheckTest.java)
- - 📄 [BitRotateTest](src/test/java/com/thealgorithms/bitmanipulation/BitRotateTest.java)
- - 📄 [BitSwapTest](src/test/java/com/thealgorithms/bitmanipulation/BitSwapTest.java)
- - 📄 [BitwiseGCDTest](src/test/java/com/thealgorithms/bitmanipulation/BitwiseGCDTest.java)
- - 📄 [BooleanAlgebraGatesTest](src/test/java/com/thealgorithms/bitmanipulation/BooleanAlgebraGatesTest.java)
- - 📄 [ClearLeftmostSetBitTest](src/test/java/com/thealgorithms/bitmanipulation/ClearLeftmostSetBitTest.java)
- - 📄 [CountBitsFlipTest](src/test/java/com/thealgorithms/bitmanipulation/CountBitsFlipTest.java)
- - 📄 [CountLeadingZerosTest](src/test/java/com/thealgorithms/bitmanipulation/CountLeadingZerosTest.java)
- - 📄 [CountSetBitsTest](src/test/java/com/thealgorithms/bitmanipulation/CountSetBitsTest.java)
- - 📄 [FindNthBitTest](src/test/java/com/thealgorithms/bitmanipulation/FindNthBitTest.java)
- - 📄 [FirstDifferentBitTest](src/test/java/com/thealgorithms/bitmanipulation/FirstDifferentBitTest.java)
- - 📄 [GenerateSubsetsTest](src/test/java/com/thealgorithms/bitmanipulation/GenerateSubsetsTest.java)
- - 📄 [GrayCodeConversionTest](src/test/java/com/thealgorithms/bitmanipulation/GrayCodeConversionTest.java)
- - 📄 [HammingDistanceTest](src/test/java/com/thealgorithms/bitmanipulation/HammingDistanceTest.java)
- - 📄 [HigherLowerPowerOfTwoTest](src/test/java/com/thealgorithms/bitmanipulation/HigherLowerPowerOfTwoTest.java)
- - 📄 [HighestSetBitTest](src/test/java/com/thealgorithms/bitmanipulation/HighestSetBitTest.java)
- - 📄 [IndexOfRightMostSetBitTest](src/test/java/com/thealgorithms/bitmanipulation/IndexOfRightMostSetBitTest.java)
- - 📄 [IsEvenTest](src/test/java/com/thealgorithms/bitmanipulation/IsEvenTest.java)
- - 📄 [IsPowerTwoTest](src/test/java/com/thealgorithms/bitmanipulation/IsPowerTwoTest.java)
- - 📄 [LowestSetBitTest](src/test/java/com/thealgorithms/bitmanipulation/LowestSetBitTest.java)
- - 📄 [ModuloPowerOfTwoTest](src/test/java/com/thealgorithms/bitmanipulation/ModuloPowerOfTwoTest.java)
- - 📄 [NextHigherSameBitCountTest](src/test/java/com/thealgorithms/bitmanipulation/NextHigherSameBitCountTest.java)
- - 📄 [NonRepeatingNumberFinderTest](src/test/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinderTest.java)
- - 📄 [NumberAppearingOddTimesTest](src/test/java/com/thealgorithms/bitmanipulation/NumberAppearingOddTimesTest.java)
- - 📄 [NumbersDifferentSignsTest](src/test/java/com/thealgorithms/bitmanipulation/NumbersDifferentSignsTest.java)
- - 📄 [OneBitDifferenceTest](src/test/java/com/thealgorithms/bitmanipulation/OneBitDifferenceTest.java)
- - 📄 [OnesComplementTest](src/test/java/com/thealgorithms/bitmanipulation/OnesComplementTest.java)
- - 📄 [ParityCheckTest](src/test/java/com/thealgorithms/bitmanipulation/ParityCheckTest.java)
- - 📄 [ReverseBitsTest](src/test/java/com/thealgorithms/bitmanipulation/ReverseBitsTest.java)
- - 📄 [SingleBitOperationsTest](src/test/java/com/thealgorithms/bitmanipulation/SingleBitOperationsTest.java)
- - 📄 [SingleElementTest](src/test/java/com/thealgorithms/bitmanipulation/SingleElementTest.java)
- - 📄 [SwapAdjacentBitsTest](src/test/java/com/thealgorithms/bitmanipulation/SwapAdjacentBitsTest.java)
- - 📄 [TwosComplementTest](src/test/java/com/thealgorithms/bitmanipulation/TwosComplementTest.java)
- - 📄 [Xs3ConversionTest](src/test/java/com/thealgorithms/bitmanipulation/Xs3ConversionTest.java)
- - 📁 **ciphers**
- - 📄 [ADFGVXCipherTest](src/test/java/com/thealgorithms/ciphers/ADFGVXCipherTest.java)
- - 📄 [AESEncryptionTest](src/test/java/com/thealgorithms/ciphers/AESEncryptionTest.java)
- - 📄 [AffineCipherTest](src/test/java/com/thealgorithms/ciphers/AffineCipherTest.java)
- - 📄 [AtbashTest](src/test/java/com/thealgorithms/ciphers/AtbashTest.java)
- - 📄 [AutokeyTest](src/test/java/com/thealgorithms/ciphers/AutokeyTest.java)
- - 📄 [BaconianCipherTest](src/test/java/com/thealgorithms/ciphers/BaconianCipherTest.java)
- - 📄 [BlowfishTest](src/test/java/com/thealgorithms/ciphers/BlowfishTest.java)
- - 📄 [CaesarTest](src/test/java/com/thealgorithms/ciphers/CaesarTest.java)
- - 📄 [ColumnarTranspositionCipherTest](src/test/java/com/thealgorithms/ciphers/ColumnarTranspositionCipherTest.java)
- - 📄 [DESTest](src/test/java/com/thealgorithms/ciphers/DESTest.java)
- - 📄 [DiffieHellmanTest](src/test/java/com/thealgorithms/ciphers/DiffieHellmanTest.java)
- - 📄 [ECCTest](src/test/java/com/thealgorithms/ciphers/ECCTest.java)
- - 📄 [HillCipherTest](src/test/java/com/thealgorithms/ciphers/HillCipherTest.java)
- - 📄 [MonoAlphabeticTest](src/test/java/com/thealgorithms/ciphers/MonoAlphabeticTest.java)
- - 📄 [OneTimePadCipherTest](src/test/java/com/thealgorithms/ciphers/OneTimePadCipherTest.java)
- - 📄 [PermutationCipherTest](src/test/java/com/thealgorithms/ciphers/PermutationCipherTest.java)
- - 📄 [PlayfairTest](src/test/java/com/thealgorithms/ciphers/PlayfairTest.java)
- - 📄 [PolybiusTest](src/test/java/com/thealgorithms/ciphers/PolybiusTest.java)
- - 📄 [RSATest](src/test/java/com/thealgorithms/ciphers/RSATest.java)
- - 📄 [RailFenceTest](src/test/java/com/thealgorithms/ciphers/RailFenceTest.java)
- - 📄 [SimpleSubCipherTest](src/test/java/com/thealgorithms/ciphers/SimpleSubCipherTest.java)
- - 📄 [VigenereTest](src/test/java/com/thealgorithms/ciphers/VigenereTest.java)
- - 📄 [XORCipherTest](src/test/java/com/thealgorithms/ciphers/XORCipherTest.java)
- - 📁 **a5**
- - 📄 [A5CipherTest](src/test/java/com/thealgorithms/ciphers/a5/A5CipherTest.java)
- - 📄 [A5KeyStreamGeneratorTest](src/test/java/com/thealgorithms/ciphers/a5/A5KeyStreamGeneratorTest.java)
- - 📄 [LFSRTest](src/test/java/com/thealgorithms/ciphers/a5/LFSRTest.java)
- - 📁 **compression**
- - 📄 [ArithmeticCodingTest](src/test/java/com/thealgorithms/compression/ArithmeticCodingTest.java)
- - 📄 [BurrowsWheelerTransformTest](src/test/java/com/thealgorithms/compression/BurrowsWheelerTransformTest.java)
- - 📄 [LZ77Test](src/test/java/com/thealgorithms/compression/LZ77Test.java)
- - 📄 [LZ78Test](src/test/java/com/thealgorithms/compression/LZ78Test.java)
- - 📄 [LZWTest](src/test/java/com/thealgorithms/compression/LZWTest.java)
- - 📄 [MoveToFrontTest](src/test/java/com/thealgorithms/compression/MoveToFrontTest.java)
- - 📄 [RunLengthEncodingTest](src/test/java/com/thealgorithms/compression/RunLengthEncodingTest.java)
- - 📄 [ShannonFanoTest](src/test/java/com/thealgorithms/compression/ShannonFanoTest.java)
- - 📁 **conversions**
- - 📄 [AffineConverterTest](src/test/java/com/thealgorithms/conversions/AffineConverterTest.java)
- - 📄 [AnyBaseToDecimalTest](src/test/java/com/thealgorithms/conversions/AnyBaseToDecimalTest.java)
- - 📄 [AnytoAnyTest](src/test/java/com/thealgorithms/conversions/AnytoAnyTest.java)
- - 📄 [Base64Test](src/test/java/com/thealgorithms/conversions/Base64Test.java)
- - 📄 [BinaryToDecimalTest](src/test/java/com/thealgorithms/conversions/BinaryToDecimalTest.java)
- - 📄 [BinaryToHexadecimalTest](src/test/java/com/thealgorithms/conversions/BinaryToHexadecimalTest.java)
- - 📄 [BinaryToOctalTest](src/test/java/com/thealgorithms/conversions/BinaryToOctalTest.java)
- - 📄 [CoordinateConverterTest](src/test/java/com/thealgorithms/conversions/CoordinateConverterTest.java)
- - 📄 [DecimalToAnyBaseTest](src/test/java/com/thealgorithms/conversions/DecimalToAnyBaseTest.java)
- - 📄 [DecimalToBinaryTest](src/test/java/com/thealgorithms/conversions/DecimalToBinaryTest.java)
- - 📄 [DecimalToHexadecimalTest](src/test/java/com/thealgorithms/conversions/DecimalToHexadecimalTest.java)
- - 📄 [DecimalToOctalTest](src/test/java/com/thealgorithms/conversions/DecimalToOctalTest.java)
- - 📄 [EndianConverterTest](src/test/java/com/thealgorithms/conversions/EndianConverterTest.java)
- - 📄 [HexToOctTest](src/test/java/com/thealgorithms/conversions/HexToOctTest.java)
- - 📄 [HexaDecimalToBinaryTest](src/test/java/com/thealgorithms/conversions/HexaDecimalToBinaryTest.java)
- - 📄 [HexaDecimalToDecimalTest](src/test/java/com/thealgorithms/conversions/HexaDecimalToDecimalTest.java)
- - 📄 [IPConverterTest](src/test/java/com/thealgorithms/conversions/IPConverterTest.java)
- - 📄 [IPv6ConverterTest](src/test/java/com/thealgorithms/conversions/IPv6ConverterTest.java)
- - 📄 [IntegerToEnglishTest](src/test/java/com/thealgorithms/conversions/IntegerToEnglishTest.java)
- - 📄 [IntegerToRomanTest](src/test/java/com/thealgorithms/conversions/IntegerToRomanTest.java)
- - 📄 [MorseCodeConverterTest](src/test/java/com/thealgorithms/conversions/MorseCodeConverterTest.java)
- - 📄 [NumberToWordsTest](src/test/java/com/thealgorithms/conversions/NumberToWordsTest.java)
- - 📄 [OctalToBinaryTest](src/test/java/com/thealgorithms/conversions/OctalToBinaryTest.java)
- - 📄 [OctalToDecimalTest](src/test/java/com/thealgorithms/conversions/OctalToDecimalTest.java)
- - 📄 [OctalToHexadecimalTest](src/test/java/com/thealgorithms/conversions/OctalToHexadecimalTest.java)
- - 📄 [PhoneticAlphabetConverterTest](src/test/java/com/thealgorithms/conversions/PhoneticAlphabetConverterTest.java)
- - 📄 [RomanToIntegerTest](src/test/java/com/thealgorithms/conversions/RomanToIntegerTest.java)
- - 📄 [TemperatureConverterTest](src/test/java/com/thealgorithms/conversions/TemperatureConverterTest.java)
- - 📄 [TimeConverterTest](src/test/java/com/thealgorithms/conversions/TimeConverterTest.java)
- - 📄 [TurkishToLatinConversionTest](src/test/java/com/thealgorithms/conversions/TurkishToLatinConversionTest.java)
- - 📄 [UnitConversionsTest](src/test/java/com/thealgorithms/conversions/UnitConversionsTest.java)
- - 📄 [UnitsConverterTest](src/test/java/com/thealgorithms/conversions/UnitsConverterTest.java)
- - 📄 [WordsToNumberTest](src/test/java/com/thealgorithms/conversions/WordsToNumberTest.java)
- - 📁 **datastructures**
- - 📁 **bag**
- - 📄 [BagTest](src/test/java/com/thealgorithms/datastructures/bag/BagTest.java)
- - 📁 **bloomfilter**
- - 📄 [BloomFilterTest](src/test/java/com/thealgorithms/datastructures/bloomfilter/BloomFilterTest.java)
- - 📁 **buffers**
- - 📄 [CircularBufferTest](src/test/java/com/thealgorithms/datastructures/buffers/CircularBufferTest.java)
- - 📁 **caches**
- - 📄 [FIFOCacheTest](src/test/java/com/thealgorithms/datastructures/caches/FIFOCacheTest.java)
- - 📄 [LFUCacheTest](src/test/java/com/thealgorithms/datastructures/caches/LFUCacheTest.java)
- - 📄 [LIFOCacheTest](src/test/java/com/thealgorithms/datastructures/caches/LIFOCacheTest.java)
- - 📄 [LRUCacheTest](src/test/java/com/thealgorithms/datastructures/caches/LRUCacheTest.java)
- - 📄 [MRUCacheTest](src/test/java/com/thealgorithms/datastructures/caches/MRUCacheTest.java)
- - 📄 [RRCacheTest](src/test/java/com/thealgorithms/datastructures/caches/RRCacheTest.java)
- - 📁 **crdt**
- - 📄 [GCounterTest](src/test/java/com/thealgorithms/datastructures/crdt/GCounterTest.java)
- - 📄 [GSetTest](src/test/java/com/thealgorithms/datastructures/crdt/GSetTest.java)
- - 📄 [LWWElementSetTest](src/test/java/com/thealgorithms/datastructures/crdt/LWWElementSetTest.java)
- - 📄 [ORSetTest](src/test/java/com/thealgorithms/datastructures/crdt/ORSetTest.java)
- - 📄 [PNCounterTest](src/test/java/com/thealgorithms/datastructures/crdt/PNCounterTest.java)
- - 📄 [TwoPSetTest](src/test/java/com/thealgorithms/datastructures/crdt/TwoPSetTest.java)
- - 📁 **disjointsetunion**
- - 📄 [DisjointSetUnionBySizeTest](src/test/java/com/thealgorithms/datastructures/disjointsetunion/DisjointSetUnionBySizeTest.java)
- - 📄 [DisjointSetUnionTest](src/test/java/com/thealgorithms/datastructures/disjointsetunion/DisjointSetUnionTest.java)
- - 📁 **dynamicarray**
- - 📄 [DynamicArrayTest](src/test/java/com/thealgorithms/datastructures/dynamicarray/DynamicArrayTest.java)
- - 📁 **graphs**
- - 📄 [AStarTest](src/test/java/com/thealgorithms/datastructures/graphs/AStarTest.java)
- - 📄 [BellmanFordTest](src/test/java/com/thealgorithms/datastructures/graphs/BellmanFordTest.java)
- - 📄 [BipartiteGraphDFSTest](src/test/java/com/thealgorithms/datastructures/graphs/BipartiteGraphDFSTest.java)
- - 📄 [BoruvkaAlgorithmTest](src/test/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithmTest.java)
- - 📄 [ConnectedComponentTest](src/test/java/com/thealgorithms/datastructures/graphs/ConnectedComponentTest.java)
- - 📄 [DialsAlgorithmTest](src/test/java/com/thealgorithms/datastructures/graphs/DialsAlgorithmTest.java)
- - 📄 [DijkstraAlgorithmTest](src/test/java/com/thealgorithms/datastructures/graphs/DijkstraAlgorithmTest.java)
- - 📄 [DijkstraOptimizedAlgorithmTest](src/test/java/com/thealgorithms/datastructures/graphs/DijkstraOptimizedAlgorithmTest.java)
- - 📄 [EdmondsBlossomAlgorithmTest](src/test/java/com/thealgorithms/datastructures/graphs/EdmondsBlossomAlgorithmTest.java)
- - 📄 [FloydWarshallTest](src/test/java/com/thealgorithms/datastructures/graphs/FloydWarshallTest.java)
- - 📄 [FordFulkersonTest](src/test/java/com/thealgorithms/datastructures/graphs/FordFulkersonTest.java)
- - 📄 [HamiltonianCycleTest](src/test/java/com/thealgorithms/datastructures/graphs/HamiltonianCycleTest.java)
- - 📄 [JohnsonsAlgorithmTest](src/test/java/com/thealgorithms/datastructures/graphs/JohnsonsAlgorithmTest.java)
- - 📄 [KahnsAlgorithmTest](src/test/java/com/thealgorithms/datastructures/graphs/KahnsAlgorithmTest.java)
- - 📄 [KosarajuTest](src/test/java/com/thealgorithms/datastructures/graphs/KosarajuTest.java)
- - 📄 [KruskalTest](src/test/java/com/thealgorithms/datastructures/graphs/KruskalTest.java)
- - 📄 [MatrixGraphsTest](src/test/java/com/thealgorithms/datastructures/graphs/MatrixGraphsTest.java)
- - 📄 [PrimMSTTest](src/test/java/com/thealgorithms/datastructures/graphs/PrimMSTTest.java)
- - 📄 [TarjansAlgorithmTest](src/test/java/com/thealgorithms/datastructures/graphs/TarjansAlgorithmTest.java)
- - 📄 [TwoSatTest](src/test/java/com/thealgorithms/datastructures/graphs/TwoSatTest.java)
- - 📄 [WelshPowellTest](src/test/java/com/thealgorithms/datastructures/graphs/WelshPowellTest.java)
- - 📁 **hashmap**
- - 📁 **hashing**
- - 📄 [GenericHashMapUsingArrayListTest](src/test/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayListTest.java)
- - 📄 [GenericHashMapUsingArrayTest](src/test/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayTest.java)
- - 📄 [HashMapCuckooHashingTest](src/test/java/com/thealgorithms/datastructures/hashmap/hashing/HashMapCuckooHashingTest.java)
- - 📄 [HashMapTest](src/test/java/com/thealgorithms/datastructures/hashmap/hashing/HashMapTest.java)
- - 📄 [ImmutableHashMapTest](src/test/java/com/thealgorithms/datastructures/hashmap/hashing/ImmutableHashMapTest.java)
- - 📄 [IntersectionTest](src/test/java/com/thealgorithms/datastructures/hashmap/hashing/IntersectionTest.java)
- - 📄 [LinearProbingHashMapTest](src/test/java/com/thealgorithms/datastructures/hashmap/hashing/LinearProbingHashMapTest.java)
- - 📄 [MajorityElementTest](src/test/java/com/thealgorithms/datastructures/hashmap/hashing/MajorityElementTest.java)
- - 📄 [MapTest](src/test/java/com/thealgorithms/datastructures/hashmap/hashing/MapTest.java)
- - 📁 **heaps**
- - 📄 [FibonacciHeapTest](src/test/java/com/thealgorithms/datastructures/heaps/FibonacciHeapTest.java)
- - 📄 [GenericHeapTest](src/test/java/com/thealgorithms/datastructures/heaps/GenericHeapTest.java)
- - 📄 [HeapElementTest](src/test/java/com/thealgorithms/datastructures/heaps/HeapElementTest.java)
- - 📄 [IndexedPriorityQueueTest](src/test/java/com/thealgorithms/datastructures/heaps/IndexedPriorityQueueTest.java)
- - 📄 [KthElementFinderTest](src/test/java/com/thealgorithms/datastructures/heaps/KthElementFinderTest.java)
- - 📄 [LeftistHeapTest](src/test/java/com/thealgorithms/datastructures/heaps/LeftistHeapTest.java)
- - 📄 [MaxHeapTest](src/test/java/com/thealgorithms/datastructures/heaps/MaxHeapTest.java)
- - 📄 [MedianFinderTest](src/test/java/com/thealgorithms/datastructures/heaps/MedianFinderTest.java)
- - 📄 [MergeKSortedArraysTest](src/test/java/com/thealgorithms/datastructures/heaps/MergeKSortedArraysTest.java)
- - 📄 [MinHeapTest](src/test/java/com/thealgorithms/datastructures/heaps/MinHeapTest.java)
- - 📄 [MinPriorityQueueTest](src/test/java/com/thealgorithms/datastructures/heaps/MinPriorityQueueTest.java)
- - 📁 **lists**
- - 📄 [CircleLinkedListTest](src/test/java/com/thealgorithms/datastructures/lists/CircleLinkedListTest.java)
- - 📄 [CircularDoublyLinkedListTest](src/test/java/com/thealgorithms/datastructures/lists/CircularDoublyLinkedListTest.java)
- - 📄 [CountSinglyLinkedListRecursionTest](src/test/java/com/thealgorithms/datastructures/lists/CountSinglyLinkedListRecursionTest.java)
- - 📄 [CreateAndDetectLoopTest](src/test/java/com/thealgorithms/datastructures/lists/CreateAndDetectLoopTest.java)
- - 📄 [CursorLinkedListTest](src/test/java/com/thealgorithms/datastructures/lists/CursorLinkedListTest.java)
- - 📄 [FlattenMultilevelLinkedListTest](src/test/java/com/thealgorithms/datastructures/lists/FlattenMultilevelLinkedListTest.java)
- - 📄 [MergeKSortedLinkedListTest](src/test/java/com/thealgorithms/datastructures/lists/MergeKSortedLinkedListTest.java)
- - 📄 [MergeSortedArrayListTest](src/test/java/com/thealgorithms/datastructures/lists/MergeSortedArrayListTest.java)
- - 📄 [MergeSortedSinglyLinkedListTest](src/test/java/com/thealgorithms/datastructures/lists/MergeSortedSinglyLinkedListTest.java)
- - 📄 [QuickSortLinkedListTest](src/test/java/com/thealgorithms/datastructures/lists/QuickSortLinkedListTest.java)
- - 📄 [ReverseKGroupTest](src/test/java/com/thealgorithms/datastructures/lists/ReverseKGroupTest.java)
- - 📄 [RotateSinglyLinkedListsTest](src/test/java/com/thealgorithms/datastructures/lists/RotateSinglyLinkedListsTest.java)
- - 📄 [SearchSinglyLinkedListRecursionTest](src/test/java/com/thealgorithms/datastructures/lists/SearchSinglyLinkedListRecursionTest.java)
- - 📄 [SinglyLinkedListTest](src/test/java/com/thealgorithms/datastructures/lists/SinglyLinkedListTest.java)
- - 📄 [SkipListTest](src/test/java/com/thealgorithms/datastructures/lists/SkipListTest.java)
- - 📄 [SortedLinkedListTest](src/test/java/com/thealgorithms/datastructures/lists/SortedLinkedListTest.java)
- - 📄 [TortoiseHareAlgoTest](src/test/java/com/thealgorithms/datastructures/lists/TortoiseHareAlgoTest.java)
- - 📁 **queues**
- - 📄 [CircularQueueTest](src/test/java/com/thealgorithms/datastructures/queues/CircularQueueTest.java)
- - 📄 [DequeTest](src/test/java/com/thealgorithms/datastructures/queues/DequeTest.java)
- - 📄 [GenericArrayListQueueTest](src/test/java/com/thealgorithms/datastructures/queues/GenericArrayListQueueTest.java)
- - 📄 [LinkedQueueTest](src/test/java/com/thealgorithms/datastructures/queues/LinkedQueueTest.java)
- - 📄 [PriorityQueuesTest](src/test/java/com/thealgorithms/datastructures/queues/PriorityQueuesTest.java)
- - 📄 [QueueByTwoStacksTest](src/test/java/com/thealgorithms/datastructures/queues/QueueByTwoStacksTest.java)
- - 📄 [QueueTest](src/test/java/com/thealgorithms/datastructures/queues/QueueTest.java)
- - 📄 [SlidingWindowMaximumTest](src/test/java/com/thealgorithms/datastructures/queues/SlidingWindowMaximumTest.java)
- - 📄 [TokenBucketTest](src/test/java/com/thealgorithms/datastructures/queues/TokenBucketTest.java)
- - 📁 **stacks**
- - 📄 [NodeStackTest](src/test/java/com/thealgorithms/datastructures/stacks/NodeStackTest.java)
- - 📄 [ReverseStackTest](src/test/java/com/thealgorithms/datastructures/stacks/ReverseStackTest.java)
- - 📄 [StackArrayListTest](src/test/java/com/thealgorithms/datastructures/stacks/StackArrayListTest.java)
- - 📄 [StackArrayTest](src/test/java/com/thealgorithms/datastructures/stacks/StackArrayTest.java)
- - 📄 [StackOfLinkedListTest](src/test/java/com/thealgorithms/datastructures/stacks/StackOfLinkedListTest.java)
- - 📁 **trees**
- - 📄 [AVLTreeTest](src/test/java/com/thealgorithms/datastructures/trees/AVLTreeTest.java)
- - 📄 [BSTFromSortedArrayTest](src/test/java/com/thealgorithms/datastructures/trees/BSTFromSortedArrayTest.java)
- - 📄 [BSTIterativeTest](src/test/java/com/thealgorithms/datastructures/trees/BSTIterativeTest.java)
- - 📄 [BSTRecursiveGenericTest](src/test/java/com/thealgorithms/datastructures/trees/BSTRecursiveGenericTest.java)
- - 📄 [BSTRecursiveTest](src/test/java/com/thealgorithms/datastructures/trees/BSTRecursiveTest.java)
- - 📄 [BTreeTest](src/test/java/com/thealgorithms/datastructures/trees/BTreeTest.java)
- - 📄 [BinaryTreeTest](src/test/java/com/thealgorithms/datastructures/trees/BinaryTreeTest.java)
- - 📄 [BinaryTreeToStringTest](src/test/java/com/thealgorithms/datastructures/trees/BinaryTreeToStringTest.java)
- - 📄 [BoundaryTraversalTest](src/test/java/com/thealgorithms/datastructures/trees/BoundaryTraversalTest.java)
- - 📄 [CeilInBinarySearchTreeTest](src/test/java/com/thealgorithms/datastructures/trees/CeilInBinarySearchTreeTest.java)
- - 📄 [CentroidDecompositionTest](src/test/java/com/thealgorithms/datastructures/trees/CentroidDecompositionTest.java)
- - 📄 [CheckBinaryTreeIsValidBSTTest](src/test/java/com/thealgorithms/datastructures/trees/CheckBinaryTreeIsValidBSTTest.java)
- - 📄 [CheckIfBinaryTreeBalancedTest](src/test/java/com/thealgorithms/datastructures/trees/CheckIfBinaryTreeBalancedTest.java)
- - 📄 [CheckTreeIsSymmetricTest](src/test/java/com/thealgorithms/datastructures/trees/CheckTreeIsSymmetricTest.java)
- - 📄 [CreateBinaryTreeFromInorderPreorderTest](src/test/java/com/thealgorithms/datastructures/trees/CreateBinaryTreeFromInorderPreorderTest.java)
- - 📄 [InorderTraversalTest](src/test/java/com/thealgorithms/datastructures/trees/InorderTraversalTest.java)
- - 📄 [KDTreeTest](src/test/java/com/thealgorithms/datastructures/trees/KDTreeTest.java)
- - 📄 [LazySegmentTreeTest](src/test/java/com/thealgorithms/datastructures/trees/LazySegmentTreeTest.java)
- - 📄 [LevelOrderTraversalTest](src/test/java/com/thealgorithms/datastructures/trees/LevelOrderTraversalTest.java)
- - 📄 [PostOrderTraversalTest](src/test/java/com/thealgorithms/datastructures/trees/PostOrderTraversalTest.java)
- - 📄 [PreOrderTraversalTest](src/test/java/com/thealgorithms/datastructures/trees/PreOrderTraversalTest.java)
- - 📄 [QuadTreeTest](src/test/java/com/thealgorithms/datastructures/trees/QuadTreeTest.java)
- - 📄 [SameTreesCheckTest](src/test/java/com/thealgorithms/datastructures/trees/SameTreesCheckTest.java)
- - 📄 [SplayTreeTest](src/test/java/com/thealgorithms/datastructures/trees/SplayTreeTest.java)
- - 📄 [ThreadedBinaryTreeTest](src/test/java/com/thealgorithms/datastructures/trees/ThreadedBinaryTreeTest.java)
- - 📄 [TreapTest](src/test/java/com/thealgorithms/datastructures/trees/TreapTest.java)
- - 📄 [TreeTestUtils](src/test/java/com/thealgorithms/datastructures/trees/TreeTestUtils.java)
- - 📄 [TrieTest](src/test/java/com/thealgorithms/datastructures/trees/TrieTest.java)
- - 📄 [VerticalOrderTraversalTest](src/test/java/com/thealgorithms/datastructures/trees/VerticalOrderTraversalTest.java)
- - 📄 [ZigzagTraversalTest](src/test/java/com/thealgorithms/datastructures/trees/ZigzagTraversalTest.java)
- - 📁 **devutils**
- - 📁 **entities**
- - 📄 [ProcessDetailsTest](src/test/java/com/thealgorithms/devutils/entities/ProcessDetailsTest.java)
- - 📁 **divideandconquer**
- - 📄 [BinaryExponentiationTest](src/test/java/com/thealgorithms/divideandconquer/BinaryExponentiationTest.java)
- - 📄 [ClosestPairTest](src/test/java/com/thealgorithms/divideandconquer/ClosestPairTest.java)
- - 📄 [CountingInversionsTest](src/test/java/com/thealgorithms/divideandconquer/CountingInversionsTest.java)
- - 📄 [MedianOfTwoSortedArraysTest](src/test/java/com/thealgorithms/divideandconquer/MedianOfTwoSortedArraysTest.java)
- - 📄 [SkylineAlgorithmTest](src/test/java/com/thealgorithms/divideandconquer/SkylineAlgorithmTest.java)
- - 📄 [StrassenMatrixMultiplicationTest](src/test/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplicationTest.java)
- - 📄 [TilingProblemTest](src/test/java/com/thealgorithms/divideandconquer/TilingProblemTest.java)
- - 📁 **dynamicprogramming**
- - 📄 [AbbreviationTest](src/test/java/com/thealgorithms/dynamicprogramming/AbbreviationTest.java)
- - 📄 [AllConstructTest](src/test/java/com/thealgorithms/dynamicprogramming/AllConstructTest.java)
- - 📄 [AssignmentUsingBitmaskTest](src/test/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmaskTest.java)
- - 📄 [BoardPathTest](src/test/java/com/thealgorithms/dynamicprogramming/BoardPathTest.java)
- - 📄 [BoundaryFillTest](src/test/java/com/thealgorithms/dynamicprogramming/BoundaryFillTest.java)
- - 📄 [BruteForceKnapsackTest](src/test/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsackTest.java)
- - 📄 [CatalanNumberTest](src/test/java/com/thealgorithms/dynamicprogramming/CatalanNumberTest.java)
- - 📄 [ClimbStairsTest](src/test/java/com/thealgorithms/dynamicprogramming/ClimbStairsTest.java)
- - 📄 [CoinChangeTest](src/test/java/com/thealgorithms/dynamicprogramming/CoinChangeTest.java)
- - 📄 [CountFriendsPairingTest](src/test/java/com/thealgorithms/dynamicprogramming/CountFriendsPairingTest.java)
- - 📄 [DPTest](src/test/java/com/thealgorithms/dynamicprogramming/DPTest.java)
- - 📄 [DamerauLevenshteinDistanceTest](src/test/java/com/thealgorithms/dynamicprogramming/DamerauLevenshteinDistanceTest.java)
- - 📄 [EditDistanceTest](src/test/java/com/thealgorithms/dynamicprogramming/EditDistanceTest.java)
- - 📄 [EggDroppingTest](src/test/java/com/thealgorithms/dynamicprogramming/EggDroppingTest.java)
- - 📄 [FibonacciTest](src/test/java/com/thealgorithms/dynamicprogramming/FibonacciTest.java)
- - 📄 [KadaneAlgorithmTest](src/test/java/com/thealgorithms/dynamicprogramming/KadaneAlgorithmTest.java)
- - 📄 [KnapsackMemoizationTest](src/test/java/com/thealgorithms/dynamicprogramming/KnapsackMemoizationTest.java)
- - 📄 [KnapsackTest](src/test/java/com/thealgorithms/dynamicprogramming/KnapsackTest.java)
- - 📄 [KnapsackZeroOneTabulationTest](src/test/java/com/thealgorithms/dynamicprogramming/KnapsackZeroOneTabulationTest.java)
- - 📄 [KnapsackZeroOneTest](src/test/java/com/thealgorithms/dynamicprogramming/KnapsackZeroOneTest.java)
- - 📄 [LevenshteinDistanceTests](src/test/java/com/thealgorithms/dynamicprogramming/LevenshteinDistanceTests.java)
- - 📄 [LongestAlternatingSubsequenceTest](src/test/java/com/thealgorithms/dynamicprogramming/LongestAlternatingSubsequenceTest.java)
- - 📄 [LongestArithmeticSubsequenceTest](src/test/java/com/thealgorithms/dynamicprogramming/LongestArithmeticSubsequenceTest.java)
- - 📄 [LongestCommonSubsequenceTest](src/test/java/com/thealgorithms/dynamicprogramming/LongestCommonSubsequenceTest.java)
- - 📄 [LongestIncreasingSubsequenceNLogNTest](src/test/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequenceNLogNTest.java)
- - 📄 [LongestIncreasingSubsequenceTests](src/test/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequenceTests.java)
- - 📄 [LongestPalindromicSubstringTest](src/test/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubstringTest.java)
- - 📄 [LongestValidParenthesesTest](src/test/java/com/thealgorithms/dynamicprogramming/LongestValidParenthesesTest.java)
- - 📄 [MatrixChainMultiplicationTest](src/test/java/com/thealgorithms/dynamicprogramming/MatrixChainMultiplicationTest.java)
- - 📄 [MatrixChainRecursiveTopDownMemoisationTest](src/test/java/com/thealgorithms/dynamicprogramming/MatrixChainRecursiveTopDownMemoisationTest.java)
- - 📄 [MaximumProductSubarrayTest](src/test/java/com/thealgorithms/dynamicprogramming/MaximumProductSubarrayTest.java)
- - 📄 [MaximumSumOfNonAdjacentElementsTest](src/test/java/com/thealgorithms/dynamicprogramming/MaximumSumOfNonAdjacentElementsTest.java)
- - 📄 [MinimumPathSumTest](src/test/java/com/thealgorithms/dynamicprogramming/MinimumPathSumTest.java)
- - 📄 [MinimumSumPartitionTest](src/test/java/com/thealgorithms/dynamicprogramming/MinimumSumPartitionTest.java)
- - 📄 [NeedlemanWunschTest](src/test/java/com/thealgorithms/dynamicprogramming/NeedlemanWunschTest.java)
- - 📄 [NewManShanksPrimeTest](src/test/java/com/thealgorithms/dynamicprogramming/NewManShanksPrimeTest.java)
- - 📄 [OptimalJobSchedulingTest](src/test/java/com/thealgorithms/dynamicprogramming/OptimalJobSchedulingTest.java)
- - 📄 [PalindromicPartitioningTest](src/test/java/com/thealgorithms/dynamicprogramming/PalindromicPartitioningTest.java)
- - 📄 [PartitionProblemTest](src/test/java/com/thealgorithms/dynamicprogramming/PartitionProblemTest.java)
- - 📄 [RegexMatchingTest](src/test/java/com/thealgorithms/dynamicprogramming/RegexMatchingTest.java)
- - 📄 [RodCuttingTest](src/test/java/com/thealgorithms/dynamicprogramming/RodCuttingTest.java)
- - 📄 [ShortestCommonSupersequenceLengthTest](src/test/java/com/thealgorithms/dynamicprogramming/ShortestCommonSupersequenceLengthTest.java)
- - 📄 [SmithWatermanTest](src/test/java/com/thealgorithms/dynamicprogramming/SmithWatermanTest.java)
- - 📄 [SubsetCountTest](src/test/java/com/thealgorithms/dynamicprogramming/SubsetCountTest.java)
- - 📄 [SubsetSumSpaceOptimizedTest](src/test/java/com/thealgorithms/dynamicprogramming/SubsetSumSpaceOptimizedTest.java)
- - 📄 [SubsetSumTest](src/test/java/com/thealgorithms/dynamicprogramming/SubsetSumTest.java)
- - 📄 [SumOfSubsetTest](src/test/java/com/thealgorithms/dynamicprogramming/SumOfSubsetTest.java)
- - 📄 [TreeMatchingTest](src/test/java/com/thealgorithms/dynamicprogramming/TreeMatchingTest.java)
- - 📄 [TribonacciTest](src/test/java/com/thealgorithms/dynamicprogramming/TribonacciTest.java)
- - 📄 [UniquePathsTests](src/test/java/com/thealgorithms/dynamicprogramming/UniquePathsTests.java)
- - 📄 [UniqueSubsequencesCountTest](src/test/java/com/thealgorithms/dynamicprogramming/UniqueSubsequencesCountTest.java)
- - 📄 [WildcardMatchingTest](src/test/java/com/thealgorithms/dynamicprogramming/WildcardMatchingTest.java)
- - 📄 [WineProblemTest](src/test/java/com/thealgorithms/dynamicprogramming/WineProblemTest.java)
- - 📁 **geometry**
- - 📄 [BentleyOttmannTest](src/test/java/com/thealgorithms/geometry/BentleyOttmannTest.java)
- - 📄 [BresenhamLineTest](src/test/java/com/thealgorithms/geometry/BresenhamLineTest.java)
- - 📄 [ConvexHullTest](src/test/java/com/thealgorithms/geometry/ConvexHullTest.java)
- - 📄 [DDALineTest](src/test/java/com/thealgorithms/geometry/DDALineTest.java)
- - 📄 [GrahamScanTest](src/test/java/com/thealgorithms/geometry/GrahamScanTest.java)
- - 📄 [HaversineTest](src/test/java/com/thealgorithms/geometry/HaversineTest.java)
- - 📄 [MidpointCircleTest](src/test/java/com/thealgorithms/geometry/MidpointCircleTest.java)
- - 📄 [MidpointEllipseTest](src/test/java/com/thealgorithms/geometry/MidpointEllipseTest.java)
- - 📄 [PointTest](src/test/java/com/thealgorithms/geometry/PointTest.java)
- - 📄 [WusLineTest](src/test/java/com/thealgorithms/geometry/WusLineTest.java)
- - 📁 **graph**
- - 📄 [BronKerboschTest](src/test/java/com/thealgorithms/graph/BronKerboschTest.java)
- - 📄 [ConstrainedShortestPathTest](src/test/java/com/thealgorithms/graph/ConstrainedShortestPathTest.java)
- - 📄 [DinicTest](src/test/java/com/thealgorithms/graph/DinicTest.java)
- - 📄 [EdmondsKarpTest](src/test/java/com/thealgorithms/graph/EdmondsKarpTest.java)
- - 📄 [EdmondsTest](src/test/java/com/thealgorithms/graph/EdmondsTest.java)
- - 📄 [GomoryHuTreeTest](src/test/java/com/thealgorithms/graph/GomoryHuTreeTest.java)
- - 📄 [HierholzerAlgorithmTest](src/test/java/com/thealgorithms/graph/HierholzerAlgorithmTest.java)
- - 📄 [HierholzerEulerianPathTest](src/test/java/com/thealgorithms/graph/HierholzerEulerianPathTest.java)
- - 📄 [HopcroftKarpTest](src/test/java/com/thealgorithms/graph/HopcroftKarpTest.java)
- - 📄 [HungarianAlgorithmTest](src/test/java/com/thealgorithms/graph/HungarianAlgorithmTest.java)
- - 📄 [PredecessorConstrainedDfsTest](src/test/java/com/thealgorithms/graph/PredecessorConstrainedDfsTest.java)
- - 📄 [PushRelabelTest](src/test/java/com/thealgorithms/graph/PushRelabelTest.java)
- - 📄 [StoerWagnerTest](src/test/java/com/thealgorithms/graph/StoerWagnerTest.java)
- - 📄 [StronglyConnectedComponentOptimizedTest](src/test/java/com/thealgorithms/graph/StronglyConnectedComponentOptimizedTest.java)
- - 📄 [TravelingSalesmanTest](src/test/java/com/thealgorithms/graph/TravelingSalesmanTest.java)
- - 📄 [YensKShortestPathsTest](src/test/java/com/thealgorithms/graph/YensKShortestPathsTest.java)
- - 📄 [ZeroOneBfsTest](src/test/java/com/thealgorithms/graph/ZeroOneBfsTest.java)
- - 📁 **greedyalgorithms**
- - 📄 [ActivitySelectionTest](src/test/java/com/thealgorithms/greedyalgorithms/ActivitySelectionTest.java)
- - 📄 [BandwidthAllocationTest](src/test/java/com/thealgorithms/greedyalgorithms/BandwidthAllocationTest.java)
- - 📄 [BinaryAdditionTest](src/test/java/com/thealgorithms/greedyalgorithms/BinaryAdditionTest.java)
- - 📄 [CoinChangeTest](src/test/java/com/thealgorithms/greedyalgorithms/CoinChangeTest.java)
- - 📄 [DigitSeparationTest](src/test/java/com/thealgorithms/greedyalgorithms/DigitSeparationTest.java)
- - 📄 [EgyptianFractionTest](src/test/java/com/thealgorithms/greedyalgorithms/EgyptianFractionTest.java)
- - 📄 [FractionalKnapsackTest](src/test/java/com/thealgorithms/greedyalgorithms/FractionalKnapsackTest.java)
- - 📄 [GaleShapleyTest](src/test/java/com/thealgorithms/greedyalgorithms/GaleShapleyTest.java)
- - 📄 [JobSequencingTest](src/test/java/com/thealgorithms/greedyalgorithms/JobSequencingTest.java)
- - 📄 [KCentersTest](src/test/java/com/thealgorithms/greedyalgorithms/KCentersTest.java)
- - 📄 [MergeIntervalsTest](src/test/java/com/thealgorithms/greedyalgorithms/MergeIntervalsTest.java)
- - 📄 [MinimizingLatenessTest](src/test/java/com/thealgorithms/greedyalgorithms/MinimizingLatenessTest.java)
- - 📄 [MinimumWaitingTimeTest](src/test/java/com/thealgorithms/greedyalgorithms/MinimumWaitingTimeTest.java)
- - 📄 [OptimalFileMergingTest](src/test/java/com/thealgorithms/greedyalgorithms/OptimalFileMergingTest.java)
- - 📄 [StockProfitCalculatorTest](src/test/java/com/thealgorithms/greedyalgorithms/StockProfitCalculatorTest.java)
- - 📁 **io**
- - 📄 [BufferedReaderTest](src/test/java/com/thealgorithms/io/BufferedReaderTest.java)
- - 📁 **lineclipping**
- - 📄 [CohenSutherlandTest](src/test/java/com/thealgorithms/lineclipping/CohenSutherlandTest.java)
- - 📄 [LiangBarskyTest](src/test/java/com/thealgorithms/lineclipping/LiangBarskyTest.java)
- - 📁 **maths**
- - 📄 [ADTFractionTest](src/test/java/com/thealgorithms/maths/ADTFractionTest.java)
- - 📄 [AbsoluteMaxTest](src/test/java/com/thealgorithms/maths/AbsoluteMaxTest.java)
- - 📄 [AbsoluteMinTest](src/test/java/com/thealgorithms/maths/AbsoluteMinTest.java)
- - 📄 [AbsoluteValueTest](src/test/java/com/thealgorithms/maths/AbsoluteValueTest.java)
- - 📄 [AbundantNumberTest](src/test/java/com/thealgorithms/maths/AbundantNumberTest.java)
- - 📄 [AliquotSumTest](src/test/java/com/thealgorithms/maths/AliquotSumTest.java)
- - 📄 [AmicableNumberTest](src/test/java/com/thealgorithms/maths/AmicableNumberTest.java)
- - 📄 [AreaTest](src/test/java/com/thealgorithms/maths/AreaTest.java)
- - 📄 [ArmstrongTest](src/test/java/com/thealgorithms/maths/ArmstrongTest.java)
- - 📄 [AutoCorrelationTest](src/test/java/com/thealgorithms/maths/AutoCorrelationTest.java)
- - 📄 [AutomorphicNumberTest](src/test/java/com/thealgorithms/maths/AutomorphicNumberTest.java)
- - 📄 [AverageTest](src/test/java/com/thealgorithms/maths/AverageTest.java)
- - 📄 [BinaryPowTest](src/test/java/com/thealgorithms/maths/BinaryPowTest.java)
- - 📄 [BinomialCoefficientTest](src/test/java/com/thealgorithms/maths/BinomialCoefficientTest.java)
- - 📄 [CatalanNumbersTest](src/test/java/com/thealgorithms/maths/CatalanNumbersTest.java)
- - 📄 [CeilTest](src/test/java/com/thealgorithms/maths/CeilTest.java)
- - 📄 [ChebyshevIterationTest](src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java)
- - 📄 [ChineseRemainderTheoremTest](src/test/java/com/thealgorithms/maths/ChineseRemainderTheoremTest.java)
- - 📄 [CollatzConjectureTest](src/test/java/com/thealgorithms/maths/CollatzConjectureTest.java)
- - 📄 [CombinationsTest](src/test/java/com/thealgorithms/maths/CombinationsTest.java)
- - 📄 [ConvolutionFFTTest](src/test/java/com/thealgorithms/maths/ConvolutionFFTTest.java)
- - 📄 [ConvolutionTest](src/test/java/com/thealgorithms/maths/ConvolutionTest.java)
- - 📄 [CrossCorrelationTest](src/test/java/com/thealgorithms/maths/CrossCorrelationTest.java)
- - 📄 [DeterminantOfMatrixTest](src/test/java/com/thealgorithms/maths/DeterminantOfMatrixTest.java)
- - 📄 [DigitalRootTest](src/test/java/com/thealgorithms/maths/DigitalRootTest.java)
- - 📄 [DistanceFormulaTest](src/test/java/com/thealgorithms/maths/DistanceFormulaTest.java)
- - 📄 [DudeneyNumberTest](src/test/java/com/thealgorithms/maths/DudeneyNumberTest.java)
- - 📄 [EulerMethodTest](src/test/java/com/thealgorithms/maths/EulerMethodTest.java)
- - 📄 [EulerPseudoprimeTest](src/test/java/com/thealgorithms/maths/EulerPseudoprimeTest.java)
- - 📄 [EulersFunctionTest](src/test/java/com/thealgorithms/maths/EulersFunctionTest.java)
- - 📄 [EvilNumberTest](src/test/java/com/thealgorithms/maths/EvilNumberTest.java)
- - 📄 [ExtendedEuclideanAlgorithmTest](src/test/java/com/thealgorithms/maths/ExtendedEuclideanAlgorithmTest.java)
- - 📄 [FFTTest](src/test/java/com/thealgorithms/maths/FFTTest.java)
- - 📄 [FactorialTest](src/test/java/com/thealgorithms/maths/FactorialTest.java)
- - 📄 [FastExponentiationTest](src/test/java/com/thealgorithms/maths/FastExponentiationTest.java)
- - 📄 [FastInverseSqrtTests](src/test/java/com/thealgorithms/maths/FastInverseSqrtTests.java)
- - 📄 [FibonacciJavaStreamsTest](src/test/java/com/thealgorithms/maths/FibonacciJavaStreamsTest.java)
- - 📄 [FibonacciLoopTest](src/test/java/com/thealgorithms/maths/FibonacciLoopTest.java)
- - 📄 [FibonacciNumberCheckTest](src/test/java/com/thealgorithms/maths/FibonacciNumberCheckTest.java)
- - 📄 [FibonacciNumberGoldenRationTest](src/test/java/com/thealgorithms/maths/FibonacciNumberGoldenRationTest.java)
- - 📄 [FindKthNumberTest](src/test/java/com/thealgorithms/maths/FindKthNumberTest.java)
- - 📄 [FindMaxRecursionTest](src/test/java/com/thealgorithms/maths/FindMaxRecursionTest.java)
- - 📄 [FindMaxTest](src/test/java/com/thealgorithms/maths/FindMaxTest.java)
- - 📄 [FindMinRecursionTest](src/test/java/com/thealgorithms/maths/FindMinRecursionTest.java)
- - 📄 [FindMinTest](src/test/java/com/thealgorithms/maths/FindMinTest.java)
- - 📄 [FloorTest](src/test/java/com/thealgorithms/maths/FloorTest.java)
- - 📄 [FrizzyNumberTest](src/test/java/com/thealgorithms/maths/FrizzyNumberTest.java)
- - 📄 [GCDRecursionTest](src/test/java/com/thealgorithms/maths/GCDRecursionTest.java)
- - 📄 [GCDTest](src/test/java/com/thealgorithms/maths/GCDTest.java)
- - 📄 [GaussianTest](src/test/java/com/thealgorithms/maths/GaussianTest.java)
- - 📄 [GenericRootTest](src/test/java/com/thealgorithms/maths/GenericRootTest.java)
- - 📄 [GermainPrimeAndSafePrimeTest](src/test/java/com/thealgorithms/maths/GermainPrimeAndSafePrimeTest.java)
- - 📄 [GoldbachConjectureTest](src/test/java/com/thealgorithms/maths/GoldbachConjectureTest.java)
- - 📄 [HappyNumberTest](src/test/java/com/thealgorithms/maths/HappyNumberTest.java)
- - 📄 [HarshadNumberTest](src/test/java/com/thealgorithms/maths/HarshadNumberTest.java)
- - 📄 [HeronsFormulaTest](src/test/java/com/thealgorithms/maths/HeronsFormulaTest.java)
- - 📄 [JosephusProblemTest](src/test/java/com/thealgorithms/maths/JosephusProblemTest.java)
- - 📄 [JugglerSequenceTest](src/test/java/com/thealgorithms/maths/JugglerSequenceTest.java)
- - 📄 [KaprekarNumbersTest](src/test/java/com/thealgorithms/maths/KaprekarNumbersTest.java)
- - 📄 [KaratsubaMultiplicationTest](src/test/java/com/thealgorithms/maths/KaratsubaMultiplicationTest.java)
- - 📄 [KeithNumberTest](src/test/java/com/thealgorithms/maths/KeithNumberTest.java)
- - 📄 [KrishnamurthyNumberTest](src/test/java/com/thealgorithms/maths/KrishnamurthyNumberTest.java)
- - 📄 [LeastCommonMultipleTest](src/test/java/com/thealgorithms/maths/LeastCommonMultipleTest.java)
- - 📄 [LeonardoNumberTest](src/test/java/com/thealgorithms/maths/LeonardoNumberTest.java)
- - 📄 [LinearDiophantineEquationsSolverTest](src/test/java/com/thealgorithms/maths/LinearDiophantineEquationsSolverTest.java)
- - 📄 [LongDivisionTest](src/test/java/com/thealgorithms/maths/LongDivisionTest.java)
- - 📄 [LucasSeriesTest](src/test/java/com/thealgorithms/maths/LucasSeriesTest.java)
- - 📄 [LuckyNumberTest](src/test/java/com/thealgorithms/maths/LuckyNumberTest.java)
- - 📄 [MathBuilderTest](src/test/java/com/thealgorithms/maths/MathBuilderTest.java)
- - 📄 [MaxValueTest](src/test/java/com/thealgorithms/maths/MaxValueTest.java)
- - 📄 [MeansTest](src/test/java/com/thealgorithms/maths/MeansTest.java)
- - 📄 [MedianTest](src/test/java/com/thealgorithms/maths/MedianTest.java)
- - 📄 [MinValueTest](src/test/java/com/thealgorithms/maths/MinValueTest.java)
- - 📄 [ModeTest](src/test/java/com/thealgorithms/maths/ModeTest.java)
- - 📄 [NevilleTest](src/test/java/com/thealgorithms/maths/NevilleTest.java)
- - 📄 [NonRepeatingElementTest](src/test/java/com/thealgorithms/maths/NonRepeatingElementTest.java)
- - 📄 [NthUglyNumberTest](src/test/java/com/thealgorithms/maths/NthUglyNumberTest.java)
- - 📄 [NumberOfDigitsTest](src/test/java/com/thealgorithms/maths/NumberOfDigitsTest.java)
- - 📄 [NumberPersistenceTest](src/test/java/com/thealgorithms/maths/NumberPersistenceTest.java)
- - 📄 [PalindromeNumberTest](src/test/java/com/thealgorithms/maths/PalindromeNumberTest.java)
- - 📄 [ParseIntegerTest](src/test/java/com/thealgorithms/maths/ParseIntegerTest.java)
- - 📄 [PascalTriangleTest](src/test/java/com/thealgorithms/maths/PascalTriangleTest.java)
- - 📄 [PerfectCubeTest](src/test/java/com/thealgorithms/maths/PerfectCubeTest.java)
- - 📄 [PerfectNumberTest](src/test/java/com/thealgorithms/maths/PerfectNumberTest.java)
- - 📄 [PerfectSquareTest](src/test/java/com/thealgorithms/maths/PerfectSquareTest.java)
- - 📄 [PerimeterTest](src/test/java/com/thealgorithms/maths/PerimeterTest.java)
- - 📄 [PiApproximationTest](src/test/java/com/thealgorithms/maths/PiApproximationTest.java)
- - 📄 [PollardRhoTest](src/test/java/com/thealgorithms/maths/PollardRhoTest.java)
- - 📄 [PowTest](src/test/java/com/thealgorithms/maths/PowTest.java)
- - 📄 [PowerOfFourTest](src/test/java/com/thealgorithms/maths/PowerOfFourTest.java)
- - 📄 [PowerOfTwoOrNotTest](src/test/java/com/thealgorithms/maths/PowerOfTwoOrNotTest.java)
- - 📄 [PowerUsingRecursionTest](src/test/java/com/thealgorithms/maths/PowerUsingRecursionTest.java)
- - 📄 [PronicNumberTest](src/test/java/com/thealgorithms/maths/PronicNumberTest.java)
- - 📄 [PythagoreanTripleTest](src/test/java/com/thealgorithms/maths/PythagoreanTripleTest.java)
- - 📄 [QuadraticEquationSolverTest](src/test/java/com/thealgorithms/maths/QuadraticEquationSolverTest.java)
- - 📄 [ReverseNumberTest](src/test/java/com/thealgorithms/maths/ReverseNumberTest.java)
- - 📄 [SecondMinMaxTest](src/test/java/com/thealgorithms/maths/SecondMinMaxTest.java)
- - 📄 [SieveOfAtkinTest](src/test/java/com/thealgorithms/maths/SieveOfAtkinTest.java)
- - 📄 [SieveOfEratosthenesTest](src/test/java/com/thealgorithms/maths/SieveOfEratosthenesTest.java)
- - 📄 [SmithNumberTest](src/test/java/com/thealgorithms/maths/SmithNumberTest.java)
- - 📄 [SolovayStrassenPrimalityTestTest](src/test/java/com/thealgorithms/maths/SolovayStrassenPrimalityTestTest.java)
- - 📄 [SquareFreeIntegerTest](src/test/java/com/thealgorithms/maths/SquareFreeIntegerTest.java)
- - 📄 [SquareRootWithNewtonRaphsonTestMethod](src/test/java/com/thealgorithms/maths/SquareRootWithNewtonRaphsonTestMethod.java)
- - 📄 [SquareRootwithBabylonianMethodTest](src/test/java/com/thealgorithms/maths/SquareRootwithBabylonianMethodTest.java)
- - 📄 [StandardDeviationTest](src/test/java/com/thealgorithms/maths/StandardDeviationTest.java)
- - 📄 [StandardScoreTest](src/test/java/com/thealgorithms/maths/StandardScoreTest.java)
- - 📄 [StrobogrammaticNumberTest](src/test/java/com/thealgorithms/maths/StrobogrammaticNumberTest.java)
- - 📄 [SumOfArithmeticSeriesTest](src/test/java/com/thealgorithms/maths/SumOfArithmeticSeriesTest.java)
- - 📄 [SumOfDigitsTest](src/test/java/com/thealgorithms/maths/SumOfDigitsTest.java)
- - 📄 [SumOfOddNumbersTest](src/test/java/com/thealgorithms/maths/SumOfOddNumbersTest.java)
- - 📄 [SumOfSquaresTest](src/test/java/com/thealgorithms/maths/SumOfSquaresTest.java)
- - 📄 [SumWithoutArithmeticOperatorsTest](src/test/java/com/thealgorithms/maths/SumWithoutArithmeticOperatorsTest.java)
- - 📄 [TestArmstrong](src/test/java/com/thealgorithms/maths/TestArmstrong.java)
- - 📄 [TwinPrimeTest](src/test/java/com/thealgorithms/maths/TwinPrimeTest.java)
- - 📄 [UniformNumbersTest](src/test/java/com/thealgorithms/maths/UniformNumbersTest.java)
- - 📄 [VampireNumberTest](src/test/java/com/thealgorithms/maths/VampireNumberTest.java)
- - 📄 [VolumeTest](src/test/java/com/thealgorithms/maths/VolumeTest.java)
- - 📄 [ZellersCongruenceTest](src/test/java/com/thealgorithms/maths/ZellersCongruenceTest.java)
- - 📁 **prime**
- - 📄 [LiouvilleLambdaFunctionTest](src/test/java/com/thealgorithms/maths/prime/LiouvilleLambdaFunctionTest.java)
- - 📄 [MillerRabinPrimalityCheckTest](src/test/java/com/thealgorithms/maths/prime/MillerRabinPrimalityCheckTest.java)
- - 📄 [MobiusFunctionTest](src/test/java/com/thealgorithms/maths/prime/MobiusFunctionTest.java)
- - 📄 [PrimeCheckTest](src/test/java/com/thealgorithms/maths/prime/PrimeCheckTest.java)
- - 📄 [PrimeFactorizationTest](src/test/java/com/thealgorithms/maths/prime/PrimeFactorizationTest.java)
- - 📁 **matrix**
- - 📄 [InverseOfMatrixTest](src/test/java/com/thealgorithms/matrix/InverseOfMatrixTest.java)
- - 📄 [LUDecompositionTest](src/test/java/com/thealgorithms/matrix/LUDecompositionTest.java)
- - 📄 [MatrixMultiplicationTest](src/test/java/com/thealgorithms/matrix/MatrixMultiplicationTest.java)
- - 📄 [MatrixRankTest](src/test/java/com/thealgorithms/matrix/MatrixRankTest.java)
- - 📄 [MatrixTransposeTest](src/test/java/com/thealgorithms/matrix/MatrixTransposeTest.java)
- - 📄 [MatrixUtilTest](src/test/java/com/thealgorithms/matrix/MatrixUtilTest.java)
- - 📄 [MedianOfMatrixTest](src/test/java/com/thealgorithms/matrix/MedianOfMatrixTest.java)
- - 📄 [MirrorOfMatrixTest](src/test/java/com/thealgorithms/matrix/MirrorOfMatrixTest.java)
- - 📄 [PrintAMatrixInSpiralOrderTest](src/test/java/com/thealgorithms/matrix/PrintAMatrixInSpiralOrderTest.java)
- - 📄 [SolveSystemTest](src/test/java/com/thealgorithms/matrix/SolveSystemTest.java)
- - 📄 [StochasticMatrixTest](src/test/java/com/thealgorithms/matrix/StochasticMatrixTest.java)
- - 📁 **misc**
- - 📄 [ColorContrastRatioTest](src/test/java/com/thealgorithms/misc/ColorContrastRatioTest.java)
- - 📄 [MapReduceTest](src/test/java/com/thealgorithms/misc/MapReduceTest.java)
- - 📄 [MedianOfRunningArrayTest](src/test/java/com/thealgorithms/misc/MedianOfRunningArrayTest.java)
- - 📄 [PalindromePrimeTest](src/test/java/com/thealgorithms/misc/PalindromePrimeTest.java)
- - 📄 [PalindromeSinglyLinkedListTest](src/test/java/com/thealgorithms/misc/PalindromeSinglyLinkedListTest.java)
- - 📄 [RangeInSortedArrayTest](src/test/java/com/thealgorithms/misc/RangeInSortedArrayTest.java)
- - 📄 [ShuffleArrayTest](src/test/java/com/thealgorithms/misc/ShuffleArrayTest.java)
- - 📄 [SparsityTest](src/test/java/com/thealgorithms/misc/SparsityTest.java)
- - 📄 [ThreeSumProblemTest](src/test/java/com/thealgorithms/misc/ThreeSumProblemTest.java)
- - 📄 [TwoSumProblemTest](src/test/java/com/thealgorithms/misc/TwoSumProblemTest.java)
- - 📁 **others**
- - 📄 [ArrayLeftRotationTest](src/test/java/com/thealgorithms/others/ArrayLeftRotationTest.java)
- - 📄 [ArrayRightRotationTest](src/test/java/com/thealgorithms/others/ArrayRightRotationTest.java)
- - 📄 [BFPRTTest](src/test/java/com/thealgorithms/others/BFPRTTest.java)
- - 📄 [BestFitCPUTest](src/test/java/com/thealgorithms/others/BestFitCPUTest.java)
- - 📄 [BoyerMooreTest](src/test/java/com/thealgorithms/others/BoyerMooreTest.java)
- - 📄 [CRC16Test](src/test/java/com/thealgorithms/others/CRC16Test.java)
- - 📄 [CRCAlgorithmTest](src/test/java/com/thealgorithms/others/CRCAlgorithmTest.java)
- - 📄 [ConwayTest](src/test/java/com/thealgorithms/others/ConwayTest.java)
- - 📄 [CountFriendsPairingTest](src/test/java/com/thealgorithms/others/CountFriendsPairingTest.java)
- - 📄 [FirstFitCPUTest](src/test/java/com/thealgorithms/others/FirstFitCPUTest.java)
- - 📄 [FloydTriangleTest](src/test/java/com/thealgorithms/others/FloydTriangleTest.java)
- - 📄 [HuffmanTest](src/test/java/com/thealgorithms/others/HuffmanTest.java)
- - 📄 [InsertDeleteInArrayTest](src/test/java/com/thealgorithms/others/InsertDeleteInArrayTest.java)
- - 📄 [IterativeFloodFillTest](src/test/java/com/thealgorithms/others/IterativeFloodFillTest.java)
- - 📄 [KadaneAlogrithmTest](src/test/java/com/thealgorithms/others/KadaneAlogrithmTest.java)
- - 📄 [LineSweepTest](src/test/java/com/thealgorithms/others/LineSweepTest.java)
- - 📄 [LinkListSortTest](src/test/java/com/thealgorithms/others/LinkListSortTest.java)
- - 📄 [LowestBasePalindromeTest](src/test/java/com/thealgorithms/others/LowestBasePalindromeTest.java)
- - 📄 [MaximumSumOfDistinctSubarraysWithLengthKTest](src/test/java/com/thealgorithms/others/MaximumSumOfDistinctSubarraysWithLengthKTest.java)
- - 📄 [MiniMaxAlgorithmTest](src/test/java/com/thealgorithms/others/MiniMaxAlgorithmTest.java)
- - 📄 [MosAlgorithmTest](src/test/java/com/thealgorithms/others/MosAlgorithmTest.java)
- - 📄 [NextFitTest](src/test/java/com/thealgorithms/others/NextFitTest.java)
- - 📄 [PageRankTest](src/test/java/com/thealgorithms/others/PageRankTest.java)
- - 📄 [PasswordGenTest](src/test/java/com/thealgorithms/others/PasswordGenTest.java)
- - 📄 [PerlinNoiseTest](src/test/java/com/thealgorithms/others/PerlinNoiseTest.java)
- - 📄 [QueueUsingTwoStacksTest](src/test/java/com/thealgorithms/others/QueueUsingTwoStacksTest.java)
- - 📄 [SkylineProblemTest](src/test/java/com/thealgorithms/others/SkylineProblemTest.java)
- - 📄 [TwoPointersTest](src/test/java/com/thealgorithms/others/TwoPointersTest.java)
- - 📄 [WorstFitCPUTest](src/test/java/com/thealgorithms/others/WorstFitCPUTest.java)
- - 📁 **physics**
- - 📄 [CoulombsLawTest](src/test/java/com/thealgorithms/physics/CoulombsLawTest.java)
- - 📄 [DampedOscillatorTest](src/test/java/com/thealgorithms/physics/DampedOscillatorTest.java)
- - 📄 [ElasticCollision2DTest](src/test/java/com/thealgorithms/physics/ElasticCollision2DTest.java)
- - 📄 [GravitationTest](src/test/java/com/thealgorithms/physics/GravitationTest.java)
- - 📄 [GroundToGroundProjectileMotionTest](src/test/java/com/thealgorithms/physics/GroundToGroundProjectileMotionTest.java)
- - 📄 [KinematicsTest](src/test/java/com/thealgorithms/physics/KinematicsTest.java)
- - 📄 [ProjectileMotionTest](src/test/java/com/thealgorithms/physics/ProjectileMotionTest.java)
- - 📄 [SimplePendulumRK4Test](src/test/java/com/thealgorithms/physics/SimplePendulumRK4Test.java)
- - 📄 [SnellLawTest](src/test/java/com/thealgorithms/physics/SnellLawTest.java)
- - 📄 [ThinLensTest](src/test/java/com/thealgorithms/physics/ThinLensTest.java)
- - 📁 **puzzlesandgames**
- - 📄 [TowerOfHanoiTest](src/test/java/com/thealgorithms/puzzlesandgames/TowerOfHanoiTest.java)
- - 📄 [WordBoggleTest](src/test/java/com/thealgorithms/puzzlesandgames/WordBoggleTest.java)
- - 📁 **randomized**
- - 📄 [KargerMinCutTest](src/test/java/com/thealgorithms/randomized/KargerMinCutTest.java)
- - 📄 [MonteCarloIntegrationTest](src/test/java/com/thealgorithms/randomized/MonteCarloIntegrationTest.java)
- - 📄 [RandomizedClosestPairTest](src/test/java/com/thealgorithms/randomized/RandomizedClosestPairTest.java)
- - 📄 [RandomizedMatrixMultiplicationVerificationTest](src/test/java/com/thealgorithms/randomized/RandomizedMatrixMultiplicationVerificationTest.java)
- - 📄 [RandomizedQuickSortTest](src/test/java/com/thealgorithms/randomized/RandomizedQuickSortTest.java)
- - 📄 [ReservoirSamplingTest](src/test/java/com/thealgorithms/randomized/ReservoirSamplingTest.java)
- - 📁 **recursion**
- - 📄 [DiceThrowerTest](src/test/java/com/thealgorithms/recursion/DiceThrowerTest.java)
- - 📄 [FactorialRecursionTest](src/test/java/com/thealgorithms/recursion/FactorialRecursionTest.java)
- - 📄 [FibonacciSeriesTest](src/test/java/com/thealgorithms/recursion/FibonacciSeriesTest.java)
- - 📄 [GenerateSubsetsTest](src/test/java/com/thealgorithms/recursion/GenerateSubsetsTest.java)
- - 📄 [SylvesterSequenceTest](src/test/java/com/thealgorithms/recursion/SylvesterSequenceTest.java)
- - 📁 **scheduling**
- - 📄 [AgingSchedulingTest](src/test/java/com/thealgorithms/scheduling/AgingSchedulingTest.java)
- - 📄 [EDFSchedulingTest](src/test/java/com/thealgorithms/scheduling/EDFSchedulingTest.java)
- - 📄 [FCFSSchedulingTest](src/test/java/com/thealgorithms/scheduling/FCFSSchedulingTest.java)
- - 📄 [FairShareSchedulingTest](src/test/java/com/thealgorithms/scheduling/FairShareSchedulingTest.java)
- - 📄 [GangSchedulingTest](src/test/java/com/thealgorithms/scheduling/GangSchedulingTest.java)
- - 📄 [HighestResponseRatioNextSchedulingTest](src/test/java/com/thealgorithms/scheduling/HighestResponseRatioNextSchedulingTest.java)
- - 📄 [JobSchedulingWithDeadlineTest](src/test/java/com/thealgorithms/scheduling/JobSchedulingWithDeadlineTest.java)
- - 📄 [LotterySchedulingTest](src/test/java/com/thealgorithms/scheduling/LotterySchedulingTest.java)
- - 📄 [MLFQSchedulerTest](src/test/java/com/thealgorithms/scheduling/MLFQSchedulerTest.java)
- - 📄 [MultiAgentSchedulingTest](src/test/java/com/thealgorithms/scheduling/MultiAgentSchedulingTest.java)
- - 📄 [NonPreemptivePrioritySchedulingTest](src/test/java/com/thealgorithms/scheduling/NonPreemptivePrioritySchedulingTest.java)
- - 📄 [PreemptivePrioritySchedulingTest](src/test/java/com/thealgorithms/scheduling/PreemptivePrioritySchedulingTest.java)
- - 📄 [ProportionalFairSchedulingTest](src/test/java/com/thealgorithms/scheduling/ProportionalFairSchedulingTest.java)
- - 📄 [RRSchedulingTest](src/test/java/com/thealgorithms/scheduling/RRSchedulingTest.java)
- - 📄 [RandomSchedulingTest](src/test/java/com/thealgorithms/scheduling/RandomSchedulingTest.java)
- - 📄 [SJFSchedulingTest](src/test/java/com/thealgorithms/scheduling/SJFSchedulingTest.java)
- - 📄 [SRTFSchedulingTest](src/test/java/com/thealgorithms/scheduling/SRTFSchedulingTest.java)
- - 📄 [SelfAdjustingSchedulingTest](src/test/java/com/thealgorithms/scheduling/SelfAdjustingSchedulingTest.java)
- - 📄 [SlackTimeSchedulingTest](src/test/java/com/thealgorithms/scheduling/SlackTimeSchedulingTest.java)
- - 📁 **diskscheduling**
- - 📄 [CircularLookSchedulingTest](src/test/java/com/thealgorithms/scheduling/diskscheduling/CircularLookSchedulingTest.java)
- - 📄 [CircularScanSchedulingTest](src/test/java/com/thealgorithms/scheduling/diskscheduling/CircularScanSchedulingTest.java)
- - 📄 [LookSchedulingTest](src/test/java/com/thealgorithms/scheduling/diskscheduling/LookSchedulingTest.java)
- - 📄 [SSFSchedulingTest](src/test/java/com/thealgorithms/scheduling/diskscheduling/SSFSchedulingTest.java)
- - 📄 [ScanSchedulingTest](src/test/java/com/thealgorithms/scheduling/diskscheduling/ScanSchedulingTest.java)
- - 📁 **searches**
- - 📄 [BM25InvertedIndexTest](src/test/java/com/thealgorithms/searches/BM25InvertedIndexTest.java)
- - 📄 [BinarySearch2dArrayTest](src/test/java/com/thealgorithms/searches/BinarySearch2dArrayTest.java)
- - 📄 [BinarySearchTest](src/test/java/com/thealgorithms/searches/BinarySearchTest.java)
- - 📄 [BoyerMooreTest](src/test/java/com/thealgorithms/searches/BoyerMooreTest.java)
- - 📄 [BreadthFirstSearchTest](src/test/java/com/thealgorithms/searches/BreadthFirstSearchTest.java)
- - 📄 [DepthFirstSearchTest](src/test/java/com/thealgorithms/searches/DepthFirstSearchTest.java)
- - 📄 [ExponentialSearchTest](src/test/java/com/thealgorithms/searches/ExponentialSearchTest.java)
- - 📄 [FibonacciSearchTest](src/test/java/com/thealgorithms/searches/FibonacciSearchTest.java)
- - 📄 [HowManyTimesRotatedTest](src/test/java/com/thealgorithms/searches/HowManyTimesRotatedTest.java)
- - 📄 [InterpolationSearchTest](src/test/java/com/thealgorithms/searches/InterpolationSearchTest.java)
- - 📄 [IterativeBinarySearchTest](src/test/java/com/thealgorithms/searches/IterativeBinarySearchTest.java)
- - 📄 [IterativeTernarySearchTest](src/test/java/com/thealgorithms/searches/IterativeTernarySearchTest.java)
- - 📄 [JumpSearchTest](src/test/java/com/thealgorithms/searches/JumpSearchTest.java)
- - 📄 [KMPSearchTest](src/test/java/com/thealgorithms/searches/KMPSearchTest.java)
- - 📄 [LinearSearchTest](src/test/java/com/thealgorithms/searches/LinearSearchTest.java)
- - 📄 [LinearSearchThreadTest](src/test/java/com/thealgorithms/searches/LinearSearchThreadTest.java)
- - 📄 [LowerBoundTest](src/test/java/com/thealgorithms/searches/LowerBoundTest.java)
- - 📄 [MonteCarloTreeSearchTest](src/test/java/com/thealgorithms/searches/MonteCarloTreeSearchTest.java)
- - 📄 [OrderAgnosticBinarySearchTest](src/test/java/com/thealgorithms/searches/OrderAgnosticBinarySearchTest.java)
- - 📄 [QuickSelectTest](src/test/java/com/thealgorithms/searches/QuickSelectTest.java)
- - 📄 [RabinKarpAlgorithmTest](src/test/java/com/thealgorithms/searches/RabinKarpAlgorithmTest.java)
- - 📄 [RandomSearchTest](src/test/java/com/thealgorithms/searches/RandomSearchTest.java)
- - 📄 [RecursiveBinarySearchTest](src/test/java/com/thealgorithms/searches/RecursiveBinarySearchTest.java)
- - 📄 [RowColumnWiseSorted2dArrayBinarySearchTest](src/test/java/com/thealgorithms/searches/RowColumnWiseSorted2dArrayBinarySearchTest.java)
- - 📄 [SaddlebackSearchTest](src/test/java/com/thealgorithms/searches/SaddlebackSearchTest.java)
- - 📄 [SearchInARowAndColWiseSortedMatrixTest](src/test/java/com/thealgorithms/searches/SearchInARowAndColWiseSortedMatrixTest.java)
- - 📄 [SentinelLinearSearchTest](src/test/java/com/thealgorithms/searches/SentinelLinearSearchTest.java)
- - 📄 [SquareRootBinarySearchTest](src/test/java/com/thealgorithms/searches/SquareRootBinarySearchTest.java)
- - 📄 [TernarySearchTest](src/test/java/com/thealgorithms/searches/TernarySearchTest.java)
- - 📄 [TestSearchInARowAndColWiseSortedMatrix](src/test/java/com/thealgorithms/searches/TestSearchInARowAndColWiseSortedMatrix.java)
- - 📄 [UnionFindTest](src/test/java/com/thealgorithms/searches/UnionFindTest.java)
- - 📄 [UpperBoundTest](src/test/java/com/thealgorithms/searches/UpperBoundTest.java)
- - 📁 **slidingwindow**
- - 📄 [LongestSubarrayWithSumLessOrEqualToKTest](src/test/java/com/thealgorithms/slidingwindow/LongestSubarrayWithSumLessOrEqualToKTest.java)
- - 📄 [LongestSubstringWithoutRepeatingCharactersTest](src/test/java/com/thealgorithms/slidingwindow/LongestSubstringWithoutRepeatingCharactersTest.java)
- - 📄 [MaxSumKSizeSubarrayTest](src/test/java/com/thealgorithms/slidingwindow/MaxSumKSizeSubarrayTest.java)
- - 📄 [MaximumSlidingWindowTest](src/test/java/com/thealgorithms/slidingwindow/MaximumSlidingWindowTest.java)
- - 📄 [MinSumKSizeSubarrayTest](src/test/java/com/thealgorithms/slidingwindow/MinSumKSizeSubarrayTest.java)
- - 📄 [MinimumWindowSubstringTest](src/test/java/com/thealgorithms/slidingwindow/MinimumWindowSubstringTest.java)
- - 📄 [ShortestCoprimeSegmentTest](src/test/java/com/thealgorithms/slidingwindow/ShortestCoprimeSegmentTest.java)
- - 📁 **sorts**
- - 📄 [AdaptiveMergeSortTest](src/test/java/com/thealgorithms/sorts/AdaptiveMergeSortTest.java)
- - 📄 [BeadSortTest](src/test/java/com/thealgorithms/sorts/BeadSortTest.java)
- - 📄 [BinaryInsertionSortTest](src/test/java/com/thealgorithms/sorts/BinaryInsertionSortTest.java)
- - 📄 [BitonicSortTest](src/test/java/com/thealgorithms/sorts/BitonicSortTest.java)
- - 📄 [BogoSortTest](src/test/java/com/thealgorithms/sorts/BogoSortTest.java)
- - 📄 [BubbleSortRecursiveTest](src/test/java/com/thealgorithms/sorts/BubbleSortRecursiveTest.java)
- - 📄 [BubbleSortTest](src/test/java/com/thealgorithms/sorts/BubbleSortTest.java)
- - 📄 [BucketSortTest](src/test/java/com/thealgorithms/sorts/BucketSortTest.java)
- - 📄 [CircleSortTest](src/test/java/com/thealgorithms/sorts/CircleSortTest.java)
- - 📄 [CocktailShakerSortTest](src/test/java/com/thealgorithms/sorts/CocktailShakerSortTest.java)
- - 📄 [CombSortTest](src/test/java/com/thealgorithms/sorts/CombSortTest.java)
- - 📄 [CountingSortTest](src/test/java/com/thealgorithms/sorts/CountingSortTest.java)
- - 📄 [CycleSortTest](src/test/java/com/thealgorithms/sorts/CycleSortTest.java)
- - 📄 [DarkSortTest](src/test/java/com/thealgorithms/sorts/DarkSortTest.java)
- - 📄 [DualPivotQuickSortTest](src/test/java/com/thealgorithms/sorts/DualPivotQuickSortTest.java)
- - 📄 [DutchNationalFlagSortTest](src/test/java/com/thealgorithms/sorts/DutchNationalFlagSortTest.java)
- - 📄 [ExchangeSortTest](src/test/java/com/thealgorithms/sorts/ExchangeSortTest.java)
- - 📄 [FlashSortTest](src/test/java/com/thealgorithms/sorts/FlashSortTest.java)
- - 📄 [GnomeSortTest](src/test/java/com/thealgorithms/sorts/GnomeSortTest.java)
- - 📄 [HeapSortTest](src/test/java/com/thealgorithms/sorts/HeapSortTest.java)
- - 📄 [InsertionSortTest](src/test/java/com/thealgorithms/sorts/InsertionSortTest.java)
- - 📄 [IntrospectiveSortTest](src/test/java/com/thealgorithms/sorts/IntrospectiveSortTest.java)
- - 📄 [MergeSortNoExtraSpaceTest](src/test/java/com/thealgorithms/sorts/MergeSortNoExtraSpaceTest.java)
- - 📄 [MergeSortRecursiveTest](src/test/java/com/thealgorithms/sorts/MergeSortRecursiveTest.java)
- - 📄 [MergeSortTest](src/test/java/com/thealgorithms/sorts/MergeSortTest.java)
- - 📄 [OddEvenSortTest](src/test/java/com/thealgorithms/sorts/OddEvenSortTest.java)
- - 📄 [PancakeSortTest](src/test/java/com/thealgorithms/sorts/PancakeSortTest.java)
- - 📄 [PatienceSortTest](src/test/java/com/thealgorithms/sorts/PatienceSortTest.java)
- - 📄 [PigeonholeSortTest](src/test/java/com/thealgorithms/sorts/PigeonholeSortTest.java)
- - 📄 [PriorityQueueSortTest](src/test/java/com/thealgorithms/sorts/PriorityQueueSortTest.java)
- - 📄 [QuickSortTest](src/test/java/com/thealgorithms/sorts/QuickSortTest.java)
- - 📄 [RadixSortTest](src/test/java/com/thealgorithms/sorts/RadixSortTest.java)
- - 📄 [SelectionSortRecursiveTest](src/test/java/com/thealgorithms/sorts/SelectionSortRecursiveTest.java)
- - 📄 [SelectionSortTest](src/test/java/com/thealgorithms/sorts/SelectionSortTest.java)
- - 📄 [ShellSortTest](src/test/java/com/thealgorithms/sorts/ShellSortTest.java)
- - 📄 [SlowSortTest](src/test/java/com/thealgorithms/sorts/SlowSortTest.java)
- - 📄 [SortUtilsRandomGeneratorTest](src/test/java/com/thealgorithms/sorts/SortUtilsRandomGeneratorTest.java)
- - 📄 [SortUtilsTest](src/test/java/com/thealgorithms/sorts/SortUtilsTest.java)
- - 📄 [SortingAlgorithmTest](src/test/java/com/thealgorithms/sorts/SortingAlgorithmTest.java)
- - 📄 [SpreadSortTest](src/test/java/com/thealgorithms/sorts/SpreadSortTest.java)
- - 📄 [StalinSortTest](src/test/java/com/thealgorithms/sorts/StalinSortTest.java)
- - 📄 [StoogeSortTest](src/test/java/com/thealgorithms/sorts/StoogeSortTest.java)
- - 📄 [StrandSortTest](src/test/java/com/thealgorithms/sorts/StrandSortTest.java)
- - 📄 [SwapSortTest](src/test/java/com/thealgorithms/sorts/SwapSortTest.java)
- - 📄 [TimSortTest](src/test/java/com/thealgorithms/sorts/TimSortTest.java)
- - 📄 [TopologicalSortTest](src/test/java/com/thealgorithms/sorts/TopologicalSortTest.java)
- - 📄 [TreeSortTest](src/test/java/com/thealgorithms/sorts/TreeSortTest.java)
- - 📄 [WaveSortTest](src/test/java/com/thealgorithms/sorts/WaveSortTest.java)
- - 📄 [WiggleSortTest](src/test/java/com/thealgorithms/sorts/WiggleSortTest.java)
- - 📁 **stacks**
- - 📄 [BalancedBracketsTest](src/test/java/com/thealgorithms/stacks/BalancedBracketsTest.java)
- - 📄 [CelebrityFinderTest](src/test/java/com/thealgorithms/stacks/CelebrityFinderTest.java)
- - 📄 [DecimalToAnyUsingStackTest](src/test/java/com/thealgorithms/stacks/DecimalToAnyUsingStackTest.java)
- - 📄 [DuplicateBracketsTest](src/test/java/com/thealgorithms/stacks/DuplicateBracketsTest.java)
- - 📄 [GreatestElementConstantTimeTest](src/test/java/com/thealgorithms/stacks/GreatestElementConstantTimeTest.java)
- - 📄 [InfixToPostfixTest](src/test/java/com/thealgorithms/stacks/InfixToPostfixTest.java)
- - 📄 [InfixToPrefixTest](src/test/java/com/thealgorithms/stacks/InfixToPrefixTest.java)
- - 📄 [LargestRectangleTest](src/test/java/com/thealgorithms/stacks/LargestRectangleTest.java)
- - 📄 [MinStackUsingSingleStackTest](src/test/java/com/thealgorithms/stacks/MinStackUsingSingleStackTest.java)
- - 📄 [MinStackUsingTwoStacksTest](src/test/java/com/thealgorithms/stacks/MinStackUsingTwoStacksTest.java)
- - 📄 [NextGreaterElementTest](src/test/java/com/thealgorithms/stacks/NextGreaterElementTest.java)
- - 📄 [NextSmallerElementTest](src/test/java/com/thealgorithms/stacks/NextSmallerElementTest.java)
- - 📄 [PalindromeWithStackTest](src/test/java/com/thealgorithms/stacks/PalindromeWithStackTest.java)
- - 📄 [PostfixEvaluatorTest](src/test/java/com/thealgorithms/stacks/PostfixEvaluatorTest.java)
- - 📄 [PostfixToInfixTest](src/test/java/com/thealgorithms/stacks/PostfixToInfixTest.java)
- - 📄 [PrefixEvaluatorTest](src/test/java/com/thealgorithms/stacks/PrefixEvaluatorTest.java)
- - 📄 [PrefixToInfixTest](src/test/java/com/thealgorithms/stacks/PrefixToInfixTest.java)
- - 📄 [SmallestElementConstantTimeTest](src/test/java/com/thealgorithms/stacks/SmallestElementConstantTimeTest.java)
- - 📄 [SortStackTest](src/test/java/com/thealgorithms/stacks/SortStackTest.java)
- - 📄 [StackPostfixNotationTest](src/test/java/com/thealgorithms/stacks/StackPostfixNotationTest.java)
- - 📄 [StackUsingTwoQueuesTest](src/test/java/com/thealgorithms/stacks/StackUsingTwoQueuesTest.java)
- - 📄 [TrappingRainwaterTest](src/test/java/com/thealgorithms/stacks/TrappingRainwaterTest.java)
- - 📄 [ValidParenthesesTest](src/test/java/com/thealgorithms/stacks/ValidParenthesesTest.java)
- - 📁 **strings**
- - 📄 [AhoCorasickTest](src/test/java/com/thealgorithms/strings/AhoCorasickTest.java)
- - 📄 [AlphabeticalTest](src/test/java/com/thealgorithms/strings/AlphabeticalTest.java)
- - 📄 [AlternativeStringArrangeTest](src/test/java/com/thealgorithms/strings/AlternativeStringArrangeTest.java)
- - 📄 [AnagramsTest](src/test/java/com/thealgorithms/strings/AnagramsTest.java)
- - 📄 [CharactersSameTest](src/test/java/com/thealgorithms/strings/CharactersSameTest.java)
- - 📄 [CheckVowelsTest](src/test/java/com/thealgorithms/strings/CheckVowelsTest.java)
- - 📄 [CountCharTest](src/test/java/com/thealgorithms/strings/CountCharTest.java)
- - 📄 [CountWordsTest](src/test/java/com/thealgorithms/strings/CountWordsTest.java)
- - 📄 [HammingDistanceTest](src/test/java/com/thealgorithms/strings/HammingDistanceTest.java)
- - 📄 [HorspoolSearchTest](src/test/java/com/thealgorithms/strings/HorspoolSearchTest.java)
- - 📄 [IsogramTest](src/test/java/com/thealgorithms/strings/IsogramTest.java)
- - 📄 [IsomorphicTest](src/test/java/com/thealgorithms/strings/IsomorphicTest.java)
- - 📄 [LengthOfLastWordTest](src/test/java/com/thealgorithms/strings/LengthOfLastWordTest.java)
- - 📄 [LetterCombinationsOfPhoneNumberTest](src/test/java/com/thealgorithms/strings/LetterCombinationsOfPhoneNumberTest.java)
- - 📄 [LongestCommonPrefixTest](src/test/java/com/thealgorithms/strings/LongestCommonPrefixTest.java)
- - 📄 [LongestNonRepetitiveSubstringTest](src/test/java/com/thealgorithms/strings/LongestNonRepetitiveSubstringTest.java)
- - 📄 [LowerTest](src/test/java/com/thealgorithms/strings/LowerTest.java)
- - 📄 [ManacherTest](src/test/java/com/thealgorithms/strings/ManacherTest.java)
- - 📄 [MyAtoiTest](src/test/java/com/thealgorithms/strings/MyAtoiTest.java)
- - 📄 [PalindromeTest](src/test/java/com/thealgorithms/strings/PalindromeTest.java)
- - 📄 [PangramTest](src/test/java/com/thealgorithms/strings/PangramTest.java)
- - 📄 [PermuteStringTest](src/test/java/com/thealgorithms/strings/PermuteStringTest.java)
- - 📄 [RemoveDuplicateFromStringTest](src/test/java/com/thealgorithms/strings/RemoveDuplicateFromStringTest.java)
- - 📄 [ReturnSubsequenceTest](src/test/java/com/thealgorithms/strings/ReturnSubsequenceTest.java)
- - 📄 [ReverseStringTest](src/test/java/com/thealgorithms/strings/ReverseStringTest.java)
- - 📄 [ReverseWordsInStringTest](src/test/java/com/thealgorithms/strings/ReverseWordsInStringTest.java)
- - 📄 [RotationTest](src/test/java/com/thealgorithms/strings/RotationTest.java)
- - 📄 [StringCompressionTest](src/test/java/com/thealgorithms/strings/StringCompressionTest.java)
- - 📄 [StringMatchFiniteAutomataTest](src/test/java/com/thealgorithms/strings/StringMatchFiniteAutomataTest.java)
- - 📄 [SuffixArrayTest](src/test/java/com/thealgorithms/strings/SuffixArrayTest.java)
- - 📄 [UpperTest](src/test/java/com/thealgorithms/strings/UpperTest.java)
- - 📄 [WordLadderTest](src/test/java/com/thealgorithms/strings/WordLadderTest.java)
- - 📄 [ZAlgorithmTest](src/test/java/com/thealgorithms/strings/ZAlgorithmTest.java)
- - 📁 **zigZagPattern**
- - 📄 [ZigZagPatternTest](src/test/java/com/thealgorithms/strings/zigZagPattern/ZigZagPatternTest.java)
- - 📁 **tree**
- - 📄 [HeavyLightDecompositionTest](src/test/java/com/thealgorithms/tree/HeavyLightDecompositionTest.java)
+# Project Structure
+
+## src
+
+- 📁 **main**
+ - 📁 **java**
+ - 📁 **com**
+ - 📁 **thealgorithms**
+ - 📁 **audiofilters**
+ - 📄 [EMAFilter](src/main/java/com/thealgorithms/audiofilters/EMAFilter.java)
+ - 📄 [IIRFilter](src/main/java/com/thealgorithms/audiofilters/IIRFilter.java)
+ - 📁 **backtracking**
+ - 📄 [AllPathsFromSourceToTarget](src/main/java/com/thealgorithms/backtracking/AllPathsFromSourceToTarget.java)
+ - 📄 [ArrayCombination](src/main/java/com/thealgorithms/backtracking/ArrayCombination.java)
+ - 📄 [Combination](src/main/java/com/thealgorithms/backtracking/Combination.java)
+ - 📄 [CombinationSum](src/main/java/com/thealgorithms/backtracking/CombinationSum.java)
+ - 📄 [CrosswordSolver](src/main/java/com/thealgorithms/backtracking/CrosswordSolver.java)
+ - 📄 [FloodFill](src/main/java/com/thealgorithms/backtracking/FloodFill.java)
+ - 📄 [KnightsTour](src/main/java/com/thealgorithms/backtracking/KnightsTour.java)
+ - 📄 [MColoring](src/main/java/com/thealgorithms/backtracking/MColoring.java)
+ - 📄 [MazeRecursion](src/main/java/com/thealgorithms/backtracking/MazeRecursion.java)
+ - 📄 [NQueens](src/main/java/com/thealgorithms/backtracking/NQueens.java)
+ - 📄 [ParenthesesGenerator](src/main/java/com/thealgorithms/backtracking/ParenthesesGenerator.java)
+ - 📄 [Permutation](src/main/java/com/thealgorithms/backtracking/Permutation.java)
+ - 📄 [PowerSum](src/main/java/com/thealgorithms/backtracking/PowerSum.java)
+ - 📄 [SubsequenceFinder](src/main/java/com/thealgorithms/backtracking/SubsequenceFinder.java)
+ - 📄 [SudokuSolver](src/main/java/com/thealgorithms/backtracking/SudokuSolver.java)
+ - 📄 [UniquePermutation](src/main/java/com/thealgorithms/backtracking/UniquePermutation.java)
+ - 📄 [WordPatternMatcher](src/main/java/com/thealgorithms/backtracking/WordPatternMatcher.java)
+ - 📄 [WordSearch](src/main/java/com/thealgorithms/backtracking/WordSearch.java)
+ - 📁 **bitmanipulation**
+ - 📄 [BcdConversion](src/main/java/com/thealgorithms/bitmanipulation/BcdConversion.java)
+ - 📄 [BinaryPalindromeCheck](src/main/java/com/thealgorithms/bitmanipulation/BinaryPalindromeCheck.java)
+ - 📄 [BitRotate](src/main/java/com/thealgorithms/bitmanipulation/BitRotate.java)
+ - 📄 [BitSwap](src/main/java/com/thealgorithms/bitmanipulation/BitSwap.java)
+ - 📄 [BitwiseGCD](src/main/java/com/thealgorithms/bitmanipulation/BitwiseGCD.java)
+ - 📄 [BooleanAlgebraGates](src/main/java/com/thealgorithms/bitmanipulation/BooleanAlgebraGates.java)
+ - 📄 [ClearLeftmostSetBit](src/main/java/com/thealgorithms/bitmanipulation/ClearLeftmostSetBit.java)
+ - 📄 [CountBitsFlip](src/main/java/com/thealgorithms/bitmanipulation/CountBitsFlip.java)
+ - 📄 [CountLeadingZeros](src/main/java/com/thealgorithms/bitmanipulation/CountLeadingZeros.java)
+ - 📄 [CountSetBits](src/main/java/com/thealgorithms/bitmanipulation/CountSetBits.java)
+ - 📄 [FindNthBit](src/main/java/com/thealgorithms/bitmanipulation/FindNthBit.java)
+ - 📄 [FirstDifferentBit](src/main/java/com/thealgorithms/bitmanipulation/FirstDifferentBit.java)
+ - 📄 [GenerateSubsets](src/main/java/com/thealgorithms/bitmanipulation/GenerateSubsets.java)
+ - 📄 [GrayCodeConversion](src/main/java/com/thealgorithms/bitmanipulation/GrayCodeConversion.java)
+ - 📄 [HammingDistance](src/main/java/com/thealgorithms/bitmanipulation/HammingDistance.java)
+ - 📄 [HigherLowerPowerOfTwo](src/main/java/com/thealgorithms/bitmanipulation/HigherLowerPowerOfTwo.java)
+ - 📄 [HighestSetBit](src/main/java/com/thealgorithms/bitmanipulation/HighestSetBit.java)
+ - 📄 [IndexOfRightMostSetBit](src/main/java/com/thealgorithms/bitmanipulation/IndexOfRightMostSetBit.java)
+ - 📄 [IsEven](src/main/java/com/thealgorithms/bitmanipulation/IsEven.java)
+ - 📄 [IsPowerTwo](src/main/java/com/thealgorithms/bitmanipulation/IsPowerTwo.java)
+ - 📄 [LowestSetBit](src/main/java/com/thealgorithms/bitmanipulation/LowestSetBit.java)
+ - 📄 [ModuloPowerOfTwo](src/main/java/com/thealgorithms/bitmanipulation/ModuloPowerOfTwo.java)
+ - 📄 [NextHigherSameBitCount](src/main/java/com/thealgorithms/bitmanipulation/NextHigherSameBitCount.java)
+ - 📄 [NonRepeatingNumberFinder](src/main/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinder.java)
+ - 📄 [NumberAppearingOddTimes](src/main/java/com/thealgorithms/bitmanipulation/NumberAppearingOddTimes.java)
+ - 📄 [NumbersDifferentSigns](src/main/java/com/thealgorithms/bitmanipulation/NumbersDifferentSigns.java)
+ - 📄 [OneBitDifference](src/main/java/com/thealgorithms/bitmanipulation/OneBitDifference.java)
+ - 📄 [OnesComplement](src/main/java/com/thealgorithms/bitmanipulation/OnesComplement.java)
+ - 📄 [ParityCheck](src/main/java/com/thealgorithms/bitmanipulation/ParityCheck.java)
+ - 📄 [ReverseBits](src/main/java/com/thealgorithms/bitmanipulation/ReverseBits.java)
+ - 📄 [SingleBitOperations](src/main/java/com/thealgorithms/bitmanipulation/SingleBitOperations.java)
+ - 📄 [SingleElement](src/main/java/com/thealgorithms/bitmanipulation/SingleElement.java)
+ - 📄 [SwapAdjacentBits](src/main/java/com/thealgorithms/bitmanipulation/SwapAdjacentBits.java)
+ - 📄 [TwosComplement](src/main/java/com/thealgorithms/bitmanipulation/TwosComplement.java)
+ - 📄 [Xs3Conversion](src/main/java/com/thealgorithms/bitmanipulation/Xs3Conversion.java)
+ - 📁 **ciphers**
+ - 📄 [ADFGVXCipher](src/main/java/com/thealgorithms/ciphers/ADFGVXCipher.java)
+ - 📄 [AES](src/main/java/com/thealgorithms/ciphers/AES.java)
+ - 📄 [AESEncryption](src/main/java/com/thealgorithms/ciphers/AESEncryption.java)
+ - 📄 [AffineCipher](src/main/java/com/thealgorithms/ciphers/AffineCipher.java)
+ - 📄 [AtbashCipher](src/main/java/com/thealgorithms/ciphers/AtbashCipher.java)
+ - 📄 [Autokey](src/main/java/com/thealgorithms/ciphers/Autokey.java)
+ - 📄 [BaconianCipher](src/main/java/com/thealgorithms/ciphers/BaconianCipher.java)
+ - 📄 [Blowfish](src/main/java/com/thealgorithms/ciphers/Blowfish.java)
+ - 📄 [Caesar](src/main/java/com/thealgorithms/ciphers/Caesar.java)
+ - 📄 [ColumnarTranspositionCipher](src/main/java/com/thealgorithms/ciphers/ColumnarTranspositionCipher.java)
+ - 📄 [DES](src/main/java/com/thealgorithms/ciphers/DES.java)
+ - 📄 [DiffieHellman](src/main/java/com/thealgorithms/ciphers/DiffieHellman.java)
+ - 📄 [ECC](src/main/java/com/thealgorithms/ciphers/ECC.java)
+ - 📄 [HillCipher](src/main/java/com/thealgorithms/ciphers/HillCipher.java)
+ - 📄 [MonoAlphabetic](src/main/java/com/thealgorithms/ciphers/MonoAlphabetic.java)
+ - 📄 [OneTimePadCipher](src/main/java/com/thealgorithms/ciphers/OneTimePadCipher.java)
+ - 📄 [PermutationCipher](src/main/java/com/thealgorithms/ciphers/PermutationCipher.java)
+ - 📄 [PlayfairCipher](src/main/java/com/thealgorithms/ciphers/PlayfairCipher.java)
+ - 📄 [Polybius](src/main/java/com/thealgorithms/ciphers/Polybius.java)
+ - 📄 [ProductCipher](src/main/java/com/thealgorithms/ciphers/ProductCipher.java)
+ - 📄 [RSA](src/main/java/com/thealgorithms/ciphers/RSA.java)
+ - 📄 [RailFenceCipher](src/main/java/com/thealgorithms/ciphers/RailFenceCipher.java)
+ - 📄 [SimpleSubCipher](src/main/java/com/thealgorithms/ciphers/SimpleSubCipher.java)
+ - 📄 [Vigenere](src/main/java/com/thealgorithms/ciphers/Vigenere.java)
+ - 📄 [XORCipher](src/main/java/com/thealgorithms/ciphers/XORCipher.java)
+ - 📁 **a5**
+ - 📄 [A5Cipher](src/main/java/com/thealgorithms/ciphers/a5/A5Cipher.java)
+ - 📄 [A5KeyStreamGenerator](src/main/java/com/thealgorithms/ciphers/a5/A5KeyStreamGenerator.java)
+ - 📄 [BaseLFSR](src/main/java/com/thealgorithms/ciphers/a5/BaseLFSR.java)
+ - 📄 [CompositeLFSR](src/main/java/com/thealgorithms/ciphers/a5/CompositeLFSR.java)
+ - 📄 [LFSR](src/main/java/com/thealgorithms/ciphers/a5/LFSR.java)
+ - 📄 [Utils](src/main/java/com/thealgorithms/ciphers/a5/Utils.java)
+ - 📁 **compression**
+ - 📄 [ArithmeticCoding](src/main/java/com/thealgorithms/compression/ArithmeticCoding.java)
+ - 📄 [BurrowsWheelerTransform](src/main/java/com/thealgorithms/compression/BurrowsWheelerTransform.java)
+ - 📄 [LZ77](src/main/java/com/thealgorithms/compression/LZ77.java)
+ - 📄 [LZ78](src/main/java/com/thealgorithms/compression/LZ78.java)
+ - 📄 [LZW](src/main/java/com/thealgorithms/compression/LZW.java)
+ - 📄 [MoveToFront](src/main/java/com/thealgorithms/compression/MoveToFront.java)
+ - 📄 [RunLengthEncoding](src/main/java/com/thealgorithms/compression/RunLengthEncoding.java)
+ - 📄 [ShannonFano](src/main/java/com/thealgorithms/compression/ShannonFano.java)
+ - 📁 **conversions**
+ - 📄 [AffineConverter](src/main/java/com/thealgorithms/conversions/AffineConverter.java)
+ - 📄 [AnyBaseToAnyBase](src/main/java/com/thealgorithms/conversions/AnyBaseToAnyBase.java)
+ - 📄 [AnyBaseToDecimal](src/main/java/com/thealgorithms/conversions/AnyBaseToDecimal.java)
+ - 📄 [AnytoAny](src/main/java/com/thealgorithms/conversions/AnytoAny.java)
+ - 📄 [Base64](src/main/java/com/thealgorithms/conversions/Base64.java)
+ - 📄 [BinaryToDecimal](src/main/java/com/thealgorithms/conversions/BinaryToDecimal.java)
+ - 📄 [BinaryToHexadecimal](src/main/java/com/thealgorithms/conversions/BinaryToHexadecimal.java)
+ - 📄 [BinaryToOctal](src/main/java/com/thealgorithms/conversions/BinaryToOctal.java)
+ - 📄 [CoordinateConverter](src/main/java/com/thealgorithms/conversions/CoordinateConverter.java)
+ - 📄 [DecimalToAnyBase](src/main/java/com/thealgorithms/conversions/DecimalToAnyBase.java)
+ - 📄 [DecimalToBinary](src/main/java/com/thealgorithms/conversions/DecimalToBinary.java)
+ - 📄 [DecimalToHexadecimal](src/main/java/com/thealgorithms/conversions/DecimalToHexadecimal.java)
+ - 📄 [DecimalToOctal](src/main/java/com/thealgorithms/conversions/DecimalToOctal.java)
+ - 📄 [EndianConverter](src/main/java/com/thealgorithms/conversions/EndianConverter.java)
+ - 📄 [HexToOct](src/main/java/com/thealgorithms/conversions/HexToOct.java)
+ - 📄 [HexaDecimalToBinary](src/main/java/com/thealgorithms/conversions/HexaDecimalToBinary.java)
+ - 📄 [HexaDecimalToDecimal](src/main/java/com/thealgorithms/conversions/HexaDecimalToDecimal.java)
+ - 📄 [IPConverter](src/main/java/com/thealgorithms/conversions/IPConverter.java)
+ - 📄 [IPv6Converter](src/main/java/com/thealgorithms/conversions/IPv6Converter.java)
+ - 📄 [IntegerToEnglish](src/main/java/com/thealgorithms/conversions/IntegerToEnglish.java)
+ - 📄 [IntegerToRoman](src/main/java/com/thealgorithms/conversions/IntegerToRoman.java)
+ - 📄 [MorseCodeConverter](src/main/java/com/thealgorithms/conversions/MorseCodeConverter.java)
+ - 📄 [NumberToWords](src/main/java/com/thealgorithms/conversions/NumberToWords.java)
+ - 📄 [OctalToBinary](src/main/java/com/thealgorithms/conversions/OctalToBinary.java)
+ - 📄 [OctalToDecimal](src/main/java/com/thealgorithms/conversions/OctalToDecimal.java)
+ - 📄 [OctalToHexadecimal](src/main/java/com/thealgorithms/conversions/OctalToHexadecimal.java)
+ - 📄 [PhoneticAlphabetConverter](src/main/java/com/thealgorithms/conversions/PhoneticAlphabetConverter.java)
+ - 📄 [RgbHsvConversion](src/main/java/com/thealgorithms/conversions/RgbHsvConversion.java)
+ - 📄 [RomanToInteger](src/main/java/com/thealgorithms/conversions/RomanToInteger.java)
+ - 📄 [TemperatureConverter](src/main/java/com/thealgorithms/conversions/TemperatureConverter.java)
+ - 📄 [TimeConverter](src/main/java/com/thealgorithms/conversions/TimeConverter.java)
+ - 📄 [TurkishToLatinConversion](src/main/java/com/thealgorithms/conversions/TurkishToLatinConversion.java)
+ - 📄 [UnitConversions](src/main/java/com/thealgorithms/conversions/UnitConversions.java)
+ - 📄 [UnitsConverter](src/main/java/com/thealgorithms/conversions/UnitsConverter.java)
+ - 📄 [WordsToNumber](src/main/java/com/thealgorithms/conversions/WordsToNumber.java)
+ - 📁 **datastructures**
+ - 📄 [Node](src/main/java/com/thealgorithms/datastructures/Node.java)
+ - 📁 **bags**
+ - 📄 [Bag](src/main/java/com/thealgorithms/datastructures/bags/Bag.java)
+ - 📁 **bloomfilter**
+ - 📄 [BloomFilter](src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java)
+ - 📁 **buffers**
+ - 📄 [CircularBuffer](src/main/java/com/thealgorithms/datastructures/buffers/CircularBuffer.java)
+ - 📁 **caches**
+ - 📄 [FIFOCache](src/main/java/com/thealgorithms/datastructures/caches/FIFOCache.java)
+ - 📄 [LFUCache](src/main/java/com/thealgorithms/datastructures/caches/LFUCache.java)
+ - 📄 [LIFOCache](src/main/java/com/thealgorithms/datastructures/caches/LIFOCache.java)
+ - 📄 [LRUCache](src/main/java/com/thealgorithms/datastructures/caches/LRUCache.java)
+ - 📄 [MRUCache](src/main/java/com/thealgorithms/datastructures/caches/MRUCache.java)
+ - 📄 [RRCache](src/main/java/com/thealgorithms/datastructures/caches/RRCache.java)
+ - 📁 **crdt**
+ - 📄 [GCounter](src/main/java/com/thealgorithms/datastructures/crdt/GCounter.java)
+ - 📄 [GSet](src/main/java/com/thealgorithms/datastructures/crdt/GSet.java)
+ - 📄 [LWWElementSet](src/main/java/com/thealgorithms/datastructures/crdt/LWWElementSet.java)
+ - 📄 [ORSet](src/main/java/com/thealgorithms/datastructures/crdt/ORSet.java)
+ - 📄 [PNCounter](src/main/java/com/thealgorithms/datastructures/crdt/PNCounter.java)
+ - 📄 [TwoPSet](src/main/java/com/thealgorithms/datastructures/crdt/TwoPSet.java)
+ - 📁 **disjointsetunion**
+ - 📄 [DisjointSetUnion](src/main/java/com/thealgorithms/datastructures/disjointsetunion/DisjointSetUnion.java)
+ - 📄 [DisjointSetUnionBySize](src/main/java/com/thealgorithms/datastructures/disjointsetunion/DisjointSetUnionBySize.java)
+ - 📄 [Node](src/main/java/com/thealgorithms/datastructures/disjointsetunion/Node.java)
+ - 📁 **dynamicarray**
+ - 📄 [DynamicArray](src/main/java/com/thealgorithms/datastructures/dynamicarray/DynamicArray.java)
+ - 📁 **graphs**
+ - 📄 [AStar](src/main/java/com/thealgorithms/datastructures/graphs/AStar.java)
+ - 📄 [BellmanFord](src/main/java/com/thealgorithms/datastructures/graphs/BellmanFord.java)
+ - 📄 [BipartiteGraphDFS](src/main/java/com/thealgorithms/datastructures/graphs/BipartiteGraphDFS.java)
+ - 📄 [BoruvkaAlgorithm](src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithm.java)
+ - 📄 [ConnectedComponent](src/main/java/com/thealgorithms/datastructures/graphs/ConnectedComponent.java)
+ - 📄 [Cycles](src/main/java/com/thealgorithms/datastructures/graphs/Cycles.java)
+ - 📄 [DialsAlgorithm](src/main/java/com/thealgorithms/datastructures/graphs/DialsAlgorithm.java)
+ - 📄 [DijkstraAlgorithm](src/main/java/com/thealgorithms/datastructures/graphs/DijkstraAlgorithm.java)
+ - 📄 [DijkstraOptimizedAlgorithm](src/main/java/com/thealgorithms/datastructures/graphs/DijkstraOptimizedAlgorithm.java)
+ - 📄 [EdmondsBlossomAlgorithm](src/main/java/com/thealgorithms/datastructures/graphs/EdmondsBlossomAlgorithm.java)
+ - 📄 [FloydWarshall](src/main/java/com/thealgorithms/datastructures/graphs/FloydWarshall.java)
+ - 📄 [FordFulkerson](src/main/java/com/thealgorithms/datastructures/graphs/FordFulkerson.java)
+ - 📄 [Graphs](src/main/java/com/thealgorithms/datastructures/graphs/Graphs.java)
+ - 📄 [HamiltonianCycle](src/main/java/com/thealgorithms/datastructures/graphs/HamiltonianCycle.java)
+ - 📄 [JohnsonsAlgorithm](src/main/java/com/thealgorithms/datastructures/graphs/JohnsonsAlgorithm.java)
+ - 📄 [KahnsAlgorithm](src/main/java/com/thealgorithms/datastructures/graphs/KahnsAlgorithm.java)
+ - 📄 [Kosaraju](src/main/java/com/thealgorithms/datastructures/graphs/Kosaraju.java)
+ - 📄 [Kruskal](src/main/java/com/thealgorithms/datastructures/graphs/Kruskal.java)
+ - 📄 [MatrixGraphs](src/main/java/com/thealgorithms/datastructures/graphs/MatrixGraphs.java)
+ - 📄 [PrimMST](src/main/java/com/thealgorithms/datastructures/graphs/PrimMST.java)
+ - 📄 [TarjansAlgorithm](src/main/java/com/thealgorithms/datastructures/graphs/TarjansAlgorithm.java)
+ - 📄 [TwoSat](src/main/java/com/thealgorithms/datastructures/graphs/TwoSat.java)
+ - 📄 [UndirectedAdjacencyListGraph](src/main/java/com/thealgorithms/datastructures/graphs/UndirectedAdjacencyListGraph.java)
+ - 📄 [WelshPowell](src/main/java/com/thealgorithms/datastructures/graphs/WelshPowell.java)
+ - 📁 **hashmap**
+ - 📁 **hashing**
+ - 📄 [GenericHashMapUsingArray](src/main/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArray.java)
+ - 📄 [GenericHashMapUsingArrayList](src/main/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayList.java)
+ - 📄 [HashMap](src/main/java/com/thealgorithms/datastructures/hashmap/hashing/HashMap.java)
+ - 📄 [HashMapCuckooHashing](src/main/java/com/thealgorithms/datastructures/hashmap/hashing/HashMapCuckooHashing.java)
+ - 📄 [ImmutableHashMap](src/main/java/com/thealgorithms/datastructures/hashmap/hashing/ImmutableHashMap.java)
+ - 📄 [Intersection](src/main/java/com/thealgorithms/datastructures/hashmap/hashing/Intersection.java)
+ - 📄 [LinearProbingHashMap](src/main/java/com/thealgorithms/datastructures/hashmap/hashing/LinearProbingHashMap.java)
+ - 📄 [MainCuckooHashing](src/main/java/com/thealgorithms/datastructures/hashmap/hashing/MainCuckooHashing.java)
+ - 📄 [MajorityElement](src/main/java/com/thealgorithms/datastructures/hashmap/hashing/MajorityElement.java)
+ - 📄 [Map](src/main/java/com/thealgorithms/datastructures/hashmap/hashing/Map.java)
+ - 📁 **heaps**
+ - 📄 [EmptyHeapException](src/main/java/com/thealgorithms/datastructures/heaps/EmptyHeapException.java)
+ - 📄 [FibonacciHeap](src/main/java/com/thealgorithms/datastructures/heaps/FibonacciHeap.java)
+ - 📄 [GenericHeap](src/main/java/com/thealgorithms/datastructures/heaps/GenericHeap.java)
+ - 📄 [Heap](src/main/java/com/thealgorithms/datastructures/heaps/Heap.java)
+ - 📄 [HeapElement](src/main/java/com/thealgorithms/datastructures/heaps/HeapElement.java)
+ - 📄 [IndexedPriorityQueue](src/main/java/com/thealgorithms/datastructures/heaps/IndexedPriorityQueue.java)
+ - 📄 [KthElementFinder](src/main/java/com/thealgorithms/datastructures/heaps/KthElementFinder.java)
+ - 📄 [LeftistHeap](src/main/java/com/thealgorithms/datastructures/heaps/LeftistHeap.java)
+ - 📄 [MaxHeap](src/main/java/com/thealgorithms/datastructures/heaps/MaxHeap.java)
+ - 📄 [MedianFinder](src/main/java/com/thealgorithms/datastructures/heaps/MedianFinder.java)
+ - 📄 [MergeKSortedArrays](src/main/java/com/thealgorithms/datastructures/heaps/MergeKSortedArrays.java)
+ - 📄 [MinHeap](src/main/java/com/thealgorithms/datastructures/heaps/MinHeap.java)
+ - 📄 [MinPriorityQueue](src/main/java/com/thealgorithms/datastructures/heaps/MinPriorityQueue.java)
+ - 📁 **lists**
+ - 📄 [CircleLinkedList](src/main/java/com/thealgorithms/datastructures/lists/CircleLinkedList.java)
+ - 📄 [CircularDoublyLinkedList](src/main/java/com/thealgorithms/datastructures/lists/CircularDoublyLinkedList.java)
+ - 📄 [CountSinglyLinkedListRecursion](src/main/java/com/thealgorithms/datastructures/lists/CountSinglyLinkedListRecursion.java)
+ - 📄 [CreateAndDetectLoop](src/main/java/com/thealgorithms/datastructures/lists/CreateAndDetectLoop.java)
+ - 📄 [CursorLinkedList](src/main/java/com/thealgorithms/datastructures/lists/CursorLinkedList.java)
+ - 📄 [DoublyLinkedList](src/main/java/com/thealgorithms/datastructures/lists/DoublyLinkedList.java)
+ - 📄 [FlattenMultilevelLinkedList](src/main/java/com/thealgorithms/datastructures/lists/FlattenMultilevelLinkedList.java)
+ - 📄 [MergeKSortedLinkedList](src/main/java/com/thealgorithms/datastructures/lists/MergeKSortedLinkedList.java)
+ - 📄 [MergeSortedArrayList](src/main/java/com/thealgorithms/datastructures/lists/MergeSortedArrayList.java)
+ - 📄 [MergeSortedSinglyLinkedList](src/main/java/com/thealgorithms/datastructures/lists/MergeSortedSinglyLinkedList.java)
+ - 📄 [QuickSortLinkedList](src/main/java/com/thealgorithms/datastructures/lists/QuickSortLinkedList.java)
+ - 📄 [RandomNode](src/main/java/com/thealgorithms/datastructures/lists/RandomNode.java)
+ - 📄 [ReverseKGroup](src/main/java/com/thealgorithms/datastructures/lists/ReverseKGroup.java)
+ - 📄 [RotateSinglyLinkedLists](src/main/java/com/thealgorithms/datastructures/lists/RotateSinglyLinkedLists.java)
+ - 📄 [SearchSinglyLinkedListRecursion](src/main/java/com/thealgorithms/datastructures/lists/SearchSinglyLinkedListRecursion.java)
+ - 📄 [SinglyLinkedList](src/main/java/com/thealgorithms/datastructures/lists/SinglyLinkedList.java)
+ - 📄 [SinglyLinkedListNode](src/main/java/com/thealgorithms/datastructures/lists/SinglyLinkedListNode.java)
+ - 📄 [SkipList](src/main/java/com/thealgorithms/datastructures/lists/SkipList.java)
+ - 📄 [SortedLinkedList](src/main/java/com/thealgorithms/datastructures/lists/SortedLinkedList.java)
+ - 📄 [TortoiseHareAlgo](src/main/java/com/thealgorithms/datastructures/lists/TortoiseHareAlgo.java)
+ - 📁 **queues**
+ - 📄 [CircularQueue](src/main/java/com/thealgorithms/datastructures/queues/CircularQueue.java)
+ - 📄 [Deque](src/main/java/com/thealgorithms/datastructures/queues/Deque.java)
+ - 📄 [GenericArrayListQueue](src/main/java/com/thealgorithms/datastructures/queues/GenericArrayListQueue.java)
+ - 📄 [LinkedQueue](src/main/java/com/thealgorithms/datastructures/queues/LinkedQueue.java)
+ - 📄 [PriorityQueues](src/main/java/com/thealgorithms/datastructures/queues/PriorityQueues.java)
+ - 📄 [Queue](src/main/java/com/thealgorithms/datastructures/queues/Queue.java)
+ - 📄 [QueueByTwoStacks](src/main/java/com/thealgorithms/datastructures/queues/QueueByTwoStacks.java)
+ - 📄 [SlidingWindowMaximum](src/main/java/com/thealgorithms/datastructures/queues/SlidingWindowMaximum.java)
+ - 📄 [TokenBucket](src/main/java/com/thealgorithms/datastructures/queues/TokenBucket.java)
+ - 📁 **stacks**
+ - 📄 [NodeStack](src/main/java/com/thealgorithms/datastructures/stacks/NodeStack.java)
+ - 📄 [ReverseStack](src/main/java/com/thealgorithms/datastructures/stacks/ReverseStack.java)
+ - 📄 [Stack](src/main/java/com/thealgorithms/datastructures/stacks/Stack.java)
+ - 📄 [StackArray](src/main/java/com/thealgorithms/datastructures/stacks/StackArray.java)
+ - 📄 [StackArrayList](src/main/java/com/thealgorithms/datastructures/stacks/StackArrayList.java)
+ - 📄 [StackOfLinkedList](src/main/java/com/thealgorithms/datastructures/stacks/StackOfLinkedList.java)
+ - 📁 **trees**
+ - 📄 [AVLSimple](src/main/java/com/thealgorithms/datastructures/trees/AVLSimple.java)
+ - 📄 [AVLTree](src/main/java/com/thealgorithms/datastructures/trees/AVLTree.java)
+ - 📄 [BSTFromSortedArray](src/main/java/com/thealgorithms/datastructures/trees/BSTFromSortedArray.java)
+ - 📄 [BSTIterative](src/main/java/com/thealgorithms/datastructures/trees/BSTIterative.java)
+ - 📄 [BSTRecursive](src/main/java/com/thealgorithms/datastructures/trees/BSTRecursive.java)
+ - 📄 [BSTRecursiveGeneric](src/main/java/com/thealgorithms/datastructures/trees/BSTRecursiveGeneric.java)
+ - 📄 [BTree](src/main/java/com/thealgorithms/datastructures/trees/BTree.java)
+ - 📄 [BinaryTree](src/main/java/com/thealgorithms/datastructures/trees/BinaryTree.java)
+ - 📄 [BinaryTreeToString](src/main/java/com/thealgorithms/datastructures/trees/BinaryTreeToString.java)
+ - 📄 [BoundaryTraversal](src/main/java/com/thealgorithms/datastructures/trees/BoundaryTraversal.java)
+ - 📄 [CeilInBinarySearchTree](src/main/java/com/thealgorithms/datastructures/trees/CeilInBinarySearchTree.java)
+ - 📄 [CentroidDecomposition](src/main/java/com/thealgorithms/datastructures/trees/CentroidDecomposition.java)
+ - 📄 [CheckBinaryTreeIsValidBST](src/main/java/com/thealgorithms/datastructures/trees/CheckBinaryTreeIsValidBST.java)
+ - 📄 [CheckIfBinaryTreeBalanced](src/main/java/com/thealgorithms/datastructures/trees/CheckIfBinaryTreeBalanced.java)
+ - 📄 [CheckTreeIsSymmetric](src/main/java/com/thealgorithms/datastructures/trees/CheckTreeIsSymmetric.java)
+ - 📄 [CreateBinaryTreeFromInorderPreorder](src/main/java/com/thealgorithms/datastructures/trees/CreateBinaryTreeFromInorderPreorder.java)
+ - 📄 [FenwickTree](src/main/java/com/thealgorithms/datastructures/trees/FenwickTree.java)
+ - 📄 [GenericTree](src/main/java/com/thealgorithms/datastructures/trees/GenericTree.java)
+ - 📄 [InorderTraversal](src/main/java/com/thealgorithms/datastructures/trees/InorderTraversal.java)
+ - 📄 [KDTree](src/main/java/com/thealgorithms/datastructures/trees/KDTree.java)
+ - 📄 [LCA](src/main/java/com/thealgorithms/datastructures/trees/LCA.java)
+ - 📄 [LazySegmentTree](src/main/java/com/thealgorithms/datastructures/trees/LazySegmentTree.java)
+ - 📄 [LevelOrderTraversal](src/main/java/com/thealgorithms/datastructures/trees/LevelOrderTraversal.java)
+ - 📄 [PostOrderTraversal](src/main/java/com/thealgorithms/datastructures/trees/PostOrderTraversal.java)
+ - 📄 [PreOrderTraversal](src/main/java/com/thealgorithms/datastructures/trees/PreOrderTraversal.java)
+ - 📄 [PrintTopViewofTree](src/main/java/com/thealgorithms/datastructures/trees/PrintTopViewofTree.java)
+ - 📄 [QuadTree](src/main/java/com/thealgorithms/datastructures/trees/QuadTree.java)
+ - 📄 [RedBlackBST](src/main/java/com/thealgorithms/datastructures/trees/RedBlackBST.java)
+ - 📄 [SameTreesCheck](src/main/java/com/thealgorithms/datastructures/trees/SameTreesCheck.java)
+ - 📄 [SegmentTree](src/main/java/com/thealgorithms/datastructures/trees/SegmentTree.java)
+ - 📄 [SplayTree](src/main/java/com/thealgorithms/datastructures/trees/SplayTree.java)
+ - 📄 [ThreadedBinaryTree](src/main/java/com/thealgorithms/datastructures/trees/ThreadedBinaryTree.java)
+ - 📄 [Treap](src/main/java/com/thealgorithms/datastructures/trees/Treap.java)
+ - 📄 [TreeRandomNode](src/main/java/com/thealgorithms/datastructures/trees/TreeRandomNode.java)
+ - 📄 [Trie](src/main/java/com/thealgorithms/datastructures/trees/Trie.java)
+ - 📄 [VerticalOrderTraversal](src/main/java/com/thealgorithms/datastructures/trees/VerticalOrderTraversal.java)
+ - 📄 [ZigzagTraversal](src/main/java/com/thealgorithms/datastructures/trees/ZigzagTraversal.java)
+ - 📄 [nearestRightKey](src/main/java/com/thealgorithms/datastructures/trees/nearestRightKey.java)
+ - 📁 **devutils**
+ - 📁 **entities**
+ - 📄 [ProcessDetails](src/main/java/com/thealgorithms/devutils/entities/ProcessDetails.java)
+ - 📁 **nodes**
+ - 📄 [LargeTreeNode](src/main/java/com/thealgorithms/devutils/nodes/LargeTreeNode.java)
+ - 📄 [Node](src/main/java/com/thealgorithms/devutils/nodes/Node.java)
+ - 📄 [SimpleNode](src/main/java/com/thealgorithms/devutils/nodes/SimpleNode.java)
+ - 📄 [SimpleTreeNode](src/main/java/com/thealgorithms/devutils/nodes/SimpleTreeNode.java)
+ - 📄 [TreeNode](src/main/java/com/thealgorithms/devutils/nodes/TreeNode.java)
+ - 📁 **searches**
+ - 📄 [MatrixSearchAlgorithm](src/main/java/com/thealgorithms/devutils/searches/MatrixSearchAlgorithm.java)
+ - 📄 [SearchAlgorithm](src/main/java/com/thealgorithms/devutils/searches/SearchAlgorithm.java)
+ - 📁 **divideandconquer**
+ - 📄 [BinaryExponentiation](src/main/java/com/thealgorithms/divideandconquer/BinaryExponentiation.java)
+ - 📄 [ClosestPair](src/main/java/com/thealgorithms/divideandconquer/ClosestPair.java)
+ - 📄 [CountingInversions](src/main/java/com/thealgorithms/divideandconquer/CountingInversions.java)
+ - 📄 [MedianOfTwoSortedArrays](src/main/java/com/thealgorithms/divideandconquer/MedianOfTwoSortedArrays.java)
+ - 📄 [SkylineAlgorithm](src/main/java/com/thealgorithms/divideandconquer/SkylineAlgorithm.java)
+ - 📄 [StrassenMatrixMultiplication](src/main/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplication.java)
+ - 📄 [TilingProblem](src/main/java/com/thealgorithms/divideandconquer/TilingProblem.java)
+ - 📁 **dynamicprogramming**
+ - 📄 [Abbreviation](src/main/java/com/thealgorithms/dynamicprogramming/Abbreviation.java)
+ - 📄 [AllConstruct](src/main/java/com/thealgorithms/dynamicprogramming/AllConstruct.java)
+ - 📄 [AssignmentUsingBitmask](src/main/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmask.java)
+ - 📄 [BoardPath](src/main/java/com/thealgorithms/dynamicprogramming/BoardPath.java)
+ - 📄 [BoundaryFill](src/main/java/com/thealgorithms/dynamicprogramming/BoundaryFill.java)
+ - 📄 [BruteForceKnapsack](src/main/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsack.java)
+ - 📄 [CatalanNumber](src/main/java/com/thealgorithms/dynamicprogramming/CatalanNumber.java)
+ - 📄 [ClimbingStairs](src/main/java/com/thealgorithms/dynamicprogramming/ClimbingStairs.java)
+ - 📄 [CoinChange](src/main/java/com/thealgorithms/dynamicprogramming/CoinChange.java)
+ - 📄 [CountFriendsPairing](src/main/java/com/thealgorithms/dynamicprogramming/CountFriendsPairing.java)
+ - 📄 [DamerauLevenshteinDistance](src/main/java/com/thealgorithms/dynamicprogramming/DamerauLevenshteinDistance.java)
+ - 📄 [DiceThrow](src/main/java/com/thealgorithms/dynamicprogramming/DiceThrow.java)
+ - 📄 [EditDistance](src/main/java/com/thealgorithms/dynamicprogramming/EditDistance.java)
+ - 📄 [EggDropping](src/main/java/com/thealgorithms/dynamicprogramming/EggDropping.java)
+ - 📄 [Fibonacci](src/main/java/com/thealgorithms/dynamicprogramming/Fibonacci.java)
+ - 📄 [KadaneAlgorithm](src/main/java/com/thealgorithms/dynamicprogramming/KadaneAlgorithm.java)
+ - 📄 [Knapsack](src/main/java/com/thealgorithms/dynamicprogramming/Knapsack.java)
+ - 📄 [KnapsackMemoization](src/main/java/com/thealgorithms/dynamicprogramming/KnapsackMemoization.java)
+ - 📄 [KnapsackZeroOne](src/main/java/com/thealgorithms/dynamicprogramming/KnapsackZeroOne.java)
+ - 📄 [KnapsackZeroOneTabulation](src/main/java/com/thealgorithms/dynamicprogramming/KnapsackZeroOneTabulation.java)
+ - 📄 [LevenshteinDistance](src/main/java/com/thealgorithms/dynamicprogramming/LevenshteinDistance.java)
+ - 📄 [LongestAlternatingSubsequence](src/main/java/com/thealgorithms/dynamicprogramming/LongestAlternatingSubsequence.java)
+ - 📄 [LongestArithmeticSubsequence](src/main/java/com/thealgorithms/dynamicprogramming/LongestArithmeticSubsequence.java)
+ - 📄 [LongestCommonSubsequence](src/main/java/com/thealgorithms/dynamicprogramming/LongestCommonSubsequence.java)
+ - 📄 [LongestIncreasingSubsequence](src/main/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequence.java)
+ - 📄 [LongestIncreasingSubsequenceNLogN](src/main/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequenceNLogN.java)
+ - 📄 [LongestPalindromicSubsequence](src/main/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubsequence.java)
+ - 📄 [LongestPalindromicSubstring](src/main/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubstring.java)
+ - 📄 [LongestValidParentheses](src/main/java/com/thealgorithms/dynamicprogramming/LongestValidParentheses.java)
+ - 📄 [MatrixChainMultiplication](src/main/java/com/thealgorithms/dynamicprogramming/MatrixChainMultiplication.java)
+ - 📄 [MatrixChainRecursiveTopDownMemoisation](src/main/java/com/thealgorithms/dynamicprogramming/MatrixChainRecursiveTopDownMemoisation.java)
+ - 📄 [MaximumProductSubarray](src/main/java/com/thealgorithms/dynamicprogramming/MaximumProductSubarray.java)
+ - 📄 [MaximumSumOfNonAdjacentElements](src/main/java/com/thealgorithms/dynamicprogramming/MaximumSumOfNonAdjacentElements.java)
+ - 📄 [MinimumPathSum](src/main/java/com/thealgorithms/dynamicprogramming/MinimumPathSum.java)
+ - 📄 [MinimumSumPartition](src/main/java/com/thealgorithms/dynamicprogramming/MinimumSumPartition.java)
+ - 📄 [NeedlemanWunsch](src/main/java/com/thealgorithms/dynamicprogramming/NeedlemanWunsch.java)
+ - 📄 [NewManShanksPrime](src/main/java/com/thealgorithms/dynamicprogramming/NewManShanksPrime.java)
+ - 📄 [OptimalJobScheduling](src/main/java/com/thealgorithms/dynamicprogramming/OptimalJobScheduling.java)
+ - 📄 [PalindromicPartitioning](src/main/java/com/thealgorithms/dynamicprogramming/PalindromicPartitioning.java)
+ - 📄 [PartitionProblem](src/main/java/com/thealgorithms/dynamicprogramming/PartitionProblem.java)
+ - 📄 [RegexMatching](src/main/java/com/thealgorithms/dynamicprogramming/RegexMatching.java)
+ - 📄 [RodCutting](src/main/java/com/thealgorithms/dynamicprogramming/RodCutting.java)
+ - 📄 [ShortestCommonSupersequenceLength](src/main/java/com/thealgorithms/dynamicprogramming/ShortestCommonSupersequenceLength.java)
+ - 📄 [SmithWaterman](src/main/java/com/thealgorithms/dynamicprogramming/SmithWaterman.java)
+ - 📄 [SubsetCount](src/main/java/com/thealgorithms/dynamicprogramming/SubsetCount.java)
+ - 📄 [SubsetSum](src/main/java/com/thealgorithms/dynamicprogramming/SubsetSum.java)
+ - 📄 [SubsetSumSpaceOptimized](src/main/java/com/thealgorithms/dynamicprogramming/SubsetSumSpaceOptimized.java)
+ - 📄 [SumOfSubset](src/main/java/com/thealgorithms/dynamicprogramming/SumOfSubset.java)
+ - 📄 [TreeMatching](src/main/java/com/thealgorithms/dynamicprogramming/TreeMatching.java)
+ - 📄 [Tribonacci](src/main/java/com/thealgorithms/dynamicprogramming/Tribonacci.java)
+ - 📄 [UniquePaths](src/main/java/com/thealgorithms/dynamicprogramming/UniquePaths.java)
+ - 📄 [UniqueSubsequencesCount](src/main/java/com/thealgorithms/dynamicprogramming/UniqueSubsequencesCount.java)
+ - 📄 [WildcardMatching](src/main/java/com/thealgorithms/dynamicprogramming/WildcardMatching.java)
+ - 📄 [WineProblem](src/main/java/com/thealgorithms/dynamicprogramming/WineProblem.java)
+ - 📁 **geometry**
+ - 📄 [BentleyOttmann](src/main/java/com/thealgorithms/geometry/BentleyOttmann.java)
+ - 📄 [BresenhamLine](src/main/java/com/thealgorithms/geometry/BresenhamLine.java)
+ - 📄 [ConvexHull](src/main/java/com/thealgorithms/geometry/ConvexHull.java)
+ - 📄 [DDALine](src/main/java/com/thealgorithms/geometry/DDALine.java)
+ - 📄 [GrahamScan](src/main/java/com/thealgorithms/geometry/GrahamScan.java)
+ - 📄 [Haversine](src/main/java/com/thealgorithms/geometry/Haversine.java)
+ - 📄 [MidpointCircle](src/main/java/com/thealgorithms/geometry/MidpointCircle.java)
+ - 📄 [MidpointEllipse](src/main/java/com/thealgorithms/geometry/MidpointEllipse.java)
+ - 📄 [Point](src/main/java/com/thealgorithms/geometry/Point.java)
+ - 📄 [WusLine](src/main/java/com/thealgorithms/geometry/WusLine.java)
+ - 📁 **graph**
+ - 📄 [BronKerbosch](src/main/java/com/thealgorithms/graph/BronKerbosch.java)
+ - 📄 [ConstrainedShortestPath](src/main/java/com/thealgorithms/graph/ConstrainedShortestPath.java)
+ - 📄 [Dinic](src/main/java/com/thealgorithms/graph/Dinic.java)
+ - 📄 [Edmonds](src/main/java/com/thealgorithms/graph/Edmonds.java)
+ - 📄 [EdmondsKarp](src/main/java/com/thealgorithms/graph/EdmondsKarp.java)
+ - 📄 [GomoryHuTree](src/main/java/com/thealgorithms/graph/GomoryHuTree.java)
+ - 📄 [HierholzerAlgorithm](src/main/java/com/thealgorithms/graph/HierholzerAlgorithm.java)
+ - 📄 [HierholzerEulerianPath](src/main/java/com/thealgorithms/graph/HierholzerEulerianPath.java)
+ - 📄 [HopcroftKarp](src/main/java/com/thealgorithms/graph/HopcroftKarp.java)
+ - 📄 [HungarianAlgorithm](src/main/java/com/thealgorithms/graph/HungarianAlgorithm.java)
+ - 📄 [PredecessorConstrainedDfs](src/main/java/com/thealgorithms/graph/PredecessorConstrainedDfs.java)
+ - 📄 [PushRelabel](src/main/java/com/thealgorithms/graph/PushRelabel.java)
+ - 📄 [StoerWagner](src/main/java/com/thealgorithms/graph/StoerWagner.java)
+ - 📄 [StronglyConnectedComponentOptimized](src/main/java/com/thealgorithms/graph/StronglyConnectedComponentOptimized.java)
+ - 📄 [TravelingSalesman](src/main/java/com/thealgorithms/graph/TravelingSalesman.java)
+ - 📄 [YensKShortestPaths](src/main/java/com/thealgorithms/graph/YensKShortestPaths.java)
+ - 📄 [ZeroOneBfs](src/main/java/com/thealgorithms/graph/ZeroOneBfs.java)
+ - 📁 **greedyalgorithms**
+ - 📄 [ActivitySelection](src/main/java/com/thealgorithms/greedyalgorithms/ActivitySelection.java)
+ - 📄 [BandwidthAllocation](src/main/java/com/thealgorithms/greedyalgorithms/BandwidthAllocation.java)
+ - 📄 [BinaryAddition](src/main/java/com/thealgorithms/greedyalgorithms/BinaryAddition.java)
+ - 📄 [CoinChange](src/main/java/com/thealgorithms/greedyalgorithms/CoinChange.java)
+ - 📄 [DigitSeparation](src/main/java/com/thealgorithms/greedyalgorithms/DigitSeparation.java)
+ - 📄 [EgyptianFraction](src/main/java/com/thealgorithms/greedyalgorithms/EgyptianFraction.java)
+ - 📄 [FractionalKnapsack](src/main/java/com/thealgorithms/greedyalgorithms/FractionalKnapsack.java)
+ - 📄 [GaleShapley](src/main/java/com/thealgorithms/greedyalgorithms/GaleShapley.java)
+ - 📄 [JobSequencing](src/main/java/com/thealgorithms/greedyalgorithms/JobSequencing.java)
+ - 📄 [KCenters](src/main/java/com/thealgorithms/greedyalgorithms/KCenters.java)
+ - 📄 [MergeIntervals](src/main/java/com/thealgorithms/greedyalgorithms/MergeIntervals.java)
+ - 📄 [MinimizingLateness](src/main/java/com/thealgorithms/greedyalgorithms/MinimizingLateness.java)
+ - 📄 [MinimumWaitingTime](src/main/java/com/thealgorithms/greedyalgorithms/MinimumWaitingTime.java)
+ - 📄 [OptimalFileMerging](src/main/java/com/thealgorithms/greedyalgorithms/OptimalFileMerging.java)
+ - 📄 [StockProfitCalculator](src/main/java/com/thealgorithms/greedyalgorithms/StockProfitCalculator.java)
+ - 📁 **io**
+ - 📄 [BufferedReader](src/main/java/com/thealgorithms/io/BufferedReader.java)
+ - 📁 **lineclipping**
+ - 📄 [CohenSutherland](src/main/java/com/thealgorithms/lineclipping/CohenSutherland.java)
+ - 📄 [LiangBarsky](src/main/java/com/thealgorithms/lineclipping/LiangBarsky.java)
+ - 📁 **utils**
+ - 📄 [Line](src/main/java/com/thealgorithms/lineclipping/utils/Line.java)
+ - 📄 [Point](src/main/java/com/thealgorithms/lineclipping/utils/Point.java)
+ - 📁 **maths**
+ - 📄 [ADTFraction](src/main/java/com/thealgorithms/maths/ADTFraction.java)
+ - 📄 [AbsoluteMax](src/main/java/com/thealgorithms/maths/AbsoluteMax.java)
+ - 📄 [AbsoluteMin](src/main/java/com/thealgorithms/maths/AbsoluteMin.java)
+ - 📄 [AbsoluteValue](src/main/java/com/thealgorithms/maths/AbsoluteValue.java)
+ - 📄 [AbundantNumber](src/main/java/com/thealgorithms/maths/AbundantNumber.java)
+ - 📄 [AliquotSum](src/main/java/com/thealgorithms/maths/AliquotSum.java)
+ - 📄 [AmicableNumber](src/main/java/com/thealgorithms/maths/AmicableNumber.java)
+ - 📄 [Area](src/main/java/com/thealgorithms/maths/Area.java)
+ - 📄 [Armstrong](src/main/java/com/thealgorithms/maths/Armstrong.java)
+ - 📄 [AutoCorrelation](src/main/java/com/thealgorithms/maths/AutoCorrelation.java)
+ - 📄 [AutomorphicNumber](src/main/java/com/thealgorithms/maths/AutomorphicNumber.java)
+ - 📄 [Average](src/main/java/com/thealgorithms/maths/Average.java)
+ - 📄 [BinaryPow](src/main/java/com/thealgorithms/maths/BinaryPow.java)
+ - 📄 [BinomialCoefficient](src/main/java/com/thealgorithms/maths/BinomialCoefficient.java)
+ - 📄 [CatalanNumbers](src/main/java/com/thealgorithms/maths/CatalanNumbers.java)
+ - 📄 [Ceil](src/main/java/com/thealgorithms/maths/Ceil.java)
+ - 📄 [ChebyshevIteration](src/main/java/com/thealgorithms/maths/ChebyshevIteration.java)
+ - 📄 [ChineseRemainderTheorem](src/main/java/com/thealgorithms/maths/ChineseRemainderTheorem.java)
+ - 📄 [CircularConvolutionFFT](src/main/java/com/thealgorithms/maths/CircularConvolutionFFT.java)
+ - 📄 [CollatzConjecture](src/main/java/com/thealgorithms/maths/CollatzConjecture.java)
+ - 📄 [Combinations](src/main/java/com/thealgorithms/maths/Combinations.java)
+ - 📄 [Convolution](src/main/java/com/thealgorithms/maths/Convolution.java)
+ - 📄 [ConvolutionFFT](src/main/java/com/thealgorithms/maths/ConvolutionFFT.java)
+ - 📄 [CrossCorrelation](src/main/java/com/thealgorithms/maths/CrossCorrelation.java)
+ - 📄 [DeterminantOfMatrix](src/main/java/com/thealgorithms/maths/DeterminantOfMatrix.java)
+ - 📄 [DigitalRoot](src/main/java/com/thealgorithms/maths/DigitalRoot.java)
+ - 📄 [DistanceFormula](src/main/java/com/thealgorithms/maths/DistanceFormula.java)
+ - 📄 [DudeneyNumber](src/main/java/com/thealgorithms/maths/DudeneyNumber.java)
+ - 📄 [EulerMethod](src/main/java/com/thealgorithms/maths/EulerMethod.java)
+ - 📄 [EulerPseudoprime](src/main/java/com/thealgorithms/maths/EulerPseudoprime.java)
+ - 📄 [EulersFunction](src/main/java/com/thealgorithms/maths/EulersFunction.java)
+ - 📄 [EvilNumber](src/main/java/com/thealgorithms/maths/EvilNumber.java)
+ - 📄 [ExtendedEuclideanAlgorithm](src/main/java/com/thealgorithms/maths/ExtendedEuclideanAlgorithm.java)
+ - 📄 [FFT](src/main/java/com/thealgorithms/maths/FFT.java)
+ - 📄 [FFTBluestein](src/main/java/com/thealgorithms/maths/FFTBluestein.java)
+ - 📄 [Factorial](src/main/java/com/thealgorithms/maths/Factorial.java)
+ - 📄 [FastExponentiation](src/main/java/com/thealgorithms/maths/FastExponentiation.java)
+ - 📄 [FastInverseSqrt](src/main/java/com/thealgorithms/maths/FastInverseSqrt.java)
+ - 📄 [FibonacciJavaStreams](src/main/java/com/thealgorithms/maths/FibonacciJavaStreams.java)
+ - 📄 [FibonacciLoop](src/main/java/com/thealgorithms/maths/FibonacciLoop.java)
+ - 📄 [FibonacciNumberCheck](src/main/java/com/thealgorithms/maths/FibonacciNumberCheck.java)
+ - 📄 [FibonacciNumberGoldenRation](src/main/java/com/thealgorithms/maths/FibonacciNumberGoldenRation.java)
+ - 📄 [FindKthNumber](src/main/java/com/thealgorithms/maths/FindKthNumber.java)
+ - 📄 [FindMax](src/main/java/com/thealgorithms/maths/FindMax.java)
+ - 📄 [FindMaxRecursion](src/main/java/com/thealgorithms/maths/FindMaxRecursion.java)
+ - 📄 [FindMin](src/main/java/com/thealgorithms/maths/FindMin.java)
+ - 📄 [FindMinRecursion](src/main/java/com/thealgorithms/maths/FindMinRecursion.java)
+ - 📄 [Floor](src/main/java/com/thealgorithms/maths/Floor.java)
+ - 📄 [FrizzyNumber](src/main/java/com/thealgorithms/maths/FrizzyNumber.java)
+ - 📄 [GCD](src/main/java/com/thealgorithms/maths/GCD.java)
+ - 📄 [GCDRecursion](src/main/java/com/thealgorithms/maths/GCDRecursion.java)
+ - 📄 [Gaussian](src/main/java/com/thealgorithms/maths/Gaussian.java)
+ - 📄 [GenericRoot](src/main/java/com/thealgorithms/maths/GenericRoot.java)
+ - 📄 [GermainPrimeAndSafePrime](src/main/java/com/thealgorithms/maths/GermainPrimeAndSafePrime.java)
+ - 📄 [GoldbachConjecture](src/main/java/com/thealgorithms/maths/GoldbachConjecture.java)
+ - 📄 [HappyNumber](src/main/java/com/thealgorithms/maths/HappyNumber.java)
+ - 📄 [HarshadNumber](src/main/java/com/thealgorithms/maths/HarshadNumber.java)
+ - 📄 [HeronsFormula](src/main/java/com/thealgorithms/maths/HeronsFormula.java)
+ - 📄 [JosephusProblem](src/main/java/com/thealgorithms/maths/JosephusProblem.java)
+ - 📄 [JugglerSequence](src/main/java/com/thealgorithms/maths/JugglerSequence.java)
+ - 📄 [KaprekarNumbers](src/main/java/com/thealgorithms/maths/KaprekarNumbers.java)
+ - 📄 [KaratsubaMultiplication](src/main/java/com/thealgorithms/maths/KaratsubaMultiplication.java)
+ - 📄 [KeithNumber](src/main/java/com/thealgorithms/maths/KeithNumber.java)
+ - 📄 [KrishnamurthyNumber](src/main/java/com/thealgorithms/maths/KrishnamurthyNumber.java)
+ - 📄 [LeastCommonMultiple](src/main/java/com/thealgorithms/maths/LeastCommonMultiple.java)
+ - 📄 [LeonardoNumber](src/main/java/com/thealgorithms/maths/LeonardoNumber.java)
+ - 📄 [LinearDiophantineEquationsSolver](src/main/java/com/thealgorithms/maths/LinearDiophantineEquationsSolver.java)
+ - 📄 [LongDivision](src/main/java/com/thealgorithms/maths/LongDivision.java)
+ - 📄 [LucasSeries](src/main/java/com/thealgorithms/maths/LucasSeries.java)
+ - 📄 [LuckyNumber](src/main/java/com/thealgorithms/maths/LuckyNumber.java)
+ - 📄 [MagicSquare](src/main/java/com/thealgorithms/maths/MagicSquare.java)
+ - 📄 [MathBuilder](src/main/java/com/thealgorithms/maths/MathBuilder.java)
+ - 📄 [MaxValue](src/main/java/com/thealgorithms/maths/MaxValue.java)
+ - 📄 [Means](src/main/java/com/thealgorithms/maths/Means.java)
+ - 📄 [Median](src/main/java/com/thealgorithms/maths/Median.java)
+ - 📄 [MinValue](src/main/java/com/thealgorithms/maths/MinValue.java)
+ - 📄 [Mode](src/main/java/com/thealgorithms/maths/Mode.java)
+ - 📄 [Neville](src/main/java/com/thealgorithms/maths/Neville.java)
+ - 📄 [NonRepeatingElement](src/main/java/com/thealgorithms/maths/NonRepeatingElement.java)
+ - 📄 [NthUglyNumber](src/main/java/com/thealgorithms/maths/NthUglyNumber.java)
+ - 📄 [NumberOfDigits](src/main/java/com/thealgorithms/maths/NumberOfDigits.java)
+ - 📄 [NumberPersistence](src/main/java/com/thealgorithms/maths/NumberPersistence.java)
+ - 📄 [PalindromeNumber](src/main/java/com/thealgorithms/maths/PalindromeNumber.java)
+ - 📄 [ParseInteger](src/main/java/com/thealgorithms/maths/ParseInteger.java)
+ - 📄 [PascalTriangle](src/main/java/com/thealgorithms/maths/PascalTriangle.java)
+ - 📄 [PerfectCube](src/main/java/com/thealgorithms/maths/PerfectCube.java)
+ - 📄 [PerfectNumber](src/main/java/com/thealgorithms/maths/PerfectNumber.java)
+ - 📄 [PerfectSquare](src/main/java/com/thealgorithms/maths/PerfectSquare.java)
+ - 📄 [Perimeter](src/main/java/com/thealgorithms/maths/Perimeter.java)
+ - 📄 [PiApproximation](src/main/java/com/thealgorithms/maths/PiApproximation.java)
+ - 📄 [PiNilakantha](src/main/java/com/thealgorithms/maths/PiNilakantha.java)
+ - 📄 [PollardRho](src/main/java/com/thealgorithms/maths/PollardRho.java)
+ - 📄 [Pow](src/main/java/com/thealgorithms/maths/Pow.java)
+ - 📄 [PowerOfFour](src/main/java/com/thealgorithms/maths/PowerOfFour.java)
+ - 📄 [PowerOfTwoOrNot](src/main/java/com/thealgorithms/maths/PowerOfTwoOrNot.java)
+ - 📄 [PowerUsingRecursion](src/main/java/com/thealgorithms/maths/PowerUsingRecursion.java)
+ - 📁 **Prime**
+ - 📄 [LiouvilleLambdaFunction](src/main/java/com/thealgorithms/maths/Prime/LiouvilleLambdaFunction.java)
+ - 📄 [MillerRabinPrimalityCheck](src/main/java/com/thealgorithms/maths/Prime/MillerRabinPrimalityCheck.java)
+ - 📄 [MobiusFunction](src/main/java/com/thealgorithms/maths/Prime/MobiusFunction.java)
+ - 📄 [PrimeCheck](src/main/java/com/thealgorithms/maths/Prime/PrimeCheck.java)
+ - 📄 [PrimeFactorization](src/main/java/com/thealgorithms/maths/Prime/PrimeFactorization.java)
+ - 📄 [SquareFreeInteger](src/main/java/com/thealgorithms/maths/Prime/SquareFreeInteger.java)
+ - 📄 [PronicNumber](src/main/java/com/thealgorithms/maths/PronicNumber.java)
+ - 📄 [PythagoreanTriple](src/main/java/com/thealgorithms/maths/PythagoreanTriple.java)
+ - 📄 [QuadraticEquationSolver](src/main/java/com/thealgorithms/maths/QuadraticEquationSolver.java)
+ - 📄 [ReverseNumber](src/main/java/com/thealgorithms/maths/ReverseNumber.java)
+ - 📄 [RomanNumeralUtil](src/main/java/com/thealgorithms/maths/RomanNumeralUtil.java)
+ - 📄 [SecondMinMax](src/main/java/com/thealgorithms/maths/SecondMinMax.java)
+ - 📄 [SieveOfAtkin](src/main/java/com/thealgorithms/maths/SieveOfAtkin.java)
+ - 📄 [SieveOfEratosthenes](src/main/java/com/thealgorithms/maths/SieveOfEratosthenes.java)
+ - 📄 [SimpsonIntegration](src/main/java/com/thealgorithms/maths/SimpsonIntegration.java)
+ - 📄 [SmithNumber](src/main/java/com/thealgorithms/maths/SmithNumber.java)
+ - 📄 [SolovayStrassenPrimalityTest](src/main/java/com/thealgorithms/maths/SolovayStrassenPrimalityTest.java)
+ - 📄 [SquareRootWithBabylonianMethod](src/main/java/com/thealgorithms/maths/SquareRootWithBabylonianMethod.java)
+ - 📄 [SquareRootWithNewtonRaphsonMethod](src/main/java/com/thealgorithms/maths/SquareRootWithNewtonRaphsonMethod.java)
+ - 📄 [StandardDeviation](src/main/java/com/thealgorithms/maths/StandardDeviation.java)
+ - 📄 [StandardScore](src/main/java/com/thealgorithms/maths/StandardScore.java)
+ - 📄 [StrobogrammaticNumber](src/main/java/com/thealgorithms/maths/StrobogrammaticNumber.java)
+ - 📄 [SumOfArithmeticSeries](src/main/java/com/thealgorithms/maths/SumOfArithmeticSeries.java)
+ - 📄 [SumOfDigits](src/main/java/com/thealgorithms/maths/SumOfDigits.java)
+ - 📄 [SumOfOddNumbers](src/main/java/com/thealgorithms/maths/SumOfOddNumbers.java)
+ - 📄 [SumOfSquares](src/main/java/com/thealgorithms/maths/SumOfSquares.java)
+ - 📄 [SumWithoutArithmeticOperators](src/main/java/com/thealgorithms/maths/SumWithoutArithmeticOperators.java)
+ - 📄 [TrinomialTriangle](src/main/java/com/thealgorithms/maths/TrinomialTriangle.java)
+ - 📄 [TwinPrime](src/main/java/com/thealgorithms/maths/TwinPrime.java)
+ - 📄 [UniformNumbers](src/main/java/com/thealgorithms/maths/UniformNumbers.java)
+ - 📄 [VampireNumber](src/main/java/com/thealgorithms/maths/VampireNumber.java)
+ - 📄 [VectorCrossProduct](src/main/java/com/thealgorithms/maths/VectorCrossProduct.java)
+ - 📄 [Volume](src/main/java/com/thealgorithms/maths/Volume.java)
+ - 📄 [ZellersCongruence](src/main/java/com/thealgorithms/maths/ZellersCongruence.java)
+ - 📁 **matrix**
+ - 📄 [InverseOfMatrix](src/main/java/com/thealgorithms/matrix/InverseOfMatrix.java)
+ - 📄 [LUDecomposition](src/main/java/com/thealgorithms/matrix/LUDecomposition.java)
+ - 📄 [MatrixMultiplication](src/main/java/com/thealgorithms/matrix/MatrixMultiplication.java)
+ - 📄 [MatrixRank](src/main/java/com/thealgorithms/matrix/MatrixRank.java)
+ - 📄 [MatrixTranspose](src/main/java/com/thealgorithms/matrix/MatrixTranspose.java)
+ - 📄 [MedianOfMatrix](src/main/java/com/thealgorithms/matrix/MedianOfMatrix.java)
+ - 📄 [MirrorOfMatrix](src/main/java/com/thealgorithms/matrix/MirrorOfMatrix.java)
+ - 📄 [PrintAMatrixInSpiralOrder](src/main/java/com/thealgorithms/matrix/PrintAMatrixInSpiralOrder.java)
+ - 📄 [RotateMatrixBy90Degrees](src/main/java/com/thealgorithms/matrix/RotateMatrixBy90Degrees.java)
+ - 📄 [SolveSystem](src/main/java/com/thealgorithms/matrix/SolveSystem.java)
+ - 📄 [StochasticMatrix](src/main/java/com/thealgorithms/matrix/StochasticMatrix.java)
+ - 📁 **matrixexponentiation**
+ - 📄 [Fibonacci](src/main/java/com/thealgorithms/matrix/matrixexponentiation/Fibonacci.java)
+ - 📁 **utils**
+ - 📄 [MatrixUtil](src/main/java/com/thealgorithms/matrix/utils/MatrixUtil.java)
+ - 📁 **misc**
+ - 📄 [ColorContrastRatio](src/main/java/com/thealgorithms/misc/ColorContrastRatio.java)
+ - 📄 [MapReduce](src/main/java/com/thealgorithms/misc/MapReduce.java)
+ - 📄 [MedianOfRunningArray](src/main/java/com/thealgorithms/misc/MedianOfRunningArray.java)
+ - 📄 [MedianOfRunningArrayByte](src/main/java/com/thealgorithms/misc/MedianOfRunningArrayByte.java)
+ - 📄 [MedianOfRunningArrayDouble](src/main/java/com/thealgorithms/misc/MedianOfRunningArrayDouble.java)
+ - 📄 [MedianOfRunningArrayFloat](src/main/java/com/thealgorithms/misc/MedianOfRunningArrayFloat.java)
+ - 📄 [MedianOfRunningArrayInteger](src/main/java/com/thealgorithms/misc/MedianOfRunningArrayInteger.java)
+ - 📄 [MedianOfRunningArrayLong](src/main/java/com/thealgorithms/misc/MedianOfRunningArrayLong.java)
+ - 📄 [PalindromePrime](src/main/java/com/thealgorithms/misc/PalindromePrime.java)
+ - 📄 [PalindromeSinglyLinkedList](src/main/java/com/thealgorithms/misc/PalindromeSinglyLinkedList.java)
+ - 📄 [RangeInSortedArray](src/main/java/com/thealgorithms/misc/RangeInSortedArray.java)
+ - 📄 [ShuffleArray](src/main/java/com/thealgorithms/misc/ShuffleArray.java)
+ - 📄 [Sparsity](src/main/java/com/thealgorithms/misc/Sparsity.java)
+ - 📄 [ThreeSumProblem](src/main/java/com/thealgorithms/misc/ThreeSumProblem.java)
+ - 📄 [TwoSumProblem](src/main/java/com/thealgorithms/misc/TwoSumProblem.java)
+ - 📁 **others**
+ - 📄 [ArrayLeftRotation](src/main/java/com/thealgorithms/others/ArrayLeftRotation.java)
+ - 📄 [ArrayRightRotation](src/main/java/com/thealgorithms/others/ArrayRightRotation.java)
+ - 📄 [BFPRT](src/main/java/com/thealgorithms/others/BFPRT.java)
+ - 📄 [BankersAlgorithm](src/main/java/com/thealgorithms/others/BankersAlgorithm.java)
+ - 📄 [BoyerMoore](src/main/java/com/thealgorithms/others/BoyerMoore.java)
+ - 📄 [BrianKernighanAlgorithm](src/main/java/com/thealgorithms/others/BrianKernighanAlgorithm.java)
+ - 📄 [CRC16](src/main/java/com/thealgorithms/others/CRC16.java)
+ - 📄 [CRC32](src/main/java/com/thealgorithms/others/CRC32.java)
+ - 📄 [CRCAlgorithm](src/main/java/com/thealgorithms/others/CRCAlgorithm.java)
+ - 📄 [Conway](src/main/java/com/thealgorithms/others/Conway.java)
+ - 📄 [Damm](src/main/java/com/thealgorithms/others/Damm.java)
+ - 📄 [Dijkstra](src/main/java/com/thealgorithms/others/Dijkstra.java)
+ - 📄 [FloydTriangle](src/main/java/com/thealgorithms/others/FloydTriangle.java)
+ - 📄 [GaussLegendre](src/main/java/com/thealgorithms/others/GaussLegendre.java)
+ - 📄 [Huffman](src/main/java/com/thealgorithms/others/Huffman.java)
+ - 📄 [Implementing_auto_completing_features_using_trie](src/main/java/com/thealgorithms/others/Implementing_auto_completing_features_using_trie.java)
+ - 📄 [InsertDeleteInArray](src/main/java/com/thealgorithms/others/InsertDeleteInArray.java)
+ - 📄 [IterativeFloodFill](src/main/java/com/thealgorithms/others/IterativeFloodFill.java)
+ - 📄 [KochSnowflake](src/main/java/com/thealgorithms/others/KochSnowflake.java)
+ - 📄 [LineSweep](src/main/java/com/thealgorithms/others/LineSweep.java)
+ - 📄 [LinearCongruentialGenerator](src/main/java/com/thealgorithms/others/LinearCongruentialGenerator.java)
+ - 📄 [LowestBasePalindrome](src/main/java/com/thealgorithms/others/LowestBasePalindrome.java)
+ - 📄 [Luhn](src/main/java/com/thealgorithms/others/Luhn.java)
+ - 📄 [Mandelbrot](src/main/java/com/thealgorithms/others/Mandelbrot.java)
+ - 📄 [MaximumSumOfDistinctSubarraysWithLengthK](src/main/java/com/thealgorithms/others/MaximumSumOfDistinctSubarraysWithLengthK.java)
+ - 📄 [MemoryManagementAlgorithms](src/main/java/com/thealgorithms/others/MemoryManagementAlgorithms.java)
+ - 📄 [MiniMaxAlgorithm](src/main/java/com/thealgorithms/others/MiniMaxAlgorithm.java)
+ - 📄 [MosAlgorithm](src/main/java/com/thealgorithms/others/MosAlgorithm.java)
+ - 📄 [PageRank](src/main/java/com/thealgorithms/others/PageRank.java)
+ - 📄 [PasswordGen](src/main/java/com/thealgorithms/others/PasswordGen.java)
+ - 📄 [PerlinNoise](src/main/java/com/thealgorithms/others/PerlinNoise.java)
+ - 📄 [QueueUsingTwoStacks](src/main/java/com/thealgorithms/others/QueueUsingTwoStacks.java)
+ - 📄 [SkylineProblem](src/main/java/com/thealgorithms/others/SkylineProblem.java)
+ - 📄 [TwoPointers](src/main/java/com/thealgorithms/others/TwoPointers.java)
+ - 📄 [Verhoeff](src/main/java/com/thealgorithms/others/Verhoeff.java)
+ - 📁 **physics**
+ - 📄 [CoulombsLaw](src/main/java/com/thealgorithms/physics/CoulombsLaw.java)
+ - 📄 [DampedOscillator](src/main/java/com/thealgorithms/physics/DampedOscillator.java)
+ - 📄 [ElasticCollision2D](src/main/java/com/thealgorithms/physics/ElasticCollision2D.java)
+ - 📄 [Gravitation](src/main/java/com/thealgorithms/physics/Gravitation.java)
+ - 📄 [GroundToGroundProjectileMotion](src/main/java/com/thealgorithms/physics/GroundToGroundProjectileMotion.java)
+ - 📄 [Kinematics](src/main/java/com/thealgorithms/physics/Kinematics.java)
+ - 📄 [ProjectileMotion](src/main/java/com/thealgorithms/physics/ProjectileMotion.java)
+ - 📄 [SimplePendulumRK4](src/main/java/com/thealgorithms/physics/SimplePendulumRK4.java)
+ - 📄 [SnellLaw](src/main/java/com/thealgorithms/physics/SnellLaw.java)
+ - 📄 [ThinLens](src/main/java/com/thealgorithms/physics/ThinLens.java)
+ - 📁 **puzzlesandgames**
+ - 📄 [TowerOfHanoi](src/main/java/com/thealgorithms/puzzlesandgames/TowerOfHanoi.java)
+ - 📄 [WordBoggle](src/main/java/com/thealgorithms/puzzlesandgames/WordBoggle.java)
+ - 📁 **randomized**
+ - 📄 [KargerMinCut](src/main/java/com/thealgorithms/randomized/KargerMinCut.java)
+ - 📄 [MonteCarloIntegration](src/main/java/com/thealgorithms/randomized/MonteCarloIntegration.java)
+ - 📄 [RandomizedClosestPair](src/main/java/com/thealgorithms/randomized/RandomizedClosestPair.java)
+ - 📄 [RandomizedMatrixMultiplicationVerification](src/main/java/com/thealgorithms/randomized/RandomizedMatrixMultiplicationVerification.java)
+ - 📄 [RandomizedQuickSort](src/main/java/com/thealgorithms/randomized/RandomizedQuickSort.java)
+ - 📄 [ReservoirSampling](src/main/java/com/thealgorithms/randomized/ReservoirSampling.java)
+ - 📁 **recursion**
+ - 📄 [DiceThrower](src/main/java/com/thealgorithms/recursion/DiceThrower.java)
+ - 📄 [FactorialRecursion](src/main/java/com/thealgorithms/recursion/FactorialRecursion.java)
+ - 📄 [FibonacciSeries](src/main/java/com/thealgorithms/recursion/FibonacciSeries.java)
+ - 📄 [GenerateSubsets](src/main/java/com/thealgorithms/recursion/GenerateSubsets.java)
+ - 📄 [SylvesterSequence](src/main/java/com/thealgorithms/recursion/SylvesterSequence.java)
+ - 📁 **scheduling**
+ - 📄 [AgingScheduling](src/main/java/com/thealgorithms/scheduling/AgingScheduling.java)
+ - 📄 [EDFScheduling](src/main/java/com/thealgorithms/scheduling/EDFScheduling.java)
+ - 📄 [FCFSScheduling](src/main/java/com/thealgorithms/scheduling/FCFSScheduling.java)
+ - 📄 [FairShareScheduling](src/main/java/com/thealgorithms/scheduling/FairShareScheduling.java)
+ - 📄 [GangScheduling](src/main/java/com/thealgorithms/scheduling/GangScheduling.java)
+ - 📄 [HighestResponseRatioNextScheduling](src/main/java/com/thealgorithms/scheduling/HighestResponseRatioNextScheduling.java)
+ - 📄 [JobSchedulingWithDeadline](src/main/java/com/thealgorithms/scheduling/JobSchedulingWithDeadline.java)
+ - 📄 [LotteryScheduling](src/main/java/com/thealgorithms/scheduling/LotteryScheduling.java)
+ - 📄 [MLFQScheduler](src/main/java/com/thealgorithms/scheduling/MLFQScheduler.java)
+ - 📄 [MultiAgentScheduling](src/main/java/com/thealgorithms/scheduling/MultiAgentScheduling.java)
+ - 📄 [NonPreemptivePriorityScheduling](src/main/java/com/thealgorithms/scheduling/NonPreemptivePriorityScheduling.java)
+ - 📄 [PreemptivePriorityScheduling](src/main/java/com/thealgorithms/scheduling/PreemptivePriorityScheduling.java)
+ - 📄 [ProportionalFairScheduling](src/main/java/com/thealgorithms/scheduling/ProportionalFairScheduling.java)
+ - 📄 [RRScheduling](src/main/java/com/thealgorithms/scheduling/RRScheduling.java)
+ - 📄 [RandomScheduling](src/main/java/com/thealgorithms/scheduling/RandomScheduling.java)
+ - 📄 [SJFScheduling](src/main/java/com/thealgorithms/scheduling/SJFScheduling.java)
+ - 📄 [SRTFScheduling](src/main/java/com/thealgorithms/scheduling/SRTFScheduling.java)
+ - 📄 [SelfAdjustingScheduling](src/main/java/com/thealgorithms/scheduling/SelfAdjustingScheduling.java)
+ - 📄 [SlackTimeScheduling](src/main/java/com/thealgorithms/scheduling/SlackTimeScheduling.java)
+ - 📁 **diskscheduling**
+ - 📄 [CircularLookScheduling](src/main/java/com/thealgorithms/scheduling/diskscheduling/CircularLookScheduling.java)
+ - 📄 [CircularScanScheduling](src/main/java/com/thealgorithms/scheduling/diskscheduling/CircularScanScheduling.java)
+ - 📄 [LookScheduling](src/main/java/com/thealgorithms/scheduling/diskscheduling/LookScheduling.java)
+ - 📄 [SSFScheduling](src/main/java/com/thealgorithms/scheduling/diskscheduling/SSFScheduling.java)
+ - 📄 [ScanScheduling](src/main/java/com/thealgorithms/scheduling/diskscheduling/ScanScheduling.java)
+ - 📁 **searches**
+ - 📄 [BM25InvertedIndex](src/main/java/com/thealgorithms/searches/BM25InvertedIndex.java)
+ - 📄 [BinarySearch](src/main/java/com/thealgorithms/searches/BinarySearch.java)
+ - 📄 [BinarySearch2dArray](src/main/java/com/thealgorithms/searches/BinarySearch2dArray.java)
+ - 📄 [BoyerMoore](src/main/java/com/thealgorithms/searches/BoyerMoore.java)
+ - 📄 [BreadthFirstSearch](src/main/java/com/thealgorithms/searches/BreadthFirstSearch.java)
+ - 📄 [DepthFirstSearch](src/main/java/com/thealgorithms/searches/DepthFirstSearch.java)
+ - 📄 [ExponentialSearch](src/main/java/com/thealgorithms/searches/ExponentialSearch.java)
+ - 📄 [FibonacciSearch](src/main/java/com/thealgorithms/searches/FibonacciSearch.java)
+ - 📄 [HowManyTimesRotated](src/main/java/com/thealgorithms/searches/HowManyTimesRotated.java)
+ - 📄 [InterpolationSearch](src/main/java/com/thealgorithms/searches/InterpolationSearch.java)
+ - 📄 [IterativeBinarySearch](src/main/java/com/thealgorithms/searches/IterativeBinarySearch.java)
+ - 📄 [IterativeTernarySearch](src/main/java/com/thealgorithms/searches/IterativeTernarySearch.java)
+ - 📄 [JumpSearch](src/main/java/com/thealgorithms/searches/JumpSearch.java)
+ - 📄 [KMPSearch](src/main/java/com/thealgorithms/searches/KMPSearch.java)
+ - 📄 [LinearSearch](src/main/java/com/thealgorithms/searches/LinearSearch.java)
+ - 📄 [LinearSearchThread](src/main/java/com/thealgorithms/searches/LinearSearchThread.java)
+ - 📄 [LowerBound](src/main/java/com/thealgorithms/searches/LowerBound.java)
+ - 📄 [MonteCarloTreeSearch](src/main/java/com/thealgorithms/searches/MonteCarloTreeSearch.java)
+ - 📄 [OrderAgnosticBinarySearch](src/main/java/com/thealgorithms/searches/OrderAgnosticBinarySearch.java)
+ - 📄 [QuickSelect](src/main/java/com/thealgorithms/searches/QuickSelect.java)
+ - 📄 [RabinKarpAlgorithm](src/main/java/com/thealgorithms/searches/RabinKarpAlgorithm.java)
+ - 📄 [RandomSearch](src/main/java/com/thealgorithms/searches/RandomSearch.java)
+ - 📄 [RecursiveBinarySearch](src/main/java/com/thealgorithms/searches/RecursiveBinarySearch.java)
+ - 📄 [RowColumnWiseSorted2dArrayBinarySearch](src/main/java/com/thealgorithms/searches/RowColumnWiseSorted2dArrayBinarySearch.java)
+ - 📄 [SaddlebackSearch](src/main/java/com/thealgorithms/searches/SaddlebackSearch.java)
+ - 📄 [SearchInARowAndColWiseSortedMatrix](src/main/java/com/thealgorithms/searches/SearchInARowAndColWiseSortedMatrix.java)
+ - 📄 [SentinelLinearSearch](src/main/java/com/thealgorithms/searches/SentinelLinearSearch.java)
+ - 📄 [SquareRootBinarySearch](src/main/java/com/thealgorithms/searches/SquareRootBinarySearch.java)
+ - 📄 [TernarySearch](src/main/java/com/thealgorithms/searches/TernarySearch.java)
+ - 📄 [UnionFind](src/main/java/com/thealgorithms/searches/UnionFind.java)
+ - 📄 [UpperBound](src/main/java/com/thealgorithms/searches/UpperBound.java)
+ - 📁 **slidingwindow**
+ - 📄 [LongestSubarrayWithSumLessOrEqualToK](src/main/java/com/thealgorithms/slidingwindow/LongestSubarrayWithSumLessOrEqualToK.java)
+ - 📄 [LongestSubstringWithoutRepeatingCharacters](src/main/java/com/thealgorithms/slidingwindow/LongestSubstringWithoutRepeatingCharacters.java)
+ - 📄 [MaxSumKSizeSubarray](src/main/java/com/thealgorithms/slidingwindow/MaxSumKSizeSubarray.java)
+ - 📄 [MaximumSlidingWindow](src/main/java/com/thealgorithms/slidingwindow/MaximumSlidingWindow.java)
+ - 📄 [MinSumKSizeSubarray](src/main/java/com/thealgorithms/slidingwindow/MinSumKSizeSubarray.java)
+ - 📄 [MinimumWindowSubstring](src/main/java/com/thealgorithms/slidingwindow/MinimumWindowSubstring.java)
+ - 📄 [ShortestCoprimeSegment](src/main/java/com/thealgorithms/slidingwindow/ShortestCoprimeSegment.java)
+ - 📁 **sorts**
+ - 📄 [AdaptiveMergeSort](src/main/java/com/thealgorithms/sorts/AdaptiveMergeSort.java)
+ - 📄 [BeadSort](src/main/java/com/thealgorithms/sorts/BeadSort.java)
+ - 📄 [BinaryInsertionSort](src/main/java/com/thealgorithms/sorts/BinaryInsertionSort.java)
+ - 📄 [BitonicSort](src/main/java/com/thealgorithms/sorts/BitonicSort.java)
+ - 📄 [BogoSort](src/main/java/com/thealgorithms/sorts/BogoSort.java)
+ - 📄 [BubbleSort](src/main/java/com/thealgorithms/sorts/BubbleSort.java)
+ - 📄 [BubbleSortRecursive](src/main/java/com/thealgorithms/sorts/BubbleSortRecursive.java)
+ - 📄 [BucketSort](src/main/java/com/thealgorithms/sorts/BucketSort.java)
+ - 📄 [CircleSort](src/main/java/com/thealgorithms/sorts/CircleSort.java)
+ - 📄 [CocktailShakerSort](src/main/java/com/thealgorithms/sorts/CocktailShakerSort.java)
+ - 📄 [CombSort](src/main/java/com/thealgorithms/sorts/CombSort.java)
+ - 📄 [CountingSort](src/main/java/com/thealgorithms/sorts/CountingSort.java)
+ - 📄 [CycleSort](src/main/java/com/thealgorithms/sorts/CycleSort.java)
+ - 📄 [DarkSort](src/main/java/com/thealgorithms/sorts/DarkSort.java)
+ - 📄 [DualPivotQuickSort](src/main/java/com/thealgorithms/sorts/DualPivotQuickSort.java)
+ - 📄 [DutchNationalFlagSort](src/main/java/com/thealgorithms/sorts/DutchNationalFlagSort.java)
+ - 📄 [ExchangeSort](src/main/java/com/thealgorithms/sorts/ExchangeSort.java)
+ - 📄 [FlashSort](src/main/java/com/thealgorithms/sorts/FlashSort.java)
+ - 📄 [GnomeSort](src/main/java/com/thealgorithms/sorts/GnomeSort.java)
+ - 📄 [HeapSort](src/main/java/com/thealgorithms/sorts/HeapSort.java)
+ - 📄 [InsertionSort](src/main/java/com/thealgorithms/sorts/InsertionSort.java)
+ - 📄 [IntrospectiveSort](src/main/java/com/thealgorithms/sorts/IntrospectiveSort.java)
+ - 📄 [LinkListSort](src/main/java/com/thealgorithms/sorts/LinkListSort.java)
+ - 📄 [MergeSort](src/main/java/com/thealgorithms/sorts/MergeSort.java)
+ - 📄 [MergeSortNoExtraSpace](src/main/java/com/thealgorithms/sorts/MergeSortNoExtraSpace.java)
+ - 📄 [MergeSortRecursive](src/main/java/com/thealgorithms/sorts/MergeSortRecursive.java)
+ - 📄 [OddEvenSort](src/main/java/com/thealgorithms/sorts/OddEvenSort.java)
+ - 📄 [PancakeSort](src/main/java/com/thealgorithms/sorts/PancakeSort.java)
+ - 📄 [PatienceSort](src/main/java/com/thealgorithms/sorts/PatienceSort.java)
+ - 📄 [PigeonholeSort](src/main/java/com/thealgorithms/sorts/PigeonholeSort.java)
+ - 📄 [PriorityQueueSort](src/main/java/com/thealgorithms/sorts/PriorityQueueSort.java)
+ - 📄 [QuickSort](src/main/java/com/thealgorithms/sorts/QuickSort.java)
+ - 📄 [RadixSort](src/main/java/com/thealgorithms/sorts/RadixSort.java)
+ - 📄 [SelectionSort](src/main/java/com/thealgorithms/sorts/SelectionSort.java)
+ - 📄 [SelectionSortRecursive](src/main/java/com/thealgorithms/sorts/SelectionSortRecursive.java)
+ - 📄 [ShellSort](src/main/java/com/thealgorithms/sorts/ShellSort.java)
+ - 📄 [SlowSort](src/main/java/com/thealgorithms/sorts/SlowSort.java)
+ - 📄 [SortAlgorithm](src/main/java/com/thealgorithms/sorts/SortAlgorithm.java)
+ - 📄 [SortUtils](src/main/java/com/thealgorithms/sorts/SortUtils.java)
+ - 📄 [SortUtilsRandomGenerator](src/main/java/com/thealgorithms/sorts/SortUtilsRandomGenerator.java)
+ - 📄 [SpreadSort](src/main/java/com/thealgorithms/sorts/SpreadSort.java)
+ - 📄 [StalinSort](src/main/java/com/thealgorithms/sorts/StalinSort.java)
+ - 📄 [StoogeSort](src/main/java/com/thealgorithms/sorts/StoogeSort.java)
+ - 📄 [StrandSort](src/main/java/com/thealgorithms/sorts/StrandSort.java)
+ - 📄 [SwapSort](src/main/java/com/thealgorithms/sorts/SwapSort.java)
+ - 📄 [TimSort](src/main/java/com/thealgorithms/sorts/TimSort.java)
+ - 📄 [TopologicalSort](src/main/java/com/thealgorithms/sorts/TopologicalSort.java)
+ - 📄 [TreeSort](src/main/java/com/thealgorithms/sorts/TreeSort.java)
+ - 📄 [WaveSort](src/main/java/com/thealgorithms/sorts/WaveSort.java)
+ - 📄 [WiggleSort](src/main/java/com/thealgorithms/sorts/WiggleSort.java)
+ - 📁 **stacks**
+ - 📄 [BalancedBrackets](src/main/java/com/thealgorithms/stacks/BalancedBrackets.java)
+ - 📄 [CelebrityFinder](src/main/java/com/thealgorithms/stacks/CelebrityFinder.java)
+ - 📄 [DecimalToAnyUsingStack](src/main/java/com/thealgorithms/stacks/DecimalToAnyUsingStack.java)
+ - 📄 [DuplicateBrackets](src/main/java/com/thealgorithms/stacks/DuplicateBrackets.java)
+ - 📄 [GreatestElementConstantTime](src/main/java/com/thealgorithms/stacks/GreatestElementConstantTime.java)
+ - 📄 [InfixToPostfix](src/main/java/com/thealgorithms/stacks/InfixToPostfix.java)
+ - 📄 [InfixToPrefix](src/main/java/com/thealgorithms/stacks/InfixToPrefix.java)
+ - 📄 [LargestRectangle](src/main/java/com/thealgorithms/stacks/LargestRectangle.java)
+ - 📄 [MaximumMinimumWindow](src/main/java/com/thealgorithms/stacks/MaximumMinimumWindow.java)
+ - 📄 [MinStackUsingSingleStack](src/main/java/com/thealgorithms/stacks/MinStackUsingSingleStack.java)
+ - 📄 [MinStackUsingTwoStacks](src/main/java/com/thealgorithms/stacks/MinStackUsingTwoStacks.java)
+ - 📄 [NextGreaterElement](src/main/java/com/thealgorithms/stacks/NextGreaterElement.java)
+ - 📄 [NextSmallerElement](src/main/java/com/thealgorithms/stacks/NextSmallerElement.java)
+ - 📄 [PalindromeWithStack](src/main/java/com/thealgorithms/stacks/PalindromeWithStack.java)
+ - 📄 [PostfixEvaluator](src/main/java/com/thealgorithms/stacks/PostfixEvaluator.java)
+ - 📄 [PostfixToInfix](src/main/java/com/thealgorithms/stacks/PostfixToInfix.java)
+ - 📄 [PrefixEvaluator](src/main/java/com/thealgorithms/stacks/PrefixEvaluator.java)
+ - 📄 [PrefixToInfix](src/main/java/com/thealgorithms/stacks/PrefixToInfix.java)
+ - 📄 [SmallestElementConstantTime](src/main/java/com/thealgorithms/stacks/SmallestElementConstantTime.java)
+ - 📄 [SortStack](src/main/java/com/thealgorithms/stacks/SortStack.java)
+ - 📄 [StackPostfixNotation](src/main/java/com/thealgorithms/stacks/StackPostfixNotation.java)
+ - 📄 [StackUsingTwoQueues](src/main/java/com/thealgorithms/stacks/StackUsingTwoQueues.java)
+ - 📄 [TrappingRainwater](src/main/java/com/thealgorithms/stacks/TrappingRainwater.java)
+ - 📄 [ValidParentheses](src/main/java/com/thealgorithms/stacks/ValidParentheses.java)
+ - 📁 **strings**
+ - 📄 [AhoCorasick](src/main/java/com/thealgorithms/strings/AhoCorasick.java)
+ - 📄 [Alphabetical](src/main/java/com/thealgorithms/strings/Alphabetical.java)
+ - 📄 [AlternativeStringArrange](src/main/java/com/thealgorithms/strings/AlternativeStringArrange.java)
+ - 📄 [Anagrams](src/main/java/com/thealgorithms/strings/Anagrams.java)
+ - 📄 [CharactersSame](src/main/java/com/thealgorithms/strings/CharactersSame.java)
+ - 📄 [CheckVowels](src/main/java/com/thealgorithms/strings/CheckVowels.java)
+ - 📄 [CountChar](src/main/java/com/thealgorithms/strings/CountChar.java)
+ - 📄 [CountWords](src/main/java/com/thealgorithms/strings/CountWords.java)
+ - 📄 [HammingDistance](src/main/java/com/thealgorithms/strings/HammingDistance.java)
+ - 📄 [HorspoolSearch](src/main/java/com/thealgorithms/strings/HorspoolSearch.java)
+ - 📄 [Isogram](src/main/java/com/thealgorithms/strings/Isogram.java)
+ - 📄 [Isomorphic](src/main/java/com/thealgorithms/strings/Isomorphic.java)
+ - 📄 [KMP](src/main/java/com/thealgorithms/strings/KMP.java)
+ - 📄 [LengthOfLastWord](src/main/java/com/thealgorithms/strings/LengthOfLastWord.java)
+ - 📄 [LetterCombinationsOfPhoneNumber](src/main/java/com/thealgorithms/strings/LetterCombinationsOfPhoneNumber.java)
+ - 📄 [LongestCommonPrefix](src/main/java/com/thealgorithms/strings/LongestCommonPrefix.java)
+ - 📄 [LongestNonRepetitiveSubstring](src/main/java/com/thealgorithms/strings/LongestNonRepetitiveSubstring.java)
+ - 📄 [Lower](src/main/java/com/thealgorithms/strings/Lower.java)
+ - 📄 [Manacher](src/main/java/com/thealgorithms/strings/Manacher.java)
+ - 📄 [MyAtoi](src/main/java/com/thealgorithms/strings/MyAtoi.java)
+ - 📄 [Palindrome](src/main/java/com/thealgorithms/strings/Palindrome.java)
+ - 📄 [Pangram](src/main/java/com/thealgorithms/strings/Pangram.java)
+ - 📄 [PermuteString](src/main/java/com/thealgorithms/strings/PermuteString.java)
+ - 📄 [RabinKarp](src/main/java/com/thealgorithms/strings/RabinKarp.java)
+ - 📄 [RemoveDuplicateFromString](src/main/java/com/thealgorithms/strings/RemoveDuplicateFromString.java)
+ - 📄 [ReturnSubsequence](src/main/java/com/thealgorithms/strings/ReturnSubsequence.java)
+ - 📄 [ReverseString](src/main/java/com/thealgorithms/strings/ReverseString.java)
+ - 📄 [ReverseWordsInString](src/main/java/com/thealgorithms/strings/ReverseWordsInString.java)
+ - 📄 [Rotation](src/main/java/com/thealgorithms/strings/Rotation.java)
+ - 📄 [StringCompression](src/main/java/com/thealgorithms/strings/StringCompression.java)
+ - 📄 [StringMatchFiniteAutomata](src/main/java/com/thealgorithms/strings/StringMatchFiniteAutomata.java)
+ - 📄 [SuffixArray](src/main/java/com/thealgorithms/strings/SuffixArray.java)
+ - 📄 [Upper](src/main/java/com/thealgorithms/strings/Upper.java)
+ - 📄 [WordLadder](src/main/java/com/thealgorithms/strings/WordLadder.java)
+ - 📄 [ZAlgorithm](src/main/java/com/thealgorithms/strings/ZAlgorithm.java)
+ - 📁 **zigZagPattern**
+ - 📄 [ZigZagPattern](src/main/java/com/thealgorithms/strings/zigZagPattern/ZigZagPattern.java)
+ - 📁 **tree**
+ - 📄 [HeavyLightDecomposition](src/main/java/com/thealgorithms/tree/HeavyLightDecomposition.java)
+- 📁 **test**
+ - 📁 **java**
+ - 📁 **com**
+ - 📁 **thealgorithms**
+ - 📁 **audiofilters**
+ - 📄 [EMAFilterTest](src/test/java/com/thealgorithms/audiofilters/EMAFilterTest.java)
+ - 📄 [IIRFilterTest](src/test/java/com/thealgorithms/audiofilters/IIRFilterTest.java)
+ - 📁 **backtracking**
+ - 📄 [AllPathsFromSourceToTargetTest](src/test/java/com/thealgorithms/backtracking/AllPathsFromSourceToTargetTest.java)
+ - 📄 [ArrayCombinationTest](src/test/java/com/thealgorithms/backtracking/ArrayCombinationTest.java)
+ - 📄 [CombinationSumTest](src/test/java/com/thealgorithms/backtracking/CombinationSumTest.java)
+ - 📄 [CombinationTest](src/test/java/com/thealgorithms/backtracking/CombinationTest.java)
+ - 📄 [CrosswordSolverTest](src/test/java/com/thealgorithms/backtracking/CrosswordSolverTest.java)
+ - 📄 [FloodFillTest](src/test/java/com/thealgorithms/backtracking/FloodFillTest.java)
+ - 📄 [KnightsTourTest](src/test/java/com/thealgorithms/backtracking/KnightsTourTest.java)
+ - 📄 [MColoringTest](src/test/java/com/thealgorithms/backtracking/MColoringTest.java)
+ - 📄 [MazeRecursionTest](src/test/java/com/thealgorithms/backtracking/MazeRecursionTest.java)
+ - 📄 [NQueensTest](src/test/java/com/thealgorithms/backtracking/NQueensTest.java)
+ - 📄 [ParenthesesGeneratorTest](src/test/java/com/thealgorithms/backtracking/ParenthesesGeneratorTest.java)
+ - 📄 [PermutationTest](src/test/java/com/thealgorithms/backtracking/PermutationTest.java)
+ - 📄 [PowerSumTest](src/test/java/com/thealgorithms/backtracking/PowerSumTest.java)
+ - 📄 [SubsequenceFinderTest](src/test/java/com/thealgorithms/backtracking/SubsequenceFinderTest.java)
+ - 📄 [SudokuSolverTest](src/test/java/com/thealgorithms/backtracking/SudokuSolverTest.java)
+ - 📄 [UniquePermutationTest](src/test/java/com/thealgorithms/backtracking/UniquePermutationTest.java)
+ - 📄 [WordPatternMatcherTest](src/test/java/com/thealgorithms/backtracking/WordPatternMatcherTest.java)
+ - 📄 [WordSearchTest](src/test/java/com/thealgorithms/backtracking/WordSearchTest.java)
+ - 📁 **bitmanipulation**
+ - 📄 [BcdConversionTest](src/test/java/com/thealgorithms/bitmanipulation/BcdConversionTest.java)
+ - 📄 [BinaryPalindromeCheckTest](src/test/java/com/thealgorithms/bitmanipulation/BinaryPalindromeCheckTest.java)
+ - 📄 [BitRotateTest](src/test/java/com/thealgorithms/bitmanipulation/BitRotateTest.java)
+ - 📄 [BitSwapTest](src/test/java/com/thealgorithms/bitmanipulation/BitSwapTest.java)
+ - 📄 [BitwiseGCDTest](src/test/java/com/thealgorithms/bitmanipulation/BitwiseGCDTest.java)
+ - 📄 [BooleanAlgebraGatesTest](src/test/java/com/thealgorithms/bitmanipulation/BooleanAlgebraGatesTest.java)
+ - 📄 [ClearLeftmostSetBitTest](src/test/java/com/thealgorithms/bitmanipulation/ClearLeftmostSetBitTest.java)
+ - 📄 [CountBitsFlipTest](src/test/java/com/thealgorithms/bitmanipulation/CountBitsFlipTest.java)
+ - 📄 [CountLeadingZerosTest](src/test/java/com/thealgorithms/bitmanipulation/CountLeadingZerosTest.java)
+ - 📄 [CountSetBitsTest](src/test/java/com/thealgorithms/bitmanipulation/CountSetBitsTest.java)
+ - 📄 [FindNthBitTest](src/test/java/com/thealgorithms/bitmanipulation/FindNthBitTest.java)
+ - 📄 [FirstDifferentBitTest](src/test/java/com/thealgorithms/bitmanipulation/FirstDifferentBitTest.java)
+ - 📄 [GenerateSubsetsTest](src/test/java/com/thealgorithms/bitmanipulation/GenerateSubsetsTest.java)
+ - 📄 [GrayCodeConversionTest](src/test/java/com/thealgorithms/bitmanipulation/GrayCodeConversionTest.java)
+ - 📄 [HammingDistanceTest](src/test/java/com/thealgorithms/bitmanipulation/HammingDistanceTest.java)
+ - 📄 [HigherLowerPowerOfTwoTest](src/test/java/com/thealgorithms/bitmanipulation/HigherLowerPowerOfTwoTest.java)
+ - 📄 [HighestSetBitTest](src/test/java/com/thealgorithms/bitmanipulation/HighestSetBitTest.java)
+ - 📄 [IndexOfRightMostSetBitTest](src/test/java/com/thealgorithms/bitmanipulation/IndexOfRightMostSetBitTest.java)
+ - 📄 [IsEvenTest](src/test/java/com/thealgorithms/bitmanipulation/IsEvenTest.java)
+ - 📄 [IsPowerTwoTest](src/test/java/com/thealgorithms/bitmanipulation/IsPowerTwoTest.java)
+ - 📄 [LowestSetBitTest](src/test/java/com/thealgorithms/bitmanipulation/LowestSetBitTest.java)
+ - 📄 [ModuloPowerOfTwoTest](src/test/java/com/thealgorithms/bitmanipulation/ModuloPowerOfTwoTest.java)
+ - 📄 [NextHigherSameBitCountTest](src/test/java/com/thealgorithms/bitmanipulation/NextHigherSameBitCountTest.java)
+ - 📄 [NonRepeatingNumberFinderTest](src/test/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinderTest.java)
+ - 📄 [NumberAppearingOddTimesTest](src/test/java/com/thealgorithms/bitmanipulation/NumberAppearingOddTimesTest.java)
+ - 📄 [NumbersDifferentSignsTest](src/test/java/com/thealgorithms/bitmanipulation/NumbersDifferentSignsTest.java)
+ - 📄 [OneBitDifferenceTest](src/test/java/com/thealgorithms/bitmanipulation/OneBitDifferenceTest.java)
+ - 📄 [OnesComplementTest](src/test/java/com/thealgorithms/bitmanipulation/OnesComplementTest.java)
+ - 📄 [ParityCheckTest](src/test/java/com/thealgorithms/bitmanipulation/ParityCheckTest.java)
+ - 📄 [ReverseBitsTest](src/test/java/com/thealgorithms/bitmanipulation/ReverseBitsTest.java)
+ - 📄 [SingleBitOperationsTest](src/test/java/com/thealgorithms/bitmanipulation/SingleBitOperationsTest.java)
+ - 📄 [SingleElementTest](src/test/java/com/thealgorithms/bitmanipulation/SingleElementTest.java)
+ - 📄 [SwapAdjacentBitsTest](src/test/java/com/thealgorithms/bitmanipulation/SwapAdjacentBitsTest.java)
+ - 📄 [TwosComplementTest](src/test/java/com/thealgorithms/bitmanipulation/TwosComplementTest.java)
+ - 📄 [Xs3ConversionTest](src/test/java/com/thealgorithms/bitmanipulation/Xs3ConversionTest.java)
+ - 📁 **ciphers**
+ - 📄 [ADFGVXCipherTest](src/test/java/com/thealgorithms/ciphers/ADFGVXCipherTest.java)
+ - 📄 [AESEncryptionTest](src/test/java/com/thealgorithms/ciphers/AESEncryptionTest.java)
+ - 📄 [AffineCipherTest](src/test/java/com/thealgorithms/ciphers/AffineCipherTest.java)
+ - 📄 [AtbashTest](src/test/java/com/thealgorithms/ciphers/AtbashTest.java)
+ - 📄 [AutokeyTest](src/test/java/com/thealgorithms/ciphers/AutokeyTest.java)
+ - 📄 [BaconianCipherTest](src/test/java/com/thealgorithms/ciphers/BaconianCipherTest.java)
+ - 📄 [BlowfishTest](src/test/java/com/thealgorithms/ciphers/BlowfishTest.java)
+ - 📄 [CaesarTest](src/test/java/com/thealgorithms/ciphers/CaesarTest.java)
+ - 📄 [ColumnarTranspositionCipherTest](src/test/java/com/thealgorithms/ciphers/ColumnarTranspositionCipherTest.java)
+ - 📄 [DESTest](src/test/java/com/thealgorithms/ciphers/DESTest.java)
+ - 📄 [DiffieHellmanTest](src/test/java/com/thealgorithms/ciphers/DiffieHellmanTest.java)
+ - 📄 [ECCTest](src/test/java/com/thealgorithms/ciphers/ECCTest.java)
+ - 📄 [HillCipherTest](src/test/java/com/thealgorithms/ciphers/HillCipherTest.java)
+ - 📄 [MonoAlphabeticTest](src/test/java/com/thealgorithms/ciphers/MonoAlphabeticTest.java)
+ - 📄 [OneTimePadCipherTest](src/test/java/com/thealgorithms/ciphers/OneTimePadCipherTest.java)
+ - 📄 [PermutationCipherTest](src/test/java/com/thealgorithms/ciphers/PermutationCipherTest.java)
+ - 📄 [PlayfairTest](src/test/java/com/thealgorithms/ciphers/PlayfairTest.java)
+ - 📄 [PolybiusTest](src/test/java/com/thealgorithms/ciphers/PolybiusTest.java)
+ - 📄 [RSATest](src/test/java/com/thealgorithms/ciphers/RSATest.java)
+ - 📄 [RailFenceTest](src/test/java/com/thealgorithms/ciphers/RailFenceTest.java)
+ - 📄 [SimpleSubCipherTest](src/test/java/com/thealgorithms/ciphers/SimpleSubCipherTest.java)
+ - 📄 [VigenereTest](src/test/java/com/thealgorithms/ciphers/VigenereTest.java)
+ - 📄 [XORCipherTest](src/test/java/com/thealgorithms/ciphers/XORCipherTest.java)
+ - 📁 **a5**
+ - 📄 [A5CipherTest](src/test/java/com/thealgorithms/ciphers/a5/A5CipherTest.java)
+ - 📄 [A5KeyStreamGeneratorTest](src/test/java/com/thealgorithms/ciphers/a5/A5KeyStreamGeneratorTest.java)
+ - 📄 [LFSRTest](src/test/java/com/thealgorithms/ciphers/a5/LFSRTest.java)
+ - 📁 **compression**
+ - 📄 [ArithmeticCodingTest](src/test/java/com/thealgorithms/compression/ArithmeticCodingTest.java)
+ - 📄 [BurrowsWheelerTransformTest](src/test/java/com/thealgorithms/compression/BurrowsWheelerTransformTest.java)
+ - 📄 [LZ77Test](src/test/java/com/thealgorithms/compression/LZ77Test.java)
+ - 📄 [LZ78Test](src/test/java/com/thealgorithms/compression/LZ78Test.java)
+ - 📄 [LZWTest](src/test/java/com/thealgorithms/compression/LZWTest.java)
+ - 📄 [MoveToFrontTest](src/test/java/com/thealgorithms/compression/MoveToFrontTest.java)
+ - 📄 [RunLengthEncodingTest](src/test/java/com/thealgorithms/compression/RunLengthEncodingTest.java)
+ - 📄 [ShannonFanoTest](src/test/java/com/thealgorithms/compression/ShannonFanoTest.java)
+ - 📁 **conversions**
+ - 📄 [AffineConverterTest](src/test/java/com/thealgorithms/conversions/AffineConverterTest.java)
+ - 📄 [AnyBaseToDecimalTest](src/test/java/com/thealgorithms/conversions/AnyBaseToDecimalTest.java)
+ - 📄 [AnytoAnyTest](src/test/java/com/thealgorithms/conversions/AnytoAnyTest.java)
+ - 📄 [Base64Test](src/test/java/com/thealgorithms/conversions/Base64Test.java)
+ - 📄 [BinaryToDecimalTest](src/test/java/com/thealgorithms/conversions/BinaryToDecimalTest.java)
+ - 📄 [BinaryToHexadecimalTest](src/test/java/com/thealgorithms/conversions/BinaryToHexadecimalTest.java)
+ - 📄 [BinaryToOctalTest](src/test/java/com/thealgorithms/conversions/BinaryToOctalTest.java)
+ - 📄 [CoordinateConverterTest](src/test/java/com/thealgorithms/conversions/CoordinateConverterTest.java)
+ - 📄 [DecimalToAnyBaseTest](src/test/java/com/thealgorithms/conversions/DecimalToAnyBaseTest.java)
+ - 📄 [DecimalToBinaryTest](src/test/java/com/thealgorithms/conversions/DecimalToBinaryTest.java)
+ - 📄 [DecimalToHexadecimalTest](src/test/java/com/thealgorithms/conversions/DecimalToHexadecimalTest.java)
+ - 📄 [DecimalToOctalTest](src/test/java/com/thealgorithms/conversions/DecimalToOctalTest.java)
+ - 📄 [EndianConverterTest](src/test/java/com/thealgorithms/conversions/EndianConverterTest.java)
+ - 📄 [HexToOctTest](src/test/java/com/thealgorithms/conversions/HexToOctTest.java)
+ - 📄 [HexaDecimalToBinaryTest](src/test/java/com/thealgorithms/conversions/HexaDecimalToBinaryTest.java)
+ - 📄 [HexaDecimalToDecimalTest](src/test/java/com/thealgorithms/conversions/HexaDecimalToDecimalTest.java)
+ - 📄 [IPConverterTest](src/test/java/com/thealgorithms/conversions/IPConverterTest.java)
+ - 📄 [IPv6ConverterTest](src/test/java/com/thealgorithms/conversions/IPv6ConverterTest.java)
+ - 📄 [IntegerToEnglishTest](src/test/java/com/thealgorithms/conversions/IntegerToEnglishTest.java)
+ - 📄 [IntegerToRomanTest](src/test/java/com/thealgorithms/conversions/IntegerToRomanTest.java)
+ - 📄 [MorseCodeConverterTest](src/test/java/com/thealgorithms/conversions/MorseCodeConverterTest.java)
+ - 📄 [NumberToWordsTest](src/test/java/com/thealgorithms/conversions/NumberToWordsTest.java)
+ - 📄 [OctalToBinaryTest](src/test/java/com/thealgorithms/conversions/OctalToBinaryTest.java)
+ - 📄 [OctalToDecimalTest](src/test/java/com/thealgorithms/conversions/OctalToDecimalTest.java)
+ - 📄 [OctalToHexadecimalTest](src/test/java/com/thealgorithms/conversions/OctalToHexadecimalTest.java)
+ - 📄 [PhoneticAlphabetConverterTest](src/test/java/com/thealgorithms/conversions/PhoneticAlphabetConverterTest.java)
+ - 📄 [RomanToIntegerTest](src/test/java/com/thealgorithms/conversions/RomanToIntegerTest.java)
+ - 📄 [TemperatureConverterTest](src/test/java/com/thealgorithms/conversions/TemperatureConverterTest.java)
+ - 📄 [TimeConverterTest](src/test/java/com/thealgorithms/conversions/TimeConverterTest.java)
+ - 📄 [TurkishToLatinConversionTest](src/test/java/com/thealgorithms/conversions/TurkishToLatinConversionTest.java)
+ - 📄 [UnitConversionsTest](src/test/java/com/thealgorithms/conversions/UnitConversionsTest.java)
+ - 📄 [UnitsConverterTest](src/test/java/com/thealgorithms/conversions/UnitsConverterTest.java)
+ - 📄 [WordsToNumberTest](src/test/java/com/thealgorithms/conversions/WordsToNumberTest.java)
+ - 📁 **datastructures**
+ - 📁 **bag**
+ - 📄 [BagTest](src/test/java/com/thealgorithms/datastructures/bag/BagTest.java)
+ - 📁 **bloomfilter**
+ - 📄 [BloomFilterTest](src/test/java/com/thealgorithms/datastructures/bloomfilter/BloomFilterTest.java)
+ - 📁 **buffers**
+ - 📄 [CircularBufferTest](src/test/java/com/thealgorithms/datastructures/buffers/CircularBufferTest.java)
+ - 📁 **caches**
+ - 📄 [FIFOCacheTest](src/test/java/com/thealgorithms/datastructures/caches/FIFOCacheTest.java)
+ - 📄 [LFUCacheTest](src/test/java/com/thealgorithms/datastructures/caches/LFUCacheTest.java)
+ - 📄 [LIFOCacheTest](src/test/java/com/thealgorithms/datastructures/caches/LIFOCacheTest.java)
+ - 📄 [LRUCacheTest](src/test/java/com/thealgorithms/datastructures/caches/LRUCacheTest.java)
+ - 📄 [MRUCacheTest](src/test/java/com/thealgorithms/datastructures/caches/MRUCacheTest.java)
+ - 📄 [RRCacheTest](src/test/java/com/thealgorithms/datastructures/caches/RRCacheTest.java)
+ - 📁 **crdt**
+ - 📄 [GCounterTest](src/test/java/com/thealgorithms/datastructures/crdt/GCounterTest.java)
+ - 📄 [GSetTest](src/test/java/com/thealgorithms/datastructures/crdt/GSetTest.java)
+ - 📄 [LWWElementSetTest](src/test/java/com/thealgorithms/datastructures/crdt/LWWElementSetTest.java)
+ - 📄 [ORSetTest](src/test/java/com/thealgorithms/datastructures/crdt/ORSetTest.java)
+ - 📄 [PNCounterTest](src/test/java/com/thealgorithms/datastructures/crdt/PNCounterTest.java)
+ - 📄 [TwoPSetTest](src/test/java/com/thealgorithms/datastructures/crdt/TwoPSetTest.java)
+ - 📁 **disjointsetunion**
+ - 📄 [DisjointSetUnionBySizeTest](src/test/java/com/thealgorithms/datastructures/disjointsetunion/DisjointSetUnionBySizeTest.java)
+ - 📄 [DisjointSetUnionTest](src/test/java/com/thealgorithms/datastructures/disjointsetunion/DisjointSetUnionTest.java)
+ - 📁 **dynamicarray**
+ - 📄 [DynamicArrayTest](src/test/java/com/thealgorithms/datastructures/dynamicarray/DynamicArrayTest.java)
+ - 📁 **graphs**
+ - 📄 [AStarTest](src/test/java/com/thealgorithms/datastructures/graphs/AStarTest.java)
+ - 📄 [BellmanFordTest](src/test/java/com/thealgorithms/datastructures/graphs/BellmanFordTest.java)
+ - 📄 [BipartiteGraphDFSTest](src/test/java/com/thealgorithms/datastructures/graphs/BipartiteGraphDFSTest.java)
+ - 📄 [BoruvkaAlgorithmTest](src/test/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithmTest.java)
+ - 📄 [ConnectedComponentTest](src/test/java/com/thealgorithms/datastructures/graphs/ConnectedComponentTest.java)
+ - 📄 [DialsAlgorithmTest](src/test/java/com/thealgorithms/datastructures/graphs/DialsAlgorithmTest.java)
+ - 📄 [DijkstraAlgorithmTest](src/test/java/com/thealgorithms/datastructures/graphs/DijkstraAlgorithmTest.java)
+ - 📄 [DijkstraOptimizedAlgorithmTest](src/test/java/com/thealgorithms/datastructures/graphs/DijkstraOptimizedAlgorithmTest.java)
+ - 📄 [EdmondsBlossomAlgorithmTest](src/test/java/com/thealgorithms/datastructures/graphs/EdmondsBlossomAlgorithmTest.java)
+ - 📄 [FloydWarshallTest](src/test/java/com/thealgorithms/datastructures/graphs/FloydWarshallTest.java)
+ - 📄 [FordFulkersonTest](src/test/java/com/thealgorithms/datastructures/graphs/FordFulkersonTest.java)
+ - 📄 [HamiltonianCycleTest](src/test/java/com/thealgorithms/datastructures/graphs/HamiltonianCycleTest.java)
+ - 📄 [JohnsonsAlgorithmTest](src/test/java/com/thealgorithms/datastructures/graphs/JohnsonsAlgorithmTest.java)
+ - 📄 [KahnsAlgorithmTest](src/test/java/com/thealgorithms/datastructures/graphs/KahnsAlgorithmTest.java)
+ - 📄 [KosarajuTest](src/test/java/com/thealgorithms/datastructures/graphs/KosarajuTest.java)
+ - 📄 [KruskalTest](src/test/java/com/thealgorithms/datastructures/graphs/KruskalTest.java)
+ - 📄 [MatrixGraphsTest](src/test/java/com/thealgorithms/datastructures/graphs/MatrixGraphsTest.java)
+ - 📄 [PrimMSTTest](src/test/java/com/thealgorithms/datastructures/graphs/PrimMSTTest.java)
+ - 📄 [TarjansAlgorithmTest](src/test/java/com/thealgorithms/datastructures/graphs/TarjansAlgorithmTest.java)
+ - 📄 [TwoSatTest](src/test/java/com/thealgorithms/datastructures/graphs/TwoSatTest.java)
+ - 📄 [WelshPowellTest](src/test/java/com/thealgorithms/datastructures/graphs/WelshPowellTest.java)
+ - 📁 **hashmap**
+ - 📁 **hashing**
+ - 📄 [GenericHashMapUsingArrayListTest](src/test/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayListTest.java)
+ - 📄 [GenericHashMapUsingArrayTest](src/test/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayTest.java)
+ - 📄 [HashMapCuckooHashingTest](src/test/java/com/thealgorithms/datastructures/hashmap/hashing/HashMapCuckooHashingTest.java)
+ - 📄 [HashMapTest](src/test/java/com/thealgorithms/datastructures/hashmap/hashing/HashMapTest.java)
+ - 📄 [ImmutableHashMapTest](src/test/java/com/thealgorithms/datastructures/hashmap/hashing/ImmutableHashMapTest.java)
+ - 📄 [IntersectionTest](src/test/java/com/thealgorithms/datastructures/hashmap/hashing/IntersectionTest.java)
+ - 📄 [LinearProbingHashMapTest](src/test/java/com/thealgorithms/datastructures/hashmap/hashing/LinearProbingHashMapTest.java)
+ - 📄 [MajorityElementTest](src/test/java/com/thealgorithms/datastructures/hashmap/hashing/MajorityElementTest.java)
+ - 📄 [MapTest](src/test/java/com/thealgorithms/datastructures/hashmap/hashing/MapTest.java)
+ - 📁 **heaps**
+ - 📄 [FibonacciHeapTest](src/test/java/com/thealgorithms/datastructures/heaps/FibonacciHeapTest.java)
+ - 📄 [GenericHeapTest](src/test/java/com/thealgorithms/datastructures/heaps/GenericHeapTest.java)
+ - 📄 [HeapElementTest](src/test/java/com/thealgorithms/datastructures/heaps/HeapElementTest.java)
+ - 📄 [IndexedPriorityQueueTest](src/test/java/com/thealgorithms/datastructures/heaps/IndexedPriorityQueueTest.java)
+ - 📄 [KthElementFinderTest](src/test/java/com/thealgorithms/datastructures/heaps/KthElementFinderTest.java)
+ - 📄 [LeftistHeapTest](src/test/java/com/thealgorithms/datastructures/heaps/LeftistHeapTest.java)
+ - 📄 [MaxHeapTest](src/test/java/com/thealgorithms/datastructures/heaps/MaxHeapTest.java)
+ - 📄 [MedianFinderTest](src/test/java/com/thealgorithms/datastructures/heaps/MedianFinderTest.java)
+ - 📄 [MergeKSortedArraysTest](src/test/java/com/thealgorithms/datastructures/heaps/MergeKSortedArraysTest.java)
+ - 📄 [MinHeapTest](src/test/java/com/thealgorithms/datastructures/heaps/MinHeapTest.java)
+ - 📄 [MinPriorityQueueTest](src/test/java/com/thealgorithms/datastructures/heaps/MinPriorityQueueTest.java)
+ - 📁 **lists**
+ - 📄 [CircleLinkedListTest](src/test/java/com/thealgorithms/datastructures/lists/CircleLinkedListTest.java)
+ - 📄 [CircularDoublyLinkedListTest](src/test/java/com/thealgorithms/datastructures/lists/CircularDoublyLinkedListTest.java)
+ - 📄 [CountSinglyLinkedListRecursionTest](src/test/java/com/thealgorithms/datastructures/lists/CountSinglyLinkedListRecursionTest.java)
+ - 📄 [CreateAndDetectLoopTest](src/test/java/com/thealgorithms/datastructures/lists/CreateAndDetectLoopTest.java)
+ - 📄 [CursorLinkedListTest](src/test/java/com/thealgorithms/datastructures/lists/CursorLinkedListTest.java)
+ - 📄 [FlattenMultilevelLinkedListTest](src/test/java/com/thealgorithms/datastructures/lists/FlattenMultilevelLinkedListTest.java)
+ - 📄 [MergeKSortedLinkedListTest](src/test/java/com/thealgorithms/datastructures/lists/MergeKSortedLinkedListTest.java)
+ - 📄 [MergeSortedArrayListTest](src/test/java/com/thealgorithms/datastructures/lists/MergeSortedArrayListTest.java)
+ - 📄 [MergeSortedSinglyLinkedListTest](src/test/java/com/thealgorithms/datastructures/lists/MergeSortedSinglyLinkedListTest.java)
+ - 📄 [QuickSortLinkedListTest](src/test/java/com/thealgorithms/datastructures/lists/QuickSortLinkedListTest.java)
+ - 📄 [ReverseKGroupTest](src/test/java/com/thealgorithms/datastructures/lists/ReverseKGroupTest.java)
+ - 📄 [RotateSinglyLinkedListsTest](src/test/java/com/thealgorithms/datastructures/lists/RotateSinglyLinkedListsTest.java)
+ - 📄 [SearchSinglyLinkedListRecursionTest](src/test/java/com/thealgorithms/datastructures/lists/SearchSinglyLinkedListRecursionTest.java)
+ - 📄 [SinglyLinkedListTest](src/test/java/com/thealgorithms/datastructures/lists/SinglyLinkedListTest.java)
+ - 📄 [SkipListTest](src/test/java/com/thealgorithms/datastructures/lists/SkipListTest.java)
+ - 📄 [SortedLinkedListTest](src/test/java/com/thealgorithms/datastructures/lists/SortedLinkedListTest.java)
+ - 📄 [TortoiseHareAlgoTest](src/test/java/com/thealgorithms/datastructures/lists/TortoiseHareAlgoTest.java)
+ - 📁 **queues**
+ - 📄 [CircularQueueTest](src/test/java/com/thealgorithms/datastructures/queues/CircularQueueTest.java)
+ - 📄 [DequeTest](src/test/java/com/thealgorithms/datastructures/queues/DequeTest.java)
+ - 📄 [GenericArrayListQueueTest](src/test/java/com/thealgorithms/datastructures/queues/GenericArrayListQueueTest.java)
+ - 📄 [LinkedQueueTest](src/test/java/com/thealgorithms/datastructures/queues/LinkedQueueTest.java)
+ - 📄 [PriorityQueuesTest](src/test/java/com/thealgorithms/datastructures/queues/PriorityQueuesTest.java)
+ - 📄 [QueueByTwoStacksTest](src/test/java/com/thealgorithms/datastructures/queues/QueueByTwoStacksTest.java)
+ - 📄 [QueueTest](src/test/java/com/thealgorithms/datastructures/queues/QueueTest.java)
+ - 📄 [SlidingWindowMaximumTest](src/test/java/com/thealgorithms/datastructures/queues/SlidingWindowMaximumTest.java)
+ - 📄 [TokenBucketTest](src/test/java/com/thealgorithms/datastructures/queues/TokenBucketTest.java)
+ - 📁 **stacks**
+ - 📄 [NodeStackTest](src/test/java/com/thealgorithms/datastructures/stacks/NodeStackTest.java)
+ - 📄 [ReverseStackTest](src/test/java/com/thealgorithms/datastructures/stacks/ReverseStackTest.java)
+ - 📄 [StackArrayListTest](src/test/java/com/thealgorithms/datastructures/stacks/StackArrayListTest.java)
+ - 📄 [StackArrayTest](src/test/java/com/thealgorithms/datastructures/stacks/StackArrayTest.java)
+ - 📄 [StackOfLinkedListTest](src/test/java/com/thealgorithms/datastructures/stacks/StackOfLinkedListTest.java)
+ - 📁 **trees**
+ - 📄 [AVLTreeTest](src/test/java/com/thealgorithms/datastructures/trees/AVLTreeTest.java)
+ - 📄 [BSTFromSortedArrayTest](src/test/java/com/thealgorithms/datastructures/trees/BSTFromSortedArrayTest.java)
+ - 📄 [BSTIterativeTest](src/test/java/com/thealgorithms/datastructures/trees/BSTIterativeTest.java)
+ - 📄 [BSTRecursiveGenericTest](src/test/java/com/thealgorithms/datastructures/trees/BSTRecursiveGenericTest.java)
+ - 📄 [BSTRecursiveTest](src/test/java/com/thealgorithms/datastructures/trees/BSTRecursiveTest.java)
+ - 📄 [BTreeTest](src/test/java/com/thealgorithms/datastructures/trees/BTreeTest.java)
+ - 📄 [BinaryTreeTest](src/test/java/com/thealgorithms/datastructures/trees/BinaryTreeTest.java)
+ - 📄 [BinaryTreeToStringTest](src/test/java/com/thealgorithms/datastructures/trees/BinaryTreeToStringTest.java)
+ - 📄 [BoundaryTraversalTest](src/test/java/com/thealgorithms/datastructures/trees/BoundaryTraversalTest.java)
+ - 📄 [CeilInBinarySearchTreeTest](src/test/java/com/thealgorithms/datastructures/trees/CeilInBinarySearchTreeTest.java)
+ - 📄 [CentroidDecompositionTest](src/test/java/com/thealgorithms/datastructures/trees/CentroidDecompositionTest.java)
+ - 📄 [CheckBinaryTreeIsValidBSTTest](src/test/java/com/thealgorithms/datastructures/trees/CheckBinaryTreeIsValidBSTTest.java)
+ - 📄 [CheckIfBinaryTreeBalancedTest](src/test/java/com/thealgorithms/datastructures/trees/CheckIfBinaryTreeBalancedTest.java)
+ - 📄 [CheckTreeIsSymmetricTest](src/test/java/com/thealgorithms/datastructures/trees/CheckTreeIsSymmetricTest.java)
+ - 📄 [CreateBinaryTreeFromInorderPreorderTest](src/test/java/com/thealgorithms/datastructures/trees/CreateBinaryTreeFromInorderPreorderTest.java)
+ - 📄 [InorderTraversalTest](src/test/java/com/thealgorithms/datastructures/trees/InorderTraversalTest.java)
+ - 📄 [KDTreeTest](src/test/java/com/thealgorithms/datastructures/trees/KDTreeTest.java)
+ - 📄 [LazySegmentTreeTest](src/test/java/com/thealgorithms/datastructures/trees/LazySegmentTreeTest.java)
+ - 📄 [LevelOrderTraversalTest](src/test/java/com/thealgorithms/datastructures/trees/LevelOrderTraversalTest.java)
+ - 📄 [PostOrderTraversalTest](src/test/java/com/thealgorithms/datastructures/trees/PostOrderTraversalTest.java)
+ - 📄 [PreOrderTraversalTest](src/test/java/com/thealgorithms/datastructures/trees/PreOrderTraversalTest.java)
+ - 📄 [QuadTreeTest](src/test/java/com/thealgorithms/datastructures/trees/QuadTreeTest.java)
+ - 📄 [SameTreesCheckTest](src/test/java/com/thealgorithms/datastructures/trees/SameTreesCheckTest.java)
+ - 📄 [SplayTreeTest](src/test/java/com/thealgorithms/datastructures/trees/SplayTreeTest.java)
+ - 📄 [ThreadedBinaryTreeTest](src/test/java/com/thealgorithms/datastructures/trees/ThreadedBinaryTreeTest.java)
+ - 📄 [TreapTest](src/test/java/com/thealgorithms/datastructures/trees/TreapTest.java)
+ - 📄 [TreeTestUtils](src/test/java/com/thealgorithms/datastructures/trees/TreeTestUtils.java)
+ - 📄 [TrieTest](src/test/java/com/thealgorithms/datastructures/trees/TrieTest.java)
+ - 📄 [VerticalOrderTraversalTest](src/test/java/com/thealgorithms/datastructures/trees/VerticalOrderTraversalTest.java)
+ - 📄 [ZigzagTraversalTest](src/test/java/com/thealgorithms/datastructures/trees/ZigzagTraversalTest.java)
+ - 📁 **devutils**
+ - 📁 **entities**
+ - 📄 [ProcessDetailsTest](src/test/java/com/thealgorithms/devutils/entities/ProcessDetailsTest.java)
+ - 📁 **divideandconquer**
+ - 📄 [BinaryExponentiationTest](src/test/java/com/thealgorithms/divideandconquer/BinaryExponentiationTest.java)
+ - 📄 [ClosestPairTest](src/test/java/com/thealgorithms/divideandconquer/ClosestPairTest.java)
+ - 📄 [CountingInversionsTest](src/test/java/com/thealgorithms/divideandconquer/CountingInversionsTest.java)
+ - 📄 [MedianOfTwoSortedArraysTest](src/test/java/com/thealgorithms/divideandconquer/MedianOfTwoSortedArraysTest.java)
+ - 📄 [SkylineAlgorithmTest](src/test/java/com/thealgorithms/divideandconquer/SkylineAlgorithmTest.java)
+ - 📄 [StrassenMatrixMultiplicationTest](src/test/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplicationTest.java)
+ - 📄 [TilingProblemTest](src/test/java/com/thealgorithms/divideandconquer/TilingProblemTest.java)
+ - 📁 **dynamicprogramming**
+ - 📄 [AbbreviationTest](src/test/java/com/thealgorithms/dynamicprogramming/AbbreviationTest.java)
+ - 📄 [AllConstructTest](src/test/java/com/thealgorithms/dynamicprogramming/AllConstructTest.java)
+ - 📄 [AssignmentUsingBitmaskTest](src/test/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmaskTest.java)
+ - 📄 [BoardPathTest](src/test/java/com/thealgorithms/dynamicprogramming/BoardPathTest.java)
+ - 📄 [BoundaryFillTest](src/test/java/com/thealgorithms/dynamicprogramming/BoundaryFillTest.java)
+ - 📄 [BruteForceKnapsackTest](src/test/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsackTest.java)
+ - 📄 [CatalanNumberTest](src/test/java/com/thealgorithms/dynamicprogramming/CatalanNumberTest.java)
+ - 📄 [ClimbStairsTest](src/test/java/com/thealgorithms/dynamicprogramming/ClimbStairsTest.java)
+ - 📄 [CoinChangeTest](src/test/java/com/thealgorithms/dynamicprogramming/CoinChangeTest.java)
+ - 📄 [CountFriendsPairingTest](src/test/java/com/thealgorithms/dynamicprogramming/CountFriendsPairingTest.java)
+ - 📄 [DPTest](src/test/java/com/thealgorithms/dynamicprogramming/DPTest.java)
+ - 📄 [DamerauLevenshteinDistanceTest](src/test/java/com/thealgorithms/dynamicprogramming/DamerauLevenshteinDistanceTest.java)
+ - 📄 [EditDistanceTest](src/test/java/com/thealgorithms/dynamicprogramming/EditDistanceTest.java)
+ - 📄 [EggDroppingTest](src/test/java/com/thealgorithms/dynamicprogramming/EggDroppingTest.java)
+ - 📄 [FibonacciTest](src/test/java/com/thealgorithms/dynamicprogramming/FibonacciTest.java)
+ - 📄 [KadaneAlgorithmTest](src/test/java/com/thealgorithms/dynamicprogramming/KadaneAlgorithmTest.java)
+ - 📄 [KnapsackMemoizationTest](src/test/java/com/thealgorithms/dynamicprogramming/KnapsackMemoizationTest.java)
+ - 📄 [KnapsackTest](src/test/java/com/thealgorithms/dynamicprogramming/KnapsackTest.java)
+ - 📄 [KnapsackZeroOneTabulationTest](src/test/java/com/thealgorithms/dynamicprogramming/KnapsackZeroOneTabulationTest.java)
+ - 📄 [KnapsackZeroOneTest](src/test/java/com/thealgorithms/dynamicprogramming/KnapsackZeroOneTest.java)
+ - 📄 [LevenshteinDistanceTests](src/test/java/com/thealgorithms/dynamicprogramming/LevenshteinDistanceTests.java)
+ - 📄 [LongestAlternatingSubsequenceTest](src/test/java/com/thealgorithms/dynamicprogramming/LongestAlternatingSubsequenceTest.java)
+ - 📄 [LongestArithmeticSubsequenceTest](src/test/java/com/thealgorithms/dynamicprogramming/LongestArithmeticSubsequenceTest.java)
+ - 📄 [LongestCommonSubsequenceTest](src/test/java/com/thealgorithms/dynamicprogramming/LongestCommonSubsequenceTest.java)
+ - 📄 [LongestIncreasingSubsequenceNLogNTest](src/test/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequenceNLogNTest.java)
+ - 📄 [LongestIncreasingSubsequenceTests](src/test/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequenceTests.java)
+ - 📄 [LongestPalindromicSubstringTest](src/test/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubstringTest.java)
+ - 📄 [LongestValidParenthesesTest](src/test/java/com/thealgorithms/dynamicprogramming/LongestValidParenthesesTest.java)
+ - 📄 [MatrixChainMultiplicationTest](src/test/java/com/thealgorithms/dynamicprogramming/MatrixChainMultiplicationTest.java)
+ - 📄 [MatrixChainRecursiveTopDownMemoisationTest](src/test/java/com/thealgorithms/dynamicprogramming/MatrixChainRecursiveTopDownMemoisationTest.java)
+ - 📄 [MaximumProductSubarrayTest](src/test/java/com/thealgorithms/dynamicprogramming/MaximumProductSubarrayTest.java)
+ - 📄 [MaximumSumOfNonAdjacentElementsTest](src/test/java/com/thealgorithms/dynamicprogramming/MaximumSumOfNonAdjacentElementsTest.java)
+ - 📄 [MinimumPathSumTest](src/test/java/com/thealgorithms/dynamicprogramming/MinimumPathSumTest.java)
+ - 📄 [MinimumSumPartitionTest](src/test/java/com/thealgorithms/dynamicprogramming/MinimumSumPartitionTest.java)
+ - 📄 [NeedlemanWunschTest](src/test/java/com/thealgorithms/dynamicprogramming/NeedlemanWunschTest.java)
+ - 📄 [NewManShanksPrimeTest](src/test/java/com/thealgorithms/dynamicprogramming/NewManShanksPrimeTest.java)
+ - 📄 [OptimalJobSchedulingTest](src/test/java/com/thealgorithms/dynamicprogramming/OptimalJobSchedulingTest.java)
+ - 📄 [PalindromicPartitioningTest](src/test/java/com/thealgorithms/dynamicprogramming/PalindromicPartitioningTest.java)
+ - 📄 [PartitionProblemTest](src/test/java/com/thealgorithms/dynamicprogramming/PartitionProblemTest.java)
+ - 📄 [RegexMatchingTest](src/test/java/com/thealgorithms/dynamicprogramming/RegexMatchingTest.java)
+ - 📄 [RodCuttingTest](src/test/java/com/thealgorithms/dynamicprogramming/RodCuttingTest.java)
+ - 📄 [ShortestCommonSupersequenceLengthTest](src/test/java/com/thealgorithms/dynamicprogramming/ShortestCommonSupersequenceLengthTest.java)
+ - 📄 [SmithWatermanTest](src/test/java/com/thealgorithms/dynamicprogramming/SmithWatermanTest.java)
+ - 📄 [SubsetCountTest](src/test/java/com/thealgorithms/dynamicprogramming/SubsetCountTest.java)
+ - 📄 [SubsetSumSpaceOptimizedTest](src/test/java/com/thealgorithms/dynamicprogramming/SubsetSumSpaceOptimizedTest.java)
+ - 📄 [SubsetSumTest](src/test/java/com/thealgorithms/dynamicprogramming/SubsetSumTest.java)
+ - 📄 [SumOfSubsetTest](src/test/java/com/thealgorithms/dynamicprogramming/SumOfSubsetTest.java)
+ - 📄 [TreeMatchingTest](src/test/java/com/thealgorithms/dynamicprogramming/TreeMatchingTest.java)
+ - 📄 [TribonacciTest](src/test/java/com/thealgorithms/dynamicprogramming/TribonacciTest.java)
+ - 📄 [UniquePathsTests](src/test/java/com/thealgorithms/dynamicprogramming/UniquePathsTests.java)
+ - 📄 [UniqueSubsequencesCountTest](src/test/java/com/thealgorithms/dynamicprogramming/UniqueSubsequencesCountTest.java)
+ - 📄 [WildcardMatchingTest](src/test/java/com/thealgorithms/dynamicprogramming/WildcardMatchingTest.java)
+ - 📄 [WineProblemTest](src/test/java/com/thealgorithms/dynamicprogramming/WineProblemTest.java)
+ - 📁 **geometry**
+ - 📄 [BentleyOttmannTest](src/test/java/com/thealgorithms/geometry/BentleyOttmannTest.java)
+ - 📄 [BresenhamLineTest](src/test/java/com/thealgorithms/geometry/BresenhamLineTest.java)
+ - 📄 [ConvexHullTest](src/test/java/com/thealgorithms/geometry/ConvexHullTest.java)
+ - 📄 [DDALineTest](src/test/java/com/thealgorithms/geometry/DDALineTest.java)
+ - 📄 [GrahamScanTest](src/test/java/com/thealgorithms/geometry/GrahamScanTest.java)
+ - 📄 [HaversineTest](src/test/java/com/thealgorithms/geometry/HaversineTest.java)
+ - 📄 [MidpointCircleTest](src/test/java/com/thealgorithms/geometry/MidpointCircleTest.java)
+ - 📄 [MidpointEllipseTest](src/test/java/com/thealgorithms/geometry/MidpointEllipseTest.java)
+ - 📄 [PointTest](src/test/java/com/thealgorithms/geometry/PointTest.java)
+ - 📄 [WusLineTest](src/test/java/com/thealgorithms/geometry/WusLineTest.java)
+ - 📁 **graph**
+ - 📄 [BronKerboschTest](src/test/java/com/thealgorithms/graph/BronKerboschTest.java)
+ - 📄 [ConstrainedShortestPathTest](src/test/java/com/thealgorithms/graph/ConstrainedShortestPathTest.java)
+ - 📄 [DinicTest](src/test/java/com/thealgorithms/graph/DinicTest.java)
+ - 📄 [EdmondsKarpTest](src/test/java/com/thealgorithms/graph/EdmondsKarpTest.java)
+ - 📄 [EdmondsTest](src/test/java/com/thealgorithms/graph/EdmondsTest.java)
+ - 📄 [GomoryHuTreeTest](src/test/java/com/thealgorithms/graph/GomoryHuTreeTest.java)
+ - 📄 [HierholzerAlgorithmTest](src/test/java/com/thealgorithms/graph/HierholzerAlgorithmTest.java)
+ - 📄 [HierholzerEulerianPathTest](src/test/java/com/thealgorithms/graph/HierholzerEulerianPathTest.java)
+ - 📄 [HopcroftKarpTest](src/test/java/com/thealgorithms/graph/HopcroftKarpTest.java)
+ - 📄 [HungarianAlgorithmTest](src/test/java/com/thealgorithms/graph/HungarianAlgorithmTest.java)
+ - 📄 [PredecessorConstrainedDfsTest](src/test/java/com/thealgorithms/graph/PredecessorConstrainedDfsTest.java)
+ - 📄 [PushRelabelTest](src/test/java/com/thealgorithms/graph/PushRelabelTest.java)
+ - 📄 [StoerWagnerTest](src/test/java/com/thealgorithms/graph/StoerWagnerTest.java)
+ - 📄 [StronglyConnectedComponentOptimizedTest](src/test/java/com/thealgorithms/graph/StronglyConnectedComponentOptimizedTest.java)
+ - 📄 [TravelingSalesmanTest](src/test/java/com/thealgorithms/graph/TravelingSalesmanTest.java)
+ - 📄 [YensKShortestPathsTest](src/test/java/com/thealgorithms/graph/YensKShortestPathsTest.java)
+ - 📄 [ZeroOneBfsTest](src/test/java/com/thealgorithms/graph/ZeroOneBfsTest.java)
+ - 📁 **greedyalgorithms**
+ - 📄 [ActivitySelectionTest](src/test/java/com/thealgorithms/greedyalgorithms/ActivitySelectionTest.java)
+ - 📄 [BandwidthAllocationTest](src/test/java/com/thealgorithms/greedyalgorithms/BandwidthAllocationTest.java)
+ - 📄 [BinaryAdditionTest](src/test/java/com/thealgorithms/greedyalgorithms/BinaryAdditionTest.java)
+ - 📄 [CoinChangeTest](src/test/java/com/thealgorithms/greedyalgorithms/CoinChangeTest.java)
+ - 📄 [DigitSeparationTest](src/test/java/com/thealgorithms/greedyalgorithms/DigitSeparationTest.java)
+ - 📄 [EgyptianFractionTest](src/test/java/com/thealgorithms/greedyalgorithms/EgyptianFractionTest.java)
+ - 📄 [FractionalKnapsackTest](src/test/java/com/thealgorithms/greedyalgorithms/FractionalKnapsackTest.java)
+ - 📄 [GaleShapleyTest](src/test/java/com/thealgorithms/greedyalgorithms/GaleShapleyTest.java)
+ - 📄 [JobSequencingTest](src/test/java/com/thealgorithms/greedyalgorithms/JobSequencingTest.java)
+ - 📄 [KCentersTest](src/test/java/com/thealgorithms/greedyalgorithms/KCentersTest.java)
+ - 📄 [MergeIntervalsTest](src/test/java/com/thealgorithms/greedyalgorithms/MergeIntervalsTest.java)
+ - 📄 [MinimizingLatenessTest](src/test/java/com/thealgorithms/greedyalgorithms/MinimizingLatenessTest.java)
+ - 📄 [MinimumWaitingTimeTest](src/test/java/com/thealgorithms/greedyalgorithms/MinimumWaitingTimeTest.java)
+ - 📄 [OptimalFileMergingTest](src/test/java/com/thealgorithms/greedyalgorithms/OptimalFileMergingTest.java)
+ - 📄 [StockProfitCalculatorTest](src/test/java/com/thealgorithms/greedyalgorithms/StockProfitCalculatorTest.java)
+ - 📁 **io**
+ - 📄 [BufferedReaderTest](src/test/java/com/thealgorithms/io/BufferedReaderTest.java)
+ - 📁 **lineclipping**
+ - 📄 [CohenSutherlandTest](src/test/java/com/thealgorithms/lineclipping/CohenSutherlandTest.java)
+ - 📄 [LiangBarskyTest](src/test/java/com/thealgorithms/lineclipping/LiangBarskyTest.java)
+ - 📁 **maths**
+ - 📄 [ADTFractionTest](src/test/java/com/thealgorithms/maths/ADTFractionTest.java)
+ - 📄 [AbsoluteMaxTest](src/test/java/com/thealgorithms/maths/AbsoluteMaxTest.java)
+ - 📄 [AbsoluteMinTest](src/test/java/com/thealgorithms/maths/AbsoluteMinTest.java)
+ - 📄 [AbsoluteValueTest](src/test/java/com/thealgorithms/maths/AbsoluteValueTest.java)
+ - 📄 [AbundantNumberTest](src/test/java/com/thealgorithms/maths/AbundantNumberTest.java)
+ - 📄 [AliquotSumTest](src/test/java/com/thealgorithms/maths/AliquotSumTest.java)
+ - 📄 [AmicableNumberTest](src/test/java/com/thealgorithms/maths/AmicableNumberTest.java)
+ - 📄 [AreaTest](src/test/java/com/thealgorithms/maths/AreaTest.java)
+ - 📄 [ArmstrongTest](src/test/java/com/thealgorithms/maths/ArmstrongTest.java)
+ - 📄 [AutoCorrelationTest](src/test/java/com/thealgorithms/maths/AutoCorrelationTest.java)
+ - 📄 [AutomorphicNumberTest](src/test/java/com/thealgorithms/maths/AutomorphicNumberTest.java)
+ - 📄 [AverageTest](src/test/java/com/thealgorithms/maths/AverageTest.java)
+ - 📄 [BinaryPowTest](src/test/java/com/thealgorithms/maths/BinaryPowTest.java)
+ - 📄 [BinomialCoefficientTest](src/test/java/com/thealgorithms/maths/BinomialCoefficientTest.java)
+ - 📄 [CatalanNumbersTest](src/test/java/com/thealgorithms/maths/CatalanNumbersTest.java)
+ - 📄 [CeilTest](src/test/java/com/thealgorithms/maths/CeilTest.java)
+ - 📄 [ChebyshevIterationTest](src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java)
+ - 📄 [ChineseRemainderTheoremTest](src/test/java/com/thealgorithms/maths/ChineseRemainderTheoremTest.java)
+ - 📄 [CollatzConjectureTest](src/test/java/com/thealgorithms/maths/CollatzConjectureTest.java)
+ - 📄 [CombinationsTest](src/test/java/com/thealgorithms/maths/CombinationsTest.java)
+ - 📄 [ConvolutionFFTTest](src/test/java/com/thealgorithms/maths/ConvolutionFFTTest.java)
+ - 📄 [ConvolutionTest](src/test/java/com/thealgorithms/maths/ConvolutionTest.java)
+ - 📄 [CrossCorrelationTest](src/test/java/com/thealgorithms/maths/CrossCorrelationTest.java)
+ - 📄 [DeterminantOfMatrixTest](src/test/java/com/thealgorithms/maths/DeterminantOfMatrixTest.java)
+ - 📄 [DigitalRootTest](src/test/java/com/thealgorithms/maths/DigitalRootTest.java)
+ - 📄 [DistanceFormulaTest](src/test/java/com/thealgorithms/maths/DistanceFormulaTest.java)
+ - 📄 [DudeneyNumberTest](src/test/java/com/thealgorithms/maths/DudeneyNumberTest.java)
+ - 📄 [EulerMethodTest](src/test/java/com/thealgorithms/maths/EulerMethodTest.java)
+ - 📄 [EulerPseudoprimeTest](src/test/java/com/thealgorithms/maths/EulerPseudoprimeTest.java)
+ - 📄 [EulersFunctionTest](src/test/java/com/thealgorithms/maths/EulersFunctionTest.java)
+ - 📄 [EvilNumberTest](src/test/java/com/thealgorithms/maths/EvilNumberTest.java)
+ - 📄 [ExtendedEuclideanAlgorithmTest](src/test/java/com/thealgorithms/maths/ExtendedEuclideanAlgorithmTest.java)
+ - 📄 [FFTTest](src/test/java/com/thealgorithms/maths/FFTTest.java)
+ - 📄 [FactorialTest](src/test/java/com/thealgorithms/maths/FactorialTest.java)
+ - 📄 [FastExponentiationTest](src/test/java/com/thealgorithms/maths/FastExponentiationTest.java)
+ - 📄 [FastInverseSqrtTests](src/test/java/com/thealgorithms/maths/FastInverseSqrtTests.java)
+ - 📄 [FibonacciJavaStreamsTest](src/test/java/com/thealgorithms/maths/FibonacciJavaStreamsTest.java)
+ - 📄 [FibonacciLoopTest](src/test/java/com/thealgorithms/maths/FibonacciLoopTest.java)
+ - 📄 [FibonacciNumberCheckTest](src/test/java/com/thealgorithms/maths/FibonacciNumberCheckTest.java)
+ - 📄 [FibonacciNumberGoldenRationTest](src/test/java/com/thealgorithms/maths/FibonacciNumberGoldenRationTest.java)
+ - 📄 [FindKthNumberTest](src/test/java/com/thealgorithms/maths/FindKthNumberTest.java)
+ - 📄 [FindMaxRecursionTest](src/test/java/com/thealgorithms/maths/FindMaxRecursionTest.java)
+ - 📄 [FindMaxTest](src/test/java/com/thealgorithms/maths/FindMaxTest.java)
+ - 📄 [FindMinRecursionTest](src/test/java/com/thealgorithms/maths/FindMinRecursionTest.java)
+ - 📄 [FindMinTest](src/test/java/com/thealgorithms/maths/FindMinTest.java)
+ - 📄 [FloorTest](src/test/java/com/thealgorithms/maths/FloorTest.java)
+ - 📄 [FrizzyNumberTest](src/test/java/com/thealgorithms/maths/FrizzyNumberTest.java)
+ - 📄 [GCDRecursionTest](src/test/java/com/thealgorithms/maths/GCDRecursionTest.java)
+ - 📄 [GCDTest](src/test/java/com/thealgorithms/maths/GCDTest.java)
+ - 📄 [GaussianTest](src/test/java/com/thealgorithms/maths/GaussianTest.java)
+ - 📄 [GenericRootTest](src/test/java/com/thealgorithms/maths/GenericRootTest.java)
+ - 📄 [GermainPrimeAndSafePrimeTest](src/test/java/com/thealgorithms/maths/GermainPrimeAndSafePrimeTest.java)
+ - 📄 [GoldbachConjectureTest](src/test/java/com/thealgorithms/maths/GoldbachConjectureTest.java)
+ - 📄 [HappyNumberTest](src/test/java/com/thealgorithms/maths/HappyNumberTest.java)
+ - 📄 [HarshadNumberTest](src/test/java/com/thealgorithms/maths/HarshadNumberTest.java)
+ - 📄 [HeronsFormulaTest](src/test/java/com/thealgorithms/maths/HeronsFormulaTest.java)
+ - 📄 [JosephusProblemTest](src/test/java/com/thealgorithms/maths/JosephusProblemTest.java)
+ - 📄 [JugglerSequenceTest](src/test/java/com/thealgorithms/maths/JugglerSequenceTest.java)
+ - 📄 [KaprekarNumbersTest](src/test/java/com/thealgorithms/maths/KaprekarNumbersTest.java)
+ - 📄 [KaratsubaMultiplicationTest](src/test/java/com/thealgorithms/maths/KaratsubaMultiplicationTest.java)
+ - 📄 [KeithNumberTest](src/test/java/com/thealgorithms/maths/KeithNumberTest.java)
+ - 📄 [KrishnamurthyNumberTest](src/test/java/com/thealgorithms/maths/KrishnamurthyNumberTest.java)
+ - 📄 [LeastCommonMultipleTest](src/test/java/com/thealgorithms/maths/LeastCommonMultipleTest.java)
+ - 📄 [LeonardoNumberTest](src/test/java/com/thealgorithms/maths/LeonardoNumberTest.java)
+ - 📄 [LinearDiophantineEquationsSolverTest](src/test/java/com/thealgorithms/maths/LinearDiophantineEquationsSolverTest.java)
+ - 📄 [LongDivisionTest](src/test/java/com/thealgorithms/maths/LongDivisionTest.java)
+ - 📄 [LucasSeriesTest](src/test/java/com/thealgorithms/maths/LucasSeriesTest.java)
+ - 📄 [LuckyNumberTest](src/test/java/com/thealgorithms/maths/LuckyNumberTest.java)
+ - 📄 [MathBuilderTest](src/test/java/com/thealgorithms/maths/MathBuilderTest.java)
+ - 📄 [MaxValueTest](src/test/java/com/thealgorithms/maths/MaxValueTest.java)
+ - 📄 [MeansTest](src/test/java/com/thealgorithms/maths/MeansTest.java)
+ - 📄 [MedianTest](src/test/java/com/thealgorithms/maths/MedianTest.java)
+ - 📄 [MinValueTest](src/test/java/com/thealgorithms/maths/MinValueTest.java)
+ - 📄 [ModeTest](src/test/java/com/thealgorithms/maths/ModeTest.java)
+ - 📄 [NevilleTest](src/test/java/com/thealgorithms/maths/NevilleTest.java)
+ - 📄 [NonRepeatingElementTest](src/test/java/com/thealgorithms/maths/NonRepeatingElementTest.java)
+ - 📄 [NthUglyNumberTest](src/test/java/com/thealgorithms/maths/NthUglyNumberTest.java)
+ - 📄 [NumberOfDigitsTest](src/test/java/com/thealgorithms/maths/NumberOfDigitsTest.java)
+ - 📄 [NumberPersistenceTest](src/test/java/com/thealgorithms/maths/NumberPersistenceTest.java)
+ - 📄 [PalindromeNumberTest](src/test/java/com/thealgorithms/maths/PalindromeNumberTest.java)
+ - 📄 [ParseIntegerTest](src/test/java/com/thealgorithms/maths/ParseIntegerTest.java)
+ - 📄 [PascalTriangleTest](src/test/java/com/thealgorithms/maths/PascalTriangleTest.java)
+ - 📄 [PerfectCubeTest](src/test/java/com/thealgorithms/maths/PerfectCubeTest.java)
+ - 📄 [PerfectNumberTest](src/test/java/com/thealgorithms/maths/PerfectNumberTest.java)
+ - 📄 [PerfectSquareTest](src/test/java/com/thealgorithms/maths/PerfectSquareTest.java)
+ - 📄 [PerimeterTest](src/test/java/com/thealgorithms/maths/PerimeterTest.java)
+ - 📄 [PiApproximationTest](src/test/java/com/thealgorithms/maths/PiApproximationTest.java)
+ - 📄 [PollardRhoTest](src/test/java/com/thealgorithms/maths/PollardRhoTest.java)
+ - 📄 [PowTest](src/test/java/com/thealgorithms/maths/PowTest.java)
+ - 📄 [PowerOfFourTest](src/test/java/com/thealgorithms/maths/PowerOfFourTest.java)
+ - 📄 [PowerOfTwoOrNotTest](src/test/java/com/thealgorithms/maths/PowerOfTwoOrNotTest.java)
+ - 📄 [PowerUsingRecursionTest](src/test/java/com/thealgorithms/maths/PowerUsingRecursionTest.java)
+ - 📄 [PronicNumberTest](src/test/java/com/thealgorithms/maths/PronicNumberTest.java)
+ - 📄 [PythagoreanTripleTest](src/test/java/com/thealgorithms/maths/PythagoreanTripleTest.java)
+ - 📄 [QuadraticEquationSolverTest](src/test/java/com/thealgorithms/maths/QuadraticEquationSolverTest.java)
+ - 📄 [ReverseNumberTest](src/test/java/com/thealgorithms/maths/ReverseNumberTest.java)
+ - 📄 [SecondMinMaxTest](src/test/java/com/thealgorithms/maths/SecondMinMaxTest.java)
+ - 📄 [SieveOfAtkinTest](src/test/java/com/thealgorithms/maths/SieveOfAtkinTest.java)
+ - 📄 [SieveOfEratosthenesTest](src/test/java/com/thealgorithms/maths/SieveOfEratosthenesTest.java)
+ - 📄 [SmithNumberTest](src/test/java/com/thealgorithms/maths/SmithNumberTest.java)
+ - 📄 [SolovayStrassenPrimalityTestTest](src/test/java/com/thealgorithms/maths/SolovayStrassenPrimalityTestTest.java)
+ - 📄 [SquareFreeIntegerTest](src/test/java/com/thealgorithms/maths/SquareFreeIntegerTest.java)
+ - 📄 [SquareRootWithNewtonRaphsonTestMethod](src/test/java/com/thealgorithms/maths/SquareRootWithNewtonRaphsonTestMethod.java)
+ - 📄 [SquareRootwithBabylonianMethodTest](src/test/java/com/thealgorithms/maths/SquareRootwithBabylonianMethodTest.java)
+ - 📄 [StandardDeviationTest](src/test/java/com/thealgorithms/maths/StandardDeviationTest.java)
+ - 📄 [StandardScoreTest](src/test/java/com/thealgorithms/maths/StandardScoreTest.java)
+ - 📄 [StrobogrammaticNumberTest](src/test/java/com/thealgorithms/maths/StrobogrammaticNumberTest.java)
+ - 📄 [SumOfArithmeticSeriesTest](src/test/java/com/thealgorithms/maths/SumOfArithmeticSeriesTest.java)
+ - 📄 [SumOfDigitsTest](src/test/java/com/thealgorithms/maths/SumOfDigitsTest.java)
+ - 📄 [SumOfOddNumbersTest](src/test/java/com/thealgorithms/maths/SumOfOddNumbersTest.java)
+ - 📄 [SumOfSquaresTest](src/test/java/com/thealgorithms/maths/SumOfSquaresTest.java)
+ - 📄 [SumWithoutArithmeticOperatorsTest](src/test/java/com/thealgorithms/maths/SumWithoutArithmeticOperatorsTest.java)
+ - 📄 [TestArmstrong](src/test/java/com/thealgorithms/maths/TestArmstrong.java)
+ - 📄 [TwinPrimeTest](src/test/java/com/thealgorithms/maths/TwinPrimeTest.java)
+ - 📄 [UniformNumbersTest](src/test/java/com/thealgorithms/maths/UniformNumbersTest.java)
+ - 📄 [VampireNumberTest](src/test/java/com/thealgorithms/maths/VampireNumberTest.java)
+ - 📄 [VolumeTest](src/test/java/com/thealgorithms/maths/VolumeTest.java)
+ - 📄 [ZellersCongruenceTest](src/test/java/com/thealgorithms/maths/ZellersCongruenceTest.java)
+ - 📁 **prime**
+ - 📄 [LiouvilleLambdaFunctionTest](src/test/java/com/thealgorithms/maths/prime/LiouvilleLambdaFunctionTest.java)
+ - 📄 [MillerRabinPrimalityCheckTest](src/test/java/com/thealgorithms/maths/prime/MillerRabinPrimalityCheckTest.java)
+ - 📄 [MobiusFunctionTest](src/test/java/com/thealgorithms/maths/prime/MobiusFunctionTest.java)
+ - 📄 [PrimeCheckTest](src/test/java/com/thealgorithms/maths/prime/PrimeCheckTest.java)
+ - 📄 [PrimeFactorizationTest](src/test/java/com/thealgorithms/maths/prime/PrimeFactorizationTest.java)
+ - 📁 **matrix**
+ - 📄 [InverseOfMatrixTest](src/test/java/com/thealgorithms/matrix/InverseOfMatrixTest.java)
+ - 📄 [LUDecompositionTest](src/test/java/com/thealgorithms/matrix/LUDecompositionTest.java)
+ - 📄 [MatrixMultiplicationTest](src/test/java/com/thealgorithms/matrix/MatrixMultiplicationTest.java)
+ - 📄 [MatrixRankTest](src/test/java/com/thealgorithms/matrix/MatrixRankTest.java)
+ - 📄 [MatrixTransposeTest](src/test/java/com/thealgorithms/matrix/MatrixTransposeTest.java)
+ - 📄 [MatrixUtilTest](src/test/java/com/thealgorithms/matrix/MatrixUtilTest.java)
+ - 📄 [MedianOfMatrixTest](src/test/java/com/thealgorithms/matrix/MedianOfMatrixTest.java)
+ - 📄 [MirrorOfMatrixTest](src/test/java/com/thealgorithms/matrix/MirrorOfMatrixTest.java)
+ - 📄 [PrintAMatrixInSpiralOrderTest](src/test/java/com/thealgorithms/matrix/PrintAMatrixInSpiralOrderTest.java)
+ - 📄 [SolveSystemTest](src/test/java/com/thealgorithms/matrix/SolveSystemTest.java)
+ - 📄 [StochasticMatrixTest](src/test/java/com/thealgorithms/matrix/StochasticMatrixTest.java)
+ - 📁 **misc**
+ - 📄 [ColorContrastRatioTest](src/test/java/com/thealgorithms/misc/ColorContrastRatioTest.java)
+ - 📄 [MapReduceTest](src/test/java/com/thealgorithms/misc/MapReduceTest.java)
+ - 📄 [MedianOfRunningArrayTest](src/test/java/com/thealgorithms/misc/MedianOfRunningArrayTest.java)
+ - 📄 [PalindromePrimeTest](src/test/java/com/thealgorithms/misc/PalindromePrimeTest.java)
+ - 📄 [PalindromeSinglyLinkedListTest](src/test/java/com/thealgorithms/misc/PalindromeSinglyLinkedListTest.java)
+ - 📄 [RangeInSortedArrayTest](src/test/java/com/thealgorithms/misc/RangeInSortedArrayTest.java)
+ - 📄 [ShuffleArrayTest](src/test/java/com/thealgorithms/misc/ShuffleArrayTest.java)
+ - 📄 [SparsityTest](src/test/java/com/thealgorithms/misc/SparsityTest.java)
+ - 📄 [ThreeSumProblemTest](src/test/java/com/thealgorithms/misc/ThreeSumProblemTest.java)
+ - 📄 [TwoSumProblemTest](src/test/java/com/thealgorithms/misc/TwoSumProblemTest.java)
+ - 📁 **others**
+ - 📄 [ArrayLeftRotationTest](src/test/java/com/thealgorithms/others/ArrayLeftRotationTest.java)
+ - 📄 [ArrayRightRotationTest](src/test/java/com/thealgorithms/others/ArrayRightRotationTest.java)
+ - 📄 [BFPRTTest](src/test/java/com/thealgorithms/others/BFPRTTest.java)
+ - 📄 [BestFitCPUTest](src/test/java/com/thealgorithms/others/BestFitCPUTest.java)
+ - 📄 [BoyerMooreTest](src/test/java/com/thealgorithms/others/BoyerMooreTest.java)
+ - 📄 [CRC16Test](src/test/java/com/thealgorithms/others/CRC16Test.java)
+ - 📄 [CRCAlgorithmTest](src/test/java/com/thealgorithms/others/CRCAlgorithmTest.java)
+ - 📄 [ConwayTest](src/test/java/com/thealgorithms/others/ConwayTest.java)
+ - 📄 [CountFriendsPairingTest](src/test/java/com/thealgorithms/others/CountFriendsPairingTest.java)
+ - 📄 [FirstFitCPUTest](src/test/java/com/thealgorithms/others/FirstFitCPUTest.java)
+ - 📄 [FloydTriangleTest](src/test/java/com/thealgorithms/others/FloydTriangleTest.java)
+ - 📄 [HuffmanTest](src/test/java/com/thealgorithms/others/HuffmanTest.java)
+ - 📄 [InsertDeleteInArrayTest](src/test/java/com/thealgorithms/others/InsertDeleteInArrayTest.java)
+ - 📄 [IterativeFloodFillTest](src/test/java/com/thealgorithms/others/IterativeFloodFillTest.java)
+ - 📄 [KadaneAlogrithmTest](src/test/java/com/thealgorithms/others/KadaneAlogrithmTest.java)
+ - 📄 [LineSweepTest](src/test/java/com/thealgorithms/others/LineSweepTest.java)
+ - 📄 [LinkListSortTest](src/test/java/com/thealgorithms/others/LinkListSortTest.java)
+ - 📄 [LowestBasePalindromeTest](src/test/java/com/thealgorithms/others/LowestBasePalindromeTest.java)
+ - 📄 [MaximumSumOfDistinctSubarraysWithLengthKTest](src/test/java/com/thealgorithms/others/MaximumSumOfDistinctSubarraysWithLengthKTest.java)
+ - 📄 [MiniMaxAlgorithmTest](src/test/java/com/thealgorithms/others/MiniMaxAlgorithmTest.java)
+ - 📄 [MosAlgorithmTest](src/test/java/com/thealgorithms/others/MosAlgorithmTest.java)
+ - 📄 [NextFitTest](src/test/java/com/thealgorithms/others/NextFitTest.java)
+ - 📄 [PageRankTest](src/test/java/com/thealgorithms/others/PageRankTest.java)
+ - 📄 [PasswordGenTest](src/test/java/com/thealgorithms/others/PasswordGenTest.java)
+ - 📄 [PerlinNoiseTest](src/test/java/com/thealgorithms/others/PerlinNoiseTest.java)
+ - 📄 [QueueUsingTwoStacksTest](src/test/java/com/thealgorithms/others/QueueUsingTwoStacksTest.java)
+ - 📄 [SkylineProblemTest](src/test/java/com/thealgorithms/others/SkylineProblemTest.java)
+ - 📄 [TwoPointersTest](src/test/java/com/thealgorithms/others/TwoPointersTest.java)
+ - 📄 [WorstFitCPUTest](src/test/java/com/thealgorithms/others/WorstFitCPUTest.java)
+ - 📁 **physics**
+ - 📄 [CoulombsLawTest](src/test/java/com/thealgorithms/physics/CoulombsLawTest.java)
+ - 📄 [DampedOscillatorTest](src/test/java/com/thealgorithms/physics/DampedOscillatorTest.java)
+ - 📄 [ElasticCollision2DTest](src/test/java/com/thealgorithms/physics/ElasticCollision2DTest.java)
+ - 📄 [GravitationTest](src/test/java/com/thealgorithms/physics/GravitationTest.java)
+ - 📄 [GroundToGroundProjectileMotionTest](src/test/java/com/thealgorithms/physics/GroundToGroundProjectileMotionTest.java)
+ - 📄 [KinematicsTest](src/test/java/com/thealgorithms/physics/KinematicsTest.java)
+ - 📄 [ProjectileMotionTest](src/test/java/com/thealgorithms/physics/ProjectileMotionTest.java)
+ - 📄 [SimplePendulumRK4Test](src/test/java/com/thealgorithms/physics/SimplePendulumRK4Test.java)
+ - 📄 [SnellLawTest](src/test/java/com/thealgorithms/physics/SnellLawTest.java)
+ - 📄 [ThinLensTest](src/test/java/com/thealgorithms/physics/ThinLensTest.java)
+ - 📁 **puzzlesandgames**
+ - 📄 [TowerOfHanoiTest](src/test/java/com/thealgorithms/puzzlesandgames/TowerOfHanoiTest.java)
+ - 📄 [WordBoggleTest](src/test/java/com/thealgorithms/puzzlesandgames/WordBoggleTest.java)
+ - 📁 **randomized**
+ - 📄 [KargerMinCutTest](src/test/java/com/thealgorithms/randomized/KargerMinCutTest.java)
+ - 📄 [MonteCarloIntegrationTest](src/test/java/com/thealgorithms/randomized/MonteCarloIntegrationTest.java)
+ - 📄 [RandomizedClosestPairTest](src/test/java/com/thealgorithms/randomized/RandomizedClosestPairTest.java)
+ - 📄 [RandomizedMatrixMultiplicationVerificationTest](src/test/java/com/thealgorithms/randomized/RandomizedMatrixMultiplicationVerificationTest.java)
+ - 📄 [RandomizedQuickSortTest](src/test/java/com/thealgorithms/randomized/RandomizedQuickSortTest.java)
+ - 📄 [ReservoirSamplingTest](src/test/java/com/thealgorithms/randomized/ReservoirSamplingTest.java)
+ - 📁 **recursion**
+ - 📄 [DiceThrowerTest](src/test/java/com/thealgorithms/recursion/DiceThrowerTest.java)
+ - 📄 [FactorialRecursionTest](src/test/java/com/thealgorithms/recursion/FactorialRecursionTest.java)
+ - 📄 [FibonacciSeriesTest](src/test/java/com/thealgorithms/recursion/FibonacciSeriesTest.java)
+ - 📄 [GenerateSubsetsTest](src/test/java/com/thealgorithms/recursion/GenerateSubsetsTest.java)
+ - 📄 [SylvesterSequenceTest](src/test/java/com/thealgorithms/recursion/SylvesterSequenceTest.java)
+ - 📁 **scheduling**
+ - 📄 [AgingSchedulingTest](src/test/java/com/thealgorithms/scheduling/AgingSchedulingTest.java)
+ - 📄 [EDFSchedulingTest](src/test/java/com/thealgorithms/scheduling/EDFSchedulingTest.java)
+ - 📄 [FCFSSchedulingTest](src/test/java/com/thealgorithms/scheduling/FCFSSchedulingTest.java)
+ - 📄 [FairShareSchedulingTest](src/test/java/com/thealgorithms/scheduling/FairShareSchedulingTest.java)
+ - 📄 [GangSchedulingTest](src/test/java/com/thealgorithms/scheduling/GangSchedulingTest.java)
+ - 📄 [HighestResponseRatioNextSchedulingTest](src/test/java/com/thealgorithms/scheduling/HighestResponseRatioNextSchedulingTest.java)
+ - 📄 [JobSchedulingWithDeadlineTest](src/test/java/com/thealgorithms/scheduling/JobSchedulingWithDeadlineTest.java)
+ - 📄 [LotterySchedulingTest](src/test/java/com/thealgorithms/scheduling/LotterySchedulingTest.java)
+ - 📄 [MLFQSchedulerTest](src/test/java/com/thealgorithms/scheduling/MLFQSchedulerTest.java)
+ - 📄 [MultiAgentSchedulingTest](src/test/java/com/thealgorithms/scheduling/MultiAgentSchedulingTest.java)
+ - 📄 [NonPreemptivePrioritySchedulingTest](src/test/java/com/thealgorithms/scheduling/NonPreemptivePrioritySchedulingTest.java)
+ - 📄 [PreemptivePrioritySchedulingTest](src/test/java/com/thealgorithms/scheduling/PreemptivePrioritySchedulingTest.java)
+ - 📄 [ProportionalFairSchedulingTest](src/test/java/com/thealgorithms/scheduling/ProportionalFairSchedulingTest.java)
+ - 📄 [RRSchedulingTest](src/test/java/com/thealgorithms/scheduling/RRSchedulingTest.java)
+ - 📄 [RandomSchedulingTest](src/test/java/com/thealgorithms/scheduling/RandomSchedulingTest.java)
+ - 📄 [SJFSchedulingTest](src/test/java/com/thealgorithms/scheduling/SJFSchedulingTest.java)
+ - 📄 [SRTFSchedulingTest](src/test/java/com/thealgorithms/scheduling/SRTFSchedulingTest.java)
+ - 📄 [SelfAdjustingSchedulingTest](src/test/java/com/thealgorithms/scheduling/SelfAdjustingSchedulingTest.java)
+ - 📄 [SlackTimeSchedulingTest](src/test/java/com/thealgorithms/scheduling/SlackTimeSchedulingTest.java)
+ - 📁 **diskscheduling**
+ - 📄 [CircularLookSchedulingTest](src/test/java/com/thealgorithms/scheduling/diskscheduling/CircularLookSchedulingTest.java)
+ - 📄 [CircularScanSchedulingTest](src/test/java/com/thealgorithms/scheduling/diskscheduling/CircularScanSchedulingTest.java)
+ - 📄 [LookSchedulingTest](src/test/java/com/thealgorithms/scheduling/diskscheduling/LookSchedulingTest.java)
+ - 📄 [SSFSchedulingTest](src/test/java/com/thealgorithms/scheduling/diskscheduling/SSFSchedulingTest.java)
+ - 📄 [ScanSchedulingTest](src/test/java/com/thealgorithms/scheduling/diskscheduling/ScanSchedulingTest.java)
+ - 📁 **searches**
+ - 📄 [BM25InvertedIndexTest](src/test/java/com/thealgorithms/searches/BM25InvertedIndexTest.java)
+ - 📄 [BinarySearch2dArrayTest](src/test/java/com/thealgorithms/searches/BinarySearch2dArrayTest.java)
+ - 📄 [BinarySearchTest](src/test/java/com/thealgorithms/searches/BinarySearchTest.java)
+ - 📄 [BoyerMooreTest](src/test/java/com/thealgorithms/searches/BoyerMooreTest.java)
+ - 📄 [BreadthFirstSearchTest](src/test/java/com/thealgorithms/searches/BreadthFirstSearchTest.java)
+ - 📄 [DepthFirstSearchTest](src/test/java/com/thealgorithms/searches/DepthFirstSearchTest.java)
+ - 📄 [ExponentialSearchTest](src/test/java/com/thealgorithms/searches/ExponentialSearchTest.java)
+ - 📄 [FibonacciSearchTest](src/test/java/com/thealgorithms/searches/FibonacciSearchTest.java)
+ - 📄 [HowManyTimesRotatedTest](src/test/java/com/thealgorithms/searches/HowManyTimesRotatedTest.java)
+ - 📄 [InterpolationSearchTest](src/test/java/com/thealgorithms/searches/InterpolationSearchTest.java)
+ - 📄 [IterativeBinarySearchTest](src/test/java/com/thealgorithms/searches/IterativeBinarySearchTest.java)
+ - 📄 [IterativeTernarySearchTest](src/test/java/com/thealgorithms/searches/IterativeTernarySearchTest.java)
+ - 📄 [JumpSearchTest](src/test/java/com/thealgorithms/searches/JumpSearchTest.java)
+ - 📄 [KMPSearchTest](src/test/java/com/thealgorithms/searches/KMPSearchTest.java)
+ - 📄 [LinearSearchTest](src/test/java/com/thealgorithms/searches/LinearSearchTest.java)
+ - 📄 [LinearSearchThreadTest](src/test/java/com/thealgorithms/searches/LinearSearchThreadTest.java)
+ - 📄 [LowerBoundTest](src/test/java/com/thealgorithms/searches/LowerBoundTest.java)
+ - 📄 [MonteCarloTreeSearchTest](src/test/java/com/thealgorithms/searches/MonteCarloTreeSearchTest.java)
+ - 📄 [OrderAgnosticBinarySearchTest](src/test/java/com/thealgorithms/searches/OrderAgnosticBinarySearchTest.java)
+ - 📄 [QuickSelectTest](src/test/java/com/thealgorithms/searches/QuickSelectTest.java)
+ - 📄 [RabinKarpAlgorithmTest](src/test/java/com/thealgorithms/searches/RabinKarpAlgorithmTest.java)
+ - 📄 [RandomSearchTest](src/test/java/com/thealgorithms/searches/RandomSearchTest.java)
+ - 📄 [RecursiveBinarySearchTest](src/test/java/com/thealgorithms/searches/RecursiveBinarySearchTest.java)
+ - 📄 [RowColumnWiseSorted2dArrayBinarySearchTest](src/test/java/com/thealgorithms/searches/RowColumnWiseSorted2dArrayBinarySearchTest.java)
+ - 📄 [SaddlebackSearchTest](src/test/java/com/thealgorithms/searches/SaddlebackSearchTest.java)
+ - 📄 [SearchInARowAndColWiseSortedMatrixTest](src/test/java/com/thealgorithms/searches/SearchInARowAndColWiseSortedMatrixTest.java)
+ - 📄 [SentinelLinearSearchTest](src/test/java/com/thealgorithms/searches/SentinelLinearSearchTest.java)
+ - 📄 [SquareRootBinarySearchTest](src/test/java/com/thealgorithms/searches/SquareRootBinarySearchTest.java)
+ - 📄 [TernarySearchTest](src/test/java/com/thealgorithms/searches/TernarySearchTest.java)
+ - 📄 [TestSearchInARowAndColWiseSortedMatrix](src/test/java/com/thealgorithms/searches/TestSearchInARowAndColWiseSortedMatrix.java)
+ - 📄 [UnionFindTest](src/test/java/com/thealgorithms/searches/UnionFindTest.java)
+ - 📄 [UpperBoundTest](src/test/java/com/thealgorithms/searches/UpperBoundTest.java)
+ - 📁 **slidingwindow**
+ - 📄 [LongestSubarrayWithSumLessOrEqualToKTest](src/test/java/com/thealgorithms/slidingwindow/LongestSubarrayWithSumLessOrEqualToKTest.java)
+ - 📄 [LongestSubstringWithoutRepeatingCharactersTest](src/test/java/com/thealgorithms/slidingwindow/LongestSubstringWithoutRepeatingCharactersTest.java)
+ - 📄 [MaxSumKSizeSubarrayTest](src/test/java/com/thealgorithms/slidingwindow/MaxSumKSizeSubarrayTest.java)
+ - 📄 [MaximumSlidingWindowTest](src/test/java/com/thealgorithms/slidingwindow/MaximumSlidingWindowTest.java)
+ - 📄 [MinSumKSizeSubarrayTest](src/test/java/com/thealgorithms/slidingwindow/MinSumKSizeSubarrayTest.java)
+ - 📄 [MinimumWindowSubstringTest](src/test/java/com/thealgorithms/slidingwindow/MinimumWindowSubstringTest.java)
+ - 📄 [ShortestCoprimeSegmentTest](src/test/java/com/thealgorithms/slidingwindow/ShortestCoprimeSegmentTest.java)
+ - 📁 **sorts**
+ - 📄 [AdaptiveMergeSortTest](src/test/java/com/thealgorithms/sorts/AdaptiveMergeSortTest.java)
+ - 📄 [BeadSortTest](src/test/java/com/thealgorithms/sorts/BeadSortTest.java)
+ - 📄 [BinaryInsertionSortTest](src/test/java/com/thealgorithms/sorts/BinaryInsertionSortTest.java)
+ - 📄 [BitonicSortTest](src/test/java/com/thealgorithms/sorts/BitonicSortTest.java)
+ - 📄 [BogoSortTest](src/test/java/com/thealgorithms/sorts/BogoSortTest.java)
+ - 📄 [BubbleSortRecursiveTest](src/test/java/com/thealgorithms/sorts/BubbleSortRecursiveTest.java)
+ - 📄 [BubbleSortTest](src/test/java/com/thealgorithms/sorts/BubbleSortTest.java)
+ - 📄 [BucketSortTest](src/test/java/com/thealgorithms/sorts/BucketSortTest.java)
+ - 📄 [CircleSortTest](src/test/java/com/thealgorithms/sorts/CircleSortTest.java)
+ - 📄 [CocktailShakerSortTest](src/test/java/com/thealgorithms/sorts/CocktailShakerSortTest.java)
+ - 📄 [CombSortTest](src/test/java/com/thealgorithms/sorts/CombSortTest.java)
+ - 📄 [CountingSortTest](src/test/java/com/thealgorithms/sorts/CountingSortTest.java)
+ - 📄 [CycleSortTest](src/test/java/com/thealgorithms/sorts/CycleSortTest.java)
+ - 📄 [DarkSortTest](src/test/java/com/thealgorithms/sorts/DarkSortTest.java)
+ - 📄 [DualPivotQuickSortTest](src/test/java/com/thealgorithms/sorts/DualPivotQuickSortTest.java)
+ - 📄 [DutchNationalFlagSortTest](src/test/java/com/thealgorithms/sorts/DutchNationalFlagSortTest.java)
+ - 📄 [ExchangeSortTest](src/test/java/com/thealgorithms/sorts/ExchangeSortTest.java)
+ - 📄 [FlashSortTest](src/test/java/com/thealgorithms/sorts/FlashSortTest.java)
+ - 📄 [GnomeSortTest](src/test/java/com/thealgorithms/sorts/GnomeSortTest.java)
+ - 📄 [HeapSortTest](src/test/java/com/thealgorithms/sorts/HeapSortTest.java)
+ - 📄 [InsertionSortTest](src/test/java/com/thealgorithms/sorts/InsertionSortTest.java)
+ - 📄 [IntrospectiveSortTest](src/test/java/com/thealgorithms/sorts/IntrospectiveSortTest.java)
+ - 📄 [MergeSortNoExtraSpaceTest](src/test/java/com/thealgorithms/sorts/MergeSortNoExtraSpaceTest.java)
+ - 📄 [MergeSortRecursiveTest](src/test/java/com/thealgorithms/sorts/MergeSortRecursiveTest.java)
+ - 📄 [MergeSortTest](src/test/java/com/thealgorithms/sorts/MergeSortTest.java)
+ - 📄 [OddEvenSortTest](src/test/java/com/thealgorithms/sorts/OddEvenSortTest.java)
+ - 📄 [PancakeSortTest](src/test/java/com/thealgorithms/sorts/PancakeSortTest.java)
+ - 📄 [PatienceSortTest](src/test/java/com/thealgorithms/sorts/PatienceSortTest.java)
+ - 📄 [PigeonholeSortTest](src/test/java/com/thealgorithms/sorts/PigeonholeSortTest.java)
+ - 📄 [PriorityQueueSortTest](src/test/java/com/thealgorithms/sorts/PriorityQueueSortTest.java)
+ - 📄 [QuickSortTest](src/test/java/com/thealgorithms/sorts/QuickSortTest.java)
+ - 📄 [RadixSortTest](src/test/java/com/thealgorithms/sorts/RadixSortTest.java)
+ - 📄 [SelectionSortRecursiveTest](src/test/java/com/thealgorithms/sorts/SelectionSortRecursiveTest.java)
+ - 📄 [SelectionSortTest](src/test/java/com/thealgorithms/sorts/SelectionSortTest.java)
+ - 📄 [ShellSortTest](src/test/java/com/thealgorithms/sorts/ShellSortTest.java)
+ - 📄 [SlowSortTest](src/test/java/com/thealgorithms/sorts/SlowSortTest.java)
+ - 📄 [SortUtilsRandomGeneratorTest](src/test/java/com/thealgorithms/sorts/SortUtilsRandomGeneratorTest.java)
+ - 📄 [SortUtilsTest](src/test/java/com/thealgorithms/sorts/SortUtilsTest.java)
+ - 📄 [SortingAlgorithmTest](src/test/java/com/thealgorithms/sorts/SortingAlgorithmTest.java)
+ - 📄 [SpreadSortTest](src/test/java/com/thealgorithms/sorts/SpreadSortTest.java)
+ - 📄 [StalinSortTest](src/test/java/com/thealgorithms/sorts/StalinSortTest.java)
+ - 📄 [StoogeSortTest](src/test/java/com/thealgorithms/sorts/StoogeSortTest.java)
+ - 📄 [StrandSortTest](src/test/java/com/thealgorithms/sorts/StrandSortTest.java)
+ - 📄 [SwapSortTest](src/test/java/com/thealgorithms/sorts/SwapSortTest.java)
+ - 📄 [TimSortTest](src/test/java/com/thealgorithms/sorts/TimSortTest.java)
+ - 📄 [TopologicalSortTest](src/test/java/com/thealgorithms/sorts/TopologicalSortTest.java)
+ - 📄 [TreeSortTest](src/test/java/com/thealgorithms/sorts/TreeSortTest.java)
+ - 📄 [WaveSortTest](src/test/java/com/thealgorithms/sorts/WaveSortTest.java)
+ - 📄 [WiggleSortTest](src/test/java/com/thealgorithms/sorts/WiggleSortTest.java)
+ - 📁 **stacks**
+ - 📄 [BalancedBracketsTest](src/test/java/com/thealgorithms/stacks/BalancedBracketsTest.java)
+ - 📄 [CelebrityFinderTest](src/test/java/com/thealgorithms/stacks/CelebrityFinderTest.java)
+ - 📄 [DecimalToAnyUsingStackTest](src/test/java/com/thealgorithms/stacks/DecimalToAnyUsingStackTest.java)
+ - 📄 [DuplicateBracketsTest](src/test/java/com/thealgorithms/stacks/DuplicateBracketsTest.java)
+ - 📄 [GreatestElementConstantTimeTest](src/test/java/com/thealgorithms/stacks/GreatestElementConstantTimeTest.java)
+ - 📄 [InfixToPostfixTest](src/test/java/com/thealgorithms/stacks/InfixToPostfixTest.java)
+ - 📄 [InfixToPrefixTest](src/test/java/com/thealgorithms/stacks/InfixToPrefixTest.java)
+ - 📄 [LargestRectangleTest](src/test/java/com/thealgorithms/stacks/LargestRectangleTest.java)
+ - 📄 [MinStackUsingSingleStackTest](src/test/java/com/thealgorithms/stacks/MinStackUsingSingleStackTest.java)
+ - 📄 [MinStackUsingTwoStacksTest](src/test/java/com/thealgorithms/stacks/MinStackUsingTwoStacksTest.java)
+ - 📄 [NextGreaterElementTest](src/test/java/com/thealgorithms/stacks/NextGreaterElementTest.java)
+ - 📄 [NextSmallerElementTest](src/test/java/com/thealgorithms/stacks/NextSmallerElementTest.java)
+ - 📄 [PalindromeWithStackTest](src/test/java/com/thealgorithms/stacks/PalindromeWithStackTest.java)
+ - 📄 [PostfixEvaluatorTest](src/test/java/com/thealgorithms/stacks/PostfixEvaluatorTest.java)
+ - 📄 [PostfixToInfixTest](src/test/java/com/thealgorithms/stacks/PostfixToInfixTest.java)
+ - 📄 [PrefixEvaluatorTest](src/test/java/com/thealgorithms/stacks/PrefixEvaluatorTest.java)
+ - 📄 [PrefixToInfixTest](src/test/java/com/thealgorithms/stacks/PrefixToInfixTest.java)
+ - 📄 [SmallestElementConstantTimeTest](src/test/java/com/thealgorithms/stacks/SmallestElementConstantTimeTest.java)
+ - 📄 [SortStackTest](src/test/java/com/thealgorithms/stacks/SortStackTest.java)
+ - 📄 [StackPostfixNotationTest](src/test/java/com/thealgorithms/stacks/StackPostfixNotationTest.java)
+ - 📄 [StackUsingTwoQueuesTest](src/test/java/com/thealgorithms/stacks/StackUsingTwoQueuesTest.java)
+ - 📄 [TrappingRainwaterTest](src/test/java/com/thealgorithms/stacks/TrappingRainwaterTest.java)
+ - 📄 [ValidParenthesesTest](src/test/java/com/thealgorithms/stacks/ValidParenthesesTest.java)
+ - 📁 **strings**
+ - 📄 [AhoCorasickTest](src/test/java/com/thealgorithms/strings/AhoCorasickTest.java)
+ - 📄 [AlphabeticalTest](src/test/java/com/thealgorithms/strings/AlphabeticalTest.java)
+ - 📄 [AlternativeStringArrangeTest](src/test/java/com/thealgorithms/strings/AlternativeStringArrangeTest.java)
+ - 📄 [AnagramsTest](src/test/java/com/thealgorithms/strings/AnagramsTest.java)
+ - 📄 [CharactersSameTest](src/test/java/com/thealgorithms/strings/CharactersSameTest.java)
+ - 📄 [CheckVowelsTest](src/test/java/com/thealgorithms/strings/CheckVowelsTest.java)
+ - 📄 [CountCharTest](src/test/java/com/thealgorithms/strings/CountCharTest.java)
+ - 📄 [CountWordsTest](src/test/java/com/thealgorithms/strings/CountWordsTest.java)
+ - 📄 [HammingDistanceTest](src/test/java/com/thealgorithms/strings/HammingDistanceTest.java)
+ - 📄 [HorspoolSearchTest](src/test/java/com/thealgorithms/strings/HorspoolSearchTest.java)
+ - 📄 [IsogramTest](src/test/java/com/thealgorithms/strings/IsogramTest.java)
+ - 📄 [IsomorphicTest](src/test/java/com/thealgorithms/strings/IsomorphicTest.java)
+ - 📄 [LengthOfLastWordTest](src/test/java/com/thealgorithms/strings/LengthOfLastWordTest.java)
+ - 📄 [LetterCombinationsOfPhoneNumberTest](src/test/java/com/thealgorithms/strings/LetterCombinationsOfPhoneNumberTest.java)
+ - 📄 [LongestCommonPrefixTest](src/test/java/com/thealgorithms/strings/LongestCommonPrefixTest.java)
+ - 📄 [LongestNonRepetitiveSubstringTest](src/test/java/com/thealgorithms/strings/LongestNonRepetitiveSubstringTest.java)
+ - 📄 [LowerTest](src/test/java/com/thealgorithms/strings/LowerTest.java)
+ - 📄 [ManacherTest](src/test/java/com/thealgorithms/strings/ManacherTest.java)
+ - 📄 [MyAtoiTest](src/test/java/com/thealgorithms/strings/MyAtoiTest.java)
+ - 📄 [PalindromeTest](src/test/java/com/thealgorithms/strings/PalindromeTest.java)
+ - 📄 [PangramTest](src/test/java/com/thealgorithms/strings/PangramTest.java)
+ - 📄 [PermuteStringTest](src/test/java/com/thealgorithms/strings/PermuteStringTest.java)
+ - 📄 [RemoveDuplicateFromStringTest](src/test/java/com/thealgorithms/strings/RemoveDuplicateFromStringTest.java)
+ - 📄 [ReturnSubsequenceTest](src/test/java/com/thealgorithms/strings/ReturnSubsequenceTest.java)
+ - 📄 [ReverseStringTest](src/test/java/com/thealgorithms/strings/ReverseStringTest.java)
+ - 📄 [ReverseWordsInStringTest](src/test/java/com/thealgorithms/strings/ReverseWordsInStringTest.java)
+ - 📄 [RotationTest](src/test/java/com/thealgorithms/strings/RotationTest.java)
+ - 📄 [StringCompressionTest](src/test/java/com/thealgorithms/strings/StringCompressionTest.java)
+ - 📄 [StringMatchFiniteAutomataTest](src/test/java/com/thealgorithms/strings/StringMatchFiniteAutomataTest.java)
+ - 📄 [SuffixArrayTest](src/test/java/com/thealgorithms/strings/SuffixArrayTest.java)
+ - 📄 [UpperTest](src/test/java/com/thealgorithms/strings/UpperTest.java)
+ - 📄 [WordLadderTest](src/test/java/com/thealgorithms/strings/WordLadderTest.java)
+ - 📄 [ZAlgorithmTest](src/test/java/com/thealgorithms/strings/ZAlgorithmTest.java)
+ - 📁 **zigZagPattern**
+ - 📄 [ZigZagPatternTest](src/test/java/com/thealgorithms/strings/zigZagPattern/ZigZagPatternTest.java)
+ - 📁 **tree**
+ - 📄 [HeavyLightDecompositionTest](src/test/java/com/thealgorithms/tree/HeavyLightDecompositionTest.java)
diff --git a/LICENSE b/LICENSE
index f6bcf04e7773..e555b5b4dcbc 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,21 +1,21 @@
-MIT License
-
-Copyright (c) 2021 The Algorithms
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+MIT License
+
+Copyright (c) 2021 The Algorithms
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
index d60d5104c385..794656dc7149 100644
--- a/README.md
+++ b/README.md
@@ -1,20 +1,20 @@
-# The Algorithms - Java
-
-[](https://github.com/TheAlgorithms/Java/actions/workflows/build.yml)
-[](https://codecov.io/gh/TheAlgorithms/Java)
-[](https://discord.gg/c7MnfGFGa6)
-[](https://gitpod.io/#https://github.com/TheAlgorithms/Java)
-
-
-You can run and edit the algorithms, or contribute to them using Gitpod.io (a free online development environment) with a single click.
-
-[](https://gitpod.io/#https://github.com/TheAlgorithms/Java)
-
-### All algorithms are implemented in Java (for educational purposes)
-These implementations are intended for learning purposes. As such, they may be less efficient than the Java standard library.
-
-## Contribution Guidelines
-Please read our [Contribution Guidelines](CONTRIBUTING.md) before you contribute to this project.
-
-## Algorithms
-Our [directory](DIRECTORY.md) has the full list of applications.
+# The Algorithms - Java
+
+[](https://github.com/TheAlgorithms/Java/actions/workflows/build.yml)
+[](https://codecov.io/gh/TheAlgorithms/Java)
+[](https://discord.gg/c7MnfGFGa6)
+[](https://gitpod.io/#https://github.com/TheAlgorithms/Java)
+
+
+You can run and edit the algorithms, or contribute to them using Gitpod.io (a free online development environment) with a single click.
+
+[](https://gitpod.io/#https://github.com/TheAlgorithms/Java)
+
+### All algorithms are implemented in Java (for educational purposes)
+These implementations are intended for learning purposes. As such, they may be less efficient than the Java standard library.
+
+## Contribution Guidelines
+Please read our [Contribution Guidelines](CONTRIBUTING.md) before you contribute to this project.
+
+## Algorithms
+Our [directory](DIRECTORY.md) has the full list of applications.
diff --git a/checkstyle.xml b/checkstyle.xml
index d78724455af7..7e3332f4ccba 100644
--- a/checkstyle.xml
+++ b/checkstyle.xml
@@ -1,198 +1,198 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pmd-custom_ruleset.xml b/pmd-custom_ruleset.xml
index 19bb1c7968f0..03056c807992 100644
--- a/pmd-custom_ruleset.xml
+++ b/pmd-custom_ruleset.xml
@@ -1,28 +1,28 @@
-
-
-
- Custom PMD checks for TheAlgorithms/Java
-
-
-
- Avoid using the main method.
-
- 3
-
-
-
-
-
-
-
-
-
+
+
+
+ Custom PMD checks for TheAlgorithms/Java
+
+
+
+ Avoid using the main method.
+
+ 3
+
+
+
+
+
+
+
+
+
diff --git a/pmd-exclude.properties b/pmd-exclude.properties
index 64562c524728..4dace96b300c 100644
--- a/pmd-exclude.properties
+++ b/pmd-exclude.properties
@@ -1,111 +1,111 @@
-com.thealgorithms.ciphers.AES=UselessMainMethod
-com.thealgorithms.ciphers.AESEncryption=UselessMainMethod
-com.thealgorithms.ciphers.AffineCipher=UselessParentheses
-com.thealgorithms.ciphers.DES=UselessParentheses
-com.thealgorithms.ciphers.ProductCipher=UselessMainMethod
-com.thealgorithms.ciphers.RSA=UselessParentheses
-com.thealgorithms.conversions.AnyBaseToAnyBase=UselessMainMethod,UselessParentheses
-com.thealgorithms.conversions.AnytoAny=UselessParentheses
-com.thealgorithms.conversions.RgbHsvConversion=UselessMainMethod
-com.thealgorithms.datastructures.crdt.Pair=UnusedPrivateField
-com.thealgorithms.datastructures.graphs.AStar=UselessParentheses
-com.thealgorithms.datastructures.graphs.AdjacencyMatrixGraph=CollapsibleIfStatements,UnnecessaryFullyQualifiedName,UselessParentheses
-com.thealgorithms.datastructures.graphs.BellmanFord=UselessMainMethod
-com.thealgorithms.datastructures.graphs.BipartiteGraphDFS=CollapsibleIfStatements
-com.thealgorithms.datastructures.graphs.ConnectedComponent=UselessMainMethod
-com.thealgorithms.datastructures.graphs.Cycles=UselessMainMethod
-com.thealgorithms.datastructures.graphs.Graphs=UselessMainMethod
-com.thealgorithms.datastructures.graphs.KahnsAlgorithm=UselessMainMethod
-com.thealgorithms.datastructures.graphs.MatrixGraphs=UselessMainMethod
-com.thealgorithms.datastructures.hashmap.hashing.HashMapCuckooHashing=UselessParentheses
-com.thealgorithms.datastructures.hashmap.hashing.MainCuckooHashing=UselessMainMethod
-com.thealgorithms.datastructures.heaps.FibonacciHeap=UselessParentheses
-com.thealgorithms.datastructures.heaps.HeapNode=UselessParentheses
-com.thealgorithms.datastructures.lists.DoublyLinkedList=UselessParentheses
-com.thealgorithms.datastructures.lists.Link=UselessMainMethod
-com.thealgorithms.datastructures.lists.RandomNode=UselessMainMethod
-com.thealgorithms.datastructures.lists.SearchSinglyLinkedListRecursion=UselessParentheses
-com.thealgorithms.datastructures.lists.SinglyLinkedList=UnusedLocalVariable,UselessMainMethod
-com.thealgorithms.datastructures.queues.Deque=UselessMainMethod
-com.thealgorithms.datastructures.queues.PriorityQueue=UselessParentheses
-com.thealgorithms.datastructures.trees.BSTRecursiveGeneric=UselessMainMethod
-com.thealgorithms.datastructures.trees.CheckBinaryTreeIsValidBST=UselessParentheses
-com.thealgorithms.datastructures.trees.LCA=UselessMainMethod
-com.thealgorithms.datastructures.trees.NearestRightKey=UselessMainMethod
-com.thealgorithms.datastructures.trees.PrintTopViewofTree=UselessMainMethod
-com.thealgorithms.datastructures.trees.SegmentTree=UselessParentheses
-com.thealgorithms.devutils.nodes.LargeTreeNode=UselessParentheses
-com.thealgorithms.devutils.nodes.SimpleNode=UselessParentheses
-com.thealgorithms.devutils.nodes.SimpleTreeNode=UselessParentheses
-com.thealgorithms.devutils.nodes.TreeNode=UselessParentheses
-com.thealgorithms.divideandconquer.ClosestPair=UnnecessaryFullyQualifiedName,UselessMainMethod,UselessParentheses
-com.thealgorithms.divideandconquer.Point=UselessParentheses
-com.thealgorithms.dynamicprogramming.CatalanNumber=UselessMainMethod
-com.thealgorithms.dynamicprogramming.EggDropping=UselessMainMethod
-com.thealgorithms.dynamicprogramming.LongestPalindromicSubsequence=UselessMainMethod
-com.thealgorithms.dynamicprogramming.WineProblem=UselessParentheses
-com.thealgorithms.maths.BinomialCoefficient=UselessParentheses
-com.thealgorithms.maths.Complex=UselessParentheses
-com.thealgorithms.maths.DistanceFormulaTest=UnnecessaryFullyQualifiedName
-com.thealgorithms.maths.EulerMethod=UselessMainMethod
-com.thealgorithms.maths.GCDRecursion=UselessMainMethod
-com.thealgorithms.maths.Gaussian=UselessParentheses
-com.thealgorithms.maths.GcdSolutionWrapper=UselessParentheses
-com.thealgorithms.maths.HeronsFormula=UselessParentheses
-com.thealgorithms.maths.JugglerSequence=UselessMainMethod
-com.thealgorithms.maths.KeithNumber=UselessMainMethod,UselessParentheses
-com.thealgorithms.maths.LinearDiophantineEquationsSolver=UselessMainMethod,UselessParentheses
-com.thealgorithms.maths.MagicSquare=UselessMainMethod
-com.thealgorithms.maths.PiNilakantha=UselessMainMethod
-com.thealgorithms.maths.Prime.PrimeCheck=UselessMainMethod
-com.thealgorithms.maths.RomanNumeralUtil=UselessParentheses
-com.thealgorithms.maths.SecondMinMax=UselessParentheses
-com.thealgorithms.maths.SecondMinMaxTest=UnnecessaryFullyQualifiedName
-com.thealgorithms.maths.SimpsonIntegration=UselessMainMethod
-com.thealgorithms.maths.StandardDeviation=UselessParentheses
-com.thealgorithms.maths.SumOfArithmeticSeries=UselessParentheses
-com.thealgorithms.maths.TrinomialTriangle=UselessMainMethod,UselessParentheses
-com.thealgorithms.maths.VectorCrossProduct=UselessMainMethod
-com.thealgorithms.maths.Volume=UselessParentheses
-com.thealgorithms.matrix.RotateMatrixBy90Degrees=UselessMainMethod
-com.thealgorithms.others.BankersAlgorithm=UselessMainMethod
-com.thealgorithms.others.BrianKernighanAlgorithm=UselessMainMethod
-com.thealgorithms.others.CRC16=UselessMainMethod,UselessParentheses
-com.thealgorithms.others.CRC32=UselessMainMethod
-com.thealgorithms.others.Damm=UnnecessaryFullyQualifiedName,UselessMainMethod
-com.thealgorithms.others.Dijkstra=UselessMainMethod
-com.thealgorithms.others.GaussLegendre=UselessMainMethod
-com.thealgorithms.others.Huffman=UselessMainMethod
-com.thealgorithms.others.InsertDeleteInArray=UselessMainMethod
-com.thealgorithms.others.KochSnowflake=UselessMainMethod
-com.thealgorithms.others.LinearCongruentialGenerator=UselessMainMethod
-com.thealgorithms.others.Luhn=UnnecessaryFullyQualifiedName,UselessMainMethod
-com.thealgorithms.others.Mandelbrot=UselessMainMethod,UselessParentheses
-com.thealgorithms.others.MiniMaxAlgorithm=UselessMainMethod,UselessParentheses
-com.thealgorithms.others.MosAlgorithm=UselessMainMethod
-com.thealgorithms.others.PageRank=UselessMainMethod,UselessParentheses
-com.thealgorithms.others.PerlinNoise=UselessMainMethod,UselessParentheses
-com.thealgorithms.others.QueueUsingTwoStacks=UselessParentheses
-com.thealgorithms.others.Trieac=UselessMainMethod,UselessParentheses
-com.thealgorithms.others.Verhoeff=UnnecessaryFullyQualifiedName,UselessMainMethod
-com.thealgorithms.recursion.DiceThrower=UselessMainMethod
-com.thealgorithms.searches.HowManyTimesRotated=UselessMainMethod
-com.thealgorithms.searches.InterpolationSearch=UselessParentheses
-com.thealgorithms.searches.KMPSearch=UselessParentheses
-com.thealgorithms.searches.RabinKarpAlgorithm=UselessParentheses
-com.thealgorithms.searches.RecursiveBinarySearch=UselessMainMethod
-com.thealgorithms.sorts.BogoSort=UselessMainMethod
-com.thealgorithms.sorts.CircleSort=EmptyControlStatement
-com.thealgorithms.sorts.DutchNationalFlagSort=UselessParentheses
-com.thealgorithms.sorts.MergeSortNoExtraSpace=UselessParentheses
-com.thealgorithms.sorts.RadixSort=UselessParentheses
-com.thealgorithms.sorts.TreeSort=UselessMainMethod
-com.thealgorithms.sorts.WiggleSort=UselessParentheses
-com.thealgorithms.stacks.MaximumMinimumWindow=UselessMainMethod
-com.thealgorithms.stacks.PostfixToInfix=UselessParentheses
-com.thealgorithms.strings.HorspoolSearch=UnnecessaryFullyQualifiedName,UselessParentheses
-com.thealgorithms.strings.Lower=UselessMainMethod
-com.thealgorithms.strings.Palindrome=UselessParentheses
-com.thealgorithms.strings.Pangram=UselessMainMethod
-com.thealgorithms.strings.Rotation=UselessMainMethod
-com.thealgorithms.strings.Upper=UselessMainMethod
+com.thealgorithms.ciphers.AES=UselessMainMethod
+com.thealgorithms.ciphers.AESEncryption=UselessMainMethod
+com.thealgorithms.ciphers.AffineCipher=UselessParentheses
+com.thealgorithms.ciphers.DES=UselessParentheses
+com.thealgorithms.ciphers.ProductCipher=UselessMainMethod
+com.thealgorithms.ciphers.RSA=UselessParentheses
+com.thealgorithms.conversions.AnyBaseToAnyBase=UselessMainMethod,UselessParentheses
+com.thealgorithms.conversions.AnytoAny=UselessParentheses
+com.thealgorithms.conversions.RgbHsvConversion=UselessMainMethod
+com.thealgorithms.datastructures.crdt.Pair=UnusedPrivateField
+com.thealgorithms.datastructures.graphs.AStar=UselessParentheses
+com.thealgorithms.datastructures.graphs.AdjacencyMatrixGraph=CollapsibleIfStatements,UnnecessaryFullyQualifiedName,UselessParentheses
+com.thealgorithms.datastructures.graphs.BellmanFord=UselessMainMethod
+com.thealgorithms.datastructures.graphs.BipartiteGraphDFS=CollapsibleIfStatements
+com.thealgorithms.datastructures.graphs.ConnectedComponent=UselessMainMethod
+com.thealgorithms.datastructures.graphs.Cycles=UselessMainMethod
+com.thealgorithms.datastructures.graphs.Graphs=UselessMainMethod
+com.thealgorithms.datastructures.graphs.KahnsAlgorithm=UselessMainMethod
+com.thealgorithms.datastructures.graphs.MatrixGraphs=UselessMainMethod
+com.thealgorithms.datastructures.hashmap.hashing.HashMapCuckooHashing=UselessParentheses
+com.thealgorithms.datastructures.hashmap.hashing.MainCuckooHashing=UselessMainMethod
+com.thealgorithms.datastructures.heaps.FibonacciHeap=UselessParentheses
+com.thealgorithms.datastructures.heaps.HeapNode=UselessParentheses
+com.thealgorithms.datastructures.lists.DoublyLinkedList=UselessParentheses
+com.thealgorithms.datastructures.lists.Link=UselessMainMethod
+com.thealgorithms.datastructures.lists.RandomNode=UselessMainMethod
+com.thealgorithms.datastructures.lists.SearchSinglyLinkedListRecursion=UselessParentheses
+com.thealgorithms.datastructures.lists.SinglyLinkedList=UnusedLocalVariable,UselessMainMethod
+com.thealgorithms.datastructures.queues.Deque=UselessMainMethod
+com.thealgorithms.datastructures.queues.PriorityQueue=UselessParentheses
+com.thealgorithms.datastructures.trees.BSTRecursiveGeneric=UselessMainMethod
+com.thealgorithms.datastructures.trees.CheckBinaryTreeIsValidBST=UselessParentheses
+com.thealgorithms.datastructures.trees.LCA=UselessMainMethod
+com.thealgorithms.datastructures.trees.NearestRightKey=UselessMainMethod
+com.thealgorithms.datastructures.trees.PrintTopViewofTree=UselessMainMethod
+com.thealgorithms.datastructures.trees.SegmentTree=UselessParentheses
+com.thealgorithms.devutils.nodes.LargeTreeNode=UselessParentheses
+com.thealgorithms.devutils.nodes.SimpleNode=UselessParentheses
+com.thealgorithms.devutils.nodes.SimpleTreeNode=UselessParentheses
+com.thealgorithms.devutils.nodes.TreeNode=UselessParentheses
+com.thealgorithms.divideandconquer.ClosestPair=UnnecessaryFullyQualifiedName,UselessMainMethod,UselessParentheses
+com.thealgorithms.divideandconquer.Point=UselessParentheses
+com.thealgorithms.dynamicprogramming.CatalanNumber=UselessMainMethod
+com.thealgorithms.dynamicprogramming.EggDropping=UselessMainMethod
+com.thealgorithms.dynamicprogramming.LongestPalindromicSubsequence=UselessMainMethod
+com.thealgorithms.dynamicprogramming.WineProblem=UselessParentheses
+com.thealgorithms.maths.BinomialCoefficient=UselessParentheses
+com.thealgorithms.maths.Complex=UselessParentheses
+com.thealgorithms.maths.DistanceFormulaTest=UnnecessaryFullyQualifiedName
+com.thealgorithms.maths.EulerMethod=UselessMainMethod
+com.thealgorithms.maths.GCDRecursion=UselessMainMethod
+com.thealgorithms.maths.Gaussian=UselessParentheses
+com.thealgorithms.maths.GcdSolutionWrapper=UselessParentheses
+com.thealgorithms.maths.HeronsFormula=UselessParentheses
+com.thealgorithms.maths.JugglerSequence=UselessMainMethod
+com.thealgorithms.maths.KeithNumber=UselessMainMethod,UselessParentheses
+com.thealgorithms.maths.LinearDiophantineEquationsSolver=UselessMainMethod,UselessParentheses
+com.thealgorithms.maths.MagicSquare=UselessMainMethod
+com.thealgorithms.maths.PiNilakantha=UselessMainMethod
+com.thealgorithms.maths.Prime.PrimeCheck=UselessMainMethod
+com.thealgorithms.maths.RomanNumeralUtil=UselessParentheses
+com.thealgorithms.maths.SecondMinMax=UselessParentheses
+com.thealgorithms.maths.SecondMinMaxTest=UnnecessaryFullyQualifiedName
+com.thealgorithms.maths.SimpsonIntegration=UselessMainMethod
+com.thealgorithms.maths.StandardDeviation=UselessParentheses
+com.thealgorithms.maths.SumOfArithmeticSeries=UselessParentheses
+com.thealgorithms.maths.TrinomialTriangle=UselessMainMethod,UselessParentheses
+com.thealgorithms.maths.VectorCrossProduct=UselessMainMethod
+com.thealgorithms.maths.Volume=UselessParentheses
+com.thealgorithms.matrix.RotateMatrixBy90Degrees=UselessMainMethod
+com.thealgorithms.others.BankersAlgorithm=UselessMainMethod
+com.thealgorithms.others.BrianKernighanAlgorithm=UselessMainMethod
+com.thealgorithms.others.CRC16=UselessMainMethod,UselessParentheses
+com.thealgorithms.others.CRC32=UselessMainMethod
+com.thealgorithms.others.Damm=UnnecessaryFullyQualifiedName,UselessMainMethod
+com.thealgorithms.others.Dijkstra=UselessMainMethod
+com.thealgorithms.others.GaussLegendre=UselessMainMethod
+com.thealgorithms.others.Huffman=UselessMainMethod
+com.thealgorithms.others.InsertDeleteInArray=UselessMainMethod
+com.thealgorithms.others.KochSnowflake=UselessMainMethod
+com.thealgorithms.others.LinearCongruentialGenerator=UselessMainMethod
+com.thealgorithms.others.Luhn=UnnecessaryFullyQualifiedName,UselessMainMethod
+com.thealgorithms.others.Mandelbrot=UselessMainMethod,UselessParentheses
+com.thealgorithms.others.MiniMaxAlgorithm=UselessMainMethod,UselessParentheses
+com.thealgorithms.others.MosAlgorithm=UselessMainMethod
+com.thealgorithms.others.PageRank=UselessMainMethod,UselessParentheses
+com.thealgorithms.others.PerlinNoise=UselessMainMethod,UselessParentheses
+com.thealgorithms.others.QueueUsingTwoStacks=UselessParentheses
+com.thealgorithms.others.Trieac=UselessMainMethod,UselessParentheses
+com.thealgorithms.others.Verhoeff=UnnecessaryFullyQualifiedName,UselessMainMethod
+com.thealgorithms.recursion.DiceThrower=UselessMainMethod
+com.thealgorithms.searches.HowManyTimesRotated=UselessMainMethod
+com.thealgorithms.searches.InterpolationSearch=UselessParentheses
+com.thealgorithms.searches.KMPSearch=UselessParentheses
+com.thealgorithms.searches.RabinKarpAlgorithm=UselessParentheses
+com.thealgorithms.searches.RecursiveBinarySearch=UselessMainMethod
+com.thealgorithms.sorts.BogoSort=UselessMainMethod
+com.thealgorithms.sorts.CircleSort=EmptyControlStatement
+com.thealgorithms.sorts.DutchNationalFlagSort=UselessParentheses
+com.thealgorithms.sorts.MergeSortNoExtraSpace=UselessParentheses
+com.thealgorithms.sorts.RadixSort=UselessParentheses
+com.thealgorithms.sorts.TreeSort=UselessMainMethod
+com.thealgorithms.sorts.WiggleSort=UselessParentheses
+com.thealgorithms.stacks.MaximumMinimumWindow=UselessMainMethod
+com.thealgorithms.stacks.PostfixToInfix=UselessParentheses
+com.thealgorithms.strings.HorspoolSearch=UnnecessaryFullyQualifiedName,UselessParentheses
+com.thealgorithms.strings.Lower=UselessMainMethod
+com.thealgorithms.strings.Palindrome=UselessParentheses
+com.thealgorithms.strings.Pangram=UselessMainMethod
+com.thealgorithms.strings.Rotation=UselessMainMethod
+com.thealgorithms.strings.Upper=UselessMainMethod
diff --git a/pom.xml b/pom.xml
index 2445a1e920a8..7d14eb22c0a1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,158 +1,158 @@
-
-
- 4.0.0
- com.thealgorithms
- Java
- 1.0-SNAPSHOT
- jar
-
-
- UTF-8
- 21
- 21
- 3.27.7
-
-
-
-
-
- org.junit
- junit-bom
- 6.0.3
- pom
- import
-
-
-
-
-
-
- org.junit.jupiter
- junit-jupiter
- test
-
-
- org.assertj
- assertj-core
- ${assertj.version}
- test
-
-
- org.mockito
- mockito-core
- 5.21.0
- test
-
-
- org.apache.commons
- commons-lang3
- 3.20.0
-
-
- org.apache.commons
- commons-collections4
- 4.5.0
-
-
-
-
-
-
- maven-surefire-plugin
- 3.5.4
-
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 3.15.0
-
- 21
-
- -Xlint:all
- -Xlint:-auxiliaryclass
- -Werror
-
-
-
-
- org.jacoco
- jacoco-maven-plugin
- 0.8.14
-
-
-
- prepare-agent
-
-
-
- generate-code-coverage-report
- test
-
- report
-
-
-
-
-
- org.apache.maven.plugins
- maven-checkstyle-plugin
- 3.6.0
-
- checkstyle.xml
- true
- true
- warning
-
-
-
- com.puppycrawl.tools
- checkstyle
- 13.2.0
-
-
-
-
- com.github.spotbugs
- spotbugs-maven-plugin
- 4.9.8.2
-
- spotbugs-exclude.xml
- true
-
-
- com.mebigfatguy.fb-contrib
- fb-contrib
- 7.7.4
-
-
- com.h3xstream.findsecbugs
- findsecbugs-plugin
- 1.14.0
-
-
-
-
-
- org.apache.maven.plugins
- maven-pmd-plugin
- 3.28.0
-
-
- /rulesets/java/maven-pmd-plugin-default.xml
- /category/java/security.xml
- file://${basedir}/pmd-custom_ruleset.xml
-
- true
- true
- false
- pmd-exclude.properties
-
-
-
-
+
+
+ 4.0.0
+ com.thealgorithms
+ Java
+ 1.0-SNAPSHOT
+ jar
+
+
+ UTF-8
+ 21
+ 21
+ 3.27.7
+
+
+
+
+
+ org.junit
+ junit-bom
+ 6.0.3
+ pom
+ import
+
+
+
+
+
+
+ org.junit.jupiter
+ junit-jupiter
+ test
+
+
+ org.assertj
+ assertj-core
+ ${assertj.version}
+ test
+
+
+ org.mockito
+ mockito-core
+ 5.21.0
+ test
+
+
+ org.apache.commons
+ commons-lang3
+ 3.20.0
+
+
+ org.apache.commons
+ commons-collections4
+ 4.5.0
+
+
+
+
+
+
+ maven-surefire-plugin
+ 3.5.4
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.15.0
+
+ 21
+
+ -Xlint:all
+ -Xlint:-auxiliaryclass
+ -Werror
+
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ 0.8.14
+
+
+
+ prepare-agent
+
+
+
+ generate-code-coverage-report
+ test
+
+ report
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-checkstyle-plugin
+ 3.6.0
+
+ checkstyle.xml
+ true
+ true
+ warning
+
+
+
+ com.puppycrawl.tools
+ checkstyle
+ 13.2.0
+
+
+
+
+ com.github.spotbugs
+ spotbugs-maven-plugin
+ 4.9.8.2
+
+ spotbugs-exclude.xml
+ true
+
+
+ com.mebigfatguy.fb-contrib
+ fb-contrib
+ 7.7.4
+
+
+ com.h3xstream.findsecbugs
+ findsecbugs-plugin
+ 1.14.0
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-pmd-plugin
+ 3.28.0
+
+
+ /rulesets/java/maven-pmd-plugin-default.xml
+ /category/java/security.xml
+ file://${basedir}/pmd-custom_ruleset.xml
+
+ true
+ true
+ false
+ pmd-exclude.properties
+
+
+
+
\ No newline at end of file
diff --git a/spotbugs-exclude.xml b/spotbugs-exclude.xml
index a8eedcfed402..db487a47dff4 100644
--- a/spotbugs-exclude.xml
+++ b/spotbugs-exclude.xml
@@ -1,181 +1,181 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/java/com/thealgorithms/audiofilters/EMAFilter.java b/src/main/java/com/thealgorithms/audiofilters/EMAFilter.java
index 0dd23e937953..e70d728487a4 100644
--- a/src/main/java/com/thealgorithms/audiofilters/EMAFilter.java
+++ b/src/main/java/com/thealgorithms/audiofilters/EMAFilter.java
@@ -1,48 +1,48 @@
-package com.thealgorithms.audiofilters;
-
-/**
- * Exponential Moving Average (EMA) Filter for smoothing audio signals.
- *
- * This filter applies an exponential moving average to a sequence of audio
- * signal values, making it useful for smoothing out rapid fluctuations.
- * The smoothing factor (alpha) controls the degree of smoothing.
- *
- *
Based on the definition from
- * Wikipedia link.
- */
-public class EMAFilter {
- private final double alpha;
- private double emaValue;
- /**
- * Constructs an EMA filter with a given smoothing factor.
- *
- * @param alpha Smoothing factor (0 < alpha <= 1)
- * @throws IllegalArgumentException if alpha is not in (0, 1]
- */
- public EMAFilter(double alpha) {
- if (alpha <= 0 || alpha > 1) {
- throw new IllegalArgumentException("Alpha must be between 0 and 1.");
- }
- this.alpha = alpha;
- this.emaValue = 0.0;
- }
- /**
- * Applies the EMA filter to an audio signal array.
- *
- * @param audioSignal Array of audio samples to process
- * @return Array of processed (smoothed) samples
- */
- public double[] apply(double[] audioSignal) {
- if (audioSignal.length == 0) {
- return new double[0];
- }
- double[] emaSignal = new double[audioSignal.length];
- emaValue = audioSignal[0];
- emaSignal[0] = emaValue;
- for (int i = 1; i < audioSignal.length; i++) {
- emaValue = alpha * audioSignal[i] + (1 - alpha) * emaValue;
- emaSignal[i] = emaValue;
- }
- return emaSignal;
- }
-}
+package com.thealgorithms.audiofilters;
+
+/**
+ * Exponential Moving Average (EMA) Filter for smoothing audio signals.
+ *
+ *
This filter applies an exponential moving average to a sequence of audio
+ * signal values, making it useful for smoothing out rapid fluctuations.
+ * The smoothing factor (alpha) controls the degree of smoothing.
+ *
+ *
Based on the definition from
+ * Wikipedia link.
+ */
+public class EMAFilter {
+ private final double alpha;
+ private double emaValue;
+ /**
+ * Constructs an EMA filter with a given smoothing factor.
+ *
+ * @param alpha Smoothing factor (0 < alpha <= 1)
+ * @throws IllegalArgumentException if alpha is not in (0, 1]
+ */
+ public EMAFilter(double alpha) {
+ if (alpha <= 0 || alpha > 1) {
+ throw new IllegalArgumentException("Alpha must be between 0 and 1.");
+ }
+ this.alpha = alpha;
+ this.emaValue = 0.0;
+ }
+ /**
+ * Applies the EMA filter to an audio signal array.
+ *
+ * @param audioSignal Array of audio samples to process
+ * @return Array of processed (smoothed) samples
+ */
+ public double[] apply(double[] audioSignal) {
+ if (audioSignal.length == 0) {
+ return new double[0];
+ }
+ double[] emaSignal = new double[audioSignal.length];
+ emaValue = audioSignal[0];
+ emaSignal[0] = emaValue;
+ for (int i = 1; i < audioSignal.length; i++) {
+ emaValue = alpha * audioSignal[i] + (1 - alpha) * emaValue;
+ emaSignal[i] = emaValue;
+ }
+ return emaSignal;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/audiofilters/IIRFilter.java b/src/main/java/com/thealgorithms/audiofilters/IIRFilter.java
index fbc095909541..7574f02dd62c 100644
--- a/src/main/java/com/thealgorithms/audiofilters/IIRFilter.java
+++ b/src/main/java/com/thealgorithms/audiofilters/IIRFilter.java
@@ -1,93 +1,93 @@
-package com.thealgorithms.audiofilters;
-
-/**
- * N-Order IIR Filter Assumes inputs are normalized to [-1, 1]
- *
- * Based on the difference equation from
- * Wikipedia link
- */
-public class IIRFilter {
-
- private final int order;
- private final double[] coeffsA;
- private final double[] coeffsB;
- private final double[] historyX;
- private final double[] historyY;
-
- /**
- * Construct an IIR Filter
- *
- * @param order the filter's order
- * @throws IllegalArgumentException if order is zero or less
- */
- public IIRFilter(int order) throws IllegalArgumentException {
- if (order < 1) {
- throw new IllegalArgumentException("order must be greater than zero");
- }
-
- this.order = order;
- coeffsA = new double[order + 1];
- coeffsB = new double[order + 1];
-
- // Sane defaults
- coeffsA[0] = 1.0;
- coeffsB[0] = 1.0;
-
- historyX = new double[order];
- historyY = new double[order];
- }
-
- /**
- * Set coefficients
- *
- * @param aCoeffs Denominator coefficients
- * @param bCoeffs Numerator coefficients
- * @throws IllegalArgumentException if {@code aCoeffs} or {@code bCoeffs} is
- * not of size {@code order}, or if {@code aCoeffs[0]} is 0.0
- */
- public void setCoeffs(double[] aCoeffs, double[] bCoeffs) throws IllegalArgumentException {
- if (aCoeffs.length != order) {
- throw new IllegalArgumentException("aCoeffs must be of size " + order + ", got " + aCoeffs.length);
- }
-
- if (aCoeffs[0] == 0.0) {
- throw new IllegalArgumentException("aCoeffs.get(0) must not be zero");
- }
-
- if (bCoeffs.length != order) {
- throw new IllegalArgumentException("bCoeffs must be of size " + order + ", got " + bCoeffs.length);
- }
-
- for (int i = 0; i < order; i++) {
- coeffsA[i] = aCoeffs[i];
- coeffsB[i] = bCoeffs[i];
- }
- }
-
- /**
- * Process a single sample
- *
- * @param sample the sample to process
- * @return the processed sample
- */
- public double process(double sample) {
- double result = 0.0;
-
- // Process
- for (int i = 1; i <= order; i++) {
- result += (coeffsB[i] * historyX[i - 1] - coeffsA[i] * historyY[i - 1]);
- }
- result = (result + coeffsB[0] * sample) / coeffsA[0];
-
- // Feedback
- for (int i = order - 1; i > 0; i--) {
- historyX[i] = historyX[i - 1];
- historyY[i] = historyY[i - 1];
- }
-
- historyX[0] = sample;
- historyY[0] = result;
-
- return result;
- }
-}
+package com.thealgorithms.audiofilters;
+
+/**
+ * N-Order IIR Filter Assumes inputs are normalized to [-1, 1]
+ *
+ * Based on the difference equation from
+ * Wikipedia link
+ */
+public class IIRFilter {
+
+ private final int order;
+ private final double[] coeffsA;
+ private final double[] coeffsB;
+ private final double[] historyX;
+ private final double[] historyY;
+
+ /**
+ * Construct an IIR Filter
+ *
+ * @param order the filter's order
+ * @throws IllegalArgumentException if order is zero or less
+ */
+ public IIRFilter(int order) throws IllegalArgumentException {
+ if (order < 1) {
+ throw new IllegalArgumentException("order must be greater than zero");
+ }
+
+ this.order = order;
+ coeffsA = new double[order + 1];
+ coeffsB = new double[order + 1];
+
+ // Sane defaults
+ coeffsA[0] = 1.0;
+ coeffsB[0] = 1.0;
+
+ historyX = new double[order];
+ historyY = new double[order];
+ }
+
+ /**
+ * Set coefficients
+ *
+ * @param aCoeffs Denominator coefficients
+ * @param bCoeffs Numerator coefficients
+ * @throws IllegalArgumentException if {@code aCoeffs} or {@code bCoeffs} is
+ * not of size {@code order}, or if {@code aCoeffs[0]} is 0.0
+ */
+ public void setCoeffs(double[] aCoeffs, double[] bCoeffs) throws IllegalArgumentException {
+ if (aCoeffs.length != order) {
+ throw new IllegalArgumentException("aCoeffs must be of size " + order + ", got " + aCoeffs.length);
+ }
+
+ if (aCoeffs[0] == 0.0) {
+ throw new IllegalArgumentException("aCoeffs.get(0) must not be zero");
+ }
+
+ if (bCoeffs.length != order) {
+ throw new IllegalArgumentException("bCoeffs must be of size " + order + ", got " + bCoeffs.length);
+ }
+
+ for (int i = 0; i < order; i++) {
+ coeffsA[i] = aCoeffs[i];
+ coeffsB[i] = bCoeffs[i];
+ }
+ }
+
+ /**
+ * Process a single sample
+ *
+ * @param sample the sample to process
+ * @return the processed sample
+ */
+ public double process(double sample) {
+ double result = 0.0;
+
+ // Process
+ for (int i = 1; i <= order; i++) {
+ result += (coeffsB[i] * historyX[i - 1] - coeffsA[i] * historyY[i - 1]);
+ }
+ result = (result + coeffsB[0] * sample) / coeffsA[0];
+
+ // Feedback
+ for (int i = order - 1; i > 0; i--) {
+ historyX[i] = historyX[i - 1];
+ historyY[i] = historyY[i - 1];
+ }
+
+ historyX[0] = sample;
+ historyY[0] = result;
+
+ return result;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/backtracking/AllPathsFromSourceToTarget.java b/src/main/java/com/thealgorithms/backtracking/AllPathsFromSourceToTarget.java
index 269880b8ddae..6324ebcb15fd 100644
--- a/src/main/java/com/thealgorithms/backtracking/AllPathsFromSourceToTarget.java
+++ b/src/main/java/com/thealgorithms/backtracking/AllPathsFromSourceToTarget.java
@@ -1,126 +1,126 @@
-package com.thealgorithms.backtracking;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Finds all possible simple paths from a given source vertex to a destination vertex
- * in a directed graph using backtracking.
- *
- *
This algorithm performs a Depth First Search (DFS) traversal while keeping track
- * of visited vertices to avoid cycles. Whenever the destination vertex is reached,
- * the current path is stored as one valid path.
- *
- * Key Characteristics:
- *
- * - Works on directed graphs
- * - Does not allow revisiting vertices in the same path
- * - Stores all possible paths from source to destination
- *
- *
- * Time Complexity:
- *
- * - Worst Case: O(V!) — when the graph is fully connected
- *
- *
- * Space Complexity:
- *
- * - O(V) for recursion stack and visited array
- * - Additional space for storing all valid paths
- *
- *
- * This implementation is intended for educational purposes.
- *
- * @see Depth First Search
- */
-
-@SuppressWarnings({"rawtypes", "unchecked"})
-public class AllPathsFromSourceToTarget {
-
- // No. of vertices in graph
- private final int v;
-
- // To store the paths from source to destination
- static List> nm = new ArrayList<>();
- // adjacency list
- private ArrayList[] adjList;
-
- // Constructor
- public AllPathsFromSourceToTarget(int vertices) {
-
- // initialise vertex count
- this.v = vertices;
-
- // initialise adjacency list
- initAdjList();
- }
-
- // utility method to initialise adjacency list
- private void initAdjList() {
- adjList = new ArrayList[v];
-
- for (int i = 0; i < v; i++) {
- adjList[i] = new ArrayList<>();
- }
- }
-
- // add edge from u to v
- public void addEdge(int u, int v) {
- // Add v to u's list.
- adjList[u].add(v);
- }
-
- public void storeAllPaths(int s, int d) {
- boolean[] isVisited = new boolean[v];
- ArrayList pathList = new ArrayList<>();
-
- // add source to path[]
- pathList.add(s);
- // Call recursive utility
- storeAllPathsUtil(s, d, isVisited, pathList);
- }
-
- // A recursive function to print all paths from 'u' to 'd'.
- // isVisited[] keeps track of vertices in current path.
- // localPathList<> stores actual vertices in the current path
- private void storeAllPathsUtil(Integer u, Integer d, boolean[] isVisited, List localPathList) {
-
- if (u.equals(d)) {
- nm.add(new ArrayList<>(localPathList));
- return;
- }
-
- // Mark the current node
- isVisited[u] = true;
-
- // Recursion for all the vertices adjacent to current vertex
-
- for (Integer i : adjList[u]) {
- if (!isVisited[i]) {
- // store current node in path[]
- localPathList.add(i);
- storeAllPathsUtil(i, d, isVisited, localPathList);
-
- // remove current node in path[]
- localPathList.remove(i);
- }
- }
-
- // Mark the current node
- isVisited[u] = false;
- }
-
- // Driver program
- public static List> allPathsFromSourceToTarget(int vertices, int[][] a, int source, int destination) {
- // Create a sample graph
- AllPathsFromSourceToTarget g = new AllPathsFromSourceToTarget(vertices);
- for (int[] i : a) {
- g.addEdge(i[0], i[1]);
- // edges are added
- }
- g.storeAllPaths(source, destination);
- // method call to store all possible paths
- return nm;
- // returns all possible paths from source to destination
- }
-}
+package com.thealgorithms.backtracking;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Finds all possible simple paths from a given source vertex to a destination vertex
+ * in a directed graph using backtracking.
+ *
+ * This algorithm performs a Depth First Search (DFS) traversal while keeping track
+ * of visited vertices to avoid cycles. Whenever the destination vertex is reached,
+ * the current path is stored as one valid path.
+ *
+ * Key Characteristics:
+ *
+ * - Works on directed graphs
+ * - Does not allow revisiting vertices in the same path
+ * - Stores all possible paths from source to destination
+ *
+ *
+ * Time Complexity:
+ *
+ * - Worst Case: O(V!) — when the graph is fully connected
+ *
+ *
+ * Space Complexity:
+ *
+ * - O(V) for recursion stack and visited array
+ * - Additional space for storing all valid paths
+ *
+ *
+ * This implementation is intended for educational purposes.
+ *
+ * @see Depth First Search
+ */
+
+@SuppressWarnings({"rawtypes", "unchecked"})
+public class AllPathsFromSourceToTarget {
+
+ // No. of vertices in graph
+ private final int v;
+
+ // To store the paths from source to destination
+ static List> nm = new ArrayList<>();
+ // adjacency list
+ private ArrayList[] adjList;
+
+ // Constructor
+ public AllPathsFromSourceToTarget(int vertices) {
+
+ // initialise vertex count
+ this.v = vertices;
+
+ // initialise adjacency list
+ initAdjList();
+ }
+
+ // utility method to initialise adjacency list
+ private void initAdjList() {
+ adjList = new ArrayList[v];
+
+ for (int i = 0; i < v; i++) {
+ adjList[i] = new ArrayList<>();
+ }
+ }
+
+ // add edge from u to v
+ public void addEdge(int u, int v) {
+ // Add v to u's list.
+ adjList[u].add(v);
+ }
+
+ public void storeAllPaths(int s, int d) {
+ boolean[] isVisited = new boolean[v];
+ ArrayList pathList = new ArrayList<>();
+
+ // add source to path[]
+ pathList.add(s);
+ // Call recursive utility
+ storeAllPathsUtil(s, d, isVisited, pathList);
+ }
+
+ // A recursive function to print all paths from 'u' to 'd'.
+ // isVisited[] keeps track of vertices in current path.
+ // localPathList<> stores actual vertices in the current path
+ private void storeAllPathsUtil(Integer u, Integer d, boolean[] isVisited, List localPathList) {
+
+ if (u.equals(d)) {
+ nm.add(new ArrayList<>(localPathList));
+ return;
+ }
+
+ // Mark the current node
+ isVisited[u] = true;
+
+ // Recursion for all the vertices adjacent to current vertex
+
+ for (Integer i : adjList[u]) {
+ if (!isVisited[i]) {
+ // store current node in path[]
+ localPathList.add(i);
+ storeAllPathsUtil(i, d, isVisited, localPathList);
+
+ // remove current node in path[]
+ localPathList.remove(i);
+ }
+ }
+
+ // Mark the current node
+ isVisited[u] = false;
+ }
+
+ // Driver program
+ public static List> allPathsFromSourceToTarget(int vertices, int[][] a, int source, int destination) {
+ // Create a sample graph
+ AllPathsFromSourceToTarget g = new AllPathsFromSourceToTarget(vertices);
+ for (int[] i : a) {
+ g.addEdge(i[0], i[1]);
+ // edges are added
+ }
+ g.storeAllPaths(source, destination);
+ // method call to store all possible paths
+ return nm;
+ // returns all possible paths from source to destination
+ }
+}
diff --git a/src/main/java/com/thealgorithms/backtracking/ArrayCombination.java b/src/main/java/com/thealgorithms/backtracking/ArrayCombination.java
index d05e33a4242f..22118987e040 100644
--- a/src/main/java/com/thealgorithms/backtracking/ArrayCombination.java
+++ b/src/main/java/com/thealgorithms/backtracking/ArrayCombination.java
@@ -1,54 +1,54 @@
-package com.thealgorithms.backtracking;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * This class provides methods to find all combinations of integers from 0 to n-1
- * of a specified length k using backtracking.
- */
-public final class ArrayCombination {
- private ArrayCombination() {
- }
-
- /**
- * Generates all possible combinations of length k from the integers 0 to n-1.
- *
- * @param n The total number of elements (0 to n-1).
- * @param k The desired length of each combination.
- * @return A list containing all combinations of length k.
- * @throws IllegalArgumentException if n or k are negative, or if k is greater than n.
- */
- public static List> combination(int n, int k) {
- if (k < 0 || k > n) {
- throw new IllegalArgumentException("Invalid input: 0 ≤ k ≤ n is required.");
- }
-
- List> combinations = new ArrayList<>();
- combine(combinations, new ArrayList<>(), 0, n, k);
- return combinations;
- }
-
- /**
- * A helper method that uses backtracking to find combinations.
- *
- * @param combinations The list to store all valid combinations found.
- * @param current The current combination being built.
- * @param start The starting index for the current recursion.
- * @param n The total number of elements (0 to n-1).
- * @param k The desired length of each combination.
- */
- private static void combine(List> combinations, List current, int start, int n, int k) {
- // Base case: combination found
- if (current.size() == k) {
- combinations.add(new ArrayList<>(current));
- return;
- }
-
- for (int i = start; i < n; i++) {
- current.add(i);
- combine(combinations, current, i + 1, n, k);
- current.removeLast(); // Backtrack
- }
- }
-}
+package com.thealgorithms.backtracking;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class provides methods to find all combinations of integers from 0 to n-1
+ * of a specified length k using backtracking.
+ */
+public final class ArrayCombination {
+ private ArrayCombination() {
+ }
+
+ /**
+ * Generates all possible combinations of length k from the integers 0 to n-1.
+ *
+ * @param n The total number of elements (0 to n-1).
+ * @param k The desired length of each combination.
+ * @return A list containing all combinations of length k.
+ * @throws IllegalArgumentException if n or k are negative, or if k is greater than n.
+ */
+ public static List> combination(int n, int k) {
+ if (k < 0 || k > n) {
+ throw new IllegalArgumentException("Invalid input: 0 ≤ k ≤ n is required.");
+ }
+
+ List> combinations = new ArrayList<>();
+ combine(combinations, new ArrayList<>(), 0, n, k);
+ return combinations;
+ }
+
+ /**
+ * A helper method that uses backtracking to find combinations.
+ *
+ * @param combinations The list to store all valid combinations found.
+ * @param current The current combination being built.
+ * @param start The starting index for the current recursion.
+ * @param n The total number of elements (0 to n-1).
+ * @param k The desired length of each combination.
+ */
+ private static void combine(List> combinations, List current, int start, int n, int k) {
+ // Base case: combination found
+ if (current.size() == k) {
+ combinations.add(new ArrayList<>(current));
+ return;
+ }
+
+ for (int i = start; i < n; i++) {
+ current.add(i);
+ combine(combinations, current, i + 1, n, k);
+ current.removeLast(); // Backtrack
+ }
+ }
+}
diff --git a/src/main/java/com/thealgorithms/backtracking/Combination.java b/src/main/java/com/thealgorithms/backtracking/Combination.java
index 377d2c862d54..ce1e85158a4c 100644
--- a/src/main/java/com/thealgorithms/backtracking/Combination.java
+++ b/src/main/java/com/thealgorithms/backtracking/Combination.java
@@ -1,66 +1,66 @@
-package com.thealgorithms.backtracking;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.TreeSet;
-
-/**
- * Finds all combinations of a given array using backtracking algorithm * @author Alan Piao (git-Alan Piao)
- */
-public final class Combination {
- private Combination() {
- }
-
- /**
- * Find all combinations of given array using backtracking
- * @param arr the array.
- * @param n length of combination
- * @param the type of elements in the array.
- * @return a list of all combinations of length n. If n == 0, return null.
- */
- public static List> combination(T[] arr, int n) {
- if (n < 0) {
- throw new IllegalArgumentException("The combination length cannot be negative.");
- }
-
- if (n == 0) {
- return Collections.emptyList();
- }
- T[] array = arr.clone();
- Arrays.sort(array);
-
- List> result = new LinkedList<>();
- backtracking(array, n, 0, new TreeSet(), result);
- return result;
- }
-
- /**
- * Backtrack all possible combinations of a given array
- * @param arr the array.
- * @param n length of the combination
- * @param index the starting index.
- * @param currSet set that tracks current combination
- * @param result the list contains all combination.
- * @param the type of elements in the array.
- */
- private static void backtracking(T[] arr, int n, int index, TreeSet currSet, List> result) {
- if (index + n - currSet.size() > arr.length) {
- return;
- }
- if (currSet.size() == n - 1) {
- for (int i = index; i < arr.length; i++) {
- currSet.add(arr[i]);
- result.add(new TreeSet<>(currSet));
- currSet.remove(arr[i]);
- }
- return;
- }
- for (int i = index; i < arr.length; i++) {
- currSet.add(arr[i]);
- backtracking(arr, n, i + 1, currSet, result);
- currSet.remove(arr[i]);
- }
- }
-}
+package com.thealgorithms.backtracking;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.TreeSet;
+
+/**
+ * Finds all combinations of a given array using backtracking algorithm * @author Alan Piao (git-Alan Piao)
+ */
+public final class Combination {
+ private Combination() {
+ }
+
+ /**
+ * Find all combinations of given array using backtracking
+ * @param arr the array.
+ * @param n length of combination
+ * @param the type of elements in the array.
+ * @return a list of all combinations of length n. If n == 0, return null.
+ */
+ public static List> combination(T[] arr, int n) {
+ if (n < 0) {
+ throw new IllegalArgumentException("The combination length cannot be negative.");
+ }
+
+ if (n == 0) {
+ return Collections.emptyList();
+ }
+ T[] array = arr.clone();
+ Arrays.sort(array);
+
+ List> result = new LinkedList<>();
+ backtracking(array, n, 0, new TreeSet(), result);
+ return result;
+ }
+
+ /**
+ * Backtrack all possible combinations of a given array
+ * @param arr the array.
+ * @param n length of the combination
+ * @param index the starting index.
+ * @param currSet set that tracks current combination
+ * @param result the list contains all combination.
+ * @param the type of elements in the array.
+ */
+ private static void backtracking(T[] arr, int n, int index, TreeSet currSet, List> result) {
+ if (index + n - currSet.size() > arr.length) {
+ return;
+ }
+ if (currSet.size() == n - 1) {
+ for (int i = index; i < arr.length; i++) {
+ currSet.add(arr[i]);
+ result.add(new TreeSet<>(currSet));
+ currSet.remove(arr[i]);
+ }
+ return;
+ }
+ for (int i = index; i < arr.length; i++) {
+ currSet.add(arr[i]);
+ backtracking(arr, n, i + 1, currSet, result);
+ currSet.remove(arr[i]);
+ }
+ }
+}
diff --git a/src/main/java/com/thealgorithms/backtracking/CombinationSum.java b/src/main/java/com/thealgorithms/backtracking/CombinationSum.java
index 09b99032bdc1..7fe2ad530de6 100644
--- a/src/main/java/com/thealgorithms/backtracking/CombinationSum.java
+++ b/src/main/java/com/thealgorithms/backtracking/CombinationSum.java
@@ -1,48 +1,48 @@
-package com.thealgorithms.backtracking;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/** Backtracking: pick/not-pick with reuse of candidates. */
-public final class CombinationSum {
- private CombinationSum() {
- throw new UnsupportedOperationException("Utility class");
- }
-
- public static List> combinationSum(int[] candidates, int target) {
- List> results = new ArrayList<>();
- if (candidates == null || candidates.length == 0) {
- return results;
- }
-
- // Sort to help with pruning duplicates and early termination
- Arrays.sort(candidates);
- backtrack(candidates, target, 0, new ArrayList<>(), results);
- return results;
- }
-
- private static void backtrack(int[] candidates, int remaining, int start, List combination, List> results) {
- if (remaining == 0) {
- // Found valid combination; add a copy
- results.add(new ArrayList<>(combination));
- return;
- }
-
- for (int i = start; i < candidates.length; i++) {
- int candidate = candidates[i];
-
- // If candidate is greater than remaining target, further candidates (sorted) will also be too big
- if (candidate > remaining) {
- break;
- }
-
- // include candidate
- combination.add(candidate);
- // Because we can reuse the same element, we pass i (not i + 1)
- backtrack(candidates, remaining - candidate, i, combination, results);
- // backtrack: remove last
- combination.remove(combination.size() - 1);
- }
- }
-}
+package com.thealgorithms.backtracking;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/** Backtracking: pick/not-pick with reuse of candidates. */
+public final class CombinationSum {
+ private CombinationSum() {
+ throw new UnsupportedOperationException("Utility class");
+ }
+
+ public static List> combinationSum(int[] candidates, int target) {
+ List> results = new ArrayList<>();
+ if (candidates == null || candidates.length == 0) {
+ return results;
+ }
+
+ // Sort to help with pruning duplicates and early termination
+ Arrays.sort(candidates);
+ backtrack(candidates, target, 0, new ArrayList<>(), results);
+ return results;
+ }
+
+ private static void backtrack(int[] candidates, int remaining, int start, List combination, List> results) {
+ if (remaining == 0) {
+ // Found valid combination; add a copy
+ results.add(new ArrayList<>(combination));
+ return;
+ }
+
+ for (int i = start; i < candidates.length; i++) {
+ int candidate = candidates[i];
+
+ // If candidate is greater than remaining target, further candidates (sorted) will also be too big
+ if (candidate > remaining) {
+ break;
+ }
+
+ // include candidate
+ combination.add(candidate);
+ // Because we can reuse the same element, we pass i (not i + 1)
+ backtrack(candidates, remaining - candidate, i, combination, results);
+ // backtrack: remove last
+ combination.remove(combination.size() - 1);
+ }
+ }
+}
diff --git a/src/main/java/com/thealgorithms/backtracking/CrosswordSolver.java b/src/main/java/com/thealgorithms/backtracking/CrosswordSolver.java
index 6bfb026c7de9..cf0221bdba53 100644
--- a/src/main/java/com/thealgorithms/backtracking/CrosswordSolver.java
+++ b/src/main/java/com/thealgorithms/backtracking/CrosswordSolver.java
@@ -1,125 +1,125 @@
-package com.thealgorithms.backtracking;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-/**
- * A class to solve a crossword puzzle using backtracking.
- * Example:
- * Input:
- * puzzle = {
- * {' ', ' ', ' '},
- * {' ', ' ', ' '},
- * {' ', ' ', ' '}
- * }
- * words = List.of("cat", "dog")
- *
- * Output:
- * {
- * {'c', 'a', 't'},
- * {' ', ' ', ' '},
- * {'d', 'o', 'g'}
- * }
- */
-public final class CrosswordSolver {
- private CrosswordSolver() {
- }
-
- /**
- * Checks if a word can be placed at the specified position in the crossword.
- *
- * @param puzzle The crossword puzzle represented as a 2D char array.
- * @param word The word to be placed.
- * @param row The row index where the word might be placed.
- * @param col The column index where the word might be placed.
- * @param vertical If true, the word is placed vertically; otherwise, horizontally.
- * @return true if the word can be placed, false otherwise.
- */
- public static boolean isValid(char[][] puzzle, String word, int row, int col, boolean vertical) {
- for (int i = 0; i < word.length(); i++) {
- if (vertical) {
- if (row + i >= puzzle.length || puzzle[row + i][col] != ' ') {
- return false;
- }
- } else {
- if (col + i >= puzzle[0].length || puzzle[row][col + i] != ' ') {
- return false;
- }
- }
- }
- return true;
- }
-
- /**
- * Places a word at the specified position in the crossword.
- *
- * @param puzzle The crossword puzzle represented as a 2D char array.
- * @param word The word to be placed.
- * @param row The row index where the word will be placed.
- * @param col The column index where the word will be placed.
- * @param vertical If true, the word is placed vertically; otherwise, horizontally.
- */
- public static void placeWord(char[][] puzzle, String word, int row, int col, boolean vertical) {
- for (int i = 0; i < word.length(); i++) {
- if (vertical) {
- puzzle[row + i][col] = word.charAt(i);
- } else {
- puzzle[row][col + i] = word.charAt(i);
- }
- }
- }
-
- /**
- * Removes a word from the specified position in the crossword.
- *
- * @param puzzle The crossword puzzle represented as a 2D char array.
- * @param word The word to be removed.
- * @param row The row index where the word is placed.
- * @param col The column index where the word is placed.
- * @param vertical If true, the word was placed vertically; otherwise, horizontally.
- */
- public static void removeWord(char[][] puzzle, String word, int row, int col, boolean vertical) {
- for (int i = 0; i < word.length(); i++) {
- if (vertical) {
- puzzle[row + i][col] = ' ';
- } else {
- puzzle[row][col + i] = ' ';
- }
- }
- }
-
- /**
- * Solves the crossword puzzle using backtracking.
- *
- * @param puzzle The crossword puzzle represented as a 2D char array.
- * @param words The list of words to be placed.
- * @return true if the crossword is solved, false otherwise.
- */
- public static boolean solveCrossword(char[][] puzzle, Collection words) {
- // Create a mutable copy of the words list
- List remainingWords = new ArrayList<>(words);
-
- for (int row = 0; row < puzzle.length; row++) {
- for (int col = 0; col < puzzle[0].length; col++) {
- if (puzzle[row][col] == ' ') {
- for (String word : new ArrayList<>(remainingWords)) {
- for (boolean vertical : new boolean[] {true, false}) {
- if (isValid(puzzle, word, row, col, vertical)) {
- placeWord(puzzle, word, row, col, vertical);
- remainingWords.remove(word);
- if (solveCrossword(puzzle, remainingWords)) {
- return true;
- }
- remainingWords.add(word);
- removeWord(puzzle, word, row, col, vertical);
- }
- }
- }
- return false;
- }
- }
- }
- return true;
- }
-}
+package com.thealgorithms.backtracking;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * A class to solve a crossword puzzle using backtracking.
+ * Example:
+ * Input:
+ * puzzle = {
+ * {' ', ' ', ' '},
+ * {' ', ' ', ' '},
+ * {' ', ' ', ' '}
+ * }
+ * words = List.of("cat", "dog")
+ *
+ * Output:
+ * {
+ * {'c', 'a', 't'},
+ * {' ', ' ', ' '},
+ * {'d', 'o', 'g'}
+ * }
+ */
+public final class CrosswordSolver {
+ private CrosswordSolver() {
+ }
+
+ /**
+ * Checks if a word can be placed at the specified position in the crossword.
+ *
+ * @param puzzle The crossword puzzle represented as a 2D char array.
+ * @param word The word to be placed.
+ * @param row The row index where the word might be placed.
+ * @param col The column index where the word might be placed.
+ * @param vertical If true, the word is placed vertically; otherwise, horizontally.
+ * @return true if the word can be placed, false otherwise.
+ */
+ public static boolean isValid(char[][] puzzle, String word, int row, int col, boolean vertical) {
+ for (int i = 0; i < word.length(); i++) {
+ if (vertical) {
+ if (row + i >= puzzle.length || puzzle[row + i][col] != ' ') {
+ return false;
+ }
+ } else {
+ if (col + i >= puzzle[0].length || puzzle[row][col + i] != ' ') {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Places a word at the specified position in the crossword.
+ *
+ * @param puzzle The crossword puzzle represented as a 2D char array.
+ * @param word The word to be placed.
+ * @param row The row index where the word will be placed.
+ * @param col The column index where the word will be placed.
+ * @param vertical If true, the word is placed vertically; otherwise, horizontally.
+ */
+ public static void placeWord(char[][] puzzle, String word, int row, int col, boolean vertical) {
+ for (int i = 0; i < word.length(); i++) {
+ if (vertical) {
+ puzzle[row + i][col] = word.charAt(i);
+ } else {
+ puzzle[row][col + i] = word.charAt(i);
+ }
+ }
+ }
+
+ /**
+ * Removes a word from the specified position in the crossword.
+ *
+ * @param puzzle The crossword puzzle represented as a 2D char array.
+ * @param word The word to be removed.
+ * @param row The row index where the word is placed.
+ * @param col The column index where the word is placed.
+ * @param vertical If true, the word was placed vertically; otherwise, horizontally.
+ */
+ public static void removeWord(char[][] puzzle, String word, int row, int col, boolean vertical) {
+ for (int i = 0; i < word.length(); i++) {
+ if (vertical) {
+ puzzle[row + i][col] = ' ';
+ } else {
+ puzzle[row][col + i] = ' ';
+ }
+ }
+ }
+
+ /**
+ * Solves the crossword puzzle using backtracking.
+ *
+ * @param puzzle The crossword puzzle represented as a 2D char array.
+ * @param words The list of words to be placed.
+ * @return true if the crossword is solved, false otherwise.
+ */
+ public static boolean solveCrossword(char[][] puzzle, Collection words) {
+ // Create a mutable copy of the words list
+ List remainingWords = new ArrayList<>(words);
+
+ for (int row = 0; row < puzzle.length; row++) {
+ for (int col = 0; col < puzzle[0].length; col++) {
+ if (puzzle[row][col] == ' ') {
+ for (String word : new ArrayList<>(remainingWords)) {
+ for (boolean vertical : new boolean[] {true, false}) {
+ if (isValid(puzzle, word, row, col, vertical)) {
+ placeWord(puzzle, word, row, col, vertical);
+ remainingWords.remove(word);
+ if (solveCrossword(puzzle, remainingWords)) {
+ return true;
+ }
+ remainingWords.add(word);
+ removeWord(puzzle, word, row, col, vertical);
+ }
+ }
+ }
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/backtracking/FloodFill.java b/src/main/java/com/thealgorithms/backtracking/FloodFill.java
index 0f31a9c5a30e..b0eef6273fc4 100644
--- a/src/main/java/com/thealgorithms/backtracking/FloodFill.java
+++ b/src/main/java/com/thealgorithms/backtracking/FloodFill.java
@@ -1,62 +1,62 @@
-package com.thealgorithms.backtracking;
-
-/**
- * Java program for Flood fill algorithm.
- * @author Akshay Dubey (Git-Akshay Dubey)
- */
-public final class FloodFill {
- private FloodFill() {
- }
-
- /**
- * Get the color at the given coordinates of a 2D image
- *
- * @param image The image to be filled
- * @param x The x coordinate of which color is to be obtained
- * @param y The y coordinate of which color is to be obtained
- */
-
- public static int getPixel(final int[][] image, final int x, final int y) {
- return image[x][y];
- }
-
- /**
- * Put the color at the given coordinates of a 2D image
- *
- * @param image The image to be filled
- * @param x The x coordinate at which color is to be filled
- * @param y The y coordinate at which color is to be filled
- */
- public static void putPixel(final int[][] image, final int x, final int y, final int newColor) {
- image[x][y] = newColor;
- }
-
- /**
- * Fill the 2D image with new color
- *
- * @param image The image to be filled
- * @param x The x coordinate at which color is to be filled
- * @param y The y coordinate at which color is to be filled
- * @param newColor The new color which to be filled in the image
- * @param oldColor The old color which is to be replaced in the image
- */
- public static void floodFill(final int[][] image, final int x, final int y, final int newColor, final int oldColor) {
- if (newColor == oldColor || x < 0 || x >= image.length || y < 0 || y >= image[x].length || getPixel(image, x, y) != oldColor) {
- return;
- }
-
- putPixel(image, x, y, newColor);
-
- /* Recursively check for horizontally & vertically adjacent coordinates */
- floodFill(image, x + 1, y, newColor, oldColor);
- floodFill(image, x - 1, y, newColor, oldColor);
- floodFill(image, x, y + 1, newColor, oldColor);
- floodFill(image, x, y - 1, newColor, oldColor);
-
- /* Recursively check for diagonally adjacent coordinates */
- floodFill(image, x + 1, y - 1, newColor, oldColor);
- floodFill(image, x - 1, y + 1, newColor, oldColor);
- floodFill(image, x + 1, y + 1, newColor, oldColor);
- floodFill(image, x - 1, y - 1, newColor, oldColor);
- }
-}
+package com.thealgorithms.backtracking;
+
+/**
+ * Java program for Flood fill algorithm.
+ * @author Akshay Dubey (Git-Akshay Dubey)
+ */
+public final class FloodFill {
+ private FloodFill() {
+ }
+
+ /**
+ * Get the color at the given coordinates of a 2D image
+ *
+ * @param image The image to be filled
+ * @param x The x coordinate of which color is to be obtained
+ * @param y The y coordinate of which color is to be obtained
+ */
+
+ public static int getPixel(final int[][] image, final int x, final int y) {
+ return image[x][y];
+ }
+
+ /**
+ * Put the color at the given coordinates of a 2D image
+ *
+ * @param image The image to be filled
+ * @param x The x coordinate at which color is to be filled
+ * @param y The y coordinate at which color is to be filled
+ */
+ public static void putPixel(final int[][] image, final int x, final int y, final int newColor) {
+ image[x][y] = newColor;
+ }
+
+ /**
+ * Fill the 2D image with new color
+ *
+ * @param image The image to be filled
+ * @param x The x coordinate at which color is to be filled
+ * @param y The y coordinate at which color is to be filled
+ * @param newColor The new color which to be filled in the image
+ * @param oldColor The old color which is to be replaced in the image
+ */
+ public static void floodFill(final int[][] image, final int x, final int y, final int newColor, final int oldColor) {
+ if (newColor == oldColor || x < 0 || x >= image.length || y < 0 || y >= image[x].length || getPixel(image, x, y) != oldColor) {
+ return;
+ }
+
+ putPixel(image, x, y, newColor);
+
+ /* Recursively check for horizontally & vertically adjacent coordinates */
+ floodFill(image, x + 1, y, newColor, oldColor);
+ floodFill(image, x - 1, y, newColor, oldColor);
+ floodFill(image, x, y + 1, newColor, oldColor);
+ floodFill(image, x, y - 1, newColor, oldColor);
+
+ /* Recursively check for diagonally adjacent coordinates */
+ floodFill(image, x + 1, y - 1, newColor, oldColor);
+ floodFill(image, x - 1, y + 1, newColor, oldColor);
+ floodFill(image, x + 1, y + 1, newColor, oldColor);
+ floodFill(image, x - 1, y - 1, newColor, oldColor);
+ }
+}
diff --git a/src/main/java/com/thealgorithms/backtracking/KnightsTour.java b/src/main/java/com/thealgorithms/backtracking/KnightsTour.java
index 2c2da659f3aa..b2212563625b 100644
--- a/src/main/java/com/thealgorithms/backtracking/KnightsTour.java
+++ b/src/main/java/com/thealgorithms/backtracking/KnightsTour.java
@@ -1,156 +1,156 @@
-package com.thealgorithms.backtracking;
-
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.List;
-
-/**
- * The KnightsTour class solves the Knight's Tour problem using backtracking.
- *
- * Problem Statement:
- * Given an N*N board with a knight placed on the first block, the knight must
- * move according to chess rules and visit each square on the board exactly once.
- * The class outputs the sequence of moves for the knight.
- *
- * Example:
- * Input: N = 8 (8x8 chess board)
- * Output: The sequence of numbers representing the order in which the knight visits each square.
- */
-public final class KnightsTour {
- private KnightsTour() {
- }
-
- // The size of the chess board (12x12 grid, with 2 extra rows/columns as a buffer around a 8x8 area)
- private static final int BASE = 12;
-
- // Possible moves for a knight in chess
- private static final int[][] MOVES = {
- {1, -2},
- {2, -1},
- {2, 1},
- {1, 2},
- {-1, 2},
- {-2, 1},
- {-2, -1},
- {-1, -2},
- };
-
- // Chess grid representing the board
- static int[][] grid;
-
- // Total number of cells the knight needs to visit
- static int total;
-
- /**
- * Resets the chess board to its initial state.
- * Initializes the grid with boundary cells marked as -1 and internal cells as 0.
- * Sets the total number of cells the knight needs to visit.
- */
- public static void resetBoard() {
- grid = new int[BASE][BASE];
- total = (BASE - 4) * (BASE - 4);
- for (int r = 0; r < BASE; r++) {
- for (int c = 0; c < BASE; c++) {
- if (r < 2 || r > BASE - 3 || c < 2 || c > BASE - 3) {
- grid[r][c] = -1; // Mark boundary cells
- }
- }
- }
- }
-
- /**
- * Recursive method to solve the Knight's Tour problem.
- *
- * @param row The current row of the knight
- * @param column The current column of the knight
- * @param count The current move number
- * @return True if a solution is found, False otherwise
- */
- static boolean solve(int row, int column, int count) {
- if (count > total) {
- return true;
- }
-
- List neighbor = neighbors(row, column);
-
- if (neighbor.isEmpty() && count != total) {
- return false;
- }
-
- // Sort neighbors by Warnsdorff's rule (fewest onward moves)
- neighbor.sort(Comparator.comparingInt(a -> a[2]));
-
- for (int[] nb : neighbor) {
- int nextRow = nb[0];
- int nextCol = nb[1];
- grid[nextRow][nextCol] = count;
- if (!orphanDetected(count, nextRow, nextCol) && solve(nextRow, nextCol, count + 1)) {
- return true;
- }
- grid[nextRow][nextCol] = 0; // Backtrack
- }
-
- return false;
- }
-
- /**
- * Returns a list of valid neighboring cells where the knight can move.
- *
- * @param row The current row of the knight
- * @param column The current column of the knight
- * @return A list of arrays representing valid moves, where each array contains:
- * {nextRow, nextCol, numberOfPossibleNextMoves}
- */
- static List neighbors(int row, int column) {
- List neighbour = new ArrayList<>();
-
- for (int[] m : MOVES) {
- int x = m[0];
- int y = m[1];
- if (row + y >= 0 && row + y < BASE && column + x >= 0 && column + x < BASE && grid[row + y][column + x] == 0) {
- int num = countNeighbors(row + y, column + x);
- neighbour.add(new int[] {row + y, column + x, num});
- }
- }
- return neighbour;
- }
-
- /**
- * Counts the number of possible valid moves for a knight from a given position.
- *
- * @param row The row of the current position
- * @param column The column of the current position
- * @return The number of valid neighboring moves
- */
- static int countNeighbors(int row, int column) {
- int num = 0;
- for (int[] m : MOVES) {
- int x = m[0];
- int y = m[1];
- if (row + y >= 0 && row + y < BASE && column + x >= 0 && column + x < BASE && grid[row + y][column + x] == 0) {
- num++;
- }
- }
- return num;
- }
-
- /**
- * Detects if moving to a given position will create an orphan (a position with no further valid moves).
- *
- * @param count The current move number
- * @param row The row of the current position
- * @param column The column of the current position
- * @return True if an orphan is detected, False otherwise
- */
- static boolean orphanDetected(int count, int row, int column) {
- if (count < total - 1) {
- List neighbor = neighbors(row, column);
- for (int[] nb : neighbor) {
- if (countNeighbors(nb[0], nb[1]) == 0) {
- return true;
- }
- }
- }
- return false;
- }
-}
+package com.thealgorithms.backtracking;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * The KnightsTour class solves the Knight's Tour problem using backtracking.
+ *
+ * Problem Statement:
+ * Given an N*N board with a knight placed on the first block, the knight must
+ * move according to chess rules and visit each square on the board exactly once.
+ * The class outputs the sequence of moves for the knight.
+ *
+ * Example:
+ * Input: N = 8 (8x8 chess board)
+ * Output: The sequence of numbers representing the order in which the knight visits each square.
+ */
+public final class KnightsTour {
+ private KnightsTour() {
+ }
+
+ // The size of the chess board (12x12 grid, with 2 extra rows/columns as a buffer around a 8x8 area)
+ private static final int BASE = 12;
+
+ // Possible moves for a knight in chess
+ private static final int[][] MOVES = {
+ {1, -2},
+ {2, -1},
+ {2, 1},
+ {1, 2},
+ {-1, 2},
+ {-2, 1},
+ {-2, -1},
+ {-1, -2},
+ };
+
+ // Chess grid representing the board
+ static int[][] grid;
+
+ // Total number of cells the knight needs to visit
+ static int total;
+
+ /**
+ * Resets the chess board to its initial state.
+ * Initializes the grid with boundary cells marked as -1 and internal cells as 0.
+ * Sets the total number of cells the knight needs to visit.
+ */
+ public static void resetBoard() {
+ grid = new int[BASE][BASE];
+ total = (BASE - 4) * (BASE - 4);
+ for (int r = 0; r < BASE; r++) {
+ for (int c = 0; c < BASE; c++) {
+ if (r < 2 || r > BASE - 3 || c < 2 || c > BASE - 3) {
+ grid[r][c] = -1; // Mark boundary cells
+ }
+ }
+ }
+ }
+
+ /**
+ * Recursive method to solve the Knight's Tour problem.
+ *
+ * @param row The current row of the knight
+ * @param column The current column of the knight
+ * @param count The current move number
+ * @return True if a solution is found, False otherwise
+ */
+ static boolean solve(int row, int column, int count) {
+ if (count > total) {
+ return true;
+ }
+
+ List neighbor = neighbors(row, column);
+
+ if (neighbor.isEmpty() && count != total) {
+ return false;
+ }
+
+ // Sort neighbors by Warnsdorff's rule (fewest onward moves)
+ neighbor.sort(Comparator.comparingInt(a -> a[2]));
+
+ for (int[] nb : neighbor) {
+ int nextRow = nb[0];
+ int nextCol = nb[1];
+ grid[nextRow][nextCol] = count;
+ if (!orphanDetected(count, nextRow, nextCol) && solve(nextRow, nextCol, count + 1)) {
+ return true;
+ }
+ grid[nextRow][nextCol] = 0; // Backtrack
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns a list of valid neighboring cells where the knight can move.
+ *
+ * @param row The current row of the knight
+ * @param column The current column of the knight
+ * @return A list of arrays representing valid moves, where each array contains:
+ * {nextRow, nextCol, numberOfPossibleNextMoves}
+ */
+ static List neighbors(int row, int column) {
+ List neighbour = new ArrayList<>();
+
+ for (int[] m : MOVES) {
+ int x = m[0];
+ int y = m[1];
+ if (row + y >= 0 && row + y < BASE && column + x >= 0 && column + x < BASE && grid[row + y][column + x] == 0) {
+ int num = countNeighbors(row + y, column + x);
+ neighbour.add(new int[] {row + y, column + x, num});
+ }
+ }
+ return neighbour;
+ }
+
+ /**
+ * Counts the number of possible valid moves for a knight from a given position.
+ *
+ * @param row The row of the current position
+ * @param column The column of the current position
+ * @return The number of valid neighboring moves
+ */
+ static int countNeighbors(int row, int column) {
+ int num = 0;
+ for (int[] m : MOVES) {
+ int x = m[0];
+ int y = m[1];
+ if (row + y >= 0 && row + y < BASE && column + x >= 0 && column + x < BASE && grid[row + y][column + x] == 0) {
+ num++;
+ }
+ }
+ return num;
+ }
+
+ /**
+ * Detects if moving to a given position will create an orphan (a position with no further valid moves).
+ *
+ * @param count The current move number
+ * @param row The row of the current position
+ * @param column The column of the current position
+ * @return True if an orphan is detected, False otherwise
+ */
+ static boolean orphanDetected(int count, int row, int column) {
+ if (count < total - 1) {
+ List neighbor = neighbors(row, column);
+ for (int[] nb : neighbor) {
+ if (countNeighbors(nb[0], nb[1]) == 0) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/backtracking/MColoring.java b/src/main/java/com/thealgorithms/backtracking/MColoring.java
index d0188dfd13aa..ac96e6398ad3 100644
--- a/src/main/java/com/thealgorithms/backtracking/MColoring.java
+++ b/src/main/java/com/thealgorithms/backtracking/MColoring.java
@@ -1,96 +1,96 @@
-package com.thealgorithms.backtracking;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.Queue;
-import java.util.Set;
-
-/**
- * Node class represents a graph node. Each node is associated with a color
- * (initially 1) and contains a set of edges representing its adjacent nodes.
- *
- * @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi)
- */
-class Node {
- int color = 1; // Initial color for each node
- Set edges = new HashSet(); // Set of edges representing adjacent nodes
-}
-
-/**
- * MColoring class solves the M-Coloring problem where the goal is to determine
- * if it's possible to color a graph using at most M colors such that no two
- * adjacent nodes have the same color.
- */
-public final class MColoring {
-
- private MColoring() {
- } // Prevent instantiation of utility class
-
- /**
- * Determines whether it is possible to color the graph using at most M colors.
- *
- * @param nodes List of nodes representing the graph.
- * @param n The total number of nodes in the graph.
- * @param m The maximum number of allowed colors.
- * @return true if the graph can be colored using M colors, false otherwise.
- */
- static boolean isColoringPossible(ArrayList nodes, int n, int m) {
-
- // Visited array keeps track of whether each node has been processed.
- ArrayList visited = new ArrayList();
- for (int i = 0; i < n + 1; i++) {
- visited.add(0); // Initialize all nodes as unvisited (0)
- }
-
- // The number of colors used so far (initially set to 1, since all nodes
- // start with color 1).
- int maxColors = 1;
-
- // Loop through all the nodes to ensure every node is visited, in case the
- // graph is disconnected.
- for (int sv = 1; sv <= n; sv++) {
- if (visited.get(sv) > 0) {
- continue; // Skip nodes that are already visited
- }
-
- // If the node is unvisited, mark it as visited and add it to the queue for BFS.
- visited.set(sv, 1);
- Queue q = new LinkedList<>();
- q.add(sv);
-
- // Perform BFS to process all nodes and their adjacent nodes
- while (q.size() != 0) {
- int top = q.peek(); // Get the current node from the queue
- q.remove();
-
- // Check all adjacent nodes of the current node
- for (int it : nodes.get(top).edges) {
-
- // If the adjacent node has the same color as the current node, increment its
- // color to avoid conflict.
- if (nodes.get(top).color == nodes.get(it).color) {
- nodes.get(it).color += 1;
- }
-
- // Keep track of the maximum number of colors used so far
- maxColors = Math.max(maxColors, Math.max(nodes.get(top).color, nodes.get(it).color));
-
- // If the number of colors used exceeds the allowed limit M, return false.
- if (maxColors > m) {
- return false;
- }
-
- // If the adjacent node hasn't been visited yet, mark it as visited and add it
- // to the queue for further processing.
- if (visited.get(it) == 0) {
- visited.set(it, 1);
- q.add(it);
- }
- }
- }
- }
-
- return true; // Possible to color the entire graph with M or fewer colors.
- }
-}
+package com.thealgorithms.backtracking;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Queue;
+import java.util.Set;
+
+/**
+ * Node class represents a graph node. Each node is associated with a color
+ * (initially 1) and contains a set of edges representing its adjacent nodes.
+ *
+ * @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi)
+ */
+class Node {
+ int color = 1; // Initial color for each node
+ Set edges = new HashSet(); // Set of edges representing adjacent nodes
+}
+
+/**
+ * MColoring class solves the M-Coloring problem where the goal is to determine
+ * if it's possible to color a graph using at most M colors such that no two
+ * adjacent nodes have the same color.
+ */
+public final class MColoring {
+
+ private MColoring() {
+ } // Prevent instantiation of utility class
+
+ /**
+ * Determines whether it is possible to color the graph using at most M colors.
+ *
+ * @param nodes List of nodes representing the graph.
+ * @param n The total number of nodes in the graph.
+ * @param m The maximum number of allowed colors.
+ * @return true if the graph can be colored using M colors, false otherwise.
+ */
+ static boolean isColoringPossible(ArrayList nodes, int n, int m) {
+
+ // Visited array keeps track of whether each node has been processed.
+ ArrayList visited = new ArrayList();
+ for (int i = 0; i < n + 1; i++) {
+ visited.add(0); // Initialize all nodes as unvisited (0)
+ }
+
+ // The number of colors used so far (initially set to 1, since all nodes
+ // start with color 1).
+ int maxColors = 1;
+
+ // Loop through all the nodes to ensure every node is visited, in case the
+ // graph is disconnected.
+ for (int sv = 1; sv <= n; sv++) {
+ if (visited.get(sv) > 0) {
+ continue; // Skip nodes that are already visited
+ }
+
+ // If the node is unvisited, mark it as visited and add it to the queue for BFS.
+ visited.set(sv, 1);
+ Queue q = new LinkedList<>();
+ q.add(sv);
+
+ // Perform BFS to process all nodes and their adjacent nodes
+ while (q.size() != 0) {
+ int top = q.peek(); // Get the current node from the queue
+ q.remove();
+
+ // Check all adjacent nodes of the current node
+ for (int it : nodes.get(top).edges) {
+
+ // If the adjacent node has the same color as the current node, increment its
+ // color to avoid conflict.
+ if (nodes.get(top).color == nodes.get(it).color) {
+ nodes.get(it).color += 1;
+ }
+
+ // Keep track of the maximum number of colors used so far
+ maxColors = Math.max(maxColors, Math.max(nodes.get(top).color, nodes.get(it).color));
+
+ // If the number of colors used exceeds the allowed limit M, return false.
+ if (maxColors > m) {
+ return false;
+ }
+
+ // If the adjacent node hasn't been visited yet, mark it as visited and add it
+ // to the queue for further processing.
+ if (visited.get(it) == 0) {
+ visited.set(it, 1);
+ q.add(it);
+ }
+ }
+ }
+ }
+
+ return true; // Possible to color the entire graph with M or fewer colors.
+ }
+}
diff --git a/src/main/java/com/thealgorithms/backtracking/MazeRecursion.java b/src/main/java/com/thealgorithms/backtracking/MazeRecursion.java
index 8247172e7ee0..8945441055fb 100644
--- a/src/main/java/com/thealgorithms/backtracking/MazeRecursion.java
+++ b/src/main/java/com/thealgorithms/backtracking/MazeRecursion.java
@@ -1,125 +1,125 @@
-package com.thealgorithms.backtracking;
-
-/**
- * This class contains methods to solve a maze using recursive backtracking.
- * The maze is represented as a 2D array where walls, paths, and visited/dead
- * ends are marked with different integers.
- *
- * The goal is to find a path from a starting position to the target position
- * (map[6][5]) while navigating through the maze.
- */
-public final class MazeRecursion {
-
- private MazeRecursion() {
- }
-
- /**
- * This method solves the maze using the "down -> right -> up -> left"
- * movement strategy.
- *
- * @param map The 2D array representing the maze (walls, paths, etc.)
- * @return The solved maze with paths marked, or null if no solution exists.
- */
- public static int[][] solveMazeUsingFirstStrategy(int[][] map) {
- if (setWay(map, 1, 1)) {
- return map;
- }
- return null;
- }
-
- /**
- * This method solves the maze using the "up -> right -> down -> left"
- * movement strategy.
- *
- * @param map The 2D array representing the maze (walls, paths, etc.)
- * @return The solved maze with paths marked, or null if no solution exists.
- */
- public static int[][] solveMazeUsingSecondStrategy(int[][] map) {
- if (setWay2(map, 1, 1)) {
- return map;
- }
- return null;
- }
-
- /**
- * Attempts to find a path through the maze using a "down -> right -> up -> left"
- * movement strategy. The path is marked with '2' for valid paths and '3' for dead ends.
- *
- * @param map The 2D array representing the maze (walls, paths, etc.)
- * @param i The current x-coordinate of the ball (row index)
- * @param j The current y-coordinate of the ball (column index)
- * @return True if a path is found to (6,5), otherwise false
- */
- private static boolean setWay(int[][] map, int i, int j) {
- if (map[6][5] == 2) {
- return true;
- }
-
- // If the current position is unvisited (0), explore it
- if (map[i][j] == 0) {
- // Mark the current position as '2'
- map[i][j] = 2;
-
- // Move down
- if (setWay(map, i + 1, j)) {
- return true;
- }
- // Move right
- else if (setWay(map, i, j + 1)) {
- return true;
- }
- // Move up
- else if (setWay(map, i - 1, j)) {
- return true;
- }
- // Move left
- else if (setWay(map, i, j - 1)) {
- return true;
- }
-
- map[i][j] = 3; // Mark as dead end (3) if no direction worked
- return false;
- }
- return false;
- }
-
- /**
- * Attempts to find a path through the maze using an alternative movement
- * strategy "up -> right -> down -> left".
- *
- * @param map The 2D array representing the maze (walls, paths, etc.)
- * @param i The current x-coordinate of the ball (row index)
- * @param j The current y-coordinate of the ball (column index)
- * @return True if a path is found to (6,5), otherwise false
- */
- private static boolean setWay2(int[][] map, int i, int j) {
- if (map[6][5] == 2) {
- return true;
- }
-
- if (map[i][j] == 0) {
- map[i][j] = 2;
-
- // Move up
- if (setWay2(map, i - 1, j)) {
- return true;
- }
- // Move right
- else if (setWay2(map, i, j + 1)) {
- return true;
- }
- // Move down
- else if (setWay2(map, i + 1, j)) {
- return true;
- }
- // Move left
- else if (setWay2(map, i, j - 1)) {
- return true;
- }
-
- map[i][j] = 3; // Mark as dead end (3) if no direction worked
- return false;
- }
- return false;
- }
-}
+package com.thealgorithms.backtracking;
+
+/**
+ * This class contains methods to solve a maze using recursive backtracking.
+ * The maze is represented as a 2D array where walls, paths, and visited/dead
+ * ends are marked with different integers.
+ *
+ * The goal is to find a path from a starting position to the target position
+ * (map[6][5]) while navigating through the maze.
+ */
+public final class MazeRecursion {
+
+ private MazeRecursion() {
+ }
+
+ /**
+ * This method solves the maze using the "down -> right -> up -> left"
+ * movement strategy.
+ *
+ * @param map The 2D array representing the maze (walls, paths, etc.)
+ * @return The solved maze with paths marked, or null if no solution exists.
+ */
+ public static int[][] solveMazeUsingFirstStrategy(int[][] map) {
+ if (setWay(map, 1, 1)) {
+ return map;
+ }
+ return null;
+ }
+
+ /**
+ * This method solves the maze using the "up -> right -> down -> left"
+ * movement strategy.
+ *
+ * @param map The 2D array representing the maze (walls, paths, etc.)
+ * @return The solved maze with paths marked, or null if no solution exists.
+ */
+ public static int[][] solveMazeUsingSecondStrategy(int[][] map) {
+ if (setWay2(map, 1, 1)) {
+ return map;
+ }
+ return null;
+ }
+
+ /**
+ * Attempts to find a path through the maze using a "down -> right -> up -> left"
+ * movement strategy. The path is marked with '2' for valid paths and '3' for dead ends.
+ *
+ * @param map The 2D array representing the maze (walls, paths, etc.)
+ * @param i The current x-coordinate of the ball (row index)
+ * @param j The current y-coordinate of the ball (column index)
+ * @return True if a path is found to (6,5), otherwise false
+ */
+ private static boolean setWay(int[][] map, int i, int j) {
+ if (map[6][5] == 2) {
+ return true;
+ }
+
+ // If the current position is unvisited (0), explore it
+ if (map[i][j] == 0) {
+ // Mark the current position as '2'
+ map[i][j] = 2;
+
+ // Move down
+ if (setWay(map, i + 1, j)) {
+ return true;
+ }
+ // Move right
+ else if (setWay(map, i, j + 1)) {
+ return true;
+ }
+ // Move up
+ else if (setWay(map, i - 1, j)) {
+ return true;
+ }
+ // Move left
+ else if (setWay(map, i, j - 1)) {
+ return true;
+ }
+
+ map[i][j] = 3; // Mark as dead end (3) if no direction worked
+ return false;
+ }
+ return false;
+ }
+
+ /**
+ * Attempts to find a path through the maze using an alternative movement
+ * strategy "up -> right -> down -> left".
+ *
+ * @param map The 2D array representing the maze (walls, paths, etc.)
+ * @param i The current x-coordinate of the ball (row index)
+ * @param j The current y-coordinate of the ball (column index)
+ * @return True if a path is found to (6,5), otherwise false
+ */
+ private static boolean setWay2(int[][] map, int i, int j) {
+ if (map[6][5] == 2) {
+ return true;
+ }
+
+ if (map[i][j] == 0) {
+ map[i][j] = 2;
+
+ // Move up
+ if (setWay2(map, i - 1, j)) {
+ return true;
+ }
+ // Move right
+ else if (setWay2(map, i, j + 1)) {
+ return true;
+ }
+ // Move down
+ else if (setWay2(map, i + 1, j)) {
+ return true;
+ }
+ // Move left
+ else if (setWay2(map, i, j - 1)) {
+ return true;
+ }
+
+ map[i][j] = 3; // Mark as dead end (3) if no direction worked
+ return false;
+ }
+ return false;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/backtracking/NQueens.java b/src/main/java/com/thealgorithms/backtracking/NQueens.java
index 1a8e453e34cb..2120d69265e6 100644
--- a/src/main/java/com/thealgorithms/backtracking/NQueens.java
+++ b/src/main/java/com/thealgorithms/backtracking/NQueens.java
@@ -1,111 +1,111 @@
-package com.thealgorithms.backtracking;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Problem statement: Given a N x N chess board. Return all arrangements in
- * which N queens can be placed on the board such no two queens attack each
- * other. Ex. N = 6 Solution= There are 4 possible ways Arrangement: 1 ".Q....",
- * "...Q..", ".....Q", "Q.....", "..Q...", "....Q."
- *
- * Arrangement: 2 "..Q...", ".....Q", ".Q....", "....Q.", "Q.....", "...Q.."
- *
- * Arrangement: 3 "...Q..", "Q.....", "....Q.", ".Q....", ".....Q", "..Q..."
- *
- * Arrangement: 4 "....Q.", "..Q...", "Q.....", ".....Q", "...Q..", ".Q...."
- *
- * Solution: Brute Force approach:
- *
- * Generate all possible arrangement to place N queens on N*N board. Check each
- * board if queens are placed safely. If it is safe, include arrangement in
- * solution set. Otherwise, ignore it
- *
- * Optimized solution: This can be solved using backtracking in below steps
- *
- * Start with first column and place queen on first row Try placing queen in a
- * row on second column If placing second queen in second column attacks any of
- * the previous queens, change the row in second column otherwise move to next
- * column and try to place next queen In case if there is no rows where a queen
- * can be placed such that it doesn't attack previous queens, then go back to
- * previous column and change row of previous queen. Keep doing this until last
- * queen is not placed safely. If there is no such way then return an empty list
- * as solution
- */
-public final class NQueens {
- private NQueens() {
- }
-
- public static List> getNQueensArrangements(int queens) {
- List> arrangements = new ArrayList<>();
- getSolution(queens, arrangements, new int[queens], 0);
- return arrangements;
- }
-
- public static void placeQueens(final int queens) {
- List> arrangements = new ArrayList>();
- getSolution(queens, arrangements, new int[queens], 0);
- if (arrangements.isEmpty()) {
- System.out.println("There is no way to place " + queens + " queens on board of size " + queens + "x" + queens);
- } else {
- System.out.println("Arrangement for placing " + queens + " queens");
- }
- for (List arrangement : arrangements) {
- arrangement.forEach(System.out::println);
- System.out.println();
- }
- }
-
- /**
- * This is backtracking function which tries to place queen recursively
- *
- * @param boardSize: size of chess board
- * @param solutions: this holds all possible arrangements
- * @param columns: columns[i] = rowId where queen is placed in ith column.
- * @param columnIndex: This is the column in which queen is being placed
- */
- private static void getSolution(int boardSize, List> solutions, int[] columns, int columnIndex) {
- if (columnIndex == boardSize) {
- // this means that all queens have been placed
- List sol = new ArrayList();
- for (int i = 0; i < boardSize; i++) {
- StringBuilder sb = new StringBuilder();
- for (int j = 0; j < boardSize; j++) {
- sb.append(j == columns[i] ? "Q" : ".");
- }
- sol.add(sb.toString());
- }
- solutions.add(sol);
- return;
- }
-
- // This loop tries to place queen in a row one by one
- for (int rowIndex = 0; rowIndex < boardSize; rowIndex++) {
- columns[columnIndex] = rowIndex;
- if (isPlacedCorrectly(columns, rowIndex, columnIndex)) {
- // If queen is placed successfully at rowIndex in column=columnIndex then try
- // placing queen in next column
- getSolution(boardSize, solutions, columns, columnIndex + 1);
- }
- }
- }
-
- /**
- * This function checks if queen can be placed at row = rowIndex in column =
- * columnIndex safely
- *
- * @param columns: columns[i] = rowId where queen is placed in ith column.
- * @param rowIndex: row in which queen has to be placed
- * @param columnIndex: column in which queen is being placed
- * @return true: if queen can be placed safely false: otherwise
- */
- private static boolean isPlacedCorrectly(int[] columns, int rowIndex, int columnIndex) {
- for (int i = 0; i < columnIndex; i++) {
- int diff = Math.abs(columns[i] - rowIndex);
- if (diff == 0 || columnIndex - i == diff) {
- return false;
- }
- }
- return true;
- }
-}
+package com.thealgorithms.backtracking;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Problem statement: Given a N x N chess board. Return all arrangements in
+ * which N queens can be placed on the board such no two queens attack each
+ * other. Ex. N = 6 Solution= There are 4 possible ways Arrangement: 1 ".Q....",
+ * "...Q..", ".....Q", "Q.....", "..Q...", "....Q."
+ *
+ * Arrangement: 2 "..Q...", ".....Q", ".Q....", "....Q.", "Q.....", "...Q.."
+ *
+ * Arrangement: 3 "...Q..", "Q.....", "....Q.", ".Q....", ".....Q", "..Q..."
+ *
+ * Arrangement: 4 "....Q.", "..Q...", "Q.....", ".....Q", "...Q..", ".Q...."
+ *
+ * Solution: Brute Force approach:
+ *
+ * Generate all possible arrangement to place N queens on N*N board. Check each
+ * board if queens are placed safely. If it is safe, include arrangement in
+ * solution set. Otherwise, ignore it
+ *
+ * Optimized solution: This can be solved using backtracking in below steps
+ *
+ * Start with first column and place queen on first row Try placing queen in a
+ * row on second column If placing second queen in second column attacks any of
+ * the previous queens, change the row in second column otherwise move to next
+ * column and try to place next queen In case if there is no rows where a queen
+ * can be placed such that it doesn't attack previous queens, then go back to
+ * previous column and change row of previous queen. Keep doing this until last
+ * queen is not placed safely. If there is no such way then return an empty list
+ * as solution
+ */
+public final class NQueens {
+ private NQueens() {
+ }
+
+ public static List> getNQueensArrangements(int queens) {
+ List> arrangements = new ArrayList<>();
+ getSolution(queens, arrangements, new int[queens], 0);
+ return arrangements;
+ }
+
+ public static void placeQueens(final int queens) {
+ List> arrangements = new ArrayList>();
+ getSolution(queens, arrangements, new int[queens], 0);
+ if (arrangements.isEmpty()) {
+ System.out.println("There is no way to place " + queens + " queens on board of size " + queens + "x" + queens);
+ } else {
+ System.out.println("Arrangement for placing " + queens + " queens");
+ }
+ for (List arrangement : arrangements) {
+ arrangement.forEach(System.out::println);
+ System.out.println();
+ }
+ }
+
+ /**
+ * This is backtracking function which tries to place queen recursively
+ *
+ * @param boardSize: size of chess board
+ * @param solutions: this holds all possible arrangements
+ * @param columns: columns[i] = rowId where queen is placed in ith column.
+ * @param columnIndex: This is the column in which queen is being placed
+ */
+ private static void getSolution(int boardSize, List> solutions, int[] columns, int columnIndex) {
+ if (columnIndex == boardSize) {
+ // this means that all queens have been placed
+ List sol = new ArrayList();
+ for (int i = 0; i < boardSize; i++) {
+ StringBuilder sb = new StringBuilder();
+ for (int j = 0; j < boardSize; j++) {
+ sb.append(j == columns[i] ? "Q" : ".");
+ }
+ sol.add(sb.toString());
+ }
+ solutions.add(sol);
+ return;
+ }
+
+ // This loop tries to place queen in a row one by one
+ for (int rowIndex = 0; rowIndex < boardSize; rowIndex++) {
+ columns[columnIndex] = rowIndex;
+ if (isPlacedCorrectly(columns, rowIndex, columnIndex)) {
+ // If queen is placed successfully at rowIndex in column=columnIndex then try
+ // placing queen in next column
+ getSolution(boardSize, solutions, columns, columnIndex + 1);
+ }
+ }
+ }
+
+ /**
+ * This function checks if queen can be placed at row = rowIndex in column =
+ * columnIndex safely
+ *
+ * @param columns: columns[i] = rowId where queen is placed in ith column.
+ * @param rowIndex: row in which queen has to be placed
+ * @param columnIndex: column in which queen is being placed
+ * @return true: if queen can be placed safely false: otherwise
+ */
+ private static boolean isPlacedCorrectly(int[] columns, int rowIndex, int columnIndex) {
+ for (int i = 0; i < columnIndex; i++) {
+ int diff = Math.abs(columns[i] - rowIndex);
+ if (diff == 0 || columnIndex - i == diff) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/backtracking/ParenthesesGenerator.java b/src/main/java/com/thealgorithms/backtracking/ParenthesesGenerator.java
index bf93f946ab7b..c46efe4a8f94 100644
--- a/src/main/java/com/thealgorithms/backtracking/ParenthesesGenerator.java
+++ b/src/main/java/com/thealgorithms/backtracking/ParenthesesGenerator.java
@@ -1,50 +1,50 @@
-package com.thealgorithms.backtracking;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * This class generates all valid combinations of parentheses for a given number of pairs using backtracking.
- */
-public final class ParenthesesGenerator {
- private ParenthesesGenerator() {
- }
-
- /**
- * Generates all valid combinations of parentheses for a given number of pairs.
- *
- * @param n The number of pairs of parentheses.
- * @return A list of strings representing valid combinations of parentheses.
- * @throws IllegalArgumentException if n is less than 0.
- */
- public static List generateParentheses(final int n) {
- if (n < 0) {
- throw new IllegalArgumentException("The number of pairs of parentheses cannot be negative");
- }
- List result = new ArrayList<>();
- generateParenthesesHelper(result, "", 0, 0, n);
- return result;
- }
-
- /**
- * Helper function for generating all valid combinations of parentheses recursively.
- *
- * @param result The list to store valid combinations.
- * @param current The current combination being formed.
- * @param open The number of open parentheses.
- * @param close The number of closed parentheses.
- * @param n The total number of pairs of parentheses.
- */
- private static void generateParenthesesHelper(List result, final String current, final int open, final int close, final int n) {
- if (current.length() == n * 2) {
- result.add(current);
- return;
- }
- if (open < n) {
- generateParenthesesHelper(result, current + "(", open + 1, close, n);
- }
- if (close < open) {
- generateParenthesesHelper(result, current + ")", open, close + 1, n);
- }
- }
-}
+package com.thealgorithms.backtracking;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class generates all valid combinations of parentheses for a given number of pairs using backtracking.
+ */
+public final class ParenthesesGenerator {
+ private ParenthesesGenerator() {
+ }
+
+ /**
+ * Generates all valid combinations of parentheses for a given number of pairs.
+ *
+ * @param n The number of pairs of parentheses.
+ * @return A list of strings representing valid combinations of parentheses.
+ * @throws IllegalArgumentException if n is less than 0.
+ */
+ public static List generateParentheses(final int n) {
+ if (n < 0) {
+ throw new IllegalArgumentException("The number of pairs of parentheses cannot be negative");
+ }
+ List result = new ArrayList<>();
+ generateParenthesesHelper(result, "", 0, 0, n);
+ return result;
+ }
+
+ /**
+ * Helper function for generating all valid combinations of parentheses recursively.
+ *
+ * @param result The list to store valid combinations.
+ * @param current The current combination being formed.
+ * @param open The number of open parentheses.
+ * @param close The number of closed parentheses.
+ * @param n The total number of pairs of parentheses.
+ */
+ private static void generateParenthesesHelper(List result, final String current, final int open, final int close, final int n) {
+ if (current.length() == n * 2) {
+ result.add(current);
+ return;
+ }
+ if (open < n) {
+ generateParenthesesHelper(result, current + "(", open + 1, close, n);
+ }
+ if (close < open) {
+ generateParenthesesHelper(result, current + ")", open, close + 1, n);
+ }
+ }
+}
diff --git a/src/main/java/com/thealgorithms/backtracking/Permutation.java b/src/main/java/com/thealgorithms/backtracking/Permutation.java
index 21d26e53980f..a4e8f2ac8c14 100644
--- a/src/main/java/com/thealgorithms/backtracking/Permutation.java
+++ b/src/main/java/com/thealgorithms/backtracking/Permutation.java
@@ -1,57 +1,57 @@
-package com.thealgorithms.backtracking;
-
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * Finds all permutations of given array
- * @author Alan Piao (Git-Alan Piao)
- */
-public final class Permutation {
- private Permutation() {
- }
-
- /**
- * Find all permutations of given array using backtracking
- * @param arr the array.
- * @param the type of elements in the array.
- * @return a list of all permutations.
- */
- public static List permutation(T[] arr) {
- T[] array = arr.clone();
- List result = new LinkedList<>();
- backtracking(array, 0, result);
- return result;
- }
-
- /**
- * Backtrack all possible orders of a given array
- * @param arr the array.
- * @param index the starting index.
- * @param result the list contains all permutations.
- * @param the type of elements in the array.
- */
- private static void backtracking(T[] arr, int index, List result) {
- if (index == arr.length) {
- result.add(arr.clone());
- }
- for (int i = index; i < arr.length; i++) {
- swap(index, i, arr);
- backtracking(arr, index + 1, result);
- swap(index, i, arr);
- }
- }
-
- /**
- * Swap two element for a given array
- * @param a first index
- * @param b second index
- * @param arr the array.
- * @param the type of elements in the array.
- */
- private static void swap(int a, int b, T[] arr) {
- T temp = arr[a];
- arr[a] = arr[b];
- arr[b] = temp;
- }
-}
+package com.thealgorithms.backtracking;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Finds all permutations of given array
+ * @author Alan Piao (Git-Alan Piao)
+ */
+public final class Permutation {
+ private Permutation() {
+ }
+
+ /**
+ * Find all permutations of given array using backtracking
+ * @param arr the array.
+ * @param the type of elements in the array.
+ * @return a list of all permutations.
+ */
+ public static List permutation(T[] arr) {
+ T[] array = arr.clone();
+ List result = new LinkedList<>();
+ backtracking(array, 0, result);
+ return result;
+ }
+
+ /**
+ * Backtrack all possible orders of a given array
+ * @param arr the array.
+ * @param index the starting index.
+ * @param result the list contains all permutations.
+ * @param the type of elements in the array.
+ */
+ private static void backtracking(T[] arr, int index, List result) {
+ if (index == arr.length) {
+ result.add(arr.clone());
+ }
+ for (int i = index; i < arr.length; i++) {
+ swap(index, i, arr);
+ backtracking(arr, index + 1, result);
+ swap(index, i, arr);
+ }
+ }
+
+ /**
+ * Swap two element for a given array
+ * @param a first index
+ * @param b second index
+ * @param arr the array.
+ * @param the type of elements in the array.
+ */
+ private static void swap(int a, int b, T[] arr) {
+ T temp = arr[a];
+ arr[a] = arr[b];
+ arr[b] = temp;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/backtracking/PowerSum.java b/src/main/java/com/thealgorithms/backtracking/PowerSum.java
index b34ba660ebd7..0286446ebe1b 100644
--- a/src/main/java/com/thealgorithms/backtracking/PowerSum.java
+++ b/src/main/java/com/thealgorithms/backtracking/PowerSum.java
@@ -1,51 +1,51 @@
-package com.thealgorithms.backtracking;
-
-/**
- * Problem Statement:
- * Find the number of ways that a given integer, N, can be expressed as the sum of the Xth powers
- * of unique, natural numbers.
- * For example, if N=100 and X=3, we have to find all combinations of unique cubes adding up to 100.
- * The only solution is 1^3 + 2^3 + 3^3 + 4^3. Therefore, the output will be 1.
- *
- * N is represented by the parameter 'targetSum' in the code.
- * X is represented by the parameter 'power' in the code.
- */
-public class PowerSum {
-
- /**
- * Calculates the number of ways to express the target sum as a sum of Xth powers of unique natural numbers.
- *
- * @param targetSum The target sum to achieve (N in the problem statement)
- * @param power The power to raise natural numbers to (X in the problem statement)
- * @return The number of ways to express the target sum
- */
- public int powSum(int targetSum, int power) {
- // Special case: when both targetSum and power are zero
- if (targetSum == 0 && power == 0) {
- return 1; // by convention, one way to sum to zero: use nothing
- }
- return sumRecursive(targetSum, power, 1, 0);
- }
-
- /**
- * Recursively calculates the number of ways to express the remaining sum as a sum of Xth powers.
- *
- * @param remainingSum The remaining sum to achieve
- * @param power The power to raise natural numbers to (X in the problem statement)
- * @param currentNumber The current natural number being considered
- * @param currentSum The current sum of powered numbers
- * @return The number of valid combinations
- */
- private int sumRecursive(int remainingSum, int power, int currentNumber, int currentSum) {
- int newSum = currentSum + (int) Math.pow(currentNumber, power);
-
- if (newSum == remainingSum) {
- return 1;
- }
- if (newSum > remainingSum) {
- return 0;
- }
-
- return sumRecursive(remainingSum, power, currentNumber + 1, newSum) + sumRecursive(remainingSum, power, currentNumber + 1, currentSum);
- }
-}
+package com.thealgorithms.backtracking;
+
+/**
+ * Problem Statement:
+ * Find the number of ways that a given integer, N, can be expressed as the sum of the Xth powers
+ * of unique, natural numbers.
+ * For example, if N=100 and X=3, we have to find all combinations of unique cubes adding up to 100.
+ * The only solution is 1^3 + 2^3 + 3^3 + 4^3. Therefore, the output will be 1.
+ *
+ * N is represented by the parameter 'targetSum' in the code.
+ * X is represented by the parameter 'power' in the code.
+ */
+public class PowerSum {
+
+ /**
+ * Calculates the number of ways to express the target sum as a sum of Xth powers of unique natural numbers.
+ *
+ * @param targetSum The target sum to achieve (N in the problem statement)
+ * @param power The power to raise natural numbers to (X in the problem statement)
+ * @return The number of ways to express the target sum
+ */
+ public int powSum(int targetSum, int power) {
+ // Special case: when both targetSum and power are zero
+ if (targetSum == 0 && power == 0) {
+ return 1; // by convention, one way to sum to zero: use nothing
+ }
+ return sumRecursive(targetSum, power, 1, 0);
+ }
+
+ /**
+ * Recursively calculates the number of ways to express the remaining sum as a sum of Xth powers.
+ *
+ * @param remainingSum The remaining sum to achieve
+ * @param power The power to raise natural numbers to (X in the problem statement)
+ * @param currentNumber The current natural number being considered
+ * @param currentSum The current sum of powered numbers
+ * @return The number of valid combinations
+ */
+ private int sumRecursive(int remainingSum, int power, int currentNumber, int currentSum) {
+ int newSum = currentSum + (int) Math.pow(currentNumber, power);
+
+ if (newSum == remainingSum) {
+ return 1;
+ }
+ if (newSum > remainingSum) {
+ return 0;
+ }
+
+ return sumRecursive(remainingSum, power, currentNumber + 1, newSum) + sumRecursive(remainingSum, power, currentNumber + 1, currentSum);
+ }
+}
diff --git a/src/main/java/com/thealgorithms/backtracking/SubsequenceFinder.java b/src/main/java/com/thealgorithms/backtracking/SubsequenceFinder.java
index 4a159dbfe0b1..c5bc87e54b3c 100644
--- a/src/main/java/com/thealgorithms/backtracking/SubsequenceFinder.java
+++ b/src/main/java/com/thealgorithms/backtracking/SubsequenceFinder.java
@@ -1,54 +1,54 @@
-package com.thealgorithms.backtracking;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Class generates all subsequences for a given list of elements using backtracking
- */
-public final class SubsequenceFinder {
- private SubsequenceFinder() {
- }
-
- /**
- * Find all subsequences of given list using backtracking
- *
- * @param sequence a list of items on the basis of which we need to generate all subsequences
- * @param the type of elements in the array
- * @return a list of all subsequences
- */
- public static List> generateAll(List sequence) {
- List> allSubSequences = new ArrayList<>();
- if (sequence.isEmpty()) {
- allSubSequences.add(new ArrayList<>());
- return allSubSequences;
- }
- List currentSubsequence = new ArrayList<>();
- backtrack(sequence, currentSubsequence, 0, allSubSequences);
- return allSubSequences;
- }
-
- /**
- * Iterate through each branch of states
- * We know that each state has exactly two branching
- * It terminates when it reaches the end of the given sequence
- *
- * @param sequence all elements
- * @param currentSubsequence current subsequence
- * @param index current index
- * @param allSubSequences contains all sequences
- * @param the type of elements which we generate
- */
- private static void backtrack(List sequence, List currentSubsequence, final int index, List> allSubSequences) {
- assert index <= sequence.size();
- if (index == sequence.size()) {
- allSubSequences.add(new ArrayList<>(currentSubsequence));
- return;
- }
-
- backtrack(sequence, currentSubsequence, index + 1, allSubSequences);
- currentSubsequence.add(sequence.get(index));
- backtrack(sequence, currentSubsequence, index + 1, allSubSequences);
- currentSubsequence.removeLast();
- }
-}
+package com.thealgorithms.backtracking;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Class generates all subsequences for a given list of elements using backtracking
+ */
+public final class SubsequenceFinder {
+ private SubsequenceFinder() {
+ }
+
+ /**
+ * Find all subsequences of given list using backtracking
+ *
+ * @param sequence a list of items on the basis of which we need to generate all subsequences
+ * @param the type of elements in the array
+ * @return a list of all subsequences
+ */
+ public static List> generateAll(List sequence) {
+ List> allSubSequences = new ArrayList<>();
+ if (sequence.isEmpty()) {
+ allSubSequences.add(new ArrayList<>());
+ return allSubSequences;
+ }
+ List currentSubsequence = new ArrayList<>();
+ backtrack(sequence, currentSubsequence, 0, allSubSequences);
+ return allSubSequences;
+ }
+
+ /**
+ * Iterate through each branch of states
+ * We know that each state has exactly two branching
+ * It terminates when it reaches the end of the given sequence
+ *
+ * @param sequence all elements
+ * @param currentSubsequence current subsequence
+ * @param index current index
+ * @param allSubSequences contains all sequences
+ * @param the type of elements which we generate
+ */
+ private static void backtrack(List sequence, List currentSubsequence, final int index, List> allSubSequences) {
+ assert index <= sequence.size();
+ if (index == sequence.size()) {
+ allSubSequences.add(new ArrayList<>(currentSubsequence));
+ return;
+ }
+
+ backtrack(sequence, currentSubsequence, index + 1, allSubSequences);
+ currentSubsequence.add(sequence.get(index));
+ backtrack(sequence, currentSubsequence, index + 1, allSubSequences);
+ currentSubsequence.removeLast();
+ }
+}
diff --git a/src/main/java/com/thealgorithms/backtracking/SudokuSolver.java b/src/main/java/com/thealgorithms/backtracking/SudokuSolver.java
index 543fe2d02b50..f347fcfd19d1 100644
--- a/src/main/java/com/thealgorithms/backtracking/SudokuSolver.java
+++ b/src/main/java/com/thealgorithms/backtracking/SudokuSolver.java
@@ -1,157 +1,157 @@
-package com.thealgorithms.backtracking;
-
-/**
- * Sudoku Solver using Backtracking Algorithm
- * Solves a 9x9 Sudoku puzzle by filling empty cells with valid digits (1-9)
- *
- * @author Navadeep0007
- */
-public final class SudokuSolver {
-
- private static final int GRID_SIZE = 9;
- private static final int SUBGRID_SIZE = 3;
- private static final int EMPTY_CELL = 0;
-
- private SudokuSolver() {
- // Utility class, prevent instantiation
- }
-
- /**
- * Solves the Sudoku puzzle using backtracking
- *
- * @param board 9x9 Sudoku board with 0 representing empty cells
- * @return true if puzzle is solved, false otherwise
- */
- public static boolean solveSudoku(int[][] board) {
- if (board == null || board.length != GRID_SIZE) {
- return false;
- }
-
- for (int row = 0; row < GRID_SIZE; row++) {
- if (board[row].length != GRID_SIZE) {
- return false;
- }
- }
-
- return solve(board);
- }
-
- /**
- * Recursive helper method to solve the Sudoku puzzle
- *
- * @param board the Sudoku board
- * @return true if solution is found, false otherwise
- */
- private static boolean solve(int[][] board) {
- for (int row = 0; row < GRID_SIZE; row++) {
- for (int col = 0; col < GRID_SIZE; col++) {
- if (board[row][col] == EMPTY_CELL) {
- for (int number = 1; number <= GRID_SIZE; number++) {
- if (isValidPlacement(board, row, col, number)) {
- board[row][col] = number;
-
- if (solve(board)) {
- return true;
- }
-
- // Backtrack
- board[row][col] = EMPTY_CELL;
- }
- }
- return false;
- }
- }
- }
- return true;
- }
-
- /**
- * Checks if placing a number at given position is valid
- *
- * @param board the Sudoku board
- * @param row row index
- * @param col column index
- * @param number number to place (1-9)
- * @return true if placement is valid, false otherwise
- */
- private static boolean isValidPlacement(int[][] board, int row, int col, int number) {
- return !isNumberInRow(board, row, number) && !isNumberInColumn(board, col, number) && !isNumberInSubgrid(board, row, col, number);
- }
-
- /**
- * Checks if number exists in the given row
- *
- * @param board the Sudoku board
- * @param row row index
- * @param number number to check
- * @return true if number exists in row, false otherwise
- */
- private static boolean isNumberInRow(int[][] board, int row, int number) {
- for (int col = 0; col < GRID_SIZE; col++) {
- if (board[row][col] == number) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Checks if number exists in the given column
- *
- * @param board the Sudoku board
- * @param col column index
- * @param number number to check
- * @return true if number exists in column, false otherwise
- */
- private static boolean isNumberInColumn(int[][] board, int col, int number) {
- for (int row = 0; row < GRID_SIZE; row++) {
- if (board[row][col] == number) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Checks if number exists in the 3x3 subgrid
- *
- * @param board the Sudoku board
- * @param row row index
- * @param col column index
- * @param number number to check
- * @return true if number exists in subgrid, false otherwise
- */
- private static boolean isNumberInSubgrid(int[][] board, int row, int col, int number) {
- int subgridRowStart = row - row % SUBGRID_SIZE;
- int subgridColStart = col - col % SUBGRID_SIZE;
-
- for (int i = subgridRowStart; i < subgridRowStart + SUBGRID_SIZE; i++) {
- for (int j = subgridColStart; j < subgridColStart + SUBGRID_SIZE; j++) {
- if (board[i][j] == number) {
- return true;
- }
- }
- }
- return false;
- }
-
- /**
- * Prints the Sudoku board
- *
- * @param board the Sudoku board
- */
- public static void printBoard(int[][] board) {
- for (int row = 0; row < GRID_SIZE; row++) {
- if (row % SUBGRID_SIZE == 0 && row != 0) {
- System.out.println("-----------");
- }
- for (int col = 0; col < GRID_SIZE; col++) {
- if (col % SUBGRID_SIZE == 0 && col != 0) {
- System.out.print("|");
- }
- System.out.print(board[row][col]);
- }
- System.out.println();
- }
- }
-}
+package com.thealgorithms.backtracking;
+
+/**
+ * Sudoku Solver using Backtracking Algorithm
+ * Solves a 9x9 Sudoku puzzle by filling empty cells with valid digits (1-9)
+ *
+ * @author Navadeep0007
+ */
+public final class SudokuSolver {
+
+ private static final int GRID_SIZE = 9;
+ private static final int SUBGRID_SIZE = 3;
+ private static final int EMPTY_CELL = 0;
+
+ private SudokuSolver() {
+ // Utility class, prevent instantiation
+ }
+
+ /**
+ * Solves the Sudoku puzzle using backtracking
+ *
+ * @param board 9x9 Sudoku board with 0 representing empty cells
+ * @return true if puzzle is solved, false otherwise
+ */
+ public static boolean solveSudoku(int[][] board) {
+ if (board == null || board.length != GRID_SIZE) {
+ return false;
+ }
+
+ for (int row = 0; row < GRID_SIZE; row++) {
+ if (board[row].length != GRID_SIZE) {
+ return false;
+ }
+ }
+
+ return solve(board);
+ }
+
+ /**
+ * Recursive helper method to solve the Sudoku puzzle
+ *
+ * @param board the Sudoku board
+ * @return true if solution is found, false otherwise
+ */
+ private static boolean solve(int[][] board) {
+ for (int row = 0; row < GRID_SIZE; row++) {
+ for (int col = 0; col < GRID_SIZE; col++) {
+ if (board[row][col] == EMPTY_CELL) {
+ for (int number = 1; number <= GRID_SIZE; number++) {
+ if (isValidPlacement(board, row, col, number)) {
+ board[row][col] = number;
+
+ if (solve(board)) {
+ return true;
+ }
+
+ // Backtrack
+ board[row][col] = EMPTY_CELL;
+ }
+ }
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Checks if placing a number at given position is valid
+ *
+ * @param board the Sudoku board
+ * @param row row index
+ * @param col column index
+ * @param number number to place (1-9)
+ * @return true if placement is valid, false otherwise
+ */
+ private static boolean isValidPlacement(int[][] board, int row, int col, int number) {
+ return !isNumberInRow(board, row, number) && !isNumberInColumn(board, col, number) && !isNumberInSubgrid(board, row, col, number);
+ }
+
+ /**
+ * Checks if number exists in the given row
+ *
+ * @param board the Sudoku board
+ * @param row row index
+ * @param number number to check
+ * @return true if number exists in row, false otherwise
+ */
+ private static boolean isNumberInRow(int[][] board, int row, int number) {
+ for (int col = 0; col < GRID_SIZE; col++) {
+ if (board[row][col] == number) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Checks if number exists in the given column
+ *
+ * @param board the Sudoku board
+ * @param col column index
+ * @param number number to check
+ * @return true if number exists in column, false otherwise
+ */
+ private static boolean isNumberInColumn(int[][] board, int col, int number) {
+ for (int row = 0; row < GRID_SIZE; row++) {
+ if (board[row][col] == number) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Checks if number exists in the 3x3 subgrid
+ *
+ * @param board the Sudoku board
+ * @param row row index
+ * @param col column index
+ * @param number number to check
+ * @return true if number exists in subgrid, false otherwise
+ */
+ private static boolean isNumberInSubgrid(int[][] board, int row, int col, int number) {
+ int subgridRowStart = row - row % SUBGRID_SIZE;
+ int subgridColStart = col - col % SUBGRID_SIZE;
+
+ for (int i = subgridRowStart; i < subgridRowStart + SUBGRID_SIZE; i++) {
+ for (int j = subgridColStart; j < subgridColStart + SUBGRID_SIZE; j++) {
+ if (board[i][j] == number) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Prints the Sudoku board
+ *
+ * @param board the Sudoku board
+ */
+ public static void printBoard(int[][] board) {
+ for (int row = 0; row < GRID_SIZE; row++) {
+ if (row % SUBGRID_SIZE == 0 && row != 0) {
+ System.out.println("-----------");
+ }
+ for (int col = 0; col < GRID_SIZE; col++) {
+ if (col % SUBGRID_SIZE == 0 && col != 0) {
+ System.out.print("|");
+ }
+ System.out.print(board[row][col]);
+ }
+ System.out.println();
+ }
+ }
+}
diff --git a/src/main/java/com/thealgorithms/backtracking/UniquePermutation.java b/src/main/java/com/thealgorithms/backtracking/UniquePermutation.java
index 4804e247ab03..dac0c80b951d 100644
--- a/src/main/java/com/thealgorithms/backtracking/UniquePermutation.java
+++ b/src/main/java/com/thealgorithms/backtracking/UniquePermutation.java
@@ -1,62 +1,62 @@
-package com.thealgorithms.backtracking;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Generates all UNIQUE permutations of a string, even when duplicate characters exist.
- *
- * Example:
- * Input: "AAB"
- * Output: ["AAB", "ABA", "BAA"]
- *
- * Time Complexity: O(n! * n)
- */
-public final class UniquePermutation {
-
- private UniquePermutation() {
- // Prevent instantiation
- throw new UnsupportedOperationException("Utility class");
- }
-
- public static List generateUniquePermutations(String input) {
- List result = new ArrayList<>();
- if (input == null) {
- return result;
- }
-
- char[] chars = input.toCharArray();
- Arrays.sort(chars); // important: sort to detect duplicates
-
- backtrack(chars, new boolean[chars.length], new StringBuilder(), result);
- return result;
- }
-
- private static void backtrack(char[] chars, boolean[] used, StringBuilder current, List result) {
-
- if (current.length() == chars.length) {
- result.add(current.toString());
- return;
- }
-
- for (int i = 0; i < chars.length; i++) {
-
- // skip duplicates
- if (i > 0 && chars[i] == chars[i - 1] && !used[i - 1]) {
- continue;
- }
-
- if (!used[i]) {
- used[i] = true;
- current.append(chars[i]);
-
- backtrack(chars, used, current, result);
-
- // undo changes
- used[i] = false;
- current.deleteCharAt(current.length() - 1);
- }
- }
- }
-}
+package com.thealgorithms.backtracking;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Generates all UNIQUE permutations of a string, even when duplicate characters exist.
+ *
+ * Example:
+ * Input: "AAB"
+ * Output: ["AAB", "ABA", "BAA"]
+ *
+ * Time Complexity: O(n! * n)
+ */
+public final class UniquePermutation {
+
+ private UniquePermutation() {
+ // Prevent instantiation
+ throw new UnsupportedOperationException("Utility class");
+ }
+
+ public static List generateUniquePermutations(String input) {
+ List result = new ArrayList<>();
+ if (input == null) {
+ return result;
+ }
+
+ char[] chars = input.toCharArray();
+ Arrays.sort(chars); // important: sort to detect duplicates
+
+ backtrack(chars, new boolean[chars.length], new StringBuilder(), result);
+ return result;
+ }
+
+ private static void backtrack(char[] chars, boolean[] used, StringBuilder current, List result) {
+
+ if (current.length() == chars.length) {
+ result.add(current.toString());
+ return;
+ }
+
+ for (int i = 0; i < chars.length; i++) {
+
+ // skip duplicates
+ if (i > 0 && chars[i] == chars[i - 1] && !used[i - 1]) {
+ continue;
+ }
+
+ if (!used[i]) {
+ used[i] = true;
+ current.append(chars[i]);
+
+ backtrack(chars, used, current, result);
+
+ // undo changes
+ used[i] = false;
+ current.deleteCharAt(current.length() - 1);
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/thealgorithms/backtracking/WordPatternMatcher.java b/src/main/java/com/thealgorithms/backtracking/WordPatternMatcher.java
index 1854cab20a7f..12605a7bbc75 100644
--- a/src/main/java/com/thealgorithms/backtracking/WordPatternMatcher.java
+++ b/src/main/java/com/thealgorithms/backtracking/WordPatternMatcher.java
@@ -1,86 +1,86 @@
-package com.thealgorithms.backtracking;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Class to determine if a pattern matches a string using backtracking.
- *
- * Example:
- * Pattern: "abab"
- * Input String: "JavaPythonJavaPython"
- * Output: true
- *
- * Pattern: "aaaa"
- * Input String: "JavaJavaJavaJava"
- * Output: true
- *
- * Pattern: "aabb"
- * Input String: "JavaPythonPythonJava"
- * Output: false
- */
-public final class WordPatternMatcher {
- private WordPatternMatcher() {
- }
-
- /**
- * Determines if the given pattern matches the input string using backtracking.
- *
- * @param pattern The pattern to match.
- * @param inputString The string to match against the pattern.
- * @return True if the pattern matches the string, False otherwise.
- */
- public static boolean matchWordPattern(String pattern, String inputString) {
- Map patternMap = new HashMap<>();
- Map strMap = new HashMap<>();
- return backtrack(pattern, inputString, 0, 0, patternMap, strMap);
- }
-
- /**
- * Backtracking helper function to check if the pattern matches the string.
- *
- * @param pattern The pattern string.
- * @param inputString The string to match against the pattern.
- * @param patternIndex Current index in the pattern.
- * @param strIndex Current index in the input string.
- * @param patternMap Map to store pattern characters to string mappings.
- * @param strMap Map to store string to pattern character mappings.
- * @return True if the pattern matches, False otherwise.
- */
- private static boolean backtrack(String pattern, String inputString, int patternIndex, int strIndex, Map patternMap, Map strMap) {
- if (patternIndex == pattern.length() && strIndex == inputString.length()) {
- return true;
- }
- if (patternIndex == pattern.length() || strIndex == inputString.length()) {
- return false;
- }
-
- char currentChar = pattern.charAt(patternIndex);
- if (patternMap.containsKey(currentChar)) {
- String mappedStr = patternMap.get(currentChar);
- if (inputString.startsWith(mappedStr, strIndex)) {
- return backtrack(pattern, inputString, patternIndex + 1, strIndex + mappedStr.length(), patternMap, strMap);
- } else {
- return false;
- }
- }
-
- for (int end = strIndex + 1; end <= inputString.length(); end++) {
- String substring = inputString.substring(strIndex, end);
- if (strMap.containsKey(substring)) {
- continue;
- }
-
- patternMap.put(currentChar, substring);
- strMap.put(substring, currentChar);
- if (backtrack(pattern, inputString, patternIndex + 1, end, patternMap, strMap)) {
- return true;
- }
-
- patternMap.remove(currentChar);
- strMap.remove(substring);
- }
-
- return false;
- }
-}
+package com.thealgorithms.backtracking;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Class to determine if a pattern matches a string using backtracking.
+ *
+ * Example:
+ * Pattern: "abab"
+ * Input String: "JavaPythonJavaPython"
+ * Output: true
+ *
+ * Pattern: "aaaa"
+ * Input String: "JavaJavaJavaJava"
+ * Output: true
+ *
+ * Pattern: "aabb"
+ * Input String: "JavaPythonPythonJava"
+ * Output: false
+ */
+public final class WordPatternMatcher {
+ private WordPatternMatcher() {
+ }
+
+ /**
+ * Determines if the given pattern matches the input string using backtracking.
+ *
+ * @param pattern The pattern to match.
+ * @param inputString The string to match against the pattern.
+ * @return True if the pattern matches the string, False otherwise.
+ */
+ public static boolean matchWordPattern(String pattern, String inputString) {
+ Map patternMap = new HashMap<>();
+ Map strMap = new HashMap<>();
+ return backtrack(pattern, inputString, 0, 0, patternMap, strMap);
+ }
+
+ /**
+ * Backtracking helper function to check if the pattern matches the string.
+ *
+ * @param pattern The pattern string.
+ * @param inputString The string to match against the pattern.
+ * @param patternIndex Current index in the pattern.
+ * @param strIndex Current index in the input string.
+ * @param patternMap Map to store pattern characters to string mappings.
+ * @param strMap Map to store string to pattern character mappings.
+ * @return True if the pattern matches, False otherwise.
+ */
+ private static boolean backtrack(String pattern, String inputString, int patternIndex, int strIndex, Map patternMap, Map strMap) {
+ if (patternIndex == pattern.length() && strIndex == inputString.length()) {
+ return true;
+ }
+ if (patternIndex == pattern.length() || strIndex == inputString.length()) {
+ return false;
+ }
+
+ char currentChar = pattern.charAt(patternIndex);
+ if (patternMap.containsKey(currentChar)) {
+ String mappedStr = patternMap.get(currentChar);
+ if (inputString.startsWith(mappedStr, strIndex)) {
+ return backtrack(pattern, inputString, patternIndex + 1, strIndex + mappedStr.length(), patternMap, strMap);
+ } else {
+ return false;
+ }
+ }
+
+ for (int end = strIndex + 1; end <= inputString.length(); end++) {
+ String substring = inputString.substring(strIndex, end);
+ if (strMap.containsKey(substring)) {
+ continue;
+ }
+
+ patternMap.put(currentChar, substring);
+ strMap.put(substring, currentChar);
+ if (backtrack(pattern, inputString, patternIndex + 1, end, patternMap, strMap)) {
+ return true;
+ }
+
+ patternMap.remove(currentChar);
+ strMap.remove(substring);
+ }
+
+ return false;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/backtracking/WordSearch.java b/src/main/java/com/thealgorithms/backtracking/WordSearch.java
index 174ca90ccaab..911a5e7d48d3 100644
--- a/src/main/java/com/thealgorithms/backtracking/WordSearch.java
+++ b/src/main/java/com/thealgorithms/backtracking/WordSearch.java
@@ -1,109 +1,109 @@
-package com.thealgorithms.backtracking;
-
-/**
- * Word Search Problem
- *
- * This class solves the word search problem where given an m x n grid of characters (board)
- * and a target word, the task is to check if the word exists in the grid.
- * The word can be constructed from sequentially adjacent cells (horizontally or vertically),
- * and the same cell may not be used more than once in constructing the word.
- *
- * Example:
- * - For board =
- * [
- * ['A','B','C','E'],
- * ['S','F','C','S'],
- * ['A','D','E','E']
- * ]
- * and word = "ABCCED", -> returns true
- * and word = "SEE", -> returns true
- * and word = "ABCB", -> returns false
- *
- * Solution:
- * - Depth First Search (DFS) with backtracking is used to explore possible paths from any cell
- * matching the first letter of the word. DFS ensures that we search all valid paths, while
- * backtracking helps in reverting decisions when a path fails to lead to a solution.
- *
- * Time Complexity: O(m * n * 3^L)
- * - m = number of rows in the board
- * - n = number of columns in the board
- * - L = length of the word
- * - For each cell, we look at 3 possible directions (since we exclude the previously visited direction),
- * and we do this for L letters.
- *
- * Space Complexity: O(L)
- * - Stack space for the recursive DFS function, where L is the maximum depth of recursion (length of the word).
- */
-public class WordSearch {
- private final int[] dx = {0, 0, 1, -1};
- private final int[] dy = {1, -1, 0, 0};
- private boolean[][] visited;
- private char[][] board;
- private String word;
-
- /**
- * Checks if the given (x, y) coordinates are valid positions in the board.
- *
- * @param x The row index.
- * @param y The column index.
- * @return True if the coordinates are within the bounds of the board; false otherwise.
- */
- private boolean isValid(int x, int y) {
- return x >= 0 && x < board.length && y >= 0 && y < board[0].length;
- }
-
- /**
- * Performs Depth First Search (DFS) from the cell (x, y)
- * to search for the next character in the word.
- *
- * @param x The current row index.
- * @param y The current column index.
- * @param nextIdx The index of the next character in the word to be matched.
- * @return True if a valid path is found to match the remaining characters of the word; false otherwise.
- */
- private boolean doDFS(int x, int y, int nextIdx) {
- visited[x][y] = true;
- if (nextIdx == word.length()) {
- return true;
- }
-
- for (int i = 0; i < 4; ++i) {
- int xi = x + dx[i];
- int yi = y + dy[i];
- if (isValid(xi, yi) && board[xi][yi] == word.charAt(nextIdx) && !visited[xi][yi]) {
- boolean exists = doDFS(xi, yi, nextIdx + 1);
- if (exists) {
- return true;
- }
- }
- }
-
- visited[x][y] = false; // Backtrack
- return false;
- }
-
- /**
- * Main function to check if the word exists in the board. It initiates DFS from any
- * cell that matches the first character of the word.
- *
- * @param board The 2D grid of characters (the board).
- * @param word The target word to search for in the board.
- * @return True if the word exists in the board; false otherwise.
- */
- public boolean exist(char[][] board, String word) {
- this.board = board;
- this.word = word;
- for (int i = 0; i < board.length; ++i) {
- for (int j = 0; j < board[0].length; ++j) {
- if (board[i][j] == word.charAt(0)) {
- visited = new boolean[board.length][board[0].length];
- boolean exists = doDFS(i, j, 1);
- if (exists) {
- return true;
- }
- }
- }
- }
- return false;
- }
-}
+package com.thealgorithms.backtracking;
+
+/**
+ * Word Search Problem
+ *
+ * This class solves the word search problem where given an m x n grid of characters (board)
+ * and a target word, the task is to check if the word exists in the grid.
+ * The word can be constructed from sequentially adjacent cells (horizontally or vertically),
+ * and the same cell may not be used more than once in constructing the word.
+ *
+ * Example:
+ * - For board =
+ * [
+ * ['A','B','C','E'],
+ * ['S','F','C','S'],
+ * ['A','D','E','E']
+ * ]
+ * and word = "ABCCED", -> returns true
+ * and word = "SEE", -> returns true
+ * and word = "ABCB", -> returns false
+ *
+ * Solution:
+ * - Depth First Search (DFS) with backtracking is used to explore possible paths from any cell
+ * matching the first letter of the word. DFS ensures that we search all valid paths, while
+ * backtracking helps in reverting decisions when a path fails to lead to a solution.
+ *
+ * Time Complexity: O(m * n * 3^L)
+ * - m = number of rows in the board
+ * - n = number of columns in the board
+ * - L = length of the word
+ * - For each cell, we look at 3 possible directions (since we exclude the previously visited direction),
+ * and we do this for L letters.
+ *
+ * Space Complexity: O(L)
+ * - Stack space for the recursive DFS function, where L is the maximum depth of recursion (length of the word).
+ */
+public class WordSearch {
+ private final int[] dx = {0, 0, 1, -1};
+ private final int[] dy = {1, -1, 0, 0};
+ private boolean[][] visited;
+ private char[][] board;
+ private String word;
+
+ /**
+ * Checks if the given (x, y) coordinates are valid positions in the board.
+ *
+ * @param x The row index.
+ * @param y The column index.
+ * @return True if the coordinates are within the bounds of the board; false otherwise.
+ */
+ private boolean isValid(int x, int y) {
+ return x >= 0 && x < board.length && y >= 0 && y < board[0].length;
+ }
+
+ /**
+ * Performs Depth First Search (DFS) from the cell (x, y)
+ * to search for the next character in the word.
+ *
+ * @param x The current row index.
+ * @param y The current column index.
+ * @param nextIdx The index of the next character in the word to be matched.
+ * @return True if a valid path is found to match the remaining characters of the word; false otherwise.
+ */
+ private boolean doDFS(int x, int y, int nextIdx) {
+ visited[x][y] = true;
+ if (nextIdx == word.length()) {
+ return true;
+ }
+
+ for (int i = 0; i < 4; ++i) {
+ int xi = x + dx[i];
+ int yi = y + dy[i];
+ if (isValid(xi, yi) && board[xi][yi] == word.charAt(nextIdx) && !visited[xi][yi]) {
+ boolean exists = doDFS(xi, yi, nextIdx + 1);
+ if (exists) {
+ return true;
+ }
+ }
+ }
+
+ visited[x][y] = false; // Backtrack
+ return false;
+ }
+
+ /**
+ * Main function to check if the word exists in the board. It initiates DFS from any
+ * cell that matches the first character of the word.
+ *
+ * @param board The 2D grid of characters (the board).
+ * @param word The target word to search for in the board.
+ * @return True if the word exists in the board; false otherwise.
+ */
+ public boolean exist(char[][] board, String word) {
+ this.board = board;
+ this.word = word;
+ for (int i = 0; i < board.length; ++i) {
+ for (int j = 0; j < board[0].length; ++j) {
+ if (board[i][j] == word.charAt(0)) {
+ visited = new boolean[board.length][board[0].length];
+ boolean exists = doDFS(i, j, 1);
+ if (exists) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/BcdConversion.java b/src/main/java/com/thealgorithms/bitmanipulation/BcdConversion.java
index e6bd35720d9f..6692ac9df219 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/BcdConversion.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/BcdConversion.java
@@ -1,82 +1,82 @@
-package com.thealgorithms.bitmanipulation;
-
-/**
- * This class provides methods to convert between BCD (Binary-Coded Decimal) and decimal numbers.
- *
- * BCD is a class of binary encodings of decimal numbers where each decimal digit is represented by a fixed number of binary digits, usually four or eight.
- *
- * For more information, refer to the
- * Binary-Coded Decimal Wikipedia page.
- *
- * Example usage:
- *
- * int decimal = BcdConversion.bcdToDecimal(0x1234);
- * System.out.println("BCD 0x1234 to decimal: " + decimal); // Output: 1234
- *
- * int bcd = BcdConversion.decimalToBcd(1234);
- * System.out.println("Decimal 1234 to BCD: " + Integer.toHexString(bcd)); // Output: 0x1234
- *
- */
-public final class BcdConversion {
- private BcdConversion() {
- }
-
- /**
- * Converts a BCD (Binary-Coded Decimal) number to a decimal number.
- * Steps:
- *
1. Validate the BCD number to ensure all digits are between 0 and 9.
- *
2. Extract the last 4 bits (one BCD digit) from the BCD number.
- *
3. Multiply the extracted digit by the corresponding power of 10 and add it to the decimal number.
- *
4. Shift the BCD number right by 4 bits to process the next BCD digit.
- *
5. Repeat steps 1-4 until the BCD number is zero.
- *
- * @param bcd The BCD number.
- * @return The corresponding decimal number.
- * @throws IllegalArgumentException if the BCD number contains invalid digits.
- */
- public static int bcdToDecimal(int bcd) {
- int decimal = 0;
- int multiplier = 1;
-
- // Validate BCD digits
- while (bcd > 0) {
- int digit = bcd & 0xF;
- if (digit > 9) {
- throw new IllegalArgumentException("Invalid BCD digit: " + digit);
- }
- decimal += digit * multiplier;
- multiplier *= 10;
- bcd >>= 4;
- }
- return decimal;
- }
-
- /**
- * Converts a decimal number to BCD (Binary-Coded Decimal).
- *
Steps:
- *
1. Check if the decimal number is within the valid range for BCD (0 to 9999).
- *
2. Extract the last decimal digit from the decimal number.
- *
3. Shift the digit to the correct BCD position and add it to the BCD number.
- *
4. Remove the last decimal digit from the decimal number.
- *
5. Repeat steps 2-4 until the decimal number is zero.
- *
- * @param decimal The decimal number.
- * @return The corresponding BCD number.
- * @throws IllegalArgumentException if the decimal number is greater than 9999.
- */
- public static int decimalToBcd(int decimal) {
- if (decimal < 0 || decimal > 9999) {
- throw new IllegalArgumentException("Value out of bounds for BCD representation: " + decimal);
- }
-
- int bcd = 0;
- int shift = 0;
- while (decimal > 0) {
- int digit = decimal % 10;
- bcd |= (digit << (shift * 4));
- decimal /= 10;
- shift++;
- }
- return bcd;
- }
-}
+package com.thealgorithms.bitmanipulation;
+
+/**
+ * This class provides methods to convert between BCD (Binary-Coded Decimal) and decimal numbers.
+ *
+ * BCD is a class of binary encodings of decimal numbers where each decimal digit is represented by a fixed number of binary digits, usually four or eight.
+ *
+ * For more information, refer to the
+ * Binary-Coded Decimal Wikipedia page.
+ *
+ * Example usage:
+ *
+ * int decimal = BcdConversion.bcdToDecimal(0x1234);
+ * System.out.println("BCD 0x1234 to decimal: " + decimal); // Output: 1234
+ *
+ * int bcd = BcdConversion.decimalToBcd(1234);
+ * System.out.println("Decimal 1234 to BCD: " + Integer.toHexString(bcd)); // Output: 0x1234
+ *
+ */
+public final class BcdConversion {
+ private BcdConversion() {
+ }
+
+ /**
+ * Converts a BCD (Binary-Coded Decimal) number to a decimal number.
+ * Steps:
+ *
1. Validate the BCD number to ensure all digits are between 0 and 9.
+ *
2. Extract the last 4 bits (one BCD digit) from the BCD number.
+ *
3. Multiply the extracted digit by the corresponding power of 10 and add it to the decimal number.
+ *
4. Shift the BCD number right by 4 bits to process the next BCD digit.
+ *
5. Repeat steps 1-4 until the BCD number is zero.
+ *
+ * @param bcd The BCD number.
+ * @return The corresponding decimal number.
+ * @throws IllegalArgumentException if the BCD number contains invalid digits.
+ */
+ public static int bcdToDecimal(int bcd) {
+ int decimal = 0;
+ int multiplier = 1;
+
+ // Validate BCD digits
+ while (bcd > 0) {
+ int digit = bcd & 0xF;
+ if (digit > 9) {
+ throw new IllegalArgumentException("Invalid BCD digit: " + digit);
+ }
+ decimal += digit * multiplier;
+ multiplier *= 10;
+ bcd >>= 4;
+ }
+ return decimal;
+ }
+
+ /**
+ * Converts a decimal number to BCD (Binary-Coded Decimal).
+ *
Steps:
+ *
1. Check if the decimal number is within the valid range for BCD (0 to 9999).
+ *
2. Extract the last decimal digit from the decimal number.
+ *
3. Shift the digit to the correct BCD position and add it to the BCD number.
+ *
4. Remove the last decimal digit from the decimal number.
+ *
5. Repeat steps 2-4 until the decimal number is zero.
+ *
+ * @param decimal The decimal number.
+ * @return The corresponding BCD number.
+ * @throws IllegalArgumentException if the decimal number is greater than 9999.
+ */
+ public static int decimalToBcd(int decimal) {
+ if (decimal < 0 || decimal > 9999) {
+ throw new IllegalArgumentException("Value out of bounds for BCD representation: " + decimal);
+ }
+
+ int bcd = 0;
+ int shift = 0;
+ while (decimal > 0) {
+ int digit = decimal % 10;
+ bcd |= (digit << (shift * 4));
+ decimal /= 10;
+ shift++;
+ }
+ return bcd;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/BinaryPalindromeCheck.java b/src/main/java/com/thealgorithms/bitmanipulation/BinaryPalindromeCheck.java
index 0d6fd140c720..e0998c748c5b 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/BinaryPalindromeCheck.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/BinaryPalindromeCheck.java
@@ -1,43 +1,43 @@
-package com.thealgorithms.bitmanipulation;
-
-/**
- * This class contains a method to check if the binary representation of a number is a palindrome.
- *
- * A binary palindrome is a number whose binary representation is the same when read from left to right and right to left.
- * For example, the number 9 has a binary representation of 1001, which is a palindrome.
- * The number 10 has a binary representation of 1010, which is not a palindrome.
- *
- *
- * @author Hardvan
- */
-public final class BinaryPalindromeCheck {
- private BinaryPalindromeCheck() {
- }
-
- /**
- * Checks if the binary representation of a number is a palindrome.
- *
- * @param x The number to check.
- * @return True if the binary representation is a palindrome, otherwise false.
- */
- public static boolean isBinaryPalindrome(int x) {
- int reversed = reverseBits(x);
- return x == reversed;
- }
-
- /**
- * Helper function to reverse all the bits of an integer.
- *
- * @param x The number to reverse the bits of.
- * @return The number with reversed bits.
- */
- private static int reverseBits(int x) {
- int result = 0;
- while (x > 0) {
- result <<= 1;
- result |= (x & 1);
- x >>= 1;
- }
- return result;
- }
-}
+package com.thealgorithms.bitmanipulation;
+
+/**
+ * This class contains a method to check if the binary representation of a number is a palindrome.
+ *
+ * A binary palindrome is a number whose binary representation is the same when read from left to right and right to left.
+ * For example, the number 9 has a binary representation of 1001, which is a palindrome.
+ * The number 10 has a binary representation of 1010, which is not a palindrome.
+ *
+ *
+ * @author Hardvan
+ */
+public final class BinaryPalindromeCheck {
+ private BinaryPalindromeCheck() {
+ }
+
+ /**
+ * Checks if the binary representation of a number is a palindrome.
+ *
+ * @param x The number to check.
+ * @return True if the binary representation is a palindrome, otherwise false.
+ */
+ public static boolean isBinaryPalindrome(int x) {
+ int reversed = reverseBits(x);
+ return x == reversed;
+ }
+
+ /**
+ * Helper function to reverse all the bits of an integer.
+ *
+ * @param x The number to reverse the bits of.
+ * @return The number with reversed bits.
+ */
+ private static int reverseBits(int x) {
+ int result = 0;
+ while (x > 0) {
+ result <<= 1;
+ result |= (x & 1);
+ x >>= 1;
+ }
+ return result;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/BitRotate.java b/src/main/java/com/thealgorithms/bitmanipulation/BitRotate.java
index 226e09e78d1f..2b06471a358e 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/BitRotate.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/BitRotate.java
@@ -1,83 +1,83 @@
-package com.thealgorithms.bitmanipulation;
-
-/**
- * Utility class for performing circular bit rotations on 32-bit integers.
- * Bit rotation is a circular shift operation where bits shifted out on one end
- * are reinserted on the opposite end.
- *
- * This class provides methods for both left and right circular rotations,
- * supporting only 32-bit integer operations with proper shift normalization
- * and error handling.
- *
- * @see Bit Rotation
- */
-public final class BitRotate {
-
- /**
- * Private constructor to prevent instantiation.
- * This is a utility class with only static methods.
- */
- private BitRotate() {
- throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
- }
-
- /**
- * Performs a circular left rotation (left shift) on a 32-bit integer.
- * Bits shifted out from the left side are inserted on the right side.
- *
- * @param value the 32-bit integer value to rotate
- * @param shift the number of positions to rotate left (must be non-negative)
- * @return the result of left rotating the value by the specified shift amount
- * @throws IllegalArgumentException if shift is negative
- *
- * @example
- * // Binary: 10000000 00000000 00000000 00000001
- * rotateLeft(0x80000001, 1)
- * // Returns: 3 (binary: 00000000 00000000 00000000 00000011)
- */
- public static int rotateLeft(int value, int shift) {
- if (shift < 0) {
- throw new IllegalArgumentException("Shift amount cannot be negative: " + shift);
- }
-
- // Normalize shift to the range [0, 31] using modulo 32
- shift = shift % 32;
-
- if (shift == 0) {
- return value;
- }
-
- // Left rotation: (value << shift) | (value >>> (32 - shift))
- return (value << shift) | (value >>> (32 - shift));
- }
-
- /**
- * Performs a circular right rotation (right shift) on a 32-bit integer.
- * Bits shifted out from the right side are inserted on the left side.
- *
- * @param value the 32-bit integer value to rotate
- * @param shift the number of positions to rotate right (must be non-negative)
- * @return the result of right rotating the value by the specified shift amount
- * @throws IllegalArgumentException if shift is negative
- *
- * @example
- * // Binary: 00000000 00000000 00000000 00000011
- * rotateRight(3, 1)
- * // Returns: -2147483647 (binary: 10000000 00000000 00000000 00000001)
- */
- public static int rotateRight(int value, int shift) {
- if (shift < 0) {
- throw new IllegalArgumentException("Shift amount cannot be negative: " + shift);
- }
-
- // Normalize shift to the range [0, 31] using modulo 32
- shift = shift % 32;
-
- if (shift == 0) {
- return value;
- }
-
- // Right rotation: (value >>> shift) | (value << (32 - shift))
- return (value >>> shift) | (value << (32 - shift));
- }
-}
+package com.thealgorithms.bitmanipulation;
+
+/**
+ * Utility class for performing circular bit rotations on 32-bit integers.
+ * Bit rotation is a circular shift operation where bits shifted out on one end
+ * are reinserted on the opposite end.
+ *
+ * This class provides methods for both left and right circular rotations,
+ * supporting only 32-bit integer operations with proper shift normalization
+ * and error handling.
+ *
+ * @see Bit Rotation
+ */
+public final class BitRotate {
+
+ /**
+ * Private constructor to prevent instantiation.
+ * This is a utility class with only static methods.
+ */
+ private BitRotate() {
+ throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
+ }
+
+ /**
+ * Performs a circular left rotation (left shift) on a 32-bit integer.
+ * Bits shifted out from the left side are inserted on the right side.
+ *
+ * @param value the 32-bit integer value to rotate
+ * @param shift the number of positions to rotate left (must be non-negative)
+ * @return the result of left rotating the value by the specified shift amount
+ * @throws IllegalArgumentException if shift is negative
+ *
+ * @example
+ * // Binary: 10000000 00000000 00000000 00000001
+ * rotateLeft(0x80000001, 1)
+ * // Returns: 3 (binary: 00000000 00000000 00000000 00000011)
+ */
+ public static int rotateLeft(int value, int shift) {
+ if (shift < 0) {
+ throw new IllegalArgumentException("Shift amount cannot be negative: " + shift);
+ }
+
+ // Normalize shift to the range [0, 31] using modulo 32
+ shift = shift % 32;
+
+ if (shift == 0) {
+ return value;
+ }
+
+ // Left rotation: (value << shift) | (value >>> (32 - shift))
+ return (value << shift) | (value >>> (32 - shift));
+ }
+
+ /**
+ * Performs a circular right rotation (right shift) on a 32-bit integer.
+ * Bits shifted out from the right side are inserted on the left side.
+ *
+ * @param value the 32-bit integer value to rotate
+ * @param shift the number of positions to rotate right (must be non-negative)
+ * @return the result of right rotating the value by the specified shift amount
+ * @throws IllegalArgumentException if shift is negative
+ *
+ * @example
+ * // Binary: 00000000 00000000 00000000 00000011
+ * rotateRight(3, 1)
+ * // Returns: -2147483647 (binary: 10000000 00000000 00000000 00000001)
+ */
+ public static int rotateRight(int value, int shift) {
+ if (shift < 0) {
+ throw new IllegalArgumentException("Shift amount cannot be negative: " + shift);
+ }
+
+ // Normalize shift to the range [0, 31] using modulo 32
+ shift = shift % 32;
+
+ if (shift == 0) {
+ return value;
+ }
+
+ // Right rotation: (value >>> shift) | (value << (32 - shift))
+ return (value >>> shift) | (value << (32 - shift));
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/BitSwap.java b/src/main/java/com/thealgorithms/bitmanipulation/BitSwap.java
index 634c9e7b3b44..1fdd2ef91b9d 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/BitSwap.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/BitSwap.java
@@ -1,33 +1,33 @@
-package com.thealgorithms.bitmanipulation;
-
-/**
- * Utility class for performing bit-swapping operations on integers.
- * This class cannot be instantiated.
- */
-public final class BitSwap {
- private BitSwap() {
- }
-
- /**
- * Swaps two bits at specified positions in an integer.
- *
- * @param data The input integer whose bits need to be swapped
- * @param posA The position of the first bit (0-based, from least significant)
- * @param posB The position of the second bit (0-based, from least significant)
- * @return The modified value with swapped bits
- * @throws IllegalArgumentException if either position is negative or ≥ 32
- */
-
- public static int bitSwap(int data, final int posA, final int posB) {
- if (posA < 0 || posA >= Integer.SIZE || posB < 0 || posB >= Integer.SIZE) {
- throw new IllegalArgumentException("Bit positions must be between 0 and 31");
- }
-
- boolean bitA = ((data >> posA) & 1) != 0;
- boolean bitB = ((data >> posB) & 1) != 0;
- if (bitA != bitB) {
- data ^= (1 << posA) ^ (1 << posB);
- }
- return data;
- }
-}
+package com.thealgorithms.bitmanipulation;
+
+/**
+ * Utility class for performing bit-swapping operations on integers.
+ * This class cannot be instantiated.
+ */
+public final class BitSwap {
+ private BitSwap() {
+ }
+
+ /**
+ * Swaps two bits at specified positions in an integer.
+ *
+ * @param data The input integer whose bits need to be swapped
+ * @param posA The position of the first bit (0-based, from least significant)
+ * @param posB The position of the second bit (0-based, from least significant)
+ * @return The modified value with swapped bits
+ * @throws IllegalArgumentException if either position is negative or ≥ 32
+ */
+
+ public static int bitSwap(int data, final int posA, final int posB) {
+ if (posA < 0 || posA >= Integer.SIZE || posB < 0 || posB >= Integer.SIZE) {
+ throw new IllegalArgumentException("Bit positions must be between 0 and 31");
+ }
+
+ boolean bitA = ((data >> posA) & 1) != 0;
+ boolean bitB = ((data >> posB) & 1) != 0;
+ if (bitA != bitB) {
+ data ^= (1 << posA) ^ (1 << posB);
+ }
+ return data;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/BitwiseGCD.java b/src/main/java/com/thealgorithms/bitmanipulation/BitwiseGCD.java
index 516563459256..42b23e3128c5 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/BitwiseGCD.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/BitwiseGCD.java
@@ -1,147 +1,147 @@
-package com.thealgorithms.bitmanipulation;
-
-import java.math.BigInteger;
-
-/**
- * Bitwise GCD implementation with full-range support utilities.
- *
- * This class provides a fast binary (Stein's) GCD implementation for {@code long}
- * inputs and a BigInteger-backed API for full 2's-complement range support (including
- * {@code Long.MIN_VALUE}). The {@code long} implementation is efficient and avoids
- * division/modulo operations. For edge-cases that overflow signed-64-bit ranges
- * (e.g., gcd(Long.MIN_VALUE, 0) = 2^63), use the BigInteger API {@code gcdBig}.
- *
- *
Behaviour:
- *
- * - {@code gcd(long,long)} : returns non-negative {@code long} gcd for inputs whose
- * absolute values fit in signed {@code long} (i.e., not causing an unsigned 2^63 result).
- * If the true gcd does not fit in a signed {@code long} (for example gcd(Long.MIN_VALUE,0) = 2^63)
- * this method will delegate to BigInteger and throw {@link ArithmeticException} if the
- * BigInteger result does not fit into a signed {@code long}.
- * - {@code gcdBig(BigInteger, BigInteger)} : returns the exact gcd as a {@link BigInteger}
- * and works for the full signed-64-bit range and beyond.
- *
- */
-public final class BitwiseGCD {
-
- private BitwiseGCD() {
- }
-
- /**
- * Computes GCD of two long values using Stein's algorithm (binary GCD).
- * Handles negative inputs. If either input is {@code Long.MIN_VALUE} the
- * method delegates to the BigInteger implementation and will throw {@link ArithmeticException}
- * if the result cannot be represented as a signed {@code long}.
- *
- * @param a first value (may be negative)
- * @param b second value (may be negative)
- * @return non-negative gcd as a {@code long}
- * @throws ArithmeticException when the exact gcd does not fit into a signed {@code long}
- */
- public static long gcd(long a, long b) {
- // Trivial cases
- if (a == 0L) {
- return absOrThrowIfOverflow(b);
- }
- if (b == 0L) {
- return absOrThrowIfOverflow(a);
- }
-
- // If either is Long.MIN_VALUE, absolute value doesn't fit into signed long.
- if (a == Long.MIN_VALUE || b == Long.MIN_VALUE) {
- // Delegate to BigInteger and try to return a long if it fits
- BigInteger g = gcdBig(BigInteger.valueOf(a), BigInteger.valueOf(b));
- return g.longValueExact();
- }
-
- // Work with non-negative long values now (safe because we excluded Long.MIN_VALUE)
- a = (a < 0) ? -a : a;
- b = (b < 0) ? -b : b;
-
- // Count common factors of 2
- int commonTwos = Long.numberOfTrailingZeros(a | b);
-
- // Remove all factors of 2 from a
- a >>= Long.numberOfTrailingZeros(a);
-
- while (b != 0L) {
- // Remove all factors of 2 from b
- b >>= Long.numberOfTrailingZeros(b);
-
- // Now both a and b are odd. Ensure a <= b
- if (a > b) {
- long tmp = a;
- a = b;
- b = tmp;
- }
-
- // b >= a; subtract a from b (result is even)
- b = b - a;
- }
-
- // Restore common powers of two
- return a << commonTwos;
- }
-
- /**
- * Helper to return absolute value of x unless x == Long.MIN_VALUE, in which
- * case we delegate to BigInteger and throw to indicate overflow.
- */
- private static long absOrThrowIfOverflow(long x) {
- if (x == Long.MIN_VALUE) {
- // |Long.MIN_VALUE| = 2^63 which does not fit into signed long
- throw new ArithmeticException("Absolute value of Long.MIN_VALUE does not fit into signed long. Use gcdBig() for full-range support.");
- }
- return (x < 0) ? -x : x;
- }
-
- /**
- * Computes GCD for an array of {@code long} values. Returns 0 for empty/null arrays.
- * If any intermediate gcd cannot be represented in signed long (rare), an ArithmeticException
- * will be thrown.
- */
- public static long gcd(long... values) {
-
- if (values == null || values.length == 0) {
- return 0L;
- }
- long result = values[0];
- for (int i = 1; i < values.length; i++) {
- result = gcd(result, values[i]);
- if (result == 1L) {
- return 1L; // early exit
- }
- }
- return result;
- }
-
- /**
- * BigInteger-backed gcd that works for the full integer range (and beyond).
- * This is the recommended method when inputs may be Long.MIN_VALUE or when you
- * need an exact result even if it is greater than Long.MAX_VALUE.
- * @param a first value (may be negative)
- * @param b second value (may be negative)
- * @return non-negative gcd as a {@link BigInteger}
- */
- public static BigInteger gcdBig(BigInteger a, BigInteger b) {
-
- if (a == null || b == null) {
- throw new NullPointerException("Arguments must not be null");
- }
- return a.abs().gcd(b.abs());
- }
-
- /**
- * Convenience overload that accepts signed-64 inputs and returns BigInteger gcd.
- */
- public static BigInteger gcdBig(long a, long b) {
- return gcdBig(BigInteger.valueOf(a), BigInteger.valueOf(b));
- }
-
- /**
- * int overload for convenience.
- */
- public static int gcd(int a, int b) {
- return (int) gcd((long) a, (long) b);
- }
-}
+package com.thealgorithms.bitmanipulation;
+
+import java.math.BigInteger;
+
+/**
+ * Bitwise GCD implementation with full-range support utilities.
+ *
+ *
This class provides a fast binary (Stein's) GCD implementation for {@code long}
+ * inputs and a BigInteger-backed API for full 2's-complement range support (including
+ * {@code Long.MIN_VALUE}). The {@code long} implementation is efficient and avoids
+ * division/modulo operations. For edge-cases that overflow signed-64-bit ranges
+ * (e.g., gcd(Long.MIN_VALUE, 0) = 2^63), use the BigInteger API {@code gcdBig}.
+ *
+ *
Behaviour:
+ *
+ * - {@code gcd(long,long)} : returns non-negative {@code long} gcd for inputs whose
+ * absolute values fit in signed {@code long} (i.e., not causing an unsigned 2^63 result).
+ * If the true gcd does not fit in a signed {@code long} (for example gcd(Long.MIN_VALUE,0) = 2^63)
+ * this method will delegate to BigInteger and throw {@link ArithmeticException} if the
+ * BigInteger result does not fit into a signed {@code long}.
+ * - {@code gcdBig(BigInteger, BigInteger)} : returns the exact gcd as a {@link BigInteger}
+ * and works for the full signed-64-bit range and beyond.
+ *
+ */
+public final class BitwiseGCD {
+
+ private BitwiseGCD() {
+ }
+
+ /**
+ * Computes GCD of two long values using Stein's algorithm (binary GCD).
+ * Handles negative inputs. If either input is {@code Long.MIN_VALUE} the
+ * method delegates to the BigInteger implementation and will throw {@link ArithmeticException}
+ * if the result cannot be represented as a signed {@code long}.
+ *
+ * @param a first value (may be negative)
+ * @param b second value (may be negative)
+ * @return non-negative gcd as a {@code long}
+ * @throws ArithmeticException when the exact gcd does not fit into a signed {@code long}
+ */
+ public static long gcd(long a, long b) {
+ // Trivial cases
+ if (a == 0L) {
+ return absOrThrowIfOverflow(b);
+ }
+ if (b == 0L) {
+ return absOrThrowIfOverflow(a);
+ }
+
+ // If either is Long.MIN_VALUE, absolute value doesn't fit into signed long.
+ if (a == Long.MIN_VALUE || b == Long.MIN_VALUE) {
+ // Delegate to BigInteger and try to return a long if it fits
+ BigInteger g = gcdBig(BigInteger.valueOf(a), BigInteger.valueOf(b));
+ return g.longValueExact();
+ }
+
+ // Work with non-negative long values now (safe because we excluded Long.MIN_VALUE)
+ a = (a < 0) ? -a : a;
+ b = (b < 0) ? -b : b;
+
+ // Count common factors of 2
+ int commonTwos = Long.numberOfTrailingZeros(a | b);
+
+ // Remove all factors of 2 from a
+ a >>= Long.numberOfTrailingZeros(a);
+
+ while (b != 0L) {
+ // Remove all factors of 2 from b
+ b >>= Long.numberOfTrailingZeros(b);
+
+ // Now both a and b are odd. Ensure a <= b
+ if (a > b) {
+ long tmp = a;
+ a = b;
+ b = tmp;
+ }
+
+ // b >= a; subtract a from b (result is even)
+ b = b - a;
+ }
+
+ // Restore common powers of two
+ return a << commonTwos;
+ }
+
+ /**
+ * Helper to return absolute value of x unless x == Long.MIN_VALUE, in which
+ * case we delegate to BigInteger and throw to indicate overflow.
+ */
+ private static long absOrThrowIfOverflow(long x) {
+ if (x == Long.MIN_VALUE) {
+ // |Long.MIN_VALUE| = 2^63 which does not fit into signed long
+ throw new ArithmeticException("Absolute value of Long.MIN_VALUE does not fit into signed long. Use gcdBig() for full-range support.");
+ }
+ return (x < 0) ? -x : x;
+ }
+
+ /**
+ * Computes GCD for an array of {@code long} values. Returns 0 for empty/null arrays.
+ * If any intermediate gcd cannot be represented in signed long (rare), an ArithmeticException
+ * will be thrown.
+ */
+ public static long gcd(long... values) {
+
+ if (values == null || values.length == 0) {
+ return 0L;
+ }
+ long result = values[0];
+ for (int i = 1; i < values.length; i++) {
+ result = gcd(result, values[i]);
+ if (result == 1L) {
+ return 1L; // early exit
+ }
+ }
+ return result;
+ }
+
+ /**
+ * BigInteger-backed gcd that works for the full integer range (and beyond).
+ * This is the recommended method when inputs may be Long.MIN_VALUE or when you
+ * need an exact result even if it is greater than Long.MAX_VALUE.
+ * @param a first value (may be negative)
+ * @param b second value (may be negative)
+ * @return non-negative gcd as a {@link BigInteger}
+ */
+ public static BigInteger gcdBig(BigInteger a, BigInteger b) {
+
+ if (a == null || b == null) {
+ throw new NullPointerException("Arguments must not be null");
+ }
+ return a.abs().gcd(b.abs());
+ }
+
+ /**
+ * Convenience overload that accepts signed-64 inputs and returns BigInteger gcd.
+ */
+ public static BigInteger gcdBig(long a, long b) {
+ return gcdBig(BigInteger.valueOf(a), BigInteger.valueOf(b));
+ }
+
+ /**
+ * int overload for convenience.
+ */
+ public static int gcd(int a, int b) {
+ return (int) gcd((long) a, (long) b);
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/BooleanAlgebraGates.java b/src/main/java/com/thealgorithms/bitmanipulation/BooleanAlgebraGates.java
index 869466320831..462d8459fc83 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/BooleanAlgebraGates.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/BooleanAlgebraGates.java
@@ -1,111 +1,111 @@
-package com.thealgorithms.bitmanipulation;
-
-import java.util.List;
-
-/**
- * Implements various Boolean algebra gates (AND, OR, NOT, XOR, NAND, NOR)
- */
-public final class BooleanAlgebraGates {
-
- private BooleanAlgebraGates() {
- // Prevent instantiation
- }
-
- /**
- * Represents a Boolean gate that takes multiple inputs and returns a result.
- */
- interface BooleanGate {
- /**
- * Evaluates the gate with the given inputs.
- *
- * @param inputs The input values for the gate.
- * @return The result of the evaluation.
- */
- boolean evaluate(List inputs);
- }
-
- /**
- * AND Gate implementation.
- * Returns true if all inputs are true; otherwise, false.
- */
- static class ANDGate implements BooleanGate {
- @Override
- public boolean evaluate(List inputs) {
- for (boolean input : inputs) {
- if (!input) {
- return false;
- }
- }
- return true;
- }
- }
-
- /**
- * OR Gate implementation.
- * Returns true if at least one input is true; otherwise, false.
- */
- static class ORGate implements BooleanGate {
- @Override
- public boolean evaluate(List inputs) {
- for (boolean input : inputs) {
- if (input) {
- return true;
- }
- }
- return false;
- }
- }
-
- /**
- * NOT Gate implementation (Unary operation).
- * Negates a single input value.
- */
- static class NOTGate {
- /**
- * Evaluates the negation of the input.
- *
- * @param input The input value to be negated.
- * @return The negated value.
- */
- public boolean evaluate(boolean input) {
- return !input;
- }
- }
-
- /**
- * XOR Gate implementation.
- * Returns true if an odd number of inputs are true; otherwise, false.
- */
- static class XORGate implements BooleanGate {
- @Override
- public boolean evaluate(List inputs) {
- boolean result = false;
- for (boolean input : inputs) {
- result ^= input;
- }
- return result;
- }
- }
-
- /**
- * NAND Gate implementation.
- * Returns true if at least one input is false; otherwise, false.
- */
- static class NANDGate implements BooleanGate {
- @Override
- public boolean evaluate(List inputs) {
- return !new ANDGate().evaluate(inputs); // Equivalent to negation of AND
- }
- }
-
- /**
- * NOR Gate implementation.
- * Returns true if all inputs are false; otherwise, false.
- */
- static class NORGate implements BooleanGate {
- @Override
- public boolean evaluate(List inputs) {
- return !new ORGate().evaluate(inputs); // Equivalent to negation of OR
- }
- }
-}
+package com.thealgorithms.bitmanipulation;
+
+import java.util.List;
+
+/**
+ * Implements various Boolean algebra gates (AND, OR, NOT, XOR, NAND, NOR)
+ */
+public final class BooleanAlgebraGates {
+
+ private BooleanAlgebraGates() {
+ // Prevent instantiation
+ }
+
+ /**
+ * Represents a Boolean gate that takes multiple inputs and returns a result.
+ */
+ interface BooleanGate {
+ /**
+ * Evaluates the gate with the given inputs.
+ *
+ * @param inputs The input values for the gate.
+ * @return The result of the evaluation.
+ */
+ boolean evaluate(List inputs);
+ }
+
+ /**
+ * AND Gate implementation.
+ * Returns true if all inputs are true; otherwise, false.
+ */
+ static class ANDGate implements BooleanGate {
+ @Override
+ public boolean evaluate(List inputs) {
+ for (boolean input : inputs) {
+ if (!input) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+
+ /**
+ * OR Gate implementation.
+ * Returns true if at least one input is true; otherwise, false.
+ */
+ static class ORGate implements BooleanGate {
+ @Override
+ public boolean evaluate(List inputs) {
+ for (boolean input : inputs) {
+ if (input) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ /**
+ * NOT Gate implementation (Unary operation).
+ * Negates a single input value.
+ */
+ static class NOTGate {
+ /**
+ * Evaluates the negation of the input.
+ *
+ * @param input The input value to be negated.
+ * @return The negated value.
+ */
+ public boolean evaluate(boolean input) {
+ return !input;
+ }
+ }
+
+ /**
+ * XOR Gate implementation.
+ * Returns true if an odd number of inputs are true; otherwise, false.
+ */
+ static class XORGate implements BooleanGate {
+ @Override
+ public boolean evaluate(List inputs) {
+ boolean result = false;
+ for (boolean input : inputs) {
+ result ^= input;
+ }
+ return result;
+ }
+ }
+
+ /**
+ * NAND Gate implementation.
+ * Returns true if at least one input is false; otherwise, false.
+ */
+ static class NANDGate implements BooleanGate {
+ @Override
+ public boolean evaluate(List inputs) {
+ return !new ANDGate().evaluate(inputs); // Equivalent to negation of AND
+ }
+ }
+
+ /**
+ * NOR Gate implementation.
+ * Returns true if all inputs are false; otherwise, false.
+ */
+ static class NORGate implements BooleanGate {
+ @Override
+ public boolean evaluate(List inputs) {
+ return !new ORGate().evaluate(inputs); // Equivalent to negation of OR
+ }
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/ClearLeftmostSetBit.java b/src/main/java/com/thealgorithms/bitmanipulation/ClearLeftmostSetBit.java
index 3e9a4a21183f..9ddcc2e65066 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/ClearLeftmostSetBit.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/ClearLeftmostSetBit.java
@@ -1,39 +1,39 @@
-package com.thealgorithms.bitmanipulation;
-
-/**
- * ClearLeftmostSetBit class contains a method to clear the leftmost set bit of a number.
- * The leftmost set bit is the leftmost bit that is set to 1 in the binary representation of a number.
- *
- * Example:
- * 26 (11010) -> 10 (01010)
- * 1 (1) -> 0 (0)
- * 7 (111) -> 3 (011)
- * 6 (0110) -> 2 (0010)
- *
- * @author Hardvan
- */
-public final class ClearLeftmostSetBit {
- private ClearLeftmostSetBit() {
- }
-
- /**
- * Clears the leftmost set bit (1) of a given number.
- * Step 1: Find the position of the leftmost set bit
- * Step 2: Create a mask with all bits set except for the leftmost set bit
- * Step 3: Clear the leftmost set bit using AND with the mask
- *
- * @param num The input number.
- * @return The number after clearing the leftmost set bit.
- */
- public static int clearLeftmostSetBit(int num) {
- int pos = 0;
- int temp = num;
- while (temp > 0) {
- temp >>= 1;
- pos++;
- }
-
- int mask = ~(1 << (pos - 1));
- return num & mask;
- }
-}
+package com.thealgorithms.bitmanipulation;
+
+/**
+ * ClearLeftmostSetBit class contains a method to clear the leftmost set bit of a number.
+ * The leftmost set bit is the leftmost bit that is set to 1 in the binary representation of a number.
+ *
+ * Example:
+ * 26 (11010) -> 10 (01010)
+ * 1 (1) -> 0 (0)
+ * 7 (111) -> 3 (011)
+ * 6 (0110) -> 2 (0010)
+ *
+ * @author Hardvan
+ */
+public final class ClearLeftmostSetBit {
+ private ClearLeftmostSetBit() {
+ }
+
+ /**
+ * Clears the leftmost set bit (1) of a given number.
+ * Step 1: Find the position of the leftmost set bit
+ * Step 2: Create a mask with all bits set except for the leftmost set bit
+ * Step 3: Clear the leftmost set bit using AND with the mask
+ *
+ * @param num The input number.
+ * @return The number after clearing the leftmost set bit.
+ */
+ public static int clearLeftmostSetBit(int num) {
+ int pos = 0;
+ int temp = num;
+ while (temp > 0) {
+ temp >>= 1;
+ pos++;
+ }
+
+ int mask = ~(1 << (pos - 1));
+ return num & mask;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/CountBitsFlip.java b/src/main/java/com/thealgorithms/bitmanipulation/CountBitsFlip.java
index 8d2c757e5e0a..71f2d27403d5 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/CountBitsFlip.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/CountBitsFlip.java
@@ -1,63 +1,63 @@
-package com.thealgorithms.bitmanipulation;
-
-/**
- * Implementation to count number of bits to be flipped to convert A to B
- *
- * Problem: Given two numbers A and B, count the number of bits needed to be
- * flipped to convert A to B.
- *
- * Example:
- * A = 10 (01010 in binary)
- * B = 20 (10100 in binary)
- * XOR = 30 (11110 in binary) - positions where bits differ
- * Answer: 4 bits need to be flipped
- *
- * Time Complexity: O(log n) - where n is the number of set bits
- * Space Complexity: O(1)
- *
- *@author [Yash Rajput](https://github.com/the-yash-rajput)
- */
-public final class CountBitsFlip {
-
- private CountBitsFlip() {
- throw new AssertionError("No instances.");
- }
-
- /**
- * Counts the number of bits that need to be flipped to convert a to b
- *
- * Algorithm:
- * 1. XOR a and b to get positions where bits differ
- * 2. Count the number of set bits in the XOR result
- * 3. Use Brian Kernighan's algorithm: n & (n-1) removes rightmost set bit
- *
- * @param a the source number
- * @param b the target number
- * @return the number of bits to flip to convert A to B
- */
- public static long countBitsFlip(long a, long b) {
- int count = 0;
-
- // XOR gives us positions where bits differ
- long xorResult = a ^ b;
-
- // Count set bits using Brian Kernighan's algorithm
- while (xorResult != 0) {
- xorResult = xorResult & (xorResult - 1); // Remove rightmost set bit
- count++;
- }
-
- return count;
- }
-
- /**
- * Alternative implementation using Long.bitCount().
- *
- * @param a the source number
- * @param b the target number
- * @return the number of bits to flip to convert a to b
- */
- public static long countBitsFlipAlternative(long a, long b) {
- return Long.bitCount(a ^ b);
- }
-}
+package com.thealgorithms.bitmanipulation;
+
+/**
+ * Implementation to count number of bits to be flipped to convert A to B
+ *
+ * Problem: Given two numbers A and B, count the number of bits needed to be
+ * flipped to convert A to B.
+ *
+ * Example:
+ * A = 10 (01010 in binary)
+ * B = 20 (10100 in binary)
+ * XOR = 30 (11110 in binary) - positions where bits differ
+ * Answer: 4 bits need to be flipped
+ *
+ * Time Complexity: O(log n) - where n is the number of set bits
+ * Space Complexity: O(1)
+ *
+ *@author [Yash Rajput](https://github.com/the-yash-rajput)
+ */
+public final class CountBitsFlip {
+
+ private CountBitsFlip() {
+ throw new AssertionError("No instances.");
+ }
+
+ /**
+ * Counts the number of bits that need to be flipped to convert a to b
+ *
+ * Algorithm:
+ * 1. XOR a and b to get positions where bits differ
+ * 2. Count the number of set bits in the XOR result
+ * 3. Use Brian Kernighan's algorithm: n & (n-1) removes rightmost set bit
+ *
+ * @param a the source number
+ * @param b the target number
+ * @return the number of bits to flip to convert A to B
+ */
+ public static long countBitsFlip(long a, long b) {
+ int count = 0;
+
+ // XOR gives us positions where bits differ
+ long xorResult = a ^ b;
+
+ // Count set bits using Brian Kernighan's algorithm
+ while (xorResult != 0) {
+ xorResult = xorResult & (xorResult - 1); // Remove rightmost set bit
+ count++;
+ }
+
+ return count;
+ }
+
+ /**
+ * Alternative implementation using Long.bitCount().
+ *
+ * @param a the source number
+ * @param b the target number
+ * @return the number of bits to flip to convert a to b
+ */
+ public static long countBitsFlipAlternative(long a, long b) {
+ return Long.bitCount(a ^ b);
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/CountLeadingZeros.java b/src/main/java/com/thealgorithms/bitmanipulation/CountLeadingZeros.java
index 318334f0b951..479d01bee68e 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/CountLeadingZeros.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/CountLeadingZeros.java
@@ -1,39 +1,39 @@
-package com.thealgorithms.bitmanipulation;
-
-/**
- * CountLeadingZeros class contains a method to count the number of leading zeros in the binary representation of a number.
- * The number of leading zeros is the number of zeros before the leftmost 1 bit.
- * For example, the number 5 has 29 leading zeros in its 32-bit binary representation.
- * The number 0 has 32 leading zeros.
- * The number 1 has 31 leading zeros.
- * The number -1 has no leading zeros.
- *
- * @author Hardvan
- */
-public final class CountLeadingZeros {
- private CountLeadingZeros() {
- }
-
- /**
- * Counts the number of leading zeros in the binary representation of a number.
- * Method: Keep shifting the mask to the right until the leftmost bit is 1.
- * The number of shifts is the number of leading zeros.
- *
- * @param num The input number.
- * @return The number of leading zeros.
- */
- public static int countLeadingZeros(int num) {
- if (num == 0) {
- return 32;
- }
-
- int count = 0;
- int mask = 1 << 31;
- while ((mask & num) == 0) {
- count++;
- mask >>>= 1;
- }
-
- return count;
- }
-}
+package com.thealgorithms.bitmanipulation;
+
+/**
+ * CountLeadingZeros class contains a method to count the number of leading zeros in the binary representation of a number.
+ * The number of leading zeros is the number of zeros before the leftmost 1 bit.
+ * For example, the number 5 has 29 leading zeros in its 32-bit binary representation.
+ * The number 0 has 32 leading zeros.
+ * The number 1 has 31 leading zeros.
+ * The number -1 has no leading zeros.
+ *
+ * @author Hardvan
+ */
+public final class CountLeadingZeros {
+ private CountLeadingZeros() {
+ }
+
+ /**
+ * Counts the number of leading zeros in the binary representation of a number.
+ * Method: Keep shifting the mask to the right until the leftmost bit is 1.
+ * The number of shifts is the number of leading zeros.
+ *
+ * @param num The input number.
+ * @return The number of leading zeros.
+ */
+ public static int countLeadingZeros(int num) {
+ if (num == 0) {
+ return 32;
+ }
+
+ int count = 0;
+ int mask = 1 << 31;
+ while ((mask & num) == 0) {
+ count++;
+ mask >>>= 1;
+ }
+
+ return count;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/CountSetBits.java b/src/main/java/com/thealgorithms/bitmanipulation/CountSetBits.java
index 7df522ca8f69..b574a006e95c 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/CountSetBits.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/CountSetBits.java
@@ -1,79 +1,79 @@
-package com.thealgorithms.bitmanipulation;
-
-/**
- * Utility class to count total set bits from 1 to N
- * A set bit is a bit in binary representation that is 1
- *
- * @author navadeep
- */
-public final class CountSetBits {
-
- private CountSetBits() {
- // Utility class, prevent instantiation
- }
-
- /**
- * Counts total number of set bits in all numbers from 1 to n
- * Time Complexity: O(log n)
- *
- * @param n the upper limit (inclusive)
- * @return total count of set bits from 1 to n
- * @throws IllegalArgumentException if n is negative
- */
- public static int countSetBits(int n) {
- if (n < 0) {
- throw new IllegalArgumentException("Input must be non-negative");
- }
-
- if (n == 0) {
- return 0;
- }
-
- // Find the largest power of 2 <= n
- int x = largestPowerOf2InNumber(n);
-
- // Total bits at position x: x * 2^(x-1)
- int bitsAtPositionX = x * (1 << (x - 1));
-
- // Remaining numbers after 2^x
- int remainingNumbers = n - (1 << x) + 1;
-
- // Recursively count for the rest
- int rest = countSetBits(n - (1 << x));
-
- return bitsAtPositionX + remainingNumbers + rest;
- }
-
- /**
- * Finds the position of the most significant bit in n
- *
- * @param n the number
- * @return position of MSB (0-indexed from right)
- */
- private static int largestPowerOf2InNumber(int n) {
- int position = 0;
- while ((1 << position) <= n) {
- position++;
- }
- return position - 1;
- }
-
- /**
- * Alternative naive approach - counts set bits by iterating through all numbers
- * Time Complexity: O(n log n)
- *
- * @param n the upper limit (inclusive)
- * @return total count of set bits from 1 to n
- */
- public static int countSetBitsNaive(int n) {
- if (n < 0) {
- throw new IllegalArgumentException("Input must be non-negative");
- }
-
- int count = 0;
- for (int i = 1; i <= n; i++) {
- count += Integer.bitCount(i);
- }
- return count;
- }
-}
+package com.thealgorithms.bitmanipulation;
+
+/**
+ * Utility class to count total set bits from 1 to N
+ * A set bit is a bit in binary representation that is 1
+ *
+ * @author navadeep
+ */
+public final class CountSetBits {
+
+ private CountSetBits() {
+ // Utility class, prevent instantiation
+ }
+
+ /**
+ * Counts total number of set bits in all numbers from 1 to n
+ * Time Complexity: O(log n)
+ *
+ * @param n the upper limit (inclusive)
+ * @return total count of set bits from 1 to n
+ * @throws IllegalArgumentException if n is negative
+ */
+ public static int countSetBits(int n) {
+ if (n < 0) {
+ throw new IllegalArgumentException("Input must be non-negative");
+ }
+
+ if (n == 0) {
+ return 0;
+ }
+
+ // Find the largest power of 2 <= n
+ int x = largestPowerOf2InNumber(n);
+
+ // Total bits at position x: x * 2^(x-1)
+ int bitsAtPositionX = x * (1 << (x - 1));
+
+ // Remaining numbers after 2^x
+ int remainingNumbers = n - (1 << x) + 1;
+
+ // Recursively count for the rest
+ int rest = countSetBits(n - (1 << x));
+
+ return bitsAtPositionX + remainingNumbers + rest;
+ }
+
+ /**
+ * Finds the position of the most significant bit in n
+ *
+ * @param n the number
+ * @return position of MSB (0-indexed from right)
+ */
+ private static int largestPowerOf2InNumber(int n) {
+ int position = 0;
+ while ((1 << position) <= n) {
+ position++;
+ }
+ return position - 1;
+ }
+
+ /**
+ * Alternative naive approach - counts set bits by iterating through all numbers
+ * Time Complexity: O(n log n)
+ *
+ * @param n the upper limit (inclusive)
+ * @return total count of set bits from 1 to n
+ */
+ public static int countSetBitsNaive(int n) {
+ if (n < 0) {
+ throw new IllegalArgumentException("Input must be non-negative");
+ }
+
+ int count = 0;
+ for (int i = 1; i <= n; i++) {
+ count += Integer.bitCount(i);
+ }
+ return count;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/FindNthBit.java b/src/main/java/com/thealgorithms/bitmanipulation/FindNthBit.java
index 7a35fc3feebf..25c74a1ab14b 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/FindNthBit.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/FindNthBit.java
@@ -1,46 +1,46 @@
-package com.thealgorithms.bitmanipulation;
-
-/**
- * A utility class to find the Nth bit of a given number.
- *
- * This class provides a method to extract the value of the Nth bit (either 0 or 1)
- * from the binary representation of a given integer.
- *
- *
Example:
- *
{@code
- * int result = FindNthBit.findNthBit(5, 2); // returns 0 as the 2nd bit of 5 (binary 101) is 0.
- * }
- *
- * Author: Tuhinm2002
- */
-public final class FindNthBit {
-
- /**
- * Private constructor to prevent instantiation.
- *
- *
This is a utility class, and it should not be instantiated.
- * Attempting to instantiate this class will throw an UnsupportedOperationException.
- */
- private FindNthBit() {
- throw new UnsupportedOperationException("Utility class");
- }
-
- /**
- * Finds the value of the Nth bit of the given number.
- *
- *
This method uses bitwise operations to extract the Nth bit from the
- * binary representation of the given integer.
- *
- * @param num the integer number whose Nth bit is to be found
- * @param n the bit position (1-based) to retrieve
- * @return the value of the Nth bit (0 or 1)
- * @throws IllegalArgumentException if the bit position is less than 1
- */
- public static int findNthBit(int num, int n) {
- if (n < 1) {
- throw new IllegalArgumentException("Bit position must be greater than or equal to 1.");
- }
- // Shifting the number to the right by (n - 1) positions and checking the last bit
- return (num & (1 << (n - 1))) >> (n - 1);
- }
-}
+package com.thealgorithms.bitmanipulation;
+
+/**
+ * A utility class to find the Nth bit of a given number.
+ *
+ *
This class provides a method to extract the value of the Nth bit (either 0 or 1)
+ * from the binary representation of a given integer.
+ *
+ *
Example:
+ *
{@code
+ * int result = FindNthBit.findNthBit(5, 2); // returns 0 as the 2nd bit of 5 (binary 101) is 0.
+ * }
+ *
+ * Author: Tuhinm2002
+ */
+public final class FindNthBit {
+
+ /**
+ * Private constructor to prevent instantiation.
+ *
+ *
This is a utility class, and it should not be instantiated.
+ * Attempting to instantiate this class will throw an UnsupportedOperationException.
+ */
+ private FindNthBit() {
+ throw new UnsupportedOperationException("Utility class");
+ }
+
+ /**
+ * Finds the value of the Nth bit of the given number.
+ *
+ *
This method uses bitwise operations to extract the Nth bit from the
+ * binary representation of the given integer.
+ *
+ * @param num the integer number whose Nth bit is to be found
+ * @param n the bit position (1-based) to retrieve
+ * @return the value of the Nth bit (0 or 1)
+ * @throws IllegalArgumentException if the bit position is less than 1
+ */
+ public static int findNthBit(int num, int n) {
+ if (n < 1) {
+ throw new IllegalArgumentException("Bit position must be greater than or equal to 1.");
+ }
+ // Shifting the number to the right by (n - 1) positions and checking the last bit
+ return (num & (1 << (n - 1))) >> (n - 1);
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/FirstDifferentBit.java b/src/main/java/com/thealgorithms/bitmanipulation/FirstDifferentBit.java
index 9a761c572e2c..3c55707058bd 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/FirstDifferentBit.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/FirstDifferentBit.java
@@ -1,33 +1,33 @@
-package com.thealgorithms.bitmanipulation;
-
-/**
- * This class provides a method to find the first differing bit
- * between two integers.
- *
- * Example:
- * x = 10 (1010 in binary)
- * y = 12 (1100 in binary)
- * The first differing bit is at index 1 (0-based)
- * So, the output will be 1
- *
- * @author Hardvan
- */
-public final class FirstDifferentBit {
- private FirstDifferentBit() {
- }
-
- /**
- * Identifies the index of the first differing bit between two integers.
- * Steps:
- * 1. XOR the two integers to get the differing bits
- * 2. Find the index of the first set bit in XOR result
- *
- * @param x the first integer
- * @param y the second integer
- * @return the index of the first differing bit (0-based)
- */
- public static int firstDifferentBit(int x, int y) {
- int diff = x ^ y;
- return Integer.numberOfTrailingZeros(diff);
- }
-}
+package com.thealgorithms.bitmanipulation;
+
+/**
+ * This class provides a method to find the first differing bit
+ * between two integers.
+ *
+ * Example:
+ * x = 10 (1010 in binary)
+ * y = 12 (1100 in binary)
+ * The first differing bit is at index 1 (0-based)
+ * So, the output will be 1
+ *
+ * @author Hardvan
+ */
+public final class FirstDifferentBit {
+ private FirstDifferentBit() {
+ }
+
+ /**
+ * Identifies the index of the first differing bit between two integers.
+ * Steps:
+ * 1. XOR the two integers to get the differing bits
+ * 2. Find the index of the first set bit in XOR result
+ *
+ * @param x the first integer
+ * @param y the second integer
+ * @return the index of the first differing bit (0-based)
+ */
+ public static int firstDifferentBit(int x, int y) {
+ int diff = x ^ y;
+ return Integer.numberOfTrailingZeros(diff);
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/GenerateSubsets.java b/src/main/java/com/thealgorithms/bitmanipulation/GenerateSubsets.java
index f1b812495c1b..430bd8177955 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/GenerateSubsets.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/GenerateSubsets.java
@@ -1,44 +1,44 @@
-package com.thealgorithms.bitmanipulation;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * This class provides a method to generate all subsets (power set)
- * of a given set using bit manipulation.
- *
- * @author Hardvan
- */
-public final class GenerateSubsets {
- private GenerateSubsets() {
- }
-
- /**
- * Generates all subsets of a given set using bit manipulation.
- * Steps:
- * 1. Iterate over all numbers from 0 to 2^n - 1.
- * 2. For each number, iterate over all bits from 0 to n - 1.
- * 3. If the i-th bit of the number is set, add the i-th element of the set to the current subset.
- * 4. Add the current subset to the list of subsets.
- * 5. Return the list of subsets.
- *
- * @param set the input set of integers
- * @return a list of all subsets represented as lists of integers
- */
- public static List> generateSubsets(int[] set) {
- int n = set.length;
- List> subsets = new ArrayList<>();
-
- for (int mask = 0; mask < (1 << n); mask++) {
- List subset = new ArrayList<>();
- for (int i = 0; i < n; i++) {
- if ((mask & (1 << i)) != 0) {
- subset.add(set[i]);
- }
- }
- subsets.add(subset);
- }
-
- return subsets;
- }
-}
+package com.thealgorithms.bitmanipulation;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class provides a method to generate all subsets (power set)
+ * of a given set using bit manipulation.
+ *
+ * @author Hardvan
+ */
+public final class GenerateSubsets {
+ private GenerateSubsets() {
+ }
+
+ /**
+ * Generates all subsets of a given set using bit manipulation.
+ * Steps:
+ * 1. Iterate over all numbers from 0 to 2^n - 1.
+ * 2. For each number, iterate over all bits from 0 to n - 1.
+ * 3. If the i-th bit of the number is set, add the i-th element of the set to the current subset.
+ * 4. Add the current subset to the list of subsets.
+ * 5. Return the list of subsets.
+ *
+ * @param set the input set of integers
+ * @return a list of all subsets represented as lists of integers
+ */
+ public static List> generateSubsets(int[] set) {
+ int n = set.length;
+ List> subsets = new ArrayList<>();
+
+ for (int mask = 0; mask < (1 << n); mask++) {
+ List subset = new ArrayList<>();
+ for (int i = 0; i < n; i++) {
+ if ((mask & (1 << i)) != 0) {
+ subset.add(set[i]);
+ }
+ }
+ subsets.add(subset);
+ }
+
+ return subsets;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/GrayCodeConversion.java b/src/main/java/com/thealgorithms/bitmanipulation/GrayCodeConversion.java
index 83cd30c7d50a..fe7f5c9eb04b 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/GrayCodeConversion.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/GrayCodeConversion.java
@@ -1,44 +1,44 @@
-package com.thealgorithms.bitmanipulation;
-
-/**
- * Gray code is a binary numeral system where two successive values differ in only one bit.
- * This is a simple conversion between binary and Gray code.
- * Example:
- * 7 -> 0111 -> 0100 -> 4
- * 4 -> 0100 -> 0111 -> 7
- * 0 -> 0000 -> 0000 -> 0
- * 1 -> 0001 -> 0000 -> 0
- * 2 -> 0010 -> 0011 -> 3
- * 3 -> 0011 -> 0010 -> 2
- *
- * @author Hardvan
- */
-public final class GrayCodeConversion {
- private GrayCodeConversion() {
- }
-
- /**
- * Converts a binary number to Gray code.
- *
- * @param num The binary number.
- * @return The corresponding Gray code.
- */
- public static int binaryToGray(int num) {
- return num ^ (num >> 1);
- }
-
- /**
- * Converts a Gray code number back to binary.
- *
- * @param gray The Gray code number.
- * @return The corresponding binary number.
- */
- public static int grayToBinary(int gray) {
- int binary = gray;
- while (gray > 0) {
- gray >>= 1;
- binary ^= gray;
- }
- return binary;
- }
-}
+package com.thealgorithms.bitmanipulation;
+
+/**
+ * Gray code is a binary numeral system where two successive values differ in only one bit.
+ * This is a simple conversion between binary and Gray code.
+ * Example:
+ * 7 -> 0111 -> 0100 -> 4
+ * 4 -> 0100 -> 0111 -> 7
+ * 0 -> 0000 -> 0000 -> 0
+ * 1 -> 0001 -> 0000 -> 0
+ * 2 -> 0010 -> 0011 -> 3
+ * 3 -> 0011 -> 0010 -> 2
+ *
+ * @author Hardvan
+ */
+public final class GrayCodeConversion {
+ private GrayCodeConversion() {
+ }
+
+ /**
+ * Converts a binary number to Gray code.
+ *
+ * @param num The binary number.
+ * @return The corresponding Gray code.
+ */
+ public static int binaryToGray(int num) {
+ return num ^ (num >> 1);
+ }
+
+ /**
+ * Converts a Gray code number back to binary.
+ *
+ * @param gray The Gray code number.
+ * @return The corresponding binary number.
+ */
+ public static int grayToBinary(int gray) {
+ int binary = gray;
+ while (gray > 0) {
+ gray >>= 1;
+ binary ^= gray;
+ }
+ return binary;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/HammingDistance.java b/src/main/java/com/thealgorithms/bitmanipulation/HammingDistance.java
index 4c24909ef234..06d8ebe6b041 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/HammingDistance.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/HammingDistance.java
@@ -1,29 +1,29 @@
-package com.thealgorithms.bitmanipulation;
-
-/**
- * The Hamming distance between two integers is the number of positions at which the corresponding bits are different.
- * Given two integers x and y, calculate the Hamming distance.
- * Example:
- * Input: x = 1, y = 4
- * Output: 2
- * Explanation: 1 (0001) and 4 (0100) have 2 differing bits.
- *
- * @author Hardvan
- */
-public final class HammingDistance {
- private HammingDistance() {
- }
-
- /**
- * Calculates the Hamming distance between two integers.
- * The Hamming distance is the number of differing bits between the two integers.
- *
- * @param x The first integer.
- * @param y The second integer.
- * @return The Hamming distance (number of differing bits).
- */
- public static int hammingDistance(int x, int y) {
- int xor = x ^ y;
- return Integer.bitCount(xor);
- }
-}
+package com.thealgorithms.bitmanipulation;
+
+/**
+ * The Hamming distance between two integers is the number of positions at which the corresponding bits are different.
+ * Given two integers x and y, calculate the Hamming distance.
+ * Example:
+ * Input: x = 1, y = 4
+ * Output: 2
+ * Explanation: 1 (0001) and 4 (0100) have 2 differing bits.
+ *
+ * @author Hardvan
+ */
+public final class HammingDistance {
+ private HammingDistance() {
+ }
+
+ /**
+ * Calculates the Hamming distance between two integers.
+ * The Hamming distance is the number of differing bits between the two integers.
+ *
+ * @param x The first integer.
+ * @param y The second integer.
+ * @return The Hamming distance (number of differing bits).
+ */
+ public static int hammingDistance(int x, int y) {
+ int xor = x ^ y;
+ return Integer.bitCount(xor);
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/HigherLowerPowerOfTwo.java b/src/main/java/com/thealgorithms/bitmanipulation/HigherLowerPowerOfTwo.java
index 0fb058b2b8a3..85614c9ed9c3 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/HigherLowerPowerOfTwo.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/HigherLowerPowerOfTwo.java
@@ -1,54 +1,54 @@
-package com.thealgorithms.bitmanipulation;
-
-/**
- * HigherLowerPowerOfTwo class has two methods to find the next higher and lower power of two.
- *
- * nextHigherPowerOfTwo method finds the next higher power of two.
- * nextLowerPowerOfTwo method finds the next lower power of two.
- * Both methods take an integer as input and return the next higher or lower power of two.
- * If the input is less than 1, the next higher power of two is 1.
- * If the input is less than or equal to 1, the next lower power of two is 0.
- * nextHigherPowerOfTwo method uses bitwise operations to find the next higher power of two.
- * nextLowerPowerOfTwo method uses Integer.highestOneBit method to find the next lower power of two.
- * The time complexity of both methods is O(1).
- * The space complexity of both methods is O(1).
- *
- *
- * @author Hardvan
- */
-public final class HigherLowerPowerOfTwo {
- private HigherLowerPowerOfTwo() {
- }
-
- /**
- * Finds the next higher power of two.
- *
- * @param x The given number.
- * @return The next higher power of two.
- */
- public static int nextHigherPowerOfTwo(int x) {
- if (x < 1) {
- return 1;
- }
- x--;
- x |= x >> 1;
- x |= x >> 2;
- x |= x >> 4;
- x |= x >> 8;
- x |= x >> 16;
- return x + 1;
- }
-
- /**
- * Finds the next lower power of two.
- *
- * @param x The given number.
- * @return The next lower power of two.
- */
- public static int nextLowerPowerOfTwo(int x) {
- if (x < 1) {
- return 0;
- }
- return Integer.highestOneBit(x);
- }
-}
+package com.thealgorithms.bitmanipulation;
+
+/**
+ * HigherLowerPowerOfTwo class has two methods to find the next higher and lower power of two.
+ *
+ * nextHigherPowerOfTwo method finds the next higher power of two.
+ * nextLowerPowerOfTwo method finds the next lower power of two.
+ * Both methods take an integer as input and return the next higher or lower power of two.
+ * If the input is less than 1, the next higher power of two is 1.
+ * If the input is less than or equal to 1, the next lower power of two is 0.
+ * nextHigherPowerOfTwo method uses bitwise operations to find the next higher power of two.
+ * nextLowerPowerOfTwo method uses Integer.highestOneBit method to find the next lower power of two.
+ * The time complexity of both methods is O(1).
+ * The space complexity of both methods is O(1).
+ *
+ *
+ * @author Hardvan
+ */
+public final class HigherLowerPowerOfTwo {
+ private HigherLowerPowerOfTwo() {
+ }
+
+ /**
+ * Finds the next higher power of two.
+ *
+ * @param x The given number.
+ * @return The next higher power of two.
+ */
+ public static int nextHigherPowerOfTwo(int x) {
+ if (x < 1) {
+ return 1;
+ }
+ x--;
+ x |= x >> 1;
+ x |= x >> 2;
+ x |= x >> 4;
+ x |= x >> 8;
+ x |= x >> 16;
+ return x + 1;
+ }
+
+ /**
+ * Finds the next lower power of two.
+ *
+ * @param x The given number.
+ * @return The next lower power of two.
+ */
+ public static int nextLowerPowerOfTwo(int x) {
+ if (x < 1) {
+ return 0;
+ }
+ return Integer.highestOneBit(x);
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/HighestSetBit.java b/src/main/java/com/thealgorithms/bitmanipulation/HighestSetBit.java
index 2398b8214371..e145ee87269d 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/HighestSetBit.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/HighestSetBit.java
@@ -1,54 +1,54 @@
-package com.thealgorithms.bitmanipulation;
-
-import java.util.Optional;
-
-/**
- * Find Highest Set Bit
- *
- * This class provides a utility method to calculate the position of the highest
- * (most significant) bit that is set to 1 in a given non-negative integer.
- * It is often used in bit manipulation tasks to find the left-most set bit in binary
- * representation of a number.
- *
- * Example:
- * - For input 18 (binary 10010), the highest set bit is at position 4 (zero-based index).
- *
- * @author Bama Charan Chhandogi
- * @version 1.0
- * @since 2021-06-23
- */
-public final class HighestSetBit {
-
- private HighestSetBit() {
- }
-
- /**
- * Finds the highest (most significant) set bit in the given integer.
- * The method returns the position (index) of the highest set bit as an {@link Optional}.
- *
- * - If the number is 0, no bits are set, and the method returns {@link Optional#empty()}.
- * - If the number is negative, the method throws {@link IllegalArgumentException}.
- *
- * @param num The input integer for which the highest set bit is to be found. It must be non-negative.
- * @return An {@link Optional} containing the index of the highest set bit (zero-based).
- * Returns {@link Optional#empty()} if the number is 0.
- * @throws IllegalArgumentException if the input number is negative.
- */
- public static Optional findHighestSetBit(int num) {
- if (num < 0) {
- throw new IllegalArgumentException("Input cannot be negative");
- }
-
- if (num == 0) {
- return Optional.empty();
- }
-
- int position = 0;
- while (num > 0) {
- num >>= 1;
- position++;
- }
-
- return Optional.of(position - 1); // Subtract 1 to convert to zero-based index
- }
-}
+package com.thealgorithms.bitmanipulation;
+
+import java.util.Optional;
+
+/**
+ * Find Highest Set Bit
+ *
+ * This class provides a utility method to calculate the position of the highest
+ * (most significant) bit that is set to 1 in a given non-negative integer.
+ * It is often used in bit manipulation tasks to find the left-most set bit in binary
+ * representation of a number.
+ *
+ * Example:
+ * - For input 18 (binary 10010), the highest set bit is at position 4 (zero-based index).
+ *
+ * @author Bama Charan Chhandogi
+ * @version 1.0
+ * @since 2021-06-23
+ */
+public final class HighestSetBit {
+
+ private HighestSetBit() {
+ }
+
+ /**
+ * Finds the highest (most significant) set bit in the given integer.
+ * The method returns the position (index) of the highest set bit as an {@link Optional}.
+ *
+ * - If the number is 0, no bits are set, and the method returns {@link Optional#empty()}.
+ * - If the number is negative, the method throws {@link IllegalArgumentException}.
+ *
+ * @param num The input integer for which the highest set bit is to be found. It must be non-negative.
+ * @return An {@link Optional} containing the index of the highest set bit (zero-based).
+ * Returns {@link Optional#empty()} if the number is 0.
+ * @throws IllegalArgumentException if the input number is negative.
+ */
+ public static Optional findHighestSetBit(int num) {
+ if (num < 0) {
+ throw new IllegalArgumentException("Input cannot be negative");
+ }
+
+ if (num == 0) {
+ return Optional.empty();
+ }
+
+ int position = 0;
+ while (num > 0) {
+ num >>= 1;
+ position++;
+ }
+
+ return Optional.of(position - 1); // Subtract 1 to convert to zero-based index
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/IndexOfRightMostSetBit.java b/src/main/java/com/thealgorithms/bitmanipulation/IndexOfRightMostSetBit.java
index 1b8962344ea7..a1ef689c55e0 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/IndexOfRightMostSetBit.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/IndexOfRightMostSetBit.java
@@ -1,44 +1,44 @@
-package com.thealgorithms.bitmanipulation;
-
-/**
- * Utility class for bit manipulation operations.
- * This class provides methods to work with bitwise operations.
- * Specifically, it includes a method to find the index of the rightmost set bit
- * in an integer.
- * This class is not meant to be instantiated.
- *
- * Author: Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi)
- */
-public final class IndexOfRightMostSetBit {
-
- private IndexOfRightMostSetBit() {
- }
-
- /**
- * Finds the index of the rightmost set bit in the given integer.
- * The index is zero-based, meaning the rightmost bit has an index of 0.
- *
- * @param n the integer to check for the rightmost set bit
- * @return the index of the rightmost set bit; -1 if there are no set bits
- * (i.e., the input integer is 0)
- */
- public static int indexOfRightMostSetBit(int n) {
- if (n == 0) {
- return -1; // No set bits
- }
-
- // Handle negative numbers by finding the two's complement
- if (n < 0) {
- n = -n;
- n = n & (~n + 1); // Isolate the rightmost set bit
- }
-
- int index = 0;
- while ((n & 1) == 0) {
- n = n >> 1;
- index++;
- }
-
- return index;
- }
-}
+package com.thealgorithms.bitmanipulation;
+
+/**
+ * Utility class for bit manipulation operations.
+ * This class provides methods to work with bitwise operations.
+ * Specifically, it includes a method to find the index of the rightmost set bit
+ * in an integer.
+ * This class is not meant to be instantiated.
+ *
+ * Author: Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi)
+ */
+public final class IndexOfRightMostSetBit {
+
+ private IndexOfRightMostSetBit() {
+ }
+
+ /**
+ * Finds the index of the rightmost set bit in the given integer.
+ * The index is zero-based, meaning the rightmost bit has an index of 0.
+ *
+ * @param n the integer to check for the rightmost set bit
+ * @return the index of the rightmost set bit; -1 if there are no set bits
+ * (i.e., the input integer is 0)
+ */
+ public static int indexOfRightMostSetBit(int n) {
+ if (n == 0) {
+ return -1; // No set bits
+ }
+
+ // Handle negative numbers by finding the two's complement
+ if (n < 0) {
+ n = -n;
+ n = n & (~n + 1); // Isolate the rightmost set bit
+ }
+
+ int index = 0;
+ while ((n & 1) == 0) {
+ n = n >> 1;
+ index++;
+ }
+
+ return index;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/IsEven.java b/src/main/java/com/thealgorithms/bitmanipulation/IsEven.java
index 09d5383322ff..6fce39dc3074 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/IsEven.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/IsEven.java
@@ -1,14 +1,14 @@
-package com.thealgorithms.bitmanipulation;
-
-/**
- * Checks whether a number is even
- * @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi)
- */
-
-public final class IsEven {
- private IsEven() {
- }
- public static boolean isEven(int number) {
- return (number & 1) == 0;
- }
-}
+package com.thealgorithms.bitmanipulation;
+
+/**
+ * Checks whether a number is even
+ * @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi)
+ */
+
+public final class IsEven {
+ private IsEven() {
+ }
+ public static boolean isEven(int number) {
+ return (number & 1) == 0;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/IsPowerTwo.java b/src/main/java/com/thealgorithms/bitmanipulation/IsPowerTwo.java
index 4cdf3c6faa3e..1c229753c1fa 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/IsPowerTwo.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/IsPowerTwo.java
@@ -1,32 +1,32 @@
-package com.thealgorithms.bitmanipulation;
-
-/**
- * Utility class for checking if a number is a power of two.
- * A power of two is a number that can be expressed as 2^n where n is a non-negative integer.
- * This class provides a method to determine if a given integer is a power of two using bit manipulation.
- *
- * @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi)
- */
-public final class IsPowerTwo {
- private IsPowerTwo() {
- }
-
- /**
- * Checks if the given integer is a power of two.
- *
- * A number is considered a power of two if it is greater than zero and
- * has exactly one '1' bit in its binary representation. This method
- * uses the property that for any power of two (n), the expression
- * (n & (n - 1)) will be zero.
- *
- * @param number the integer to check
- * @return true if the number is a power of two, false otherwise
- */
- public static boolean isPowerTwo(int number) {
- if (number <= 0) {
- return false;
- }
- int ans = number & (number - 1);
- return ans == 0;
- }
-}
+package com.thealgorithms.bitmanipulation;
+
+/**
+ * Utility class for checking if a number is a power of two.
+ * A power of two is a number that can be expressed as 2^n where n is a non-negative integer.
+ * This class provides a method to determine if a given integer is a power of two using bit manipulation.
+ *
+ * @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi)
+ */
+public final class IsPowerTwo {
+ private IsPowerTwo() {
+ }
+
+ /**
+ * Checks if the given integer is a power of two.
+ *
+ * A number is considered a power of two if it is greater than zero and
+ * has exactly one '1' bit in its binary representation. This method
+ * uses the property that for any power of two (n), the expression
+ * (n & (n - 1)) will be zero.
+ *
+ * @param number the integer to check
+ * @return true if the number is a power of two, false otherwise
+ */
+ public static boolean isPowerTwo(int number) {
+ if (number <= 0) {
+ return false;
+ }
+ int ans = number & (number - 1);
+ return ans == 0;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/LowestSetBit.java b/src/main/java/com/thealgorithms/bitmanipulation/LowestSetBit.java
index 127b6fa2c0b1..5ab898e1c6d8 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/LowestSetBit.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/LowestSetBit.java
@@ -1,34 +1,34 @@
-package com.thealgorithms.bitmanipulation;
-
-/**
- * Lowest Set Bit
- * @author Prayas Kumar (https://github.com/prayas7102)
- */
-
-public final class LowestSetBit {
- // Private constructor to hide the default public one
- private LowestSetBit() {
- }
- /**
- * Isolates the lowest set bit of the given number. For example, if n = 18
- * (binary: 10010), the result will be 2 (binary: 00010).
- *
- * @param n the number whose lowest set bit will be isolated
- * @return the isolated lowest set bit of n
- */
- public static int isolateLowestSetBit(int n) {
- // Isolate the lowest set bit using n & -n
- return n & -n;
- }
- /**
- * Clears the lowest set bit of the given number.
- * For example, if n = 18 (binary: 10010), the result will be 16 (binary: 10000).
- *
- * @param n the number whose lowest set bit will be cleared
- * @return the number after clearing its lowest set bit
- */
- public static int clearLowestSetBit(int n) {
- // Clear the lowest set bit using n & (n - 1)
- return n & (n - 1);
- }
-}
+package com.thealgorithms.bitmanipulation;
+
+/**
+ * Lowest Set Bit
+ * @author Prayas Kumar (https://github.com/prayas7102)
+ */
+
+public final class LowestSetBit {
+ // Private constructor to hide the default public one
+ private LowestSetBit() {
+ }
+ /**
+ * Isolates the lowest set bit of the given number. For example, if n = 18
+ * (binary: 10010), the result will be 2 (binary: 00010).
+ *
+ * @param n the number whose lowest set bit will be isolated
+ * @return the isolated lowest set bit of n
+ */
+ public static int isolateLowestSetBit(int n) {
+ // Isolate the lowest set bit using n & -n
+ return n & -n;
+ }
+ /**
+ * Clears the lowest set bit of the given number.
+ * For example, if n = 18 (binary: 10010), the result will be 16 (binary: 10000).
+ *
+ * @param n the number whose lowest set bit will be cleared
+ * @return the number after clearing its lowest set bit
+ */
+ public static int clearLowestSetBit(int n) {
+ // Clear the lowest set bit using n & (n - 1)
+ return n & (n - 1);
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/ModuloPowerOfTwo.java b/src/main/java/com/thealgorithms/bitmanipulation/ModuloPowerOfTwo.java
index 537a046f77e4..27b581e78d5e 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/ModuloPowerOfTwo.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/ModuloPowerOfTwo.java
@@ -1,28 +1,28 @@
-package com.thealgorithms.bitmanipulation;
-
-/**
- * This class provides a method to compute the remainder
- * of a number when divided by a power of two (2^n)
- * without using division or modulo operations.
- *
- * @author Hardvan
- */
-public final class ModuloPowerOfTwo {
- private ModuloPowerOfTwo() {
- }
-
- /**
- * Computes the remainder of a given integer when divided by 2^n.
- *
- * @param x the input number
- * @param n the exponent (power of two)
- * @return the remainder of x divided by 2^n
- */
- public static int moduloPowerOfTwo(int x, int n) {
- if (n <= 0) {
- throw new IllegalArgumentException("The exponent must be positive");
- }
-
- return x & ((1 << n) - 1);
- }
-}
+package com.thealgorithms.bitmanipulation;
+
+/**
+ * This class provides a method to compute the remainder
+ * of a number when divided by a power of two (2^n)
+ * without using division or modulo operations.
+ *
+ * @author Hardvan
+ */
+public final class ModuloPowerOfTwo {
+ private ModuloPowerOfTwo() {
+ }
+
+ /**
+ * Computes the remainder of a given integer when divided by 2^n.
+ *
+ * @param x the input number
+ * @param n the exponent (power of two)
+ * @return the remainder of x divided by 2^n
+ */
+ public static int moduloPowerOfTwo(int x, int n) {
+ if (n <= 0) {
+ throw new IllegalArgumentException("The exponent must be positive");
+ }
+
+ return x & ((1 << n) - 1);
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/NextHigherSameBitCount.java b/src/main/java/com/thealgorithms/bitmanipulation/NextHigherSameBitCount.java
index 6a764d806279..dce0d91a239d 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/NextHigherSameBitCount.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/NextHigherSameBitCount.java
@@ -1,30 +1,30 @@
-package com.thealgorithms.bitmanipulation;
-
-/**
- * This class provides a method to find the next higher number
- * with the same number of set bits as the given number.
- *
- * @author Hardvan
- */
-public final class NextHigherSameBitCount {
- private NextHigherSameBitCount() {
- }
-
- /**
- * Finds the next higher integer with the same number of set bits.
- * Steps:
- * 1. Find {@code c}, the rightmost set bit of {@code n}.
- * 2. Find {@code r}, the rightmost set bit of {@code n + c}.
- * 3. Swap the bits of {@code r} and {@code n} to the right of {@code c}.
- * 4. Shift the bits of {@code r} and {@code n} to the right of {@code c} to the rightmost.
- * 5. Combine the results of steps 3 and 4.
- *
- * @param n the input number
- * @return the next higher integer with the same set bit count
- */
- public static int nextHigherSameBitCount(int n) {
- int c = n & -n;
- int r = n + c;
- return (((r ^ n) >> 2) / c) | r;
- }
-}
+package com.thealgorithms.bitmanipulation;
+
+/**
+ * This class provides a method to find the next higher number
+ * with the same number of set bits as the given number.
+ *
+ * @author Hardvan
+ */
+public final class NextHigherSameBitCount {
+ private NextHigherSameBitCount() {
+ }
+
+ /**
+ * Finds the next higher integer with the same number of set bits.
+ * Steps:
+ * 1. Find {@code c}, the rightmost set bit of {@code n}.
+ * 2. Find {@code r}, the rightmost set bit of {@code n + c}.
+ * 3. Swap the bits of {@code r} and {@code n} to the right of {@code c}.
+ * 4. Shift the bits of {@code r} and {@code n} to the right of {@code c} to the rightmost.
+ * 5. Combine the results of steps 3 and 4.
+ *
+ * @param n the input number
+ * @return the next higher integer with the same set bit count
+ */
+ public static int nextHigherSameBitCount(int n) {
+ int c = n & -n;
+ int r = n + c;
+ return (((r ^ n) >> 2) / c) | r;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinder.java b/src/main/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinder.java
index 17e1a73ec062..16e65fed7761 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinder.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinder.java
@@ -1,35 +1,35 @@
-package com.thealgorithms.bitmanipulation;
-
-/**
- * A utility class to find the non-repeating number in an array where every other number repeats.
- * This class contains a method to identify the single unique number using bit manipulation.
- *
- * The solution leverages the properties of the XOR operation, which states that:
- * - x ^ x = 0 for any integer x (a number XORed with itself is zero)
- * - x ^ 0 = x for any integer x (a number XORed with zero is the number itself)
- *
- * Using these properties, we can find the non-repeating number in linear time with constant space.
- *
- * Example:
- * Given the input array [2, 3, 5, 2, 3], the output will be 5 since it does not repeat.
- *
- * @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi)
- */
-public final class NonRepeatingNumberFinder {
- private NonRepeatingNumberFinder() {
- }
-
- /**
- * Finds the non-repeating number in the given array.
- *
- * @param arr an array of integers where every number except one appears twice
- * @return the integer that appears only once in the array or 0 if the array is empty
- */
- public static int findNonRepeatingNumber(int[] arr) {
- int result = 0;
- for (int num : arr) {
- result ^= num;
- }
- return result;
- }
-}
+package com.thealgorithms.bitmanipulation;
+
+/**
+ * A utility class to find the non-repeating number in an array where every other number repeats.
+ * This class contains a method to identify the single unique number using bit manipulation.
+ *
+ * The solution leverages the properties of the XOR operation, which states that:
+ * - x ^ x = 0 for any integer x (a number XORed with itself is zero)
+ * - x ^ 0 = x for any integer x (a number XORed with zero is the number itself)
+ *
+ * Using these properties, we can find the non-repeating number in linear time with constant space.
+ *
+ * Example:
+ * Given the input array [2, 3, 5, 2, 3], the output will be 5 since it does not repeat.
+ *
+ * @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi)
+ */
+public final class NonRepeatingNumberFinder {
+ private NonRepeatingNumberFinder() {
+ }
+
+ /**
+ * Finds the non-repeating number in the given array.
+ *
+ * @param arr an array of integers where every number except one appears twice
+ * @return the integer that appears only once in the array or 0 if the array is empty
+ */
+ public static int findNonRepeatingNumber(int[] arr) {
+ int result = 0;
+ for (int num : arr) {
+ result ^= num;
+ }
+ return result;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/NumberAppearingOddTimes.java b/src/main/java/com/thealgorithms/bitmanipulation/NumberAppearingOddTimes.java
index bd4868d4dbd5..cfddc7a8a940 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/NumberAppearingOddTimes.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/NumberAppearingOddTimes.java
@@ -1,41 +1,41 @@
-package com.thealgorithms.bitmanipulation;
-
-/**
- * This class provides a method to find the element that appears an
- * odd number of times in an array. All other elements in the array
- * must appear an even number of times for the logic to work.
- *
- * The solution uses the XOR operation, which has the following properties:
- * - a ^ a = 0 (XOR-ing the same numbers cancels them out)
- * - a ^ 0 = a
- * - XOR is commutative and associative.
- *
- * Time Complexity: O(n), where n is the size of the array.
- * Space Complexity: O(1), as no extra space is used.
- *
- * Usage Example:
- * int result = NumberAppearingOddTimes.findOddOccurrence(new int[]{1, 2, 1, 2, 3});
- * // result will be 3
- *
- * @author Lakshyajeet Singh Goyal (https://github.com/DarkMatter-999)
- */
-
-public final class NumberAppearingOddTimes {
- private NumberAppearingOddTimes() {
- }
-
- /**
- * Finds the element in the array that appears an odd number of times.
- *
- * @param arr the input array containing integers, where all elements
- * except one appear an even number of times.
- * @return the integer that appears an odd number of times.
- */
- public static int findOddOccurrence(int[] arr) {
- int result = 0;
- for (int num : arr) {
- result ^= num;
- }
- return result;
- }
-}
+package com.thealgorithms.bitmanipulation;
+
+/**
+ * This class provides a method to find the element that appears an
+ * odd number of times in an array. All other elements in the array
+ * must appear an even number of times for the logic to work.
+ *
+ * The solution uses the XOR operation, which has the following properties:
+ * - a ^ a = 0 (XOR-ing the same numbers cancels them out)
+ * - a ^ 0 = a
+ * - XOR is commutative and associative.
+ *
+ * Time Complexity: O(n), where n is the size of the array.
+ * Space Complexity: O(1), as no extra space is used.
+ *
+ * Usage Example:
+ * int result = NumberAppearingOddTimes.findOddOccurrence(new int[]{1, 2, 1, 2, 3});
+ * // result will be 3
+ *
+ * @author Lakshyajeet Singh Goyal (https://github.com/DarkMatter-999)
+ */
+
+public final class NumberAppearingOddTimes {
+ private NumberAppearingOddTimes() {
+ }
+
+ /**
+ * Finds the element in the array that appears an odd number of times.
+ *
+ * @param arr the input array containing integers, where all elements
+ * except one appear an even number of times.
+ * @return the integer that appears an odd number of times.
+ */
+ public static int findOddOccurrence(int[] arr) {
+ int result = 0;
+ for (int num : arr) {
+ result ^= num;
+ }
+ return result;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/NumbersDifferentSigns.java b/src/main/java/com/thealgorithms/bitmanipulation/NumbersDifferentSigns.java
index a2da37aa81ee..df8363e98508 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/NumbersDifferentSigns.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/NumbersDifferentSigns.java
@@ -1,30 +1,30 @@
-package com.thealgorithms.bitmanipulation;
-
-/**
- * This class provides a method to determine whether two integers have
- * different signs. It utilizes the XOR operation on the two numbers:
- *
- * - If two numbers have different signs, their most significant bits
- * (sign bits) will differ, resulting in a negative XOR result.
- * - If two numbers have the same sign, the XOR result will be non-negative.
- *
- * Time Complexity: O(1) - Constant time operation.
- * Space Complexity: O(1) - No extra space used.
- *
- * @author Bama Charan Chhandogi
- */
-public final class NumbersDifferentSigns {
- private NumbersDifferentSigns() {
- }
-
- /**
- * Determines if two integers have different signs using bitwise XOR.
- *
- * @param num1 the first integer
- * @param num2 the second integer
- * @return true if the two numbers have different signs, false otherwise
- */
- public static boolean differentSigns(int num1, int num2) {
- return (num1 ^ num2) < 0;
- }
-}
+package com.thealgorithms.bitmanipulation;
+
+/**
+ * This class provides a method to determine whether two integers have
+ * different signs. It utilizes the XOR operation on the two numbers:
+ *
+ * - If two numbers have different signs, their most significant bits
+ * (sign bits) will differ, resulting in a negative XOR result.
+ * - If two numbers have the same sign, the XOR result will be non-negative.
+ *
+ * Time Complexity: O(1) - Constant time operation.
+ * Space Complexity: O(1) - No extra space used.
+ *
+ * @author Bama Charan Chhandogi
+ */
+public final class NumbersDifferentSigns {
+ private NumbersDifferentSigns() {
+ }
+
+ /**
+ * Determines if two integers have different signs using bitwise XOR.
+ *
+ * @param num1 the first integer
+ * @param num2 the second integer
+ * @return true if the two numbers have different signs, false otherwise
+ */
+ public static boolean differentSigns(int num1, int num2) {
+ return (num1 ^ num2) < 0;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/OneBitDifference.java b/src/main/java/com/thealgorithms/bitmanipulation/OneBitDifference.java
index afec0188e299..63ec6514073e 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/OneBitDifference.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/OneBitDifference.java
@@ -1,32 +1,32 @@
-package com.thealgorithms.bitmanipulation;
-
-/**
- * This class provides a method to detect if two integers
- * differ by exactly one bit flip.
- *
- * Example:
- * 1 (0001) and 2 (0010) differ by exactly one bit flip.
- * 7 (0111) and 3 (0011) differ by exactly one bit flip.
- *
- * @author Hardvan
- */
-public final class OneBitDifference {
- private OneBitDifference() {
- }
-
- /**
- * Checks if two integers differ by exactly one bit.
- *
- * @param x the first integer
- * @param y the second integer
- * @return true if x and y differ by exactly one bit, false otherwise
- */
- public static boolean differByOneBit(int x, int y) {
- if (x == y) {
- return false;
- }
-
- int xor = x ^ y;
- return (xor & (xor - 1)) == 0;
- }
-}
+package com.thealgorithms.bitmanipulation;
+
+/**
+ * This class provides a method to detect if two integers
+ * differ by exactly one bit flip.
+ *
+ * Example:
+ * 1 (0001) and 2 (0010) differ by exactly one bit flip.
+ * 7 (0111) and 3 (0011) differ by exactly one bit flip.
+ *
+ * @author Hardvan
+ */
+public final class OneBitDifference {
+ private OneBitDifference() {
+ }
+
+ /**
+ * Checks if two integers differ by exactly one bit.
+ *
+ * @param x the first integer
+ * @param y the second integer
+ * @return true if x and y differ by exactly one bit, false otherwise
+ */
+ public static boolean differByOneBit(int x, int y) {
+ if (x == y) {
+ return false;
+ }
+
+ int xor = x ^ y;
+ return (xor & (xor - 1)) == 0;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/OnesComplement.java b/src/main/java/com/thealgorithms/bitmanipulation/OnesComplement.java
index aae3a996e49d..2dc3578f0c73 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/OnesComplement.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/OnesComplement.java
@@ -1,37 +1,37 @@
-package com.thealgorithms.bitmanipulation;
-
-/**
- * @author - https://github.com/Monk-AbhinayVerma
- * @Wikipedia - https://en.wikipedia.org/wiki/Ones%27_complement
- * The class OnesComplement computes the complement of binary number
- * and returns
- * the complemented binary string.
- * @return the complimented binary string
- */
-public final class OnesComplement {
- private OnesComplement() {
- }
-
- /**
- * Returns the 1's complement of a binary string.
- *
- * @param binary A string representing a binary number (e.g., "1010").
- * @return A string representing the 1's complement.
- * @throws IllegalArgumentException if the input is null or contains characters other than '0' or '1'.
- */
- public static String onesComplement(String binary) {
- if (binary == null || binary.isEmpty()) {
- throw new IllegalArgumentException("Input must be a non-empty binary string.");
- }
-
- StringBuilder complement = new StringBuilder(binary.length());
- for (char bit : binary.toCharArray()) {
- switch (bit) {
- case '0' -> complement.append('1');
- case '1' -> complement.append('0');
- default -> throw new IllegalArgumentException("Input must contain only '0' and '1'. Found: " + bit);
- }
- }
- return complement.toString();
- }
-}
+package com.thealgorithms.bitmanipulation;
+
+/**
+ * @author - https://github.com/Monk-AbhinayVerma
+ * @Wikipedia - https://en.wikipedia.org/wiki/Ones%27_complement
+ * The class OnesComplement computes the complement of binary number
+ * and returns
+ * the complemented binary string.
+ * @return the complimented binary string
+ */
+public final class OnesComplement {
+ private OnesComplement() {
+ }
+
+ /**
+ * Returns the 1's complement of a binary string.
+ *
+ * @param binary A string representing a binary number (e.g., "1010").
+ * @return A string representing the 1's complement.
+ * @throws IllegalArgumentException if the input is null or contains characters other than '0' or '1'.
+ */
+ public static String onesComplement(String binary) {
+ if (binary == null || binary.isEmpty()) {
+ throw new IllegalArgumentException("Input must be a non-empty binary string.");
+ }
+
+ StringBuilder complement = new StringBuilder(binary.length());
+ for (char bit : binary.toCharArray()) {
+ switch (bit) {
+ case '0' -> complement.append('1');
+ case '1' -> complement.append('0');
+ default -> throw new IllegalArgumentException("Input must contain only '0' and '1'. Found: " + bit);
+ }
+ }
+ return complement.toString();
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/ParityCheck.java b/src/main/java/com/thealgorithms/bitmanipulation/ParityCheck.java
index 5acab4d4a362..e0fbb39cfccc 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/ParityCheck.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/ParityCheck.java
@@ -1,34 +1,34 @@
-package com.thealgorithms.bitmanipulation;
-
-/**
- * The ParityCheck class provides a method to check the parity of a given number.
- *
- * Parity is a mathematical term that describes the property of an integer's binary representation.
- * The parity of a binary number is the number of 1s in its binary representation.
- * If the number of 1s is even, the parity is even; otherwise, it is odd.
- *
- * For example, the binary representation of 5 is 101, which has two 1s, so the parity of 5 is even.
- * The binary representation of 6 is 110, which has two 1s, so the parity of 6 is even.
- * The binary representation of 7 is 111, which has three 1s, so the parity of 7 is odd.
- *
- * @author Hardvan
- */
-public final class ParityCheck {
- private ParityCheck() {
- }
-
- /**
- * This method checks the parity of the given number.
- *
- * @param n the number to check the parity of
- * @return true if the number has even parity, false otherwise
- */
- public static boolean checkParity(int n) {
- int count = 0;
- while (n > 0) {
- count += n & 1;
- n >>= 1;
- }
- return count % 2 == 0;
- }
-}
+package com.thealgorithms.bitmanipulation;
+
+/**
+ * The ParityCheck class provides a method to check the parity of a given number.
+ *
+ * Parity is a mathematical term that describes the property of an integer's binary representation.
+ * The parity of a binary number is the number of 1s in its binary representation.
+ * If the number of 1s is even, the parity is even; otherwise, it is odd.
+ *
+ * For example, the binary representation of 5 is 101, which has two 1s, so the parity of 5 is even.
+ * The binary representation of 6 is 110, which has two 1s, so the parity of 6 is even.
+ * The binary representation of 7 is 111, which has three 1s, so the parity of 7 is odd.
+ *
+ * @author Hardvan
+ */
+public final class ParityCheck {
+ private ParityCheck() {
+ }
+
+ /**
+ * This method checks the parity of the given number.
+ *
+ * @param n the number to check the parity of
+ * @return true if the number has even parity, false otherwise
+ */
+ public static boolean checkParity(int n) {
+ int count = 0;
+ while (n > 0) {
+ count += n & 1;
+ n >>= 1;
+ }
+ return count % 2 == 0;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/ReverseBits.java b/src/main/java/com/thealgorithms/bitmanipulation/ReverseBits.java
index 12c269d9be48..b55f0397928b 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/ReverseBits.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/ReverseBits.java
@@ -1,41 +1,41 @@
-package com.thealgorithms.bitmanipulation;
-
-/**
- * This class provides a method to reverse the bits of a 32-bit integer.
- * Reversing the bits means that the least significant bit (LSB) becomes
- * the most significant bit (MSB) and vice versa.
- *
- * Example:
- * Input (binary): 00000010100101000001111010011100 (43261596)
- * Output (binary): 00111001011110000010100101000000 (964176192)
- *
- * Time Complexity: O(32) - A fixed number of 32 iterations
- * Space Complexity: O(1) - No extra space used
- *
- * Note:
- * - If the input is negative, Java handles it using two’s complement representation.
- * - This function works on 32-bit integers by default.
- *
- * @author Bama Charan Chhandogi
- */
-public final class ReverseBits {
- private ReverseBits() {
- }
-
- /**
- * Reverses the bits of a 32-bit integer.
- *
- * @param n the integer whose bits are to be reversed
- * @return the integer obtained by reversing the bits of the input
- */
- public static int reverseBits(int n) {
- int result = 0;
- int bitCount = 32;
- for (int i = 0; i < bitCount; i++) {
- result <<= 1; // Left shift the result to make space for the next bit
- result |= (n & 1); // OR operation to set the least significant bit of result with the current bit of n
- n >>= 1; // Right shift n to move on to the next bit
- }
- return result;
- }
-}
+package com.thealgorithms.bitmanipulation;
+
+/**
+ * This class provides a method to reverse the bits of a 32-bit integer.
+ * Reversing the bits means that the least significant bit (LSB) becomes
+ * the most significant bit (MSB) and vice versa.
+ *
+ * Example:
+ * Input (binary): 00000010100101000001111010011100 (43261596)
+ * Output (binary): 00111001011110000010100101000000 (964176192)
+ *
+ * Time Complexity: O(32) - A fixed number of 32 iterations
+ * Space Complexity: O(1) - No extra space used
+ *
+ * Note:
+ * - If the input is negative, Java handles it using two’s complement representation.
+ * - This function works on 32-bit integers by default.
+ *
+ * @author Bama Charan Chhandogi
+ */
+public final class ReverseBits {
+ private ReverseBits() {
+ }
+
+ /**
+ * Reverses the bits of a 32-bit integer.
+ *
+ * @param n the integer whose bits are to be reversed
+ * @return the integer obtained by reversing the bits of the input
+ */
+ public static int reverseBits(int n) {
+ int result = 0;
+ int bitCount = 32;
+ for (int i = 0; i < bitCount; i++) {
+ result <<= 1; // Left shift the result to make space for the next bit
+ result |= (n & 1); // OR operation to set the least significant bit of result with the current bit of n
+ n >>= 1; // Right shift n to move on to the next bit
+ }
+ return result;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/SingleElement.java b/src/main/java/com/thealgorithms/bitmanipulation/SingleElement.java
index 85ebdf02db25..6403449c3648 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/SingleElement.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/SingleElement.java
@@ -1,39 +1,39 @@
-package com.thealgorithms.bitmanipulation;
-
-/**
- * Utility class to find the single non-duplicate element from an array
- * where all other elements appear twice.
- *
- * The algorithm runs in O(n) time complexity and O(1) space complexity
- * using bitwise XOR.
- *
- *
- * @author Tuhin M
- */
-public final class SingleElement {
-
- /**
- * Private constructor to prevent instantiation of this utility class.
- * Throws an UnsupportedOperationException if attempted.
- */
- private SingleElement() {
- throw new UnsupportedOperationException("Utility Class");
- }
-
- /**
- * Finds the single non-duplicate element in an array where every other
- * element appears exactly twice. Uses bitwise XOR to achieve O(n) time
- * complexity and O(1) space complexity.
- *
- * @param arr the input array containing integers where every element
- * except one appears exactly twice
- * @return the single non-duplicate element
- */
- public static int findSingleElement(int[] arr) {
- int ele = 0;
- for (int i = 0; i < arr.length; i++) {
- ele ^= arr[i];
- }
- return ele;
- }
-}
+package com.thealgorithms.bitmanipulation;
+
+/**
+ * Utility class to find the single non-duplicate element from an array
+ * where all other elements appear twice.
+ *
+ * The algorithm runs in O(n) time complexity and O(1) space complexity
+ * using bitwise XOR.
+ *
+ *
+ * @author Tuhin M
+ */
+public final class SingleElement {
+
+ /**
+ * Private constructor to prevent instantiation of this utility class.
+ * Throws an UnsupportedOperationException if attempted.
+ */
+ private SingleElement() {
+ throw new UnsupportedOperationException("Utility Class");
+ }
+
+ /**
+ * Finds the single non-duplicate element in an array where every other
+ * element appears exactly twice. Uses bitwise XOR to achieve O(n) time
+ * complexity and O(1) space complexity.
+ *
+ * @param arr the input array containing integers where every element
+ * except one appears exactly twice
+ * @return the single non-duplicate element
+ */
+ public static int findSingleElement(int[] arr) {
+ int ele = 0;
+ for (int i = 0; i < arr.length; i++) {
+ ele ^= arr[i];
+ }
+ return ele;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/SwapAdjacentBits.java b/src/main/java/com/thealgorithms/bitmanipulation/SwapAdjacentBits.java
index 98a7de8bdf1a..258e37a9dffb 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/SwapAdjacentBits.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/SwapAdjacentBits.java
@@ -1,57 +1,57 @@
-package com.thealgorithms.bitmanipulation;
-
-/**
- * A utility class to swap every pair of adjacent bits in a given integer.
- * This operation shifts the even-positioned bits to odd positions and vice versa.
- *
- * Example:
- * - Input: 2 (binary: `10`) → Output: 1 (binary: `01`)
- * - Input: 43 (binary: `101011`) → Output: 23 (binary: `010111`)
- *
- * **Explanation of the Algorithm:**
- * 1. Mask even-positioned bits: Using `0xAAAAAAAA` (binary: `101010...`),
- * which selects bits in even positions.
- * 2. Mask odd-positioned bits: Using `0x55555555` (binary: `010101...`),
- * which selects bits in odd positions.
- * 3. Shift bits:
- * - Right-shift even-positioned bits by 1 to move them to odd positions.
- * - Left-shift odd-positioned bits by 1 to move them to even positions.
- * 4. Combine both shifted results using bitwise OR (`|`) to produce the final result.
- *
- * Use Case: This algorithm can be useful in applications involving low-level bit manipulation,
- * such as encoding, data compression, or cryptographic transformations.
- *
- * Time Complexity: O(1) (constant time, since operations are bitwise).
- *
- * Author: Lakshyajeet Singh Goyal (https://github.com/DarkMatter-999)
- */
-public final class SwapAdjacentBits {
- private SwapAdjacentBits() {
- }
-
- /**
- * Swaps every pair of adjacent bits of a given integer.
- * Steps:
- * 1. Mask the even-positioned bits.
- * 2. Mask the odd-positioned bits.
- * 3. Shift the even bits to the right and the odd bits to the left.
- * 4. Combine the shifted bits.
- *
- * @param num the integer whose bits are to be swapped
- * @return the integer after swapping every pair of adjacent bits
- */
- public static int swapAdjacentBits(int num) {
- // mask the even bits (0xAAAAAAAA => 10101010...)
- int evenBits = num & 0xAAAAAAAA;
-
- // mask the odd bits (0x55555555 => 01010101...)
- int oddBits = num & 0x55555555;
-
- // right shift even bits and left shift odd bits
- evenBits >>= 1;
- oddBits <<= 1;
-
- // combine shifted bits
- return evenBits | oddBits;
- }
-}
+package com.thealgorithms.bitmanipulation;
+
+/**
+ * A utility class to swap every pair of adjacent bits in a given integer.
+ * This operation shifts the even-positioned bits to odd positions and vice versa.
+ *
+ * Example:
+ * - Input: 2 (binary: `10`) → Output: 1 (binary: `01`)
+ * - Input: 43 (binary: `101011`) → Output: 23 (binary: `010111`)
+ *
+ * **Explanation of the Algorithm:**
+ * 1. Mask even-positioned bits: Using `0xAAAAAAAA` (binary: `101010...`),
+ * which selects bits in even positions.
+ * 2. Mask odd-positioned bits: Using `0x55555555` (binary: `010101...`),
+ * which selects bits in odd positions.
+ * 3. Shift bits:
+ * - Right-shift even-positioned bits by 1 to move them to odd positions.
+ * - Left-shift odd-positioned bits by 1 to move them to even positions.
+ * 4. Combine both shifted results using bitwise OR (`|`) to produce the final result.
+ *
+ * Use Case: This algorithm can be useful in applications involving low-level bit manipulation,
+ * such as encoding, data compression, or cryptographic transformations.
+ *
+ * Time Complexity: O(1) (constant time, since operations are bitwise).
+ *
+ * Author: Lakshyajeet Singh Goyal (https://github.com/DarkMatter-999)
+ */
+public final class SwapAdjacentBits {
+ private SwapAdjacentBits() {
+ }
+
+ /**
+ * Swaps every pair of adjacent bits of a given integer.
+ * Steps:
+ * 1. Mask the even-positioned bits.
+ * 2. Mask the odd-positioned bits.
+ * 3. Shift the even bits to the right and the odd bits to the left.
+ * 4. Combine the shifted bits.
+ *
+ * @param num the integer whose bits are to be swapped
+ * @return the integer after swapping every pair of adjacent bits
+ */
+ public static int swapAdjacentBits(int num) {
+ // mask the even bits (0xAAAAAAAA => 10101010...)
+ int evenBits = num & 0xAAAAAAAA;
+
+ // mask the odd bits (0x55555555 => 01010101...)
+ int oddBits = num & 0x55555555;
+
+ // right shift even bits and left shift odd bits
+ evenBits >>= 1;
+ oddBits <<= 1;
+
+ // combine shifted bits
+ return evenBits | oddBits;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/TwosComplement.java b/src/main/java/com/thealgorithms/bitmanipulation/TwosComplement.java
index 9b8cecd791a6..7b907c3f3f6d 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/TwosComplement.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/TwosComplement.java
@@ -1,62 +1,62 @@
-package com.thealgorithms.bitmanipulation;
-
-/**
- * This class provides a method to compute the Two's Complement of a given binary number.
- *
- * In two's complement representation, a binary number's negative value is obtained
- * by taking the one's complement (inverting all bits) and then adding 1 to the result.
- * This method handles both small and large binary strings and ensures the output is
- * correct for all binary inputs, including edge cases like all zeroes and all ones.
- *
- *
For more information on Two's Complement:
- * @see Wikipedia - Two's Complement
- *
- *
Algorithm originally suggested by Jon von Neumann.
- *
- * @author Abhinay Verma (https://github.com/Monk-AbhinayVerma)
- */
-public final class TwosComplement {
- private TwosComplement() {
- }
-
- /**
- * Computes the Two's Complement of the given binary string.
- * Steps:
- * 1. Compute the One's Complement (invert all bits).
- * 2. Add 1 to the One's Complement to get the Two's Complement.
- * 3. Iterate from the rightmost bit to the left, adding 1 and carrying over as needed.
- * 4. If a carry is still present after the leftmost bit, prepend '1' to handle overflow.
- *
- * @param binary The binary number as a string (only '0' and '1' characters allowed).
- * @return The two's complement of the input binary string as a new binary string.
- * @throws IllegalArgumentException If the input contains non-binary characters.
- */
- public static String twosComplement(String binary) {
- if (!binary.matches("[01]+")) {
- throw new IllegalArgumentException("Input must contain only '0' and '1'.");
- }
-
- StringBuilder onesComplement = new StringBuilder();
- for (char bit : binary.toCharArray()) {
- onesComplement.append(bit == '0' ? '1' : '0');
- }
-
- StringBuilder twosComplement = new StringBuilder(onesComplement);
- boolean carry = true;
-
- for (int i = onesComplement.length() - 1; i >= 0 && carry; i--) {
- if (onesComplement.charAt(i) == '1') {
- twosComplement.setCharAt(i, '0');
- } else {
- twosComplement.setCharAt(i, '1');
- carry = false;
- }
- }
-
- if (carry) {
- twosComplement.insert(0, '1');
- }
-
- return twosComplement.toString();
- }
-}
+package com.thealgorithms.bitmanipulation;
+
+/**
+ * This class provides a method to compute the Two's Complement of a given binary number.
+ *
+ *
In two's complement representation, a binary number's negative value is obtained
+ * by taking the one's complement (inverting all bits) and then adding 1 to the result.
+ * This method handles both small and large binary strings and ensures the output is
+ * correct for all binary inputs, including edge cases like all zeroes and all ones.
+ *
+ *
For more information on Two's Complement:
+ * @see Wikipedia - Two's Complement
+ *
+ *
Algorithm originally suggested by Jon von Neumann.
+ *
+ * @author Abhinay Verma (https://github.com/Monk-AbhinayVerma)
+ */
+public final class TwosComplement {
+ private TwosComplement() {
+ }
+
+ /**
+ * Computes the Two's Complement of the given binary string.
+ * Steps:
+ * 1. Compute the One's Complement (invert all bits).
+ * 2. Add 1 to the One's Complement to get the Two's Complement.
+ * 3. Iterate from the rightmost bit to the left, adding 1 and carrying over as needed.
+ * 4. If a carry is still present after the leftmost bit, prepend '1' to handle overflow.
+ *
+ * @param binary The binary number as a string (only '0' and '1' characters allowed).
+ * @return The two's complement of the input binary string as a new binary string.
+ * @throws IllegalArgumentException If the input contains non-binary characters.
+ */
+ public static String twosComplement(String binary) {
+ if (!binary.matches("[01]+")) {
+ throw new IllegalArgumentException("Input must contain only '0' and '1'.");
+ }
+
+ StringBuilder onesComplement = new StringBuilder();
+ for (char bit : binary.toCharArray()) {
+ onesComplement.append(bit == '0' ? '1' : '0');
+ }
+
+ StringBuilder twosComplement = new StringBuilder(onesComplement);
+ boolean carry = true;
+
+ for (int i = onesComplement.length() - 1; i >= 0 && carry; i--) {
+ if (onesComplement.charAt(i) == '1') {
+ twosComplement.setCharAt(i, '0');
+ } else {
+ twosComplement.setCharAt(i, '1');
+ carry = false;
+ }
+ }
+
+ if (carry) {
+ twosComplement.insert(0, '1');
+ }
+
+ return twosComplement.toString();
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/Xs3Conversion.java b/src/main/java/com/thealgorithms/bitmanipulation/Xs3Conversion.java
index b22abc0c04ff..758d46858866 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/Xs3Conversion.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/Xs3Conversion.java
@@ -1,58 +1,58 @@
-package com.thealgorithms.bitmanipulation;
-
-/**
- * This class provides methods to convert between XS-3 (Excess-3) and binary.
- *
- * Excess-3, also called XS-3, is a binary-coded decimal (BCD) code in which each decimal digit is represented by its corresponding 4-bit binary value plus 3.
- *
- * For more information, refer to the
- * Excess-3 Wikipedia page.
- *
- * Example usage:
- *
- * int binary = Xs3Conversion.xs3ToBinary(0x4567);
- * System.out.println("XS-3 0x4567 to binary: " + binary); // Output: 1234
- *
- * int xs3 = Xs3Conversion.binaryToXs3(1234);
- * System.out.println("Binary 1234 to XS-3: " + Integer.toHexString(xs3)); // Output: 0x4567
- *
- */
-public final class Xs3Conversion {
- private Xs3Conversion() {
- }
- /**
- * Converts an XS-3 (Excess-3) number to binary.
- *
- * @param xs3 The XS-3 number.
- * @return The corresponding binary number.
- */
- public static int xs3ToBinary(int xs3) {
- int binary = 0;
- int multiplier = 1;
- while (xs3 > 0) {
- int digit = (xs3 & 0xF) - 3; // Extract the last 4 bits (one XS-3 digit) and subtract 3
- binary += digit * multiplier;
- multiplier *= 10;
- xs3 >>= 4; // Shift right by 4 bits to process the next XS-3 digit
- }
- return binary;
- }
-
- /**
- * Converts a binary number to XS-3 (Excess-3).
- *
- * @param binary The binary number.
- * @return The corresponding XS-3 number.
- */
- public static int binaryToXs3(int binary) {
- int xs3 = 0;
- int shift = 0;
- while (binary > 0) {
- int digit = (binary % 10) + 3; // Extract the last decimal digit and add 3
- xs3 |= (digit << (shift * 4)); // Shift the digit to the correct XS-3 position
- binary /= 10; // Remove the last decimal digit
- shift++;
- }
- return xs3;
- }
-}
+package com.thealgorithms.bitmanipulation;
+
+/**
+ * This class provides methods to convert between XS-3 (Excess-3) and binary.
+ *
+ * Excess-3, also called XS-3, is a binary-coded decimal (BCD) code in which each decimal digit is represented by its corresponding 4-bit binary value plus 3.
+ *
+ * For more information, refer to the
+ * Excess-3 Wikipedia page.
+ *
+ * Example usage:
+ *
+ * int binary = Xs3Conversion.xs3ToBinary(0x4567);
+ * System.out.println("XS-3 0x4567 to binary: " + binary); // Output: 1234
+ *
+ * int xs3 = Xs3Conversion.binaryToXs3(1234);
+ * System.out.println("Binary 1234 to XS-3: " + Integer.toHexString(xs3)); // Output: 0x4567
+ *
+ */
+public final class Xs3Conversion {
+ private Xs3Conversion() {
+ }
+ /**
+ * Converts an XS-3 (Excess-3) number to binary.
+ *
+ * @param xs3 The XS-3 number.
+ * @return The corresponding binary number.
+ */
+ public static int xs3ToBinary(int xs3) {
+ int binary = 0;
+ int multiplier = 1;
+ while (xs3 > 0) {
+ int digit = (xs3 & 0xF) - 3; // Extract the last 4 bits (one XS-3 digit) and subtract 3
+ binary += digit * multiplier;
+ multiplier *= 10;
+ xs3 >>= 4; // Shift right by 4 bits to process the next XS-3 digit
+ }
+ return binary;
+ }
+
+ /**
+ * Converts a binary number to XS-3 (Excess-3).
+ *
+ * @param binary The binary number.
+ * @return The corresponding XS-3 number.
+ */
+ public static int binaryToXs3(int binary) {
+ int xs3 = 0;
+ int shift = 0;
+ while (binary > 0) {
+ int digit = (binary % 10) + 3; // Extract the last decimal digit and add 3
+ xs3 |= (digit << (shift * 4)); // Shift the digit to the correct XS-3 position
+ binary /= 10; // Remove the last decimal digit
+ shift++;
+ }
+ return xs3;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/ciphers/ADFGVXCipher.java b/src/main/java/com/thealgorithms/ciphers/ADFGVXCipher.java
index d915858f9e6f..ae6ad117ba0a 100644
--- a/src/main/java/com/thealgorithms/ciphers/ADFGVXCipher.java
+++ b/src/main/java/com/thealgorithms/ciphers/ADFGVXCipher.java
@@ -1,167 +1,167 @@
-package com.thealgorithms.ciphers;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * The ADFGVX cipher is a fractionating transposition cipher that was used by
- * the German Army during World War I. It combines a **Polybius square substitution**
- * with a **columnar transposition** to enhance encryption strength.
- *
- * The name "ADFGVX" refers to the six letters (A, D, F, G, V, X) used as row and
- * column labels in the Polybius square. This cipher was designed to secure
- * communication and create complex, hard-to-break ciphertexts.
- *
- * Learn more: ADFGVX Cipher - Wikipedia.
- *
- * Example usage:
- *
- * ADFGVXCipher cipher = new ADFGVXCipher();
- * String encrypted = cipher.encrypt("attack at 1200am", "PRIVACY");
- * String decrypted = cipher.decrypt(encrypted, "PRIVACY");
- *
- *
- * @author bennybebo
- */
-public class ADFGVXCipher {
-
- // Constants used in the Polybius square
- private static final char[] POLYBIUS_LETTERS = {'A', 'D', 'F', 'G', 'V', 'X'};
- private static final char[][] POLYBIUS_SQUARE = {{'N', 'A', '1', 'C', '3', 'H'}, {'8', 'T', 'B', '2', 'O', 'M'}, {'E', '5', 'W', 'R', 'P', 'D'}, {'4', 'F', '6', 'G', '7', 'I'}, {'9', 'J', '0', 'K', 'L', 'Q'}, {'S', 'U', 'V', 'X', 'Y', 'Z'}};
-
- // Maps for fast substitution lookups
- private static final Map POLYBIUS_MAP = new HashMap<>();
- private static final Map REVERSE_POLYBIUS_MAP = new HashMap<>();
-
- // Static block to initialize the lookup tables from the Polybius square
- static {
- for (int i = 0; i < POLYBIUS_SQUARE.length; i++) {
- for (int j = 0; j < POLYBIUS_SQUARE[i].length; j++) {
- String key = "" + POLYBIUS_LETTERS[i] + POLYBIUS_LETTERS[j];
- POLYBIUS_MAP.put(key, POLYBIUS_SQUARE[i][j]);
- REVERSE_POLYBIUS_MAP.put(POLYBIUS_SQUARE[i][j], key);
- }
- }
- }
-
- /**
- * Encrypts a given plaintext using the ADFGVX cipher with the provided keyword.
- * Steps:
- * 1. Substitute each letter in the plaintext with a pair of ADFGVX letters.
- * 2. Perform a columnar transposition on the fractionated text using the keyword.
- *
- * @param plaintext The message to be encrypted (can contain letters and digits).
- * @param key The keyword for columnar transposition.
- * @return The encrypted message as ciphertext.
- */
- public String encrypt(String plaintext, String key) {
- plaintext = plaintext.toUpperCase().replaceAll("[^A-Z0-9]", ""); // Sanitize input
- StringBuilder fractionatedText = new StringBuilder();
-
- for (char c : plaintext.toCharArray()) {
- fractionatedText.append(REVERSE_POLYBIUS_MAP.get(c));
- }
-
- return columnarTransposition(fractionatedText.toString(), key);
- }
-
- /**
- * Decrypts a given ciphertext using the ADFGVX cipher with the provided keyword.
- * Steps:
- * 1. Reverse the columnar transposition performed during encryption.
- * 2. Substitute each pair of ADFGVX letters with the corresponding plaintext letter.
- * The resulting text is the decrypted message.
- *
- * @param ciphertext The encrypted message.
- * @param key The keyword used during encryption.
- * @return The decrypted plaintext message.
- */
- public String decrypt(String ciphertext, String key) {
- String fractionatedText = reverseColumnarTransposition(ciphertext, key);
-
- StringBuilder plaintext = new StringBuilder();
- for (int i = 0; i < fractionatedText.length(); i += 2) {
- String pair = fractionatedText.substring(i, i + 2);
- plaintext.append(POLYBIUS_MAP.get(pair));
- }
-
- return plaintext.toString();
- }
-
- /**
- * Helper method: Performs columnar transposition during encryption
- *
- * @param text The fractionated text to be transposed
- * @param key The keyword for columnar transposition
- * @return The transposed text
- */
- private String columnarTransposition(String text, String key) {
- int numRows = (int) Math.ceil((double) text.length() / key.length());
- char[][] table = new char[numRows][key.length()];
- for (char[] row : table) { // Fill empty cells with underscores
- Arrays.fill(row, '_');
- }
-
- // Populate the table row by row
- for (int i = 0; i < text.length(); i++) {
- table[i / key.length()][i % key.length()] = text.charAt(i);
- }
-
- // Read columns based on the alphabetical order of the key
- StringBuilder ciphertext = new StringBuilder();
- char[] sortedKey = key.toCharArray();
- Arrays.sort(sortedKey);
-
- for (char keyChar : sortedKey) {
- int column = key.indexOf(keyChar);
- for (char[] row : table) {
- if (row[column] != '_') {
- ciphertext.append(row[column]);
- }
- }
- }
-
- return ciphertext.toString();
- }
-
- /**
- * Helper method: Reverses the columnar transposition during decryption
- *
- * @param ciphertext The transposed text to be reversed
- * @param key The keyword used during encryption
- * @return The reversed text
- */
- private String reverseColumnarTransposition(String ciphertext, String key) {
- int numRows = (int) Math.ceil((double) ciphertext.length() / key.length());
- char[][] table = new char[numRows][key.length()];
-
- char[] sortedKey = key.toCharArray();
- Arrays.sort(sortedKey);
-
- int index = 0;
- // Populate the table column by column according to the sorted key
- for (char keyChar : sortedKey) {
- int column = key.indexOf(keyChar);
- for (int row = 0; row < numRows; row++) {
- if (index < ciphertext.length()) {
- table[row][column] = ciphertext.charAt(index++);
- } else {
- table[row][column] = '_';
- }
- }
- }
-
- // Read the table row by row to reconstruct the fractionated text
- StringBuilder fractionatedText = new StringBuilder();
- for (char[] row : table) {
- for (char cell : row) {
- if (cell != '_') {
- fractionatedText.append(cell);
- }
- }
- }
-
- return fractionatedText.toString();
- }
-}
+package com.thealgorithms.ciphers;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * The ADFGVX cipher is a fractionating transposition cipher that was used by
+ * the German Army during World War I. It combines a **Polybius square substitution**
+ * with a **columnar transposition** to enhance encryption strength.
+ *
+ * The name "ADFGVX" refers to the six letters (A, D, F, G, V, X) used as row and
+ * column labels in the Polybius square. This cipher was designed to secure
+ * communication and create complex, hard-to-break ciphertexts.
+ *
+ * Learn more: ADFGVX Cipher - Wikipedia.
+ *
+ * Example usage:
+ *
+ * ADFGVXCipher cipher = new ADFGVXCipher();
+ * String encrypted = cipher.encrypt("attack at 1200am", "PRIVACY");
+ * String decrypted = cipher.decrypt(encrypted, "PRIVACY");
+ *
+ *
+ * @author bennybebo
+ */
+public class ADFGVXCipher {
+
+ // Constants used in the Polybius square
+ private static final char[] POLYBIUS_LETTERS = {'A', 'D', 'F', 'G', 'V', 'X'};
+ private static final char[][] POLYBIUS_SQUARE = {{'N', 'A', '1', 'C', '3', 'H'}, {'8', 'T', 'B', '2', 'O', 'M'}, {'E', '5', 'W', 'R', 'P', 'D'}, {'4', 'F', '6', 'G', '7', 'I'}, {'9', 'J', '0', 'K', 'L', 'Q'}, {'S', 'U', 'V', 'X', 'Y', 'Z'}};
+
+ // Maps for fast substitution lookups
+ private static final Map POLYBIUS_MAP = new HashMap<>();
+ private static final Map REVERSE_POLYBIUS_MAP = new HashMap<>();
+
+ // Static block to initialize the lookup tables from the Polybius square
+ static {
+ for (int i = 0; i < POLYBIUS_SQUARE.length; i++) {
+ for (int j = 0; j < POLYBIUS_SQUARE[i].length; j++) {
+ String key = "" + POLYBIUS_LETTERS[i] + POLYBIUS_LETTERS[j];
+ POLYBIUS_MAP.put(key, POLYBIUS_SQUARE[i][j]);
+ REVERSE_POLYBIUS_MAP.put(POLYBIUS_SQUARE[i][j], key);
+ }
+ }
+ }
+
+ /**
+ * Encrypts a given plaintext using the ADFGVX cipher with the provided keyword.
+ * Steps:
+ * 1. Substitute each letter in the plaintext with a pair of ADFGVX letters.
+ * 2. Perform a columnar transposition on the fractionated text using the keyword.
+ *
+ * @param plaintext The message to be encrypted (can contain letters and digits).
+ * @param key The keyword for columnar transposition.
+ * @return The encrypted message as ciphertext.
+ */
+ public String encrypt(String plaintext, String key) {
+ plaintext = plaintext.toUpperCase().replaceAll("[^A-Z0-9]", ""); // Sanitize input
+ StringBuilder fractionatedText = new StringBuilder();
+
+ for (char c : plaintext.toCharArray()) {
+ fractionatedText.append(REVERSE_POLYBIUS_MAP.get(c));
+ }
+
+ return columnarTransposition(fractionatedText.toString(), key);
+ }
+
+ /**
+ * Decrypts a given ciphertext using the ADFGVX cipher with the provided keyword.
+ * Steps:
+ * 1. Reverse the columnar transposition performed during encryption.
+ * 2. Substitute each pair of ADFGVX letters with the corresponding plaintext letter.
+ * The resulting text is the decrypted message.
+ *
+ * @param ciphertext The encrypted message.
+ * @param key The keyword used during encryption.
+ * @return The decrypted plaintext message.
+ */
+ public String decrypt(String ciphertext, String key) {
+ String fractionatedText = reverseColumnarTransposition(ciphertext, key);
+
+ StringBuilder plaintext = new StringBuilder();
+ for (int i = 0; i < fractionatedText.length(); i += 2) {
+ String pair = fractionatedText.substring(i, i + 2);
+ plaintext.append(POLYBIUS_MAP.get(pair));
+ }
+
+ return plaintext.toString();
+ }
+
+ /**
+ * Helper method: Performs columnar transposition during encryption
+ *
+ * @param text The fractionated text to be transposed
+ * @param key The keyword for columnar transposition
+ * @return The transposed text
+ */
+ private String columnarTransposition(String text, String key) {
+ int numRows = (int) Math.ceil((double) text.length() / key.length());
+ char[][] table = new char[numRows][key.length()];
+ for (char[] row : table) { // Fill empty cells with underscores
+ Arrays.fill(row, '_');
+ }
+
+ // Populate the table row by row
+ for (int i = 0; i < text.length(); i++) {
+ table[i / key.length()][i % key.length()] = text.charAt(i);
+ }
+
+ // Read columns based on the alphabetical order of the key
+ StringBuilder ciphertext = new StringBuilder();
+ char[] sortedKey = key.toCharArray();
+ Arrays.sort(sortedKey);
+
+ for (char keyChar : sortedKey) {
+ int column = key.indexOf(keyChar);
+ for (char[] row : table) {
+ if (row[column] != '_') {
+ ciphertext.append(row[column]);
+ }
+ }
+ }
+
+ return ciphertext.toString();
+ }
+
+ /**
+ * Helper method: Reverses the columnar transposition during decryption
+ *
+ * @param ciphertext The transposed text to be reversed
+ * @param key The keyword used during encryption
+ * @return The reversed text
+ */
+ private String reverseColumnarTransposition(String ciphertext, String key) {
+ int numRows = (int) Math.ceil((double) ciphertext.length() / key.length());
+ char[][] table = new char[numRows][key.length()];
+
+ char[] sortedKey = key.toCharArray();
+ Arrays.sort(sortedKey);
+
+ int index = 0;
+ // Populate the table column by column according to the sorted key
+ for (char keyChar : sortedKey) {
+ int column = key.indexOf(keyChar);
+ for (int row = 0; row < numRows; row++) {
+ if (index < ciphertext.length()) {
+ table[row][column] = ciphertext.charAt(index++);
+ } else {
+ table[row][column] = '_';
+ }
+ }
+ }
+
+ // Read the table row by row to reconstruct the fractionated text
+ StringBuilder fractionatedText = new StringBuilder();
+ for (char[] row : table) {
+ for (char cell : row) {
+ if (cell != '_') {
+ fractionatedText.append(cell);
+ }
+ }
+ }
+
+ return fractionatedText.toString();
+ }
+}
diff --git a/src/main/java/com/thealgorithms/ciphers/AES.java b/src/main/java/com/thealgorithms/ciphers/AES.java
index df51eba55310..3c975c6d1858 100644
--- a/src/main/java/com/thealgorithms/ciphers/AES.java
+++ b/src/main/java/com/thealgorithms/ciphers/AES.java
@@ -1,2781 +1,2781 @@
-package com.thealgorithms.ciphers;
-
-import java.math.BigInteger;
-import java.util.Scanner;
-
-/**
- * This class is build to demonstrate the application of the AES-algorithm on a
- * single 128-Bit block of data.
- */
-public final class AES {
- private AES() {
- }
-
- /**
- * Precalculated values for x to the power of 2 in Rijndaels galois field.
- * Used as 'RCON' during the key expansion.
- */
- private static final int[] RCON = {
- 0x8d,
- 0x01,
- 0x02,
- 0x04,
- 0x08,
- 0x10,
- 0x20,
- 0x40,
- 0x80,
- 0x1b,
- 0x36,
- 0x6c,
- 0xd8,
- 0xab,
- 0x4d,
- 0x9a,
- 0x2f,
- 0x5e,
- 0xbc,
- 0x63,
- 0xc6,
- 0x97,
- 0x35,
- 0x6a,
- 0xd4,
- 0xb3,
- 0x7d,
- 0xfa,
- 0xef,
- 0xc5,
- 0x91,
- 0x39,
- 0x72,
- 0xe4,
- 0xd3,
- 0xbd,
- 0x61,
- 0xc2,
- 0x9f,
- 0x25,
- 0x4a,
- 0x94,
- 0x33,
- 0x66,
- 0xcc,
- 0x83,
- 0x1d,
- 0x3a,
- 0x74,
- 0xe8,
- 0xcb,
- 0x8d,
- 0x01,
- 0x02,
- 0x04,
- 0x08,
- 0x10,
- 0x20,
- 0x40,
- 0x80,
- 0x1b,
- 0x36,
- 0x6c,
- 0xd8,
- 0xab,
- 0x4d,
- 0x9a,
- 0x2f,
- 0x5e,
- 0xbc,
- 0x63,
- 0xc6,
- 0x97,
- 0x35,
- 0x6a,
- 0xd4,
- 0xb3,
- 0x7d,
- 0xfa,
- 0xef,
- 0xc5,
- 0x91,
- 0x39,
- 0x72,
- 0xe4,
- 0xd3,
- 0xbd,
- 0x61,
- 0xc2,
- 0x9f,
- 0x25,
- 0x4a,
- 0x94,
- 0x33,
- 0x66,
- 0xcc,
- 0x83,
- 0x1d,
- 0x3a,
- 0x74,
- 0xe8,
- 0xcb,
- 0x8d,
- 0x01,
- 0x02,
- 0x04,
- 0x08,
- 0x10,
- 0x20,
- 0x40,
- 0x80,
- 0x1b,
- 0x36,
- 0x6c,
- 0xd8,
- 0xab,
- 0x4d,
- 0x9a,
- 0x2f,
- 0x5e,
- 0xbc,
- 0x63,
- 0xc6,
- 0x97,
- 0x35,
- 0x6a,
- 0xd4,
- 0xb3,
- 0x7d,
- 0xfa,
- 0xef,
- 0xc5,
- 0x91,
- 0x39,
- 0x72,
- 0xe4,
- 0xd3,
- 0xbd,
- 0x61,
- 0xc2,
- 0x9f,
- 0x25,
- 0x4a,
- 0x94,
- 0x33,
- 0x66,
- 0xcc,
- 0x83,
- 0x1d,
- 0x3a,
- 0x74,
- 0xe8,
- 0xcb,
- 0x8d,
- 0x01,
- 0x02,
- 0x04,
- 0x08,
- 0x10,
- 0x20,
- 0x40,
- 0x80,
- 0x1b,
- 0x36,
- 0x6c,
- 0xd8,
- 0xab,
- 0x4d,
- 0x9a,
- 0x2f,
- 0x5e,
- 0xbc,
- 0x63,
- 0xc6,
- 0x97,
- 0x35,
- 0x6a,
- 0xd4,
- 0xb3,
- 0x7d,
- 0xfa,
- 0xef,
- 0xc5,
- 0x91,
- 0x39,
- 0x72,
- 0xe4,
- 0xd3,
- 0xbd,
- 0x61,
- 0xc2,
- 0x9f,
- 0x25,
- 0x4a,
- 0x94,
- 0x33,
- 0x66,
- 0xcc,
- 0x83,
- 0x1d,
- 0x3a,
- 0x74,
- 0xe8,
- 0xcb,
- 0x8d,
- 0x01,
- 0x02,
- 0x04,
- 0x08,
- 0x10,
- 0x20,
- 0x40,
- 0x80,
- 0x1b,
- 0x36,
- 0x6c,
- 0xd8,
- 0xab,
- 0x4d,
- 0x9a,
- 0x2f,
- 0x5e,
- 0xbc,
- 0x63,
- 0xc6,
- 0x97,
- 0x35,
- 0x6a,
- 0xd4,
- 0xb3,
- 0x7d,
- 0xfa,
- 0xef,
- 0xc5,
- 0x91,
- 0x39,
- 0x72,
- 0xe4,
- 0xd3,
- 0xbd,
- 0x61,
- 0xc2,
- 0x9f,
- 0x25,
- 0x4a,
- 0x94,
- 0x33,
- 0x66,
- 0xcc,
- 0x83,
- 0x1d,
- 0x3a,
- 0x74,
- 0xe8,
- 0xcb,
- 0x8d,
- };
-
- /**
- * Rijndael S-box Substitution table used for encryption in the subBytes
- * step, as well as the key expansion.
- */
- private static final int[] SBOX = {
- 0x63,
- 0x7C,
- 0x77,
- 0x7B,
- 0xF2,
- 0x6B,
- 0x6F,
- 0xC5,
- 0x30,
- 0x01,
- 0x67,
- 0x2B,
- 0xFE,
- 0xD7,
- 0xAB,
- 0x76,
- 0xCA,
- 0x82,
- 0xC9,
- 0x7D,
- 0xFA,
- 0x59,
- 0x47,
- 0xF0,
- 0xAD,
- 0xD4,
- 0xA2,
- 0xAF,
- 0x9C,
- 0xA4,
- 0x72,
- 0xC0,
- 0xB7,
- 0xFD,
- 0x93,
- 0x26,
- 0x36,
- 0x3F,
- 0xF7,
- 0xCC,
- 0x34,
- 0xA5,
- 0xE5,
- 0xF1,
- 0x71,
- 0xD8,
- 0x31,
- 0x15,
- 0x04,
- 0xC7,
- 0x23,
- 0xC3,
- 0x18,
- 0x96,
- 0x05,
- 0x9A,
- 0x07,
- 0x12,
- 0x80,
- 0xE2,
- 0xEB,
- 0x27,
- 0xB2,
- 0x75,
- 0x09,
- 0x83,
- 0x2C,
- 0x1A,
- 0x1B,
- 0x6E,
- 0x5A,
- 0xA0,
- 0x52,
- 0x3B,
- 0xD6,
- 0xB3,
- 0x29,
- 0xE3,
- 0x2F,
- 0x84,
- 0x53,
- 0xD1,
- 0x00,
- 0xED,
- 0x20,
- 0xFC,
- 0xB1,
- 0x5B,
- 0x6A,
- 0xCB,
- 0xBE,
- 0x39,
- 0x4A,
- 0x4C,
- 0x58,
- 0xCF,
- 0xD0,
- 0xEF,
- 0xAA,
- 0xFB,
- 0x43,
- 0x4D,
- 0x33,
- 0x85,
- 0x45,
- 0xF9,
- 0x02,
- 0x7F,
- 0x50,
- 0x3C,
- 0x9F,
- 0xA8,
- 0x51,
- 0xA3,
- 0x40,
- 0x8F,
- 0x92,
- 0x9D,
- 0x38,
- 0xF5,
- 0xBC,
- 0xB6,
- 0xDA,
- 0x21,
- 0x10,
- 0xFF,
- 0xF3,
- 0xD2,
- 0xCD,
- 0x0C,
- 0x13,
- 0xEC,
- 0x5F,
- 0x97,
- 0x44,
- 0x17,
- 0xC4,
- 0xA7,
- 0x7E,
- 0x3D,
- 0x64,
- 0x5D,
- 0x19,
- 0x73,
- 0x60,
- 0x81,
- 0x4F,
- 0xDC,
- 0x22,
- 0x2A,
- 0x90,
- 0x88,
- 0x46,
- 0xEE,
- 0xB8,
- 0x14,
- 0xDE,
- 0x5E,
- 0x0B,
- 0xDB,
- 0xE0,
- 0x32,
- 0x3A,
- 0x0A,
- 0x49,
- 0x06,
- 0x24,
- 0x5C,
- 0xC2,
- 0xD3,
- 0xAC,
- 0x62,
- 0x91,
- 0x95,
- 0xE4,
- 0x79,
- 0xE7,
- 0xC8,
- 0x37,
- 0x6D,
- 0x8D,
- 0xD5,
- 0x4E,
- 0xA9,
- 0x6C,
- 0x56,
- 0xF4,
- 0xEA,
- 0x65,
- 0x7A,
- 0xAE,
- 0x08,
- 0xBA,
- 0x78,
- 0x25,
- 0x2E,
- 0x1C,
- 0xA6,
- 0xB4,
- 0xC6,
- 0xE8,
- 0xDD,
- 0x74,
- 0x1F,
- 0x4B,
- 0xBD,
- 0x8B,
- 0x8A,
- 0x70,
- 0x3E,
- 0xB5,
- 0x66,
- 0x48,
- 0x03,
- 0xF6,
- 0x0E,
- 0x61,
- 0x35,
- 0x57,
- 0xB9,
- 0x86,
- 0xC1,
- 0x1D,
- 0x9E,
- 0xE1,
- 0xF8,
- 0x98,
- 0x11,
- 0x69,
- 0xD9,
- 0x8E,
- 0x94,
- 0x9B,
- 0x1E,
- 0x87,
- 0xE9,
- 0xCE,
- 0x55,
- 0x28,
- 0xDF,
- 0x8C,
- 0xA1,
- 0x89,
- 0x0D,
- 0xBF,
- 0xE6,
- 0x42,
- 0x68,
- 0x41,
- 0x99,
- 0x2D,
- 0x0F,
- 0xB0,
- 0x54,
- 0xBB,
- 0x16,
- };
-
- /**
- * Inverse Rijndael S-box Substitution table used for decryption in the
- * subBytesDec step.
- */
- private static final int[] INVERSE_SBOX = {
- 0x52,
- 0x09,
- 0x6A,
- 0xD5,
- 0x30,
- 0x36,
- 0xA5,
- 0x38,
- 0xBF,
- 0x40,
- 0xA3,
- 0x9E,
- 0x81,
- 0xF3,
- 0xD7,
- 0xFB,
- 0x7C,
- 0xE3,
- 0x39,
- 0x82,
- 0x9B,
- 0x2F,
- 0xFF,
- 0x87,
- 0x34,
- 0x8E,
- 0x43,
- 0x44,
- 0xC4,
- 0xDE,
- 0xE9,
- 0xCB,
- 0x54,
- 0x7B,
- 0x94,
- 0x32,
- 0xA6,
- 0xC2,
- 0x23,
- 0x3D,
- 0xEE,
- 0x4C,
- 0x95,
- 0x0B,
- 0x42,
- 0xFA,
- 0xC3,
- 0x4E,
- 0x08,
- 0x2E,
- 0xA1,
- 0x66,
- 0x28,
- 0xD9,
- 0x24,
- 0xB2,
- 0x76,
- 0x5B,
- 0xA2,
- 0x49,
- 0x6D,
- 0x8B,
- 0xD1,
- 0x25,
- 0x72,
- 0xF8,
- 0xF6,
- 0x64,
- 0x86,
- 0x68,
- 0x98,
- 0x16,
- 0xD4,
- 0xA4,
- 0x5C,
- 0xCC,
- 0x5D,
- 0x65,
- 0xB6,
- 0x92,
- 0x6C,
- 0x70,
- 0x48,
- 0x50,
- 0xFD,
- 0xED,
- 0xB9,
- 0xDA,
- 0x5E,
- 0x15,
- 0x46,
- 0x57,
- 0xA7,
- 0x8D,
- 0x9D,
- 0x84,
- 0x90,
- 0xD8,
- 0xAB,
- 0x00,
- 0x8C,
- 0xBC,
- 0xD3,
- 0x0A,
- 0xF7,
- 0xE4,
- 0x58,
- 0x05,
- 0xB8,
- 0xB3,
- 0x45,
- 0x06,
- 0xD0,
- 0x2C,
- 0x1E,
- 0x8F,
- 0xCA,
- 0x3F,
- 0x0F,
- 0x02,
- 0xC1,
- 0xAF,
- 0xBD,
- 0x03,
- 0x01,
- 0x13,
- 0x8A,
- 0x6B,
- 0x3A,
- 0x91,
- 0x11,
- 0x41,
- 0x4F,
- 0x67,
- 0xDC,
- 0xEA,
- 0x97,
- 0xF2,
- 0xCF,
- 0xCE,
- 0xF0,
- 0xB4,
- 0xE6,
- 0x73,
- 0x96,
- 0xAC,
- 0x74,
- 0x22,
- 0xE7,
- 0xAD,
- 0x35,
- 0x85,
- 0xE2,
- 0xF9,
- 0x37,
- 0xE8,
- 0x1C,
- 0x75,
- 0xDF,
- 0x6E,
- 0x47,
- 0xF1,
- 0x1A,
- 0x71,
- 0x1D,
- 0x29,
- 0xC5,
- 0x89,
- 0x6F,
- 0xB7,
- 0x62,
- 0x0E,
- 0xAA,
- 0x18,
- 0xBE,
- 0x1B,
- 0xFC,
- 0x56,
- 0x3E,
- 0x4B,
- 0xC6,
- 0xD2,
- 0x79,
- 0x20,
- 0x9A,
- 0xDB,
- 0xC0,
- 0xFE,
- 0x78,
- 0xCD,
- 0x5A,
- 0xF4,
- 0x1F,
- 0xDD,
- 0xA8,
- 0x33,
- 0x88,
- 0x07,
- 0xC7,
- 0x31,
- 0xB1,
- 0x12,
- 0x10,
- 0x59,
- 0x27,
- 0x80,
- 0xEC,
- 0x5F,
- 0x60,
- 0x51,
- 0x7F,
- 0xA9,
- 0x19,
- 0xB5,
- 0x4A,
- 0x0D,
- 0x2D,
- 0xE5,
- 0x7A,
- 0x9F,
- 0x93,
- 0xC9,
- 0x9C,
- 0xEF,
- 0xA0,
- 0xE0,
- 0x3B,
- 0x4D,
- 0xAE,
- 0x2A,
- 0xF5,
- 0xB0,
- 0xC8,
- 0xEB,
- 0xBB,
- 0x3C,
- 0x83,
- 0x53,
- 0x99,
- 0x61,
- 0x17,
- 0x2B,
- 0x04,
- 0x7E,
- 0xBA,
- 0x77,
- 0xD6,
- 0x26,
- 0xE1,
- 0x69,
- 0x14,
- 0x63,
- 0x55,
- 0x21,
- 0x0C,
- 0x7D,
- };
-
- /**
- * Precalculated lookup table for galois field multiplication by 2 used in
- * the MixColums step during encryption.
- */
- private static final int[] MULT2 = {
- 0x00,
- 0x02,
- 0x04,
- 0x06,
- 0x08,
- 0x0a,
- 0x0c,
- 0x0e,
- 0x10,
- 0x12,
- 0x14,
- 0x16,
- 0x18,
- 0x1a,
- 0x1c,
- 0x1e,
- 0x20,
- 0x22,
- 0x24,
- 0x26,
- 0x28,
- 0x2a,
- 0x2c,
- 0x2e,
- 0x30,
- 0x32,
- 0x34,
- 0x36,
- 0x38,
- 0x3a,
- 0x3c,
- 0x3e,
- 0x40,
- 0x42,
- 0x44,
- 0x46,
- 0x48,
- 0x4a,
- 0x4c,
- 0x4e,
- 0x50,
- 0x52,
- 0x54,
- 0x56,
- 0x58,
- 0x5a,
- 0x5c,
- 0x5e,
- 0x60,
- 0x62,
- 0x64,
- 0x66,
- 0x68,
- 0x6a,
- 0x6c,
- 0x6e,
- 0x70,
- 0x72,
- 0x74,
- 0x76,
- 0x78,
- 0x7a,
- 0x7c,
- 0x7e,
- 0x80,
- 0x82,
- 0x84,
- 0x86,
- 0x88,
- 0x8a,
- 0x8c,
- 0x8e,
- 0x90,
- 0x92,
- 0x94,
- 0x96,
- 0x98,
- 0x9a,
- 0x9c,
- 0x9e,
- 0xa0,
- 0xa2,
- 0xa4,
- 0xa6,
- 0xa8,
- 0xaa,
- 0xac,
- 0xae,
- 0xb0,
- 0xb2,
- 0xb4,
- 0xb6,
- 0xb8,
- 0xba,
- 0xbc,
- 0xbe,
- 0xc0,
- 0xc2,
- 0xc4,
- 0xc6,
- 0xc8,
- 0xca,
- 0xcc,
- 0xce,
- 0xd0,
- 0xd2,
- 0xd4,
- 0xd6,
- 0xd8,
- 0xda,
- 0xdc,
- 0xde,
- 0xe0,
- 0xe2,
- 0xe4,
- 0xe6,
- 0xe8,
- 0xea,
- 0xec,
- 0xee,
- 0xf0,
- 0xf2,
- 0xf4,
- 0xf6,
- 0xf8,
- 0xfa,
- 0xfc,
- 0xfe,
- 0x1b,
- 0x19,
- 0x1f,
- 0x1d,
- 0x13,
- 0x11,
- 0x17,
- 0x15,
- 0x0b,
- 0x09,
- 0x0f,
- 0x0d,
- 0x03,
- 0x01,
- 0x07,
- 0x05,
- 0x3b,
- 0x39,
- 0x3f,
- 0x3d,
- 0x33,
- 0x31,
- 0x37,
- 0x35,
- 0x2b,
- 0x29,
- 0x2f,
- 0x2d,
- 0x23,
- 0x21,
- 0x27,
- 0x25,
- 0x5b,
- 0x59,
- 0x5f,
- 0x5d,
- 0x53,
- 0x51,
- 0x57,
- 0x55,
- 0x4b,
- 0x49,
- 0x4f,
- 0x4d,
- 0x43,
- 0x41,
- 0x47,
- 0x45,
- 0x7b,
- 0x79,
- 0x7f,
- 0x7d,
- 0x73,
- 0x71,
- 0x77,
- 0x75,
- 0x6b,
- 0x69,
- 0x6f,
- 0x6d,
- 0x63,
- 0x61,
- 0x67,
- 0x65,
- 0x9b,
- 0x99,
- 0x9f,
- 0x9d,
- 0x93,
- 0x91,
- 0x97,
- 0x95,
- 0x8b,
- 0x89,
- 0x8f,
- 0x8d,
- 0x83,
- 0x81,
- 0x87,
- 0x85,
- 0xbb,
- 0xb9,
- 0xbf,
- 0xbd,
- 0xb3,
- 0xb1,
- 0xb7,
- 0xb5,
- 0xab,
- 0xa9,
- 0xaf,
- 0xad,
- 0xa3,
- 0xa1,
- 0xa7,
- 0xa5,
- 0xdb,
- 0xd9,
- 0xdf,
- 0xdd,
- 0xd3,
- 0xd1,
- 0xd7,
- 0xd5,
- 0xcb,
- 0xc9,
- 0xcf,
- 0xcd,
- 0xc3,
- 0xc1,
- 0xc7,
- 0xc5,
- 0xfb,
- 0xf9,
- 0xff,
- 0xfd,
- 0xf3,
- 0xf1,
- 0xf7,
- 0xf5,
- 0xeb,
- 0xe9,
- 0xef,
- 0xed,
- 0xe3,
- 0xe1,
- 0xe7,
- 0xe5,
- };
-
- /**
- * Precalculated lookup table for galois field multiplication by 3 used in
- * the MixColums step during encryption.
- */
- private static final int[] MULT3 = {
- 0x00,
- 0x03,
- 0x06,
- 0x05,
- 0x0c,
- 0x0f,
- 0x0a,
- 0x09,
- 0x18,
- 0x1b,
- 0x1e,
- 0x1d,
- 0x14,
- 0x17,
- 0x12,
- 0x11,
- 0x30,
- 0x33,
- 0x36,
- 0x35,
- 0x3c,
- 0x3f,
- 0x3a,
- 0x39,
- 0x28,
- 0x2b,
- 0x2e,
- 0x2d,
- 0x24,
- 0x27,
- 0x22,
- 0x21,
- 0x60,
- 0x63,
- 0x66,
- 0x65,
- 0x6c,
- 0x6f,
- 0x6a,
- 0x69,
- 0x78,
- 0x7b,
- 0x7e,
- 0x7d,
- 0x74,
- 0x77,
- 0x72,
- 0x71,
- 0x50,
- 0x53,
- 0x56,
- 0x55,
- 0x5c,
- 0x5f,
- 0x5a,
- 0x59,
- 0x48,
- 0x4b,
- 0x4e,
- 0x4d,
- 0x44,
- 0x47,
- 0x42,
- 0x41,
- 0xc0,
- 0xc3,
- 0xc6,
- 0xc5,
- 0xcc,
- 0xcf,
- 0xca,
- 0xc9,
- 0xd8,
- 0xdb,
- 0xde,
- 0xdd,
- 0xd4,
- 0xd7,
- 0xd2,
- 0xd1,
- 0xf0,
- 0xf3,
- 0xf6,
- 0xf5,
- 0xfc,
- 0xff,
- 0xfa,
- 0xf9,
- 0xe8,
- 0xeb,
- 0xee,
- 0xed,
- 0xe4,
- 0xe7,
- 0xe2,
- 0xe1,
- 0xa0,
- 0xa3,
- 0xa6,
- 0xa5,
- 0xac,
- 0xaf,
- 0xaa,
- 0xa9,
- 0xb8,
- 0xbb,
- 0xbe,
- 0xbd,
- 0xb4,
- 0xb7,
- 0xb2,
- 0xb1,
- 0x90,
- 0x93,
- 0x96,
- 0x95,
- 0x9c,
- 0x9f,
- 0x9a,
- 0x99,
- 0x88,
- 0x8b,
- 0x8e,
- 0x8d,
- 0x84,
- 0x87,
- 0x82,
- 0x81,
- 0x9b,
- 0x98,
- 0x9d,
- 0x9e,
- 0x97,
- 0x94,
- 0x91,
- 0x92,
- 0x83,
- 0x80,
- 0x85,
- 0x86,
- 0x8f,
- 0x8c,
- 0x89,
- 0x8a,
- 0xab,
- 0xa8,
- 0xad,
- 0xae,
- 0xa7,
- 0xa4,
- 0xa1,
- 0xa2,
- 0xb3,
- 0xb0,
- 0xb5,
- 0xb6,
- 0xbf,
- 0xbc,
- 0xb9,
- 0xba,
- 0xfb,
- 0xf8,
- 0xfd,
- 0xfe,
- 0xf7,
- 0xf4,
- 0xf1,
- 0xf2,
- 0xe3,
- 0xe0,
- 0xe5,
- 0xe6,
- 0xef,
- 0xec,
- 0xe9,
- 0xea,
- 0xcb,
- 0xc8,
- 0xcd,
- 0xce,
- 0xc7,
- 0xc4,
- 0xc1,
- 0xc2,
- 0xd3,
- 0xd0,
- 0xd5,
- 0xd6,
- 0xdf,
- 0xdc,
- 0xd9,
- 0xda,
- 0x5b,
- 0x58,
- 0x5d,
- 0x5e,
- 0x57,
- 0x54,
- 0x51,
- 0x52,
- 0x43,
- 0x40,
- 0x45,
- 0x46,
- 0x4f,
- 0x4c,
- 0x49,
- 0x4a,
- 0x6b,
- 0x68,
- 0x6d,
- 0x6e,
- 0x67,
- 0x64,
- 0x61,
- 0x62,
- 0x73,
- 0x70,
- 0x75,
- 0x76,
- 0x7f,
- 0x7c,
- 0x79,
- 0x7a,
- 0x3b,
- 0x38,
- 0x3d,
- 0x3e,
- 0x37,
- 0x34,
- 0x31,
- 0x32,
- 0x23,
- 0x20,
- 0x25,
- 0x26,
- 0x2f,
- 0x2c,
- 0x29,
- 0x2a,
- 0x0b,
- 0x08,
- 0x0d,
- 0x0e,
- 0x07,
- 0x04,
- 0x01,
- 0x02,
- 0x13,
- 0x10,
- 0x15,
- 0x16,
- 0x1f,
- 0x1c,
- 0x19,
- 0x1a,
- };
-
- /**
- * Precalculated lookup table for galois field multiplication by 9 used in
- * the MixColums step during decryption.
- */
- private static final int[] MULT9 = {
- 0x00,
- 0x09,
- 0x12,
- 0x1b,
- 0x24,
- 0x2d,
- 0x36,
- 0x3f,
- 0x48,
- 0x41,
- 0x5a,
- 0x53,
- 0x6c,
- 0x65,
- 0x7e,
- 0x77,
- 0x90,
- 0x99,
- 0x82,
- 0x8b,
- 0xb4,
- 0xbd,
- 0xa6,
- 0xaf,
- 0xd8,
- 0xd1,
- 0xca,
- 0xc3,
- 0xfc,
- 0xf5,
- 0xee,
- 0xe7,
- 0x3b,
- 0x32,
- 0x29,
- 0x20,
- 0x1f,
- 0x16,
- 0x0d,
- 0x04,
- 0x73,
- 0x7a,
- 0x61,
- 0x68,
- 0x57,
- 0x5e,
- 0x45,
- 0x4c,
- 0xab,
- 0xa2,
- 0xb9,
- 0xb0,
- 0x8f,
- 0x86,
- 0x9d,
- 0x94,
- 0xe3,
- 0xea,
- 0xf1,
- 0xf8,
- 0xc7,
- 0xce,
- 0xd5,
- 0xdc,
- 0x76,
- 0x7f,
- 0x64,
- 0x6d,
- 0x52,
- 0x5b,
- 0x40,
- 0x49,
- 0x3e,
- 0x37,
- 0x2c,
- 0x25,
- 0x1a,
- 0x13,
- 0x08,
- 0x01,
- 0xe6,
- 0xef,
- 0xf4,
- 0xfd,
- 0xc2,
- 0xcb,
- 0xd0,
- 0xd9,
- 0xae,
- 0xa7,
- 0xbc,
- 0xb5,
- 0x8a,
- 0x83,
- 0x98,
- 0x91,
- 0x4d,
- 0x44,
- 0x5f,
- 0x56,
- 0x69,
- 0x60,
- 0x7b,
- 0x72,
- 0x05,
- 0x0c,
- 0x17,
- 0x1e,
- 0x21,
- 0x28,
- 0x33,
- 0x3a,
- 0xdd,
- 0xd4,
- 0xcf,
- 0xc6,
- 0xf9,
- 0xf0,
- 0xeb,
- 0xe2,
- 0x95,
- 0x9c,
- 0x87,
- 0x8e,
- 0xb1,
- 0xb8,
- 0xa3,
- 0xaa,
- 0xec,
- 0xe5,
- 0xfe,
- 0xf7,
- 0xc8,
- 0xc1,
- 0xda,
- 0xd3,
- 0xa4,
- 0xad,
- 0xb6,
- 0xbf,
- 0x80,
- 0x89,
- 0x92,
- 0x9b,
- 0x7c,
- 0x75,
- 0x6e,
- 0x67,
- 0x58,
- 0x51,
- 0x4a,
- 0x43,
- 0x34,
- 0x3d,
- 0x26,
- 0x2f,
- 0x10,
- 0x19,
- 0x02,
- 0x0b,
- 0xd7,
- 0xde,
- 0xc5,
- 0xcc,
- 0xf3,
- 0xfa,
- 0xe1,
- 0xe8,
- 0x9f,
- 0x96,
- 0x8d,
- 0x84,
- 0xbb,
- 0xb2,
- 0xa9,
- 0xa0,
- 0x47,
- 0x4e,
- 0x55,
- 0x5c,
- 0x63,
- 0x6a,
- 0x71,
- 0x78,
- 0x0f,
- 0x06,
- 0x1d,
- 0x14,
- 0x2b,
- 0x22,
- 0x39,
- 0x30,
- 0x9a,
- 0x93,
- 0x88,
- 0x81,
- 0xbe,
- 0xb7,
- 0xac,
- 0xa5,
- 0xd2,
- 0xdb,
- 0xc0,
- 0xc9,
- 0xf6,
- 0xff,
- 0xe4,
- 0xed,
- 0x0a,
- 0x03,
- 0x18,
- 0x11,
- 0x2e,
- 0x27,
- 0x3c,
- 0x35,
- 0x42,
- 0x4b,
- 0x50,
- 0x59,
- 0x66,
- 0x6f,
- 0x74,
- 0x7d,
- 0xa1,
- 0xa8,
- 0xb3,
- 0xba,
- 0x85,
- 0x8c,
- 0x97,
- 0x9e,
- 0xe9,
- 0xe0,
- 0xfb,
- 0xf2,
- 0xcd,
- 0xc4,
- 0xdf,
- 0xd6,
- 0x31,
- 0x38,
- 0x23,
- 0x2a,
- 0x15,
- 0x1c,
- 0x07,
- 0x0e,
- 0x79,
- 0x70,
- 0x6b,
- 0x62,
- 0x5d,
- 0x54,
- 0x4f,
- 0x46,
- };
-
- /**
- * Precalculated lookup table for galois field multiplication by 11 used in
- * the MixColums step during decryption.
- */
- private static final int[] MULT11 = {
- 0x00,
- 0x0b,
- 0x16,
- 0x1d,
- 0x2c,
- 0x27,
- 0x3a,
- 0x31,
- 0x58,
- 0x53,
- 0x4e,
- 0x45,
- 0x74,
- 0x7f,
- 0x62,
- 0x69,
- 0xb0,
- 0xbb,
- 0xa6,
- 0xad,
- 0x9c,
- 0x97,
- 0x8a,
- 0x81,
- 0xe8,
- 0xe3,
- 0xfe,
- 0xf5,
- 0xc4,
- 0xcf,
- 0xd2,
- 0xd9,
- 0x7b,
- 0x70,
- 0x6d,
- 0x66,
- 0x57,
- 0x5c,
- 0x41,
- 0x4a,
- 0x23,
- 0x28,
- 0x35,
- 0x3e,
- 0x0f,
- 0x04,
- 0x19,
- 0x12,
- 0xcb,
- 0xc0,
- 0xdd,
- 0xd6,
- 0xe7,
- 0xec,
- 0xf1,
- 0xfa,
- 0x93,
- 0x98,
- 0x85,
- 0x8e,
- 0xbf,
- 0xb4,
- 0xa9,
- 0xa2,
- 0xf6,
- 0xfd,
- 0xe0,
- 0xeb,
- 0xda,
- 0xd1,
- 0xcc,
- 0xc7,
- 0xae,
- 0xa5,
- 0xb8,
- 0xb3,
- 0x82,
- 0x89,
- 0x94,
- 0x9f,
- 0x46,
- 0x4d,
- 0x50,
- 0x5b,
- 0x6a,
- 0x61,
- 0x7c,
- 0x77,
- 0x1e,
- 0x15,
- 0x08,
- 0x03,
- 0x32,
- 0x39,
- 0x24,
- 0x2f,
- 0x8d,
- 0x86,
- 0x9b,
- 0x90,
- 0xa1,
- 0xaa,
- 0xb7,
- 0xbc,
- 0xd5,
- 0xde,
- 0xc3,
- 0xc8,
- 0xf9,
- 0xf2,
- 0xef,
- 0xe4,
- 0x3d,
- 0x36,
- 0x2b,
- 0x20,
- 0x11,
- 0x1a,
- 0x07,
- 0x0c,
- 0x65,
- 0x6e,
- 0x73,
- 0x78,
- 0x49,
- 0x42,
- 0x5f,
- 0x54,
- 0xf7,
- 0xfc,
- 0xe1,
- 0xea,
- 0xdb,
- 0xd0,
- 0xcd,
- 0xc6,
- 0xaf,
- 0xa4,
- 0xb9,
- 0xb2,
- 0x83,
- 0x88,
- 0x95,
- 0x9e,
- 0x47,
- 0x4c,
- 0x51,
- 0x5a,
- 0x6b,
- 0x60,
- 0x7d,
- 0x76,
- 0x1f,
- 0x14,
- 0x09,
- 0x02,
- 0x33,
- 0x38,
- 0x25,
- 0x2e,
- 0x8c,
- 0x87,
- 0x9a,
- 0x91,
- 0xa0,
- 0xab,
- 0xb6,
- 0xbd,
- 0xd4,
- 0xdf,
- 0xc2,
- 0xc9,
- 0xf8,
- 0xf3,
- 0xee,
- 0xe5,
- 0x3c,
- 0x37,
- 0x2a,
- 0x21,
- 0x10,
- 0x1b,
- 0x06,
- 0x0d,
- 0x64,
- 0x6f,
- 0x72,
- 0x79,
- 0x48,
- 0x43,
- 0x5e,
- 0x55,
- 0x01,
- 0x0a,
- 0x17,
- 0x1c,
- 0x2d,
- 0x26,
- 0x3b,
- 0x30,
- 0x59,
- 0x52,
- 0x4f,
- 0x44,
- 0x75,
- 0x7e,
- 0x63,
- 0x68,
- 0xb1,
- 0xba,
- 0xa7,
- 0xac,
- 0x9d,
- 0x96,
- 0x8b,
- 0x80,
- 0xe9,
- 0xe2,
- 0xff,
- 0xf4,
- 0xc5,
- 0xce,
- 0xd3,
- 0xd8,
- 0x7a,
- 0x71,
- 0x6c,
- 0x67,
- 0x56,
- 0x5d,
- 0x40,
- 0x4b,
- 0x22,
- 0x29,
- 0x34,
- 0x3f,
- 0x0e,
- 0x05,
- 0x18,
- 0x13,
- 0xca,
- 0xc1,
- 0xdc,
- 0xd7,
- 0xe6,
- 0xed,
- 0xf0,
- 0xfb,
- 0x92,
- 0x99,
- 0x84,
- 0x8f,
- 0xbe,
- 0xb5,
- 0xa8,
- 0xa3,
- };
-
- /**
- * Precalculated lookup table for galois field multiplication by 13 used in
- * the MixColums step during decryption.
- */
- private static final int[] MULT13 = {
- 0x00,
- 0x0d,
- 0x1a,
- 0x17,
- 0x34,
- 0x39,
- 0x2e,
- 0x23,
- 0x68,
- 0x65,
- 0x72,
- 0x7f,
- 0x5c,
- 0x51,
- 0x46,
- 0x4b,
- 0xd0,
- 0xdd,
- 0xca,
- 0xc7,
- 0xe4,
- 0xe9,
- 0xfe,
- 0xf3,
- 0xb8,
- 0xb5,
- 0xa2,
- 0xaf,
- 0x8c,
- 0x81,
- 0x96,
- 0x9b,
- 0xbb,
- 0xb6,
- 0xa1,
- 0xac,
- 0x8f,
- 0x82,
- 0x95,
- 0x98,
- 0xd3,
- 0xde,
- 0xc9,
- 0xc4,
- 0xe7,
- 0xea,
- 0xfd,
- 0xf0,
- 0x6b,
- 0x66,
- 0x71,
- 0x7c,
- 0x5f,
- 0x52,
- 0x45,
- 0x48,
- 0x03,
- 0x0e,
- 0x19,
- 0x14,
- 0x37,
- 0x3a,
- 0x2d,
- 0x20,
- 0x6d,
- 0x60,
- 0x77,
- 0x7a,
- 0x59,
- 0x54,
- 0x43,
- 0x4e,
- 0x05,
- 0x08,
- 0x1f,
- 0x12,
- 0x31,
- 0x3c,
- 0x2b,
- 0x26,
- 0xbd,
- 0xb0,
- 0xa7,
- 0xaa,
- 0x89,
- 0x84,
- 0x93,
- 0x9e,
- 0xd5,
- 0xd8,
- 0xcf,
- 0xc2,
- 0xe1,
- 0xec,
- 0xfb,
- 0xf6,
- 0xd6,
- 0xdb,
- 0xcc,
- 0xc1,
- 0xe2,
- 0xef,
- 0xf8,
- 0xf5,
- 0xbe,
- 0xb3,
- 0xa4,
- 0xa9,
- 0x8a,
- 0x87,
- 0x90,
- 0x9d,
- 0x06,
- 0x0b,
- 0x1c,
- 0x11,
- 0x32,
- 0x3f,
- 0x28,
- 0x25,
- 0x6e,
- 0x63,
- 0x74,
- 0x79,
- 0x5a,
- 0x57,
- 0x40,
- 0x4d,
- 0xda,
- 0xd7,
- 0xc0,
- 0xcd,
- 0xee,
- 0xe3,
- 0xf4,
- 0xf9,
- 0xb2,
- 0xbf,
- 0xa8,
- 0xa5,
- 0x86,
- 0x8b,
- 0x9c,
- 0x91,
- 0x0a,
- 0x07,
- 0x10,
- 0x1d,
- 0x3e,
- 0x33,
- 0x24,
- 0x29,
- 0x62,
- 0x6f,
- 0x78,
- 0x75,
- 0x56,
- 0x5b,
- 0x4c,
- 0x41,
- 0x61,
- 0x6c,
- 0x7b,
- 0x76,
- 0x55,
- 0x58,
- 0x4f,
- 0x42,
- 0x09,
- 0x04,
- 0x13,
- 0x1e,
- 0x3d,
- 0x30,
- 0x27,
- 0x2a,
- 0xb1,
- 0xbc,
- 0xab,
- 0xa6,
- 0x85,
- 0x88,
- 0x9f,
- 0x92,
- 0xd9,
- 0xd4,
- 0xc3,
- 0xce,
- 0xed,
- 0xe0,
- 0xf7,
- 0xfa,
- 0xb7,
- 0xba,
- 0xad,
- 0xa0,
- 0x83,
- 0x8e,
- 0x99,
- 0x94,
- 0xdf,
- 0xd2,
- 0xc5,
- 0xc8,
- 0xeb,
- 0xe6,
- 0xf1,
- 0xfc,
- 0x67,
- 0x6a,
- 0x7d,
- 0x70,
- 0x53,
- 0x5e,
- 0x49,
- 0x44,
- 0x0f,
- 0x02,
- 0x15,
- 0x18,
- 0x3b,
- 0x36,
- 0x21,
- 0x2c,
- 0x0c,
- 0x01,
- 0x16,
- 0x1b,
- 0x38,
- 0x35,
- 0x22,
- 0x2f,
- 0x64,
- 0x69,
- 0x7e,
- 0x73,
- 0x50,
- 0x5d,
- 0x4a,
- 0x47,
- 0xdc,
- 0xd1,
- 0xc6,
- 0xcb,
- 0xe8,
- 0xe5,
- 0xf2,
- 0xff,
- 0xb4,
- 0xb9,
- 0xae,
- 0xa3,
- 0x80,
- 0x8d,
- 0x9a,
- 0x97,
- };
-
- /**
- * Precalculated lookup table for galois field multiplication by 14 used in
- * the MixColums step during decryption.
- */
- private static final int[] MULT14 = {
- 0x00,
- 0x0e,
- 0x1c,
- 0x12,
- 0x38,
- 0x36,
- 0x24,
- 0x2a,
- 0x70,
- 0x7e,
- 0x6c,
- 0x62,
- 0x48,
- 0x46,
- 0x54,
- 0x5a,
- 0xe0,
- 0xee,
- 0xfc,
- 0xf2,
- 0xd8,
- 0xd6,
- 0xc4,
- 0xca,
- 0x90,
- 0x9e,
- 0x8c,
- 0x82,
- 0xa8,
- 0xa6,
- 0xb4,
- 0xba,
- 0xdb,
- 0xd5,
- 0xc7,
- 0xc9,
- 0xe3,
- 0xed,
- 0xff,
- 0xf1,
- 0xab,
- 0xa5,
- 0xb7,
- 0xb9,
- 0x93,
- 0x9d,
- 0x8f,
- 0x81,
- 0x3b,
- 0x35,
- 0x27,
- 0x29,
- 0x03,
- 0x0d,
- 0x1f,
- 0x11,
- 0x4b,
- 0x45,
- 0x57,
- 0x59,
- 0x73,
- 0x7d,
- 0x6f,
- 0x61,
- 0xad,
- 0xa3,
- 0xb1,
- 0xbf,
- 0x95,
- 0x9b,
- 0x89,
- 0x87,
- 0xdd,
- 0xd3,
- 0xc1,
- 0xcf,
- 0xe5,
- 0xeb,
- 0xf9,
- 0xf7,
- 0x4d,
- 0x43,
- 0x51,
- 0x5f,
- 0x75,
- 0x7b,
- 0x69,
- 0x67,
- 0x3d,
- 0x33,
- 0x21,
- 0x2f,
- 0x05,
- 0x0b,
- 0x19,
- 0x17,
- 0x76,
- 0x78,
- 0x6a,
- 0x64,
- 0x4e,
- 0x40,
- 0x52,
- 0x5c,
- 0x06,
- 0x08,
- 0x1a,
- 0x14,
- 0x3e,
- 0x30,
- 0x22,
- 0x2c,
- 0x96,
- 0x98,
- 0x8a,
- 0x84,
- 0xae,
- 0xa0,
- 0xb2,
- 0xbc,
- 0xe6,
- 0xe8,
- 0xfa,
- 0xf4,
- 0xde,
- 0xd0,
- 0xc2,
- 0xcc,
- 0x41,
- 0x4f,
- 0x5d,
- 0x53,
- 0x79,
- 0x77,
- 0x65,
- 0x6b,
- 0x31,
- 0x3f,
- 0x2d,
- 0x23,
- 0x09,
- 0x07,
- 0x15,
- 0x1b,
- 0xa1,
- 0xaf,
- 0xbd,
- 0xb3,
- 0x99,
- 0x97,
- 0x85,
- 0x8b,
- 0xd1,
- 0xdf,
- 0xcd,
- 0xc3,
- 0xe9,
- 0xe7,
- 0xf5,
- 0xfb,
- 0x9a,
- 0x94,
- 0x86,
- 0x88,
- 0xa2,
- 0xac,
- 0xbe,
- 0xb0,
- 0xea,
- 0xe4,
- 0xf6,
- 0xf8,
- 0xd2,
- 0xdc,
- 0xce,
- 0xc0,
- 0x7a,
- 0x74,
- 0x66,
- 0x68,
- 0x42,
- 0x4c,
- 0x5e,
- 0x50,
- 0x0a,
- 0x04,
- 0x16,
- 0x18,
- 0x32,
- 0x3c,
- 0x2e,
- 0x20,
- 0xec,
- 0xe2,
- 0xf0,
- 0xfe,
- 0xd4,
- 0xda,
- 0xc8,
- 0xc6,
- 0x9c,
- 0x92,
- 0x80,
- 0x8e,
- 0xa4,
- 0xaa,
- 0xb8,
- 0xb6,
- 0x0c,
- 0x02,
- 0x10,
- 0x1e,
- 0x34,
- 0x3a,
- 0x28,
- 0x26,
- 0x7c,
- 0x72,
- 0x60,
- 0x6e,
- 0x44,
- 0x4a,
- 0x58,
- 0x56,
- 0x37,
- 0x39,
- 0x2b,
- 0x25,
- 0x0f,
- 0x01,
- 0x13,
- 0x1d,
- 0x47,
- 0x49,
- 0x5b,
- 0x55,
- 0x7f,
- 0x71,
- 0x63,
- 0x6d,
- 0xd7,
- 0xd9,
- 0xcb,
- 0xc5,
- 0xef,
- 0xe1,
- 0xf3,
- 0xfd,
- 0xa7,
- 0xa9,
- 0xbb,
- 0xb5,
- 0x9f,
- 0x91,
- 0x83,
- 0x8d,
- };
-
- /**
- * Subroutine of the Rijndael key expansion.
- */
- public static BigInteger scheduleCore(BigInteger t, int rconCounter) {
- StringBuilder rBytes = new StringBuilder(t.toString(16));
-
- // Add zero padding
- while (rBytes.length() < 8) {
- rBytes.insert(0, "0");
- }
-
- // rotate the first 16 bits to the back
- String rotatingBytes = rBytes.substring(0, 2);
- String fixedBytes = rBytes.substring(2);
-
- rBytes = new StringBuilder(fixedBytes + rotatingBytes);
-
- // apply S-Box to all 8-Bit Substrings
- for (int i = 0; i < 4; i++) {
- StringBuilder currentByteBits = new StringBuilder(rBytes.substring(i * 2, (i + 1) * 2));
-
- int currentByte = Integer.parseInt(currentByteBits.toString(), 16);
- currentByte = SBOX[currentByte];
-
- // add the current RCON value to the first byte
- if (i == 0) {
- currentByte = currentByte ^ RCON[rconCounter];
- }
-
- currentByteBits = new StringBuilder(Integer.toHexString(currentByte));
-
- // Add zero padding
- while (currentByteBits.length() < 2) {
- currentByteBits.insert(0, '0');
- }
-
- // replace bytes in original string
- rBytes = new StringBuilder(rBytes.substring(0, i * 2) + currentByteBits + rBytes.substring((i + 1) * 2));
- }
-
- return new BigInteger(rBytes.toString(), 16);
- }
-
- /**
- * Returns an array of 10 + 1 round keys that are calculated by using
- * Rijndael key schedule
- *
- * @return array of 10 + 1 round keys
- */
- public static BigInteger[] keyExpansion(BigInteger initialKey) {
- BigInteger[] roundKeys = {
- initialKey,
- BigInteger.ZERO,
- BigInteger.ZERO,
- BigInteger.ZERO,
- BigInteger.ZERO,
- BigInteger.ZERO,
- BigInteger.ZERO,
- BigInteger.ZERO,
- BigInteger.ZERO,
- BigInteger.ZERO,
- BigInteger.ZERO,
- };
-
- // initialize rcon iteration
- int rconCounter = 1;
-
- for (int i = 1; i < 11; i++) {
- // get the previous 32 bits the key
- BigInteger t = roundKeys[i - 1].remainder(new BigInteger("100000000", 16));
-
- // split previous key into 8-bit segments
- BigInteger[] prevKey = {
- roundKeys[i - 1].remainder(new BigInteger("100000000", 16)),
- roundKeys[i - 1].remainder(new BigInteger("10000000000000000", 16)).divide(new BigInteger("100000000", 16)),
- roundKeys[i - 1].remainder(new BigInteger("1000000000000000000000000", 16)).divide(new BigInteger("10000000000000000", 16)),
- roundKeys[i - 1].divide(new BigInteger("1000000000000000000000000", 16)),
- };
-
- // run schedule core
- t = scheduleCore(t, rconCounter);
- rconCounter += 1;
-
- // Calculate partial round key
- BigInteger t0 = t.xor(prevKey[3]);
- BigInteger t1 = t0.xor(prevKey[2]);
- BigInteger t2 = t1.xor(prevKey[1]);
- BigInteger t3 = t2.xor(prevKey[0]);
-
- // Join round key segments
- t2 = t2.multiply(new BigInteger("100000000", 16));
- t1 = t1.multiply(new BigInteger("10000000000000000", 16));
- t0 = t0.multiply(new BigInteger("1000000000000000000000000", 16));
- roundKeys[i] = t0.add(t1).add(t2).add(t3);
- }
- return roundKeys;
- }
-
- /**
- * representation of the input 128-bit block as an array of 8-bit integers.
- *
- * @param block of 128-bit integers
- * @return array of 8-bit integers
- */
- public static int[] splitBlockIntoCells(BigInteger block) {
- int[] cells = new int[16];
- StringBuilder blockBits = new StringBuilder(block.toString(2));
-
- // Append leading 0 for full "128-bit" string
- while (blockBits.length() < 128) {
- blockBits.insert(0, '0');
- }
-
- // split 128 to 8 bit cells
- for (int i = 0; i < cells.length; i++) {
- String cellBits = blockBits.substring(8 * i, 8 * (i + 1));
- cells[i] = Integer.parseInt(cellBits, 2);
- }
-
- return cells;
- }
-
- /**
- * Returns the 128-bit BigInteger representation of the input of an array of
- * 8-bit integers.
- *
- * @param cells that we need to merge
- * @return block of merged cells
- */
- public static BigInteger mergeCellsIntoBlock(int[] cells) {
- StringBuilder blockBits = new StringBuilder();
- for (int i = 0; i < 16; i++) {
- StringBuilder cellBits = new StringBuilder(Integer.toBinaryString(cells[i]));
-
- // Append leading 0 for full "8-bit" strings
- while (cellBits.length() < 8) {
- cellBits.insert(0, '0');
- }
-
- blockBits.append(cellBits);
- }
-
- return new BigInteger(blockBits.toString(), 2);
- }
-
- /**
- * @return ciphertext XOR key
- */
- public static BigInteger addRoundKey(BigInteger ciphertext, BigInteger key) {
- return ciphertext.xor(key);
- }
-
- /**
- * substitutes 8-Bit long substrings of the input using the S-Box and
- * returns the result.
- *
- * @return subtraction Output
- */
- public static BigInteger subBytes(BigInteger ciphertext) {
- int[] cells = splitBlockIntoCells(ciphertext);
-
- for (int i = 0; i < 16; i++) {
- cells[i] = SBOX[cells[i]];
- }
-
- return mergeCellsIntoBlock(cells);
- }
-
- /**
- * substitutes 8-Bit long substrings of the input using the inverse S-Box
- * for decryption and returns the result.
- *
- * @return subtraction Output
- */
- public static BigInteger subBytesDec(BigInteger ciphertext) {
- int[] cells = splitBlockIntoCells(ciphertext);
-
- for (int i = 0; i < 16; i++) {
- cells[i] = INVERSE_SBOX[cells[i]];
- }
-
- return mergeCellsIntoBlock(cells);
- }
-
- /**
- * Cell permutation step. Shifts cells within the rows of the input and
- * returns the result.
- */
- public static BigInteger shiftRows(BigInteger ciphertext) {
- int[] cells = splitBlockIntoCells(ciphertext);
- int[] output = new int[16];
-
- // do nothing in the first row
- output[0] = cells[0];
- output[4] = cells[4];
- output[8] = cells[8];
- output[12] = cells[12];
-
- // shift the second row backwards by one cell
- output[1] = cells[5];
- output[5] = cells[9];
- output[9] = cells[13];
- output[13] = cells[1];
-
- // shift the third row backwards by two cell
- output[2] = cells[10];
- output[6] = cells[14];
- output[10] = cells[2];
- output[14] = cells[6];
-
- // shift the forth row backwards by tree cell
- output[3] = cells[15];
- output[7] = cells[3];
- output[11] = cells[7];
- output[15] = cells[11];
-
- return mergeCellsIntoBlock(output);
- }
-
- /**
- * Cell permutation step for decryption . Shifts cells within the rows of
- * the input and returns the result.
- */
- public static BigInteger shiftRowsDec(BigInteger ciphertext) {
- int[] cells = splitBlockIntoCells(ciphertext);
- int[] output = new int[16];
-
- // do nothing in the first row
- output[0] = cells[0];
- output[4] = cells[4];
- output[8] = cells[8];
- output[12] = cells[12];
-
- // shift the second row forwards by one cell
- output[1] = cells[13];
- output[5] = cells[1];
- output[9] = cells[5];
- output[13] = cells[9];
-
- // shift the third row forwards by two cell
- output[2] = cells[10];
- output[6] = cells[14];
- output[10] = cells[2];
- output[14] = cells[6];
-
- // shift the forth row forwards by tree cell
- output[3] = cells[7];
- output[7] = cells[11];
- output[11] = cells[15];
- output[15] = cells[3];
-
- return mergeCellsIntoBlock(output);
- }
-
- /**
- * Applies the Rijndael MixColumns to the input and returns the result.
- */
- public static BigInteger mixColumns(BigInteger ciphertext) {
- int[] cells = splitBlockIntoCells(ciphertext);
- int[] outputCells = new int[16];
-
- for (int i = 0; i < 4; i++) {
- int[] row = {
- cells[i * 4],
- cells[i * 4 + 1],
- cells[i * 4 + 2],
- cells[i * 4 + 3],
- };
-
- outputCells[i * 4] = MULT2[row[0]] ^ MULT3[row[1]] ^ row[2] ^ row[3];
- outputCells[i * 4 + 1] = row[0] ^ MULT2[row[1]] ^ MULT3[row[2]] ^ row[3];
- outputCells[i * 4 + 2] = row[0] ^ row[1] ^ MULT2[row[2]] ^ MULT3[row[3]];
- outputCells[i * 4 + 3] = MULT3[row[0]] ^ row[1] ^ row[2] ^ MULT2[row[3]];
- }
- return mergeCellsIntoBlock(outputCells);
- }
-
- /**
- * Applies the inverse Rijndael MixColumns for decryption to the input and
- * returns the result.
- */
- public static BigInteger mixColumnsDec(BigInteger ciphertext) {
- int[] cells = splitBlockIntoCells(ciphertext);
- int[] outputCells = new int[16];
-
- for (int i = 0; i < 4; i++) {
- int[] row = {
- cells[i * 4],
- cells[i * 4 + 1],
- cells[i * 4 + 2],
- cells[i * 4 + 3],
- };
-
- outputCells[i * 4] = MULT14[row[0]] ^ MULT11[row[1]] ^ MULT13[row[2]] ^ MULT9[row[3]];
- outputCells[i * 4 + 1] = MULT9[row[0]] ^ MULT14[row[1]] ^ MULT11[row[2]] ^ MULT13[row[3]];
- outputCells[i * 4 + 2] = MULT13[row[0]] ^ MULT9[row[1]] ^ MULT14[row[2]] ^ MULT11[row[3]];
- outputCells[i * 4 + 3] = MULT11[row[0]] ^ MULT13[row[1]] ^ MULT9[row[2]] ^ MULT14[row[3]];
- }
- return mergeCellsIntoBlock(outputCells);
- }
-
- /**
- * Encrypts the plaintext with the key and returns the result
- *
- * @param plainText which we want to encrypt
- * @param key the key for encrypt
- * @return EncryptedText
- */
- public static BigInteger encrypt(BigInteger plainText, BigInteger key) {
- BigInteger[] roundKeys = keyExpansion(key);
-
- // Initial round
- plainText = addRoundKey(plainText, roundKeys[0]);
-
- // Main rounds
- for (int i = 1; i < 10; i++) {
- plainText = subBytes(plainText);
- plainText = shiftRows(plainText);
- plainText = mixColumns(plainText);
- plainText = addRoundKey(plainText, roundKeys[i]);
- }
-
- // Final round
- plainText = subBytes(plainText);
- plainText = shiftRows(plainText);
- plainText = addRoundKey(plainText, roundKeys[10]);
-
- return plainText;
- }
-
- /**
- * Decrypts the ciphertext with the key and returns the result
- *
- * @param cipherText The Encrypted text which we want to decrypt
- * @return decryptedText
- */
- public static BigInteger decrypt(BigInteger cipherText, BigInteger key) {
- BigInteger[] roundKeys = keyExpansion(key);
-
- // Invert final round
- cipherText = addRoundKey(cipherText, roundKeys[10]);
- cipherText = shiftRowsDec(cipherText);
- cipherText = subBytesDec(cipherText);
-
- // Invert main rounds
- for (int i = 9; i > 0; i--) {
- cipherText = addRoundKey(cipherText, roundKeys[i]);
- cipherText = mixColumnsDec(cipherText);
- cipherText = shiftRowsDec(cipherText);
- cipherText = subBytesDec(cipherText);
- }
-
- // Invert initial round
- cipherText = addRoundKey(cipherText, roundKeys[0]);
-
- return cipherText;
- }
-
- public static void main(String[] args) {
- try (Scanner input = new Scanner(System.in)) {
- System.out.println("Enter (e) letter for encrypt or (d) letter for decrypt :");
- char choice = input.nextLine().charAt(0);
- String in;
- switch (choice) {
- case 'E', 'e' -> {
- System.out.println(
- "Choose a plaintext block (128-Bit Integer in base 16):"
- );
- in = input.nextLine();
- BigInteger plaintext = new BigInteger(in, 16);
- System.out.println(
- "Choose a Key (128-Bit Integer in base 16):"
- );
- in = input.nextLine();
- BigInteger encryptionKey = new BigInteger(in, 16);
- System.out.println(
- "The encrypted message is: \n"
- + encrypt(plaintext, encryptionKey).toString(16)
- );
- }
- case 'D', 'd' -> {
- System.out.println(
- "Enter your ciphertext block (128-Bit Integer in base 16):"
- );
- in = input.nextLine();
- BigInteger ciphertext = new BigInteger(in, 16);
- System.out.println(
- "Choose a Key (128-Bit Integer in base 16):"
- );
- in = input.nextLine();
- BigInteger decryptionKey = new BigInteger(in, 16);
- System.out.println(
- "The deciphered message is:\n"
- + decrypt(ciphertext, decryptionKey).toString(16)
- );
- }
- default -> System.out.println("** End **");
- }
- }
- }
-}
+package com.thealgorithms.ciphers;
+
+import java.math.BigInteger;
+import java.util.Scanner;
+
+/**
+ * This class is build to demonstrate the application of the AES-algorithm on a
+ * single 128-Bit block of data.
+ */
+public final class AES {
+ private AES() {
+ }
+
+ /**
+ * Precalculated values for x to the power of 2 in Rijndaels galois field.
+ * Used as 'RCON' during the key expansion.
+ */
+ private static final int[] RCON = {
+ 0x8d,
+ 0x01,
+ 0x02,
+ 0x04,
+ 0x08,
+ 0x10,
+ 0x20,
+ 0x40,
+ 0x80,
+ 0x1b,
+ 0x36,
+ 0x6c,
+ 0xd8,
+ 0xab,
+ 0x4d,
+ 0x9a,
+ 0x2f,
+ 0x5e,
+ 0xbc,
+ 0x63,
+ 0xc6,
+ 0x97,
+ 0x35,
+ 0x6a,
+ 0xd4,
+ 0xb3,
+ 0x7d,
+ 0xfa,
+ 0xef,
+ 0xc5,
+ 0x91,
+ 0x39,
+ 0x72,
+ 0xe4,
+ 0xd3,
+ 0xbd,
+ 0x61,
+ 0xc2,
+ 0x9f,
+ 0x25,
+ 0x4a,
+ 0x94,
+ 0x33,
+ 0x66,
+ 0xcc,
+ 0x83,
+ 0x1d,
+ 0x3a,
+ 0x74,
+ 0xe8,
+ 0xcb,
+ 0x8d,
+ 0x01,
+ 0x02,
+ 0x04,
+ 0x08,
+ 0x10,
+ 0x20,
+ 0x40,
+ 0x80,
+ 0x1b,
+ 0x36,
+ 0x6c,
+ 0xd8,
+ 0xab,
+ 0x4d,
+ 0x9a,
+ 0x2f,
+ 0x5e,
+ 0xbc,
+ 0x63,
+ 0xc6,
+ 0x97,
+ 0x35,
+ 0x6a,
+ 0xd4,
+ 0xb3,
+ 0x7d,
+ 0xfa,
+ 0xef,
+ 0xc5,
+ 0x91,
+ 0x39,
+ 0x72,
+ 0xe4,
+ 0xd3,
+ 0xbd,
+ 0x61,
+ 0xc2,
+ 0x9f,
+ 0x25,
+ 0x4a,
+ 0x94,
+ 0x33,
+ 0x66,
+ 0xcc,
+ 0x83,
+ 0x1d,
+ 0x3a,
+ 0x74,
+ 0xe8,
+ 0xcb,
+ 0x8d,
+ 0x01,
+ 0x02,
+ 0x04,
+ 0x08,
+ 0x10,
+ 0x20,
+ 0x40,
+ 0x80,
+ 0x1b,
+ 0x36,
+ 0x6c,
+ 0xd8,
+ 0xab,
+ 0x4d,
+ 0x9a,
+ 0x2f,
+ 0x5e,
+ 0xbc,
+ 0x63,
+ 0xc6,
+ 0x97,
+ 0x35,
+ 0x6a,
+ 0xd4,
+ 0xb3,
+ 0x7d,
+ 0xfa,
+ 0xef,
+ 0xc5,
+ 0x91,
+ 0x39,
+ 0x72,
+ 0xe4,
+ 0xd3,
+ 0xbd,
+ 0x61,
+ 0xc2,
+ 0x9f,
+ 0x25,
+ 0x4a,
+ 0x94,
+ 0x33,
+ 0x66,
+ 0xcc,
+ 0x83,
+ 0x1d,
+ 0x3a,
+ 0x74,
+ 0xe8,
+ 0xcb,
+ 0x8d,
+ 0x01,
+ 0x02,
+ 0x04,
+ 0x08,
+ 0x10,
+ 0x20,
+ 0x40,
+ 0x80,
+ 0x1b,
+ 0x36,
+ 0x6c,
+ 0xd8,
+ 0xab,
+ 0x4d,
+ 0x9a,
+ 0x2f,
+ 0x5e,
+ 0xbc,
+ 0x63,
+ 0xc6,
+ 0x97,
+ 0x35,
+ 0x6a,
+ 0xd4,
+ 0xb3,
+ 0x7d,
+ 0xfa,
+ 0xef,
+ 0xc5,
+ 0x91,
+ 0x39,
+ 0x72,
+ 0xe4,
+ 0xd3,
+ 0xbd,
+ 0x61,
+ 0xc2,
+ 0x9f,
+ 0x25,
+ 0x4a,
+ 0x94,
+ 0x33,
+ 0x66,
+ 0xcc,
+ 0x83,
+ 0x1d,
+ 0x3a,
+ 0x74,
+ 0xe8,
+ 0xcb,
+ 0x8d,
+ 0x01,
+ 0x02,
+ 0x04,
+ 0x08,
+ 0x10,
+ 0x20,
+ 0x40,
+ 0x80,
+ 0x1b,
+ 0x36,
+ 0x6c,
+ 0xd8,
+ 0xab,
+ 0x4d,
+ 0x9a,
+ 0x2f,
+ 0x5e,
+ 0xbc,
+ 0x63,
+ 0xc6,
+ 0x97,
+ 0x35,
+ 0x6a,
+ 0xd4,
+ 0xb3,
+ 0x7d,
+ 0xfa,
+ 0xef,
+ 0xc5,
+ 0x91,
+ 0x39,
+ 0x72,
+ 0xe4,
+ 0xd3,
+ 0xbd,
+ 0x61,
+ 0xc2,
+ 0x9f,
+ 0x25,
+ 0x4a,
+ 0x94,
+ 0x33,
+ 0x66,
+ 0xcc,
+ 0x83,
+ 0x1d,
+ 0x3a,
+ 0x74,
+ 0xe8,
+ 0xcb,
+ 0x8d,
+ };
+
+ /**
+ * Rijndael S-box Substitution table used for encryption in the subBytes
+ * step, as well as the key expansion.
+ */
+ private static final int[] SBOX = {
+ 0x63,
+ 0x7C,
+ 0x77,
+ 0x7B,
+ 0xF2,
+ 0x6B,
+ 0x6F,
+ 0xC5,
+ 0x30,
+ 0x01,
+ 0x67,
+ 0x2B,
+ 0xFE,
+ 0xD7,
+ 0xAB,
+ 0x76,
+ 0xCA,
+ 0x82,
+ 0xC9,
+ 0x7D,
+ 0xFA,
+ 0x59,
+ 0x47,
+ 0xF0,
+ 0xAD,
+ 0xD4,
+ 0xA2,
+ 0xAF,
+ 0x9C,
+ 0xA4,
+ 0x72,
+ 0xC0,
+ 0xB7,
+ 0xFD,
+ 0x93,
+ 0x26,
+ 0x36,
+ 0x3F,
+ 0xF7,
+ 0xCC,
+ 0x34,
+ 0xA5,
+ 0xE5,
+ 0xF1,
+ 0x71,
+ 0xD8,
+ 0x31,
+ 0x15,
+ 0x04,
+ 0xC7,
+ 0x23,
+ 0xC3,
+ 0x18,
+ 0x96,
+ 0x05,
+ 0x9A,
+ 0x07,
+ 0x12,
+ 0x80,
+ 0xE2,
+ 0xEB,
+ 0x27,
+ 0xB2,
+ 0x75,
+ 0x09,
+ 0x83,
+ 0x2C,
+ 0x1A,
+ 0x1B,
+ 0x6E,
+ 0x5A,
+ 0xA0,
+ 0x52,
+ 0x3B,
+ 0xD6,
+ 0xB3,
+ 0x29,
+ 0xE3,
+ 0x2F,
+ 0x84,
+ 0x53,
+ 0xD1,
+ 0x00,
+ 0xED,
+ 0x20,
+ 0xFC,
+ 0xB1,
+ 0x5B,
+ 0x6A,
+ 0xCB,
+ 0xBE,
+ 0x39,
+ 0x4A,
+ 0x4C,
+ 0x58,
+ 0xCF,
+ 0xD0,
+ 0xEF,
+ 0xAA,
+ 0xFB,
+ 0x43,
+ 0x4D,
+ 0x33,
+ 0x85,
+ 0x45,
+ 0xF9,
+ 0x02,
+ 0x7F,
+ 0x50,
+ 0x3C,
+ 0x9F,
+ 0xA8,
+ 0x51,
+ 0xA3,
+ 0x40,
+ 0x8F,
+ 0x92,
+ 0x9D,
+ 0x38,
+ 0xF5,
+ 0xBC,
+ 0xB6,
+ 0xDA,
+ 0x21,
+ 0x10,
+ 0xFF,
+ 0xF3,
+ 0xD2,
+ 0xCD,
+ 0x0C,
+ 0x13,
+ 0xEC,
+ 0x5F,
+ 0x97,
+ 0x44,
+ 0x17,
+ 0xC4,
+ 0xA7,
+ 0x7E,
+ 0x3D,
+ 0x64,
+ 0x5D,
+ 0x19,
+ 0x73,
+ 0x60,
+ 0x81,
+ 0x4F,
+ 0xDC,
+ 0x22,
+ 0x2A,
+ 0x90,
+ 0x88,
+ 0x46,
+ 0xEE,
+ 0xB8,
+ 0x14,
+ 0xDE,
+ 0x5E,
+ 0x0B,
+ 0xDB,
+ 0xE0,
+ 0x32,
+ 0x3A,
+ 0x0A,
+ 0x49,
+ 0x06,
+ 0x24,
+ 0x5C,
+ 0xC2,
+ 0xD3,
+ 0xAC,
+ 0x62,
+ 0x91,
+ 0x95,
+ 0xE4,
+ 0x79,
+ 0xE7,
+ 0xC8,
+ 0x37,
+ 0x6D,
+ 0x8D,
+ 0xD5,
+ 0x4E,
+ 0xA9,
+ 0x6C,
+ 0x56,
+ 0xF4,
+ 0xEA,
+ 0x65,
+ 0x7A,
+ 0xAE,
+ 0x08,
+ 0xBA,
+ 0x78,
+ 0x25,
+ 0x2E,
+ 0x1C,
+ 0xA6,
+ 0xB4,
+ 0xC6,
+ 0xE8,
+ 0xDD,
+ 0x74,
+ 0x1F,
+ 0x4B,
+ 0xBD,
+ 0x8B,
+ 0x8A,
+ 0x70,
+ 0x3E,
+ 0xB5,
+ 0x66,
+ 0x48,
+ 0x03,
+ 0xF6,
+ 0x0E,
+ 0x61,
+ 0x35,
+ 0x57,
+ 0xB9,
+ 0x86,
+ 0xC1,
+ 0x1D,
+ 0x9E,
+ 0xE1,
+ 0xF8,
+ 0x98,
+ 0x11,
+ 0x69,
+ 0xD9,
+ 0x8E,
+ 0x94,
+ 0x9B,
+ 0x1E,
+ 0x87,
+ 0xE9,
+ 0xCE,
+ 0x55,
+ 0x28,
+ 0xDF,
+ 0x8C,
+ 0xA1,
+ 0x89,
+ 0x0D,
+ 0xBF,
+ 0xE6,
+ 0x42,
+ 0x68,
+ 0x41,
+ 0x99,
+ 0x2D,
+ 0x0F,
+ 0xB0,
+ 0x54,
+ 0xBB,
+ 0x16,
+ };
+
+ /**
+ * Inverse Rijndael S-box Substitution table used for decryption in the
+ * subBytesDec step.
+ */
+ private static final int[] INVERSE_SBOX = {
+ 0x52,
+ 0x09,
+ 0x6A,
+ 0xD5,
+ 0x30,
+ 0x36,
+ 0xA5,
+ 0x38,
+ 0xBF,
+ 0x40,
+ 0xA3,
+ 0x9E,
+ 0x81,
+ 0xF3,
+ 0xD7,
+ 0xFB,
+ 0x7C,
+ 0xE3,
+ 0x39,
+ 0x82,
+ 0x9B,
+ 0x2F,
+ 0xFF,
+ 0x87,
+ 0x34,
+ 0x8E,
+ 0x43,
+ 0x44,
+ 0xC4,
+ 0xDE,
+ 0xE9,
+ 0xCB,
+ 0x54,
+ 0x7B,
+ 0x94,
+ 0x32,
+ 0xA6,
+ 0xC2,
+ 0x23,
+ 0x3D,
+ 0xEE,
+ 0x4C,
+ 0x95,
+ 0x0B,
+ 0x42,
+ 0xFA,
+ 0xC3,
+ 0x4E,
+ 0x08,
+ 0x2E,
+ 0xA1,
+ 0x66,
+ 0x28,
+ 0xD9,
+ 0x24,
+ 0xB2,
+ 0x76,
+ 0x5B,
+ 0xA2,
+ 0x49,
+ 0x6D,
+ 0x8B,
+ 0xD1,
+ 0x25,
+ 0x72,
+ 0xF8,
+ 0xF6,
+ 0x64,
+ 0x86,
+ 0x68,
+ 0x98,
+ 0x16,
+ 0xD4,
+ 0xA4,
+ 0x5C,
+ 0xCC,
+ 0x5D,
+ 0x65,
+ 0xB6,
+ 0x92,
+ 0x6C,
+ 0x70,
+ 0x48,
+ 0x50,
+ 0xFD,
+ 0xED,
+ 0xB9,
+ 0xDA,
+ 0x5E,
+ 0x15,
+ 0x46,
+ 0x57,
+ 0xA7,
+ 0x8D,
+ 0x9D,
+ 0x84,
+ 0x90,
+ 0xD8,
+ 0xAB,
+ 0x00,
+ 0x8C,
+ 0xBC,
+ 0xD3,
+ 0x0A,
+ 0xF7,
+ 0xE4,
+ 0x58,
+ 0x05,
+ 0xB8,
+ 0xB3,
+ 0x45,
+ 0x06,
+ 0xD0,
+ 0x2C,
+ 0x1E,
+ 0x8F,
+ 0xCA,
+ 0x3F,
+ 0x0F,
+ 0x02,
+ 0xC1,
+ 0xAF,
+ 0xBD,
+ 0x03,
+ 0x01,
+ 0x13,
+ 0x8A,
+ 0x6B,
+ 0x3A,
+ 0x91,
+ 0x11,
+ 0x41,
+ 0x4F,
+ 0x67,
+ 0xDC,
+ 0xEA,
+ 0x97,
+ 0xF2,
+ 0xCF,
+ 0xCE,
+ 0xF0,
+ 0xB4,
+ 0xE6,
+ 0x73,
+ 0x96,
+ 0xAC,
+ 0x74,
+ 0x22,
+ 0xE7,
+ 0xAD,
+ 0x35,
+ 0x85,
+ 0xE2,
+ 0xF9,
+ 0x37,
+ 0xE8,
+ 0x1C,
+ 0x75,
+ 0xDF,
+ 0x6E,
+ 0x47,
+ 0xF1,
+ 0x1A,
+ 0x71,
+ 0x1D,
+ 0x29,
+ 0xC5,
+ 0x89,
+ 0x6F,
+ 0xB7,
+ 0x62,
+ 0x0E,
+ 0xAA,
+ 0x18,
+ 0xBE,
+ 0x1B,
+ 0xFC,
+ 0x56,
+ 0x3E,
+ 0x4B,
+ 0xC6,
+ 0xD2,
+ 0x79,
+ 0x20,
+ 0x9A,
+ 0xDB,
+ 0xC0,
+ 0xFE,
+ 0x78,
+ 0xCD,
+ 0x5A,
+ 0xF4,
+ 0x1F,
+ 0xDD,
+ 0xA8,
+ 0x33,
+ 0x88,
+ 0x07,
+ 0xC7,
+ 0x31,
+ 0xB1,
+ 0x12,
+ 0x10,
+ 0x59,
+ 0x27,
+ 0x80,
+ 0xEC,
+ 0x5F,
+ 0x60,
+ 0x51,
+ 0x7F,
+ 0xA9,
+ 0x19,
+ 0xB5,
+ 0x4A,
+ 0x0D,
+ 0x2D,
+ 0xE5,
+ 0x7A,
+ 0x9F,
+ 0x93,
+ 0xC9,
+ 0x9C,
+ 0xEF,
+ 0xA0,
+ 0xE0,
+ 0x3B,
+ 0x4D,
+ 0xAE,
+ 0x2A,
+ 0xF5,
+ 0xB0,
+ 0xC8,
+ 0xEB,
+ 0xBB,
+ 0x3C,
+ 0x83,
+ 0x53,
+ 0x99,
+ 0x61,
+ 0x17,
+ 0x2B,
+ 0x04,
+ 0x7E,
+ 0xBA,
+ 0x77,
+ 0xD6,
+ 0x26,
+ 0xE1,
+ 0x69,
+ 0x14,
+ 0x63,
+ 0x55,
+ 0x21,
+ 0x0C,
+ 0x7D,
+ };
+
+ /**
+ * Precalculated lookup table for galois field multiplication by 2 used in
+ * the MixColums step during encryption.
+ */
+ private static final int[] MULT2 = {
+ 0x00,
+ 0x02,
+ 0x04,
+ 0x06,
+ 0x08,
+ 0x0a,
+ 0x0c,
+ 0x0e,
+ 0x10,
+ 0x12,
+ 0x14,
+ 0x16,
+ 0x18,
+ 0x1a,
+ 0x1c,
+ 0x1e,
+ 0x20,
+ 0x22,
+ 0x24,
+ 0x26,
+ 0x28,
+ 0x2a,
+ 0x2c,
+ 0x2e,
+ 0x30,
+ 0x32,
+ 0x34,
+ 0x36,
+ 0x38,
+ 0x3a,
+ 0x3c,
+ 0x3e,
+ 0x40,
+ 0x42,
+ 0x44,
+ 0x46,
+ 0x48,
+ 0x4a,
+ 0x4c,
+ 0x4e,
+ 0x50,
+ 0x52,
+ 0x54,
+ 0x56,
+ 0x58,
+ 0x5a,
+ 0x5c,
+ 0x5e,
+ 0x60,
+ 0x62,
+ 0x64,
+ 0x66,
+ 0x68,
+ 0x6a,
+ 0x6c,
+ 0x6e,
+ 0x70,
+ 0x72,
+ 0x74,
+ 0x76,
+ 0x78,
+ 0x7a,
+ 0x7c,
+ 0x7e,
+ 0x80,
+ 0x82,
+ 0x84,
+ 0x86,
+ 0x88,
+ 0x8a,
+ 0x8c,
+ 0x8e,
+ 0x90,
+ 0x92,
+ 0x94,
+ 0x96,
+ 0x98,
+ 0x9a,
+ 0x9c,
+ 0x9e,
+ 0xa0,
+ 0xa2,
+ 0xa4,
+ 0xa6,
+ 0xa8,
+ 0xaa,
+ 0xac,
+ 0xae,
+ 0xb0,
+ 0xb2,
+ 0xb4,
+ 0xb6,
+ 0xb8,
+ 0xba,
+ 0xbc,
+ 0xbe,
+ 0xc0,
+ 0xc2,
+ 0xc4,
+ 0xc6,
+ 0xc8,
+ 0xca,
+ 0xcc,
+ 0xce,
+ 0xd0,
+ 0xd2,
+ 0xd4,
+ 0xd6,
+ 0xd8,
+ 0xda,
+ 0xdc,
+ 0xde,
+ 0xe0,
+ 0xe2,
+ 0xe4,
+ 0xe6,
+ 0xe8,
+ 0xea,
+ 0xec,
+ 0xee,
+ 0xf0,
+ 0xf2,
+ 0xf4,
+ 0xf6,
+ 0xf8,
+ 0xfa,
+ 0xfc,
+ 0xfe,
+ 0x1b,
+ 0x19,
+ 0x1f,
+ 0x1d,
+ 0x13,
+ 0x11,
+ 0x17,
+ 0x15,
+ 0x0b,
+ 0x09,
+ 0x0f,
+ 0x0d,
+ 0x03,
+ 0x01,
+ 0x07,
+ 0x05,
+ 0x3b,
+ 0x39,
+ 0x3f,
+ 0x3d,
+ 0x33,
+ 0x31,
+ 0x37,
+ 0x35,
+ 0x2b,
+ 0x29,
+ 0x2f,
+ 0x2d,
+ 0x23,
+ 0x21,
+ 0x27,
+ 0x25,
+ 0x5b,
+ 0x59,
+ 0x5f,
+ 0x5d,
+ 0x53,
+ 0x51,
+ 0x57,
+ 0x55,
+ 0x4b,
+ 0x49,
+ 0x4f,
+ 0x4d,
+ 0x43,
+ 0x41,
+ 0x47,
+ 0x45,
+ 0x7b,
+ 0x79,
+ 0x7f,
+ 0x7d,
+ 0x73,
+ 0x71,
+ 0x77,
+ 0x75,
+ 0x6b,
+ 0x69,
+ 0x6f,
+ 0x6d,
+ 0x63,
+ 0x61,
+ 0x67,
+ 0x65,
+ 0x9b,
+ 0x99,
+ 0x9f,
+ 0x9d,
+ 0x93,
+ 0x91,
+ 0x97,
+ 0x95,
+ 0x8b,
+ 0x89,
+ 0x8f,
+ 0x8d,
+ 0x83,
+ 0x81,
+ 0x87,
+ 0x85,
+ 0xbb,
+ 0xb9,
+ 0xbf,
+ 0xbd,
+ 0xb3,
+ 0xb1,
+ 0xb7,
+ 0xb5,
+ 0xab,
+ 0xa9,
+ 0xaf,
+ 0xad,
+ 0xa3,
+ 0xa1,
+ 0xa7,
+ 0xa5,
+ 0xdb,
+ 0xd9,
+ 0xdf,
+ 0xdd,
+ 0xd3,
+ 0xd1,
+ 0xd7,
+ 0xd5,
+ 0xcb,
+ 0xc9,
+ 0xcf,
+ 0xcd,
+ 0xc3,
+ 0xc1,
+ 0xc7,
+ 0xc5,
+ 0xfb,
+ 0xf9,
+ 0xff,
+ 0xfd,
+ 0xf3,
+ 0xf1,
+ 0xf7,
+ 0xf5,
+ 0xeb,
+ 0xe9,
+ 0xef,
+ 0xed,
+ 0xe3,
+ 0xe1,
+ 0xe7,
+ 0xe5,
+ };
+
+ /**
+ * Precalculated lookup table for galois field multiplication by 3 used in
+ * the MixColums step during encryption.
+ */
+ private static final int[] MULT3 = {
+ 0x00,
+ 0x03,
+ 0x06,
+ 0x05,
+ 0x0c,
+ 0x0f,
+ 0x0a,
+ 0x09,
+ 0x18,
+ 0x1b,
+ 0x1e,
+ 0x1d,
+ 0x14,
+ 0x17,
+ 0x12,
+ 0x11,
+ 0x30,
+ 0x33,
+ 0x36,
+ 0x35,
+ 0x3c,
+ 0x3f,
+ 0x3a,
+ 0x39,
+ 0x28,
+ 0x2b,
+ 0x2e,
+ 0x2d,
+ 0x24,
+ 0x27,
+ 0x22,
+ 0x21,
+ 0x60,
+ 0x63,
+ 0x66,
+ 0x65,
+ 0x6c,
+ 0x6f,
+ 0x6a,
+ 0x69,
+ 0x78,
+ 0x7b,
+ 0x7e,
+ 0x7d,
+ 0x74,
+ 0x77,
+ 0x72,
+ 0x71,
+ 0x50,
+ 0x53,
+ 0x56,
+ 0x55,
+ 0x5c,
+ 0x5f,
+ 0x5a,
+ 0x59,
+ 0x48,
+ 0x4b,
+ 0x4e,
+ 0x4d,
+ 0x44,
+ 0x47,
+ 0x42,
+ 0x41,
+ 0xc0,
+ 0xc3,
+ 0xc6,
+ 0xc5,
+ 0xcc,
+ 0xcf,
+ 0xca,
+ 0xc9,
+ 0xd8,
+ 0xdb,
+ 0xde,
+ 0xdd,
+ 0xd4,
+ 0xd7,
+ 0xd2,
+ 0xd1,
+ 0xf0,
+ 0xf3,
+ 0xf6,
+ 0xf5,
+ 0xfc,
+ 0xff,
+ 0xfa,
+ 0xf9,
+ 0xe8,
+ 0xeb,
+ 0xee,
+ 0xed,
+ 0xe4,
+ 0xe7,
+ 0xe2,
+ 0xe1,
+ 0xa0,
+ 0xa3,
+ 0xa6,
+ 0xa5,
+ 0xac,
+ 0xaf,
+ 0xaa,
+ 0xa9,
+ 0xb8,
+ 0xbb,
+ 0xbe,
+ 0xbd,
+ 0xb4,
+ 0xb7,
+ 0xb2,
+ 0xb1,
+ 0x90,
+ 0x93,
+ 0x96,
+ 0x95,
+ 0x9c,
+ 0x9f,
+ 0x9a,
+ 0x99,
+ 0x88,
+ 0x8b,
+ 0x8e,
+ 0x8d,
+ 0x84,
+ 0x87,
+ 0x82,
+ 0x81,
+ 0x9b,
+ 0x98,
+ 0x9d,
+ 0x9e,
+ 0x97,
+ 0x94,
+ 0x91,
+ 0x92,
+ 0x83,
+ 0x80,
+ 0x85,
+ 0x86,
+ 0x8f,
+ 0x8c,
+ 0x89,
+ 0x8a,
+ 0xab,
+ 0xa8,
+ 0xad,
+ 0xae,
+ 0xa7,
+ 0xa4,
+ 0xa1,
+ 0xa2,
+ 0xb3,
+ 0xb0,
+ 0xb5,
+ 0xb6,
+ 0xbf,
+ 0xbc,
+ 0xb9,
+ 0xba,
+ 0xfb,
+ 0xf8,
+ 0xfd,
+ 0xfe,
+ 0xf7,
+ 0xf4,
+ 0xf1,
+ 0xf2,
+ 0xe3,
+ 0xe0,
+ 0xe5,
+ 0xe6,
+ 0xef,
+ 0xec,
+ 0xe9,
+ 0xea,
+ 0xcb,
+ 0xc8,
+ 0xcd,
+ 0xce,
+ 0xc7,
+ 0xc4,
+ 0xc1,
+ 0xc2,
+ 0xd3,
+ 0xd0,
+ 0xd5,
+ 0xd6,
+ 0xdf,
+ 0xdc,
+ 0xd9,
+ 0xda,
+ 0x5b,
+ 0x58,
+ 0x5d,
+ 0x5e,
+ 0x57,
+ 0x54,
+ 0x51,
+ 0x52,
+ 0x43,
+ 0x40,
+ 0x45,
+ 0x46,
+ 0x4f,
+ 0x4c,
+ 0x49,
+ 0x4a,
+ 0x6b,
+ 0x68,
+ 0x6d,
+ 0x6e,
+ 0x67,
+ 0x64,
+ 0x61,
+ 0x62,
+ 0x73,
+ 0x70,
+ 0x75,
+ 0x76,
+ 0x7f,
+ 0x7c,
+ 0x79,
+ 0x7a,
+ 0x3b,
+ 0x38,
+ 0x3d,
+ 0x3e,
+ 0x37,
+ 0x34,
+ 0x31,
+ 0x32,
+ 0x23,
+ 0x20,
+ 0x25,
+ 0x26,
+ 0x2f,
+ 0x2c,
+ 0x29,
+ 0x2a,
+ 0x0b,
+ 0x08,
+ 0x0d,
+ 0x0e,
+ 0x07,
+ 0x04,
+ 0x01,
+ 0x02,
+ 0x13,
+ 0x10,
+ 0x15,
+ 0x16,
+ 0x1f,
+ 0x1c,
+ 0x19,
+ 0x1a,
+ };
+
+ /**
+ * Precalculated lookup table for galois field multiplication by 9 used in
+ * the MixColums step during decryption.
+ */
+ private static final int[] MULT9 = {
+ 0x00,
+ 0x09,
+ 0x12,
+ 0x1b,
+ 0x24,
+ 0x2d,
+ 0x36,
+ 0x3f,
+ 0x48,
+ 0x41,
+ 0x5a,
+ 0x53,
+ 0x6c,
+ 0x65,
+ 0x7e,
+ 0x77,
+ 0x90,
+ 0x99,
+ 0x82,
+ 0x8b,
+ 0xb4,
+ 0xbd,
+ 0xa6,
+ 0xaf,
+ 0xd8,
+ 0xd1,
+ 0xca,
+ 0xc3,
+ 0xfc,
+ 0xf5,
+ 0xee,
+ 0xe7,
+ 0x3b,
+ 0x32,
+ 0x29,
+ 0x20,
+ 0x1f,
+ 0x16,
+ 0x0d,
+ 0x04,
+ 0x73,
+ 0x7a,
+ 0x61,
+ 0x68,
+ 0x57,
+ 0x5e,
+ 0x45,
+ 0x4c,
+ 0xab,
+ 0xa2,
+ 0xb9,
+ 0xb0,
+ 0x8f,
+ 0x86,
+ 0x9d,
+ 0x94,
+ 0xe3,
+ 0xea,
+ 0xf1,
+ 0xf8,
+ 0xc7,
+ 0xce,
+ 0xd5,
+ 0xdc,
+ 0x76,
+ 0x7f,
+ 0x64,
+ 0x6d,
+ 0x52,
+ 0x5b,
+ 0x40,
+ 0x49,
+ 0x3e,
+ 0x37,
+ 0x2c,
+ 0x25,
+ 0x1a,
+ 0x13,
+ 0x08,
+ 0x01,
+ 0xe6,
+ 0xef,
+ 0xf4,
+ 0xfd,
+ 0xc2,
+ 0xcb,
+ 0xd0,
+ 0xd9,
+ 0xae,
+ 0xa7,
+ 0xbc,
+ 0xb5,
+ 0x8a,
+ 0x83,
+ 0x98,
+ 0x91,
+ 0x4d,
+ 0x44,
+ 0x5f,
+ 0x56,
+ 0x69,
+ 0x60,
+ 0x7b,
+ 0x72,
+ 0x05,
+ 0x0c,
+ 0x17,
+ 0x1e,
+ 0x21,
+ 0x28,
+ 0x33,
+ 0x3a,
+ 0xdd,
+ 0xd4,
+ 0xcf,
+ 0xc6,
+ 0xf9,
+ 0xf0,
+ 0xeb,
+ 0xe2,
+ 0x95,
+ 0x9c,
+ 0x87,
+ 0x8e,
+ 0xb1,
+ 0xb8,
+ 0xa3,
+ 0xaa,
+ 0xec,
+ 0xe5,
+ 0xfe,
+ 0xf7,
+ 0xc8,
+ 0xc1,
+ 0xda,
+ 0xd3,
+ 0xa4,
+ 0xad,
+ 0xb6,
+ 0xbf,
+ 0x80,
+ 0x89,
+ 0x92,
+ 0x9b,
+ 0x7c,
+ 0x75,
+ 0x6e,
+ 0x67,
+ 0x58,
+ 0x51,
+ 0x4a,
+ 0x43,
+ 0x34,
+ 0x3d,
+ 0x26,
+ 0x2f,
+ 0x10,
+ 0x19,
+ 0x02,
+ 0x0b,
+ 0xd7,
+ 0xde,
+ 0xc5,
+ 0xcc,
+ 0xf3,
+ 0xfa,
+ 0xe1,
+ 0xe8,
+ 0x9f,
+ 0x96,
+ 0x8d,
+ 0x84,
+ 0xbb,
+ 0xb2,
+ 0xa9,
+ 0xa0,
+ 0x47,
+ 0x4e,
+ 0x55,
+ 0x5c,
+ 0x63,
+ 0x6a,
+ 0x71,
+ 0x78,
+ 0x0f,
+ 0x06,
+ 0x1d,
+ 0x14,
+ 0x2b,
+ 0x22,
+ 0x39,
+ 0x30,
+ 0x9a,
+ 0x93,
+ 0x88,
+ 0x81,
+ 0xbe,
+ 0xb7,
+ 0xac,
+ 0xa5,
+ 0xd2,
+ 0xdb,
+ 0xc0,
+ 0xc9,
+ 0xf6,
+ 0xff,
+ 0xe4,
+ 0xed,
+ 0x0a,
+ 0x03,
+ 0x18,
+ 0x11,
+ 0x2e,
+ 0x27,
+ 0x3c,
+ 0x35,
+ 0x42,
+ 0x4b,
+ 0x50,
+ 0x59,
+ 0x66,
+ 0x6f,
+ 0x74,
+ 0x7d,
+ 0xa1,
+ 0xa8,
+ 0xb3,
+ 0xba,
+ 0x85,
+ 0x8c,
+ 0x97,
+ 0x9e,
+ 0xe9,
+ 0xe0,
+ 0xfb,
+ 0xf2,
+ 0xcd,
+ 0xc4,
+ 0xdf,
+ 0xd6,
+ 0x31,
+ 0x38,
+ 0x23,
+ 0x2a,
+ 0x15,
+ 0x1c,
+ 0x07,
+ 0x0e,
+ 0x79,
+ 0x70,
+ 0x6b,
+ 0x62,
+ 0x5d,
+ 0x54,
+ 0x4f,
+ 0x46,
+ };
+
+ /**
+ * Precalculated lookup table for galois field multiplication by 11 used in
+ * the MixColums step during decryption.
+ */
+ private static final int[] MULT11 = {
+ 0x00,
+ 0x0b,
+ 0x16,
+ 0x1d,
+ 0x2c,
+ 0x27,
+ 0x3a,
+ 0x31,
+ 0x58,
+ 0x53,
+ 0x4e,
+ 0x45,
+ 0x74,
+ 0x7f,
+ 0x62,
+ 0x69,
+ 0xb0,
+ 0xbb,
+ 0xa6,
+ 0xad,
+ 0x9c,
+ 0x97,
+ 0x8a,
+ 0x81,
+ 0xe8,
+ 0xe3,
+ 0xfe,
+ 0xf5,
+ 0xc4,
+ 0xcf,
+ 0xd2,
+ 0xd9,
+ 0x7b,
+ 0x70,
+ 0x6d,
+ 0x66,
+ 0x57,
+ 0x5c,
+ 0x41,
+ 0x4a,
+ 0x23,
+ 0x28,
+ 0x35,
+ 0x3e,
+ 0x0f,
+ 0x04,
+ 0x19,
+ 0x12,
+ 0xcb,
+ 0xc0,
+ 0xdd,
+ 0xd6,
+ 0xe7,
+ 0xec,
+ 0xf1,
+ 0xfa,
+ 0x93,
+ 0x98,
+ 0x85,
+ 0x8e,
+ 0xbf,
+ 0xb4,
+ 0xa9,
+ 0xa2,
+ 0xf6,
+ 0xfd,
+ 0xe0,
+ 0xeb,
+ 0xda,
+ 0xd1,
+ 0xcc,
+ 0xc7,
+ 0xae,
+ 0xa5,
+ 0xb8,
+ 0xb3,
+ 0x82,
+ 0x89,
+ 0x94,
+ 0x9f,
+ 0x46,
+ 0x4d,
+ 0x50,
+ 0x5b,
+ 0x6a,
+ 0x61,
+ 0x7c,
+ 0x77,
+ 0x1e,
+ 0x15,
+ 0x08,
+ 0x03,
+ 0x32,
+ 0x39,
+ 0x24,
+ 0x2f,
+ 0x8d,
+ 0x86,
+ 0x9b,
+ 0x90,
+ 0xa1,
+ 0xaa,
+ 0xb7,
+ 0xbc,
+ 0xd5,
+ 0xde,
+ 0xc3,
+ 0xc8,
+ 0xf9,
+ 0xf2,
+ 0xef,
+ 0xe4,
+ 0x3d,
+ 0x36,
+ 0x2b,
+ 0x20,
+ 0x11,
+ 0x1a,
+ 0x07,
+ 0x0c,
+ 0x65,
+ 0x6e,
+ 0x73,
+ 0x78,
+ 0x49,
+ 0x42,
+ 0x5f,
+ 0x54,
+ 0xf7,
+ 0xfc,
+ 0xe1,
+ 0xea,
+ 0xdb,
+ 0xd0,
+ 0xcd,
+ 0xc6,
+ 0xaf,
+ 0xa4,
+ 0xb9,
+ 0xb2,
+ 0x83,
+ 0x88,
+ 0x95,
+ 0x9e,
+ 0x47,
+ 0x4c,
+ 0x51,
+ 0x5a,
+ 0x6b,
+ 0x60,
+ 0x7d,
+ 0x76,
+ 0x1f,
+ 0x14,
+ 0x09,
+ 0x02,
+ 0x33,
+ 0x38,
+ 0x25,
+ 0x2e,
+ 0x8c,
+ 0x87,
+ 0x9a,
+ 0x91,
+ 0xa0,
+ 0xab,
+ 0xb6,
+ 0xbd,
+ 0xd4,
+ 0xdf,
+ 0xc2,
+ 0xc9,
+ 0xf8,
+ 0xf3,
+ 0xee,
+ 0xe5,
+ 0x3c,
+ 0x37,
+ 0x2a,
+ 0x21,
+ 0x10,
+ 0x1b,
+ 0x06,
+ 0x0d,
+ 0x64,
+ 0x6f,
+ 0x72,
+ 0x79,
+ 0x48,
+ 0x43,
+ 0x5e,
+ 0x55,
+ 0x01,
+ 0x0a,
+ 0x17,
+ 0x1c,
+ 0x2d,
+ 0x26,
+ 0x3b,
+ 0x30,
+ 0x59,
+ 0x52,
+ 0x4f,
+ 0x44,
+ 0x75,
+ 0x7e,
+ 0x63,
+ 0x68,
+ 0xb1,
+ 0xba,
+ 0xa7,
+ 0xac,
+ 0x9d,
+ 0x96,
+ 0x8b,
+ 0x80,
+ 0xe9,
+ 0xe2,
+ 0xff,
+ 0xf4,
+ 0xc5,
+ 0xce,
+ 0xd3,
+ 0xd8,
+ 0x7a,
+ 0x71,
+ 0x6c,
+ 0x67,
+ 0x56,
+ 0x5d,
+ 0x40,
+ 0x4b,
+ 0x22,
+ 0x29,
+ 0x34,
+ 0x3f,
+ 0x0e,
+ 0x05,
+ 0x18,
+ 0x13,
+ 0xca,
+ 0xc1,
+ 0xdc,
+ 0xd7,
+ 0xe6,
+ 0xed,
+ 0xf0,
+ 0xfb,
+ 0x92,
+ 0x99,
+ 0x84,
+ 0x8f,
+ 0xbe,
+ 0xb5,
+ 0xa8,
+ 0xa3,
+ };
+
+ /**
+ * Precalculated lookup table for galois field multiplication by 13 used in
+ * the MixColums step during decryption.
+ */
+ private static final int[] MULT13 = {
+ 0x00,
+ 0x0d,
+ 0x1a,
+ 0x17,
+ 0x34,
+ 0x39,
+ 0x2e,
+ 0x23,
+ 0x68,
+ 0x65,
+ 0x72,
+ 0x7f,
+ 0x5c,
+ 0x51,
+ 0x46,
+ 0x4b,
+ 0xd0,
+ 0xdd,
+ 0xca,
+ 0xc7,
+ 0xe4,
+ 0xe9,
+ 0xfe,
+ 0xf3,
+ 0xb8,
+ 0xb5,
+ 0xa2,
+ 0xaf,
+ 0x8c,
+ 0x81,
+ 0x96,
+ 0x9b,
+ 0xbb,
+ 0xb6,
+ 0xa1,
+ 0xac,
+ 0x8f,
+ 0x82,
+ 0x95,
+ 0x98,
+ 0xd3,
+ 0xde,
+ 0xc9,
+ 0xc4,
+ 0xe7,
+ 0xea,
+ 0xfd,
+ 0xf0,
+ 0x6b,
+ 0x66,
+ 0x71,
+ 0x7c,
+ 0x5f,
+ 0x52,
+ 0x45,
+ 0x48,
+ 0x03,
+ 0x0e,
+ 0x19,
+ 0x14,
+ 0x37,
+ 0x3a,
+ 0x2d,
+ 0x20,
+ 0x6d,
+ 0x60,
+ 0x77,
+ 0x7a,
+ 0x59,
+ 0x54,
+ 0x43,
+ 0x4e,
+ 0x05,
+ 0x08,
+ 0x1f,
+ 0x12,
+ 0x31,
+ 0x3c,
+ 0x2b,
+ 0x26,
+ 0xbd,
+ 0xb0,
+ 0xa7,
+ 0xaa,
+ 0x89,
+ 0x84,
+ 0x93,
+ 0x9e,
+ 0xd5,
+ 0xd8,
+ 0xcf,
+ 0xc2,
+ 0xe1,
+ 0xec,
+ 0xfb,
+ 0xf6,
+ 0xd6,
+ 0xdb,
+ 0xcc,
+ 0xc1,
+ 0xe2,
+ 0xef,
+ 0xf8,
+ 0xf5,
+ 0xbe,
+ 0xb3,
+ 0xa4,
+ 0xa9,
+ 0x8a,
+ 0x87,
+ 0x90,
+ 0x9d,
+ 0x06,
+ 0x0b,
+ 0x1c,
+ 0x11,
+ 0x32,
+ 0x3f,
+ 0x28,
+ 0x25,
+ 0x6e,
+ 0x63,
+ 0x74,
+ 0x79,
+ 0x5a,
+ 0x57,
+ 0x40,
+ 0x4d,
+ 0xda,
+ 0xd7,
+ 0xc0,
+ 0xcd,
+ 0xee,
+ 0xe3,
+ 0xf4,
+ 0xf9,
+ 0xb2,
+ 0xbf,
+ 0xa8,
+ 0xa5,
+ 0x86,
+ 0x8b,
+ 0x9c,
+ 0x91,
+ 0x0a,
+ 0x07,
+ 0x10,
+ 0x1d,
+ 0x3e,
+ 0x33,
+ 0x24,
+ 0x29,
+ 0x62,
+ 0x6f,
+ 0x78,
+ 0x75,
+ 0x56,
+ 0x5b,
+ 0x4c,
+ 0x41,
+ 0x61,
+ 0x6c,
+ 0x7b,
+ 0x76,
+ 0x55,
+ 0x58,
+ 0x4f,
+ 0x42,
+ 0x09,
+ 0x04,
+ 0x13,
+ 0x1e,
+ 0x3d,
+ 0x30,
+ 0x27,
+ 0x2a,
+ 0xb1,
+ 0xbc,
+ 0xab,
+ 0xa6,
+ 0x85,
+ 0x88,
+ 0x9f,
+ 0x92,
+ 0xd9,
+ 0xd4,
+ 0xc3,
+ 0xce,
+ 0xed,
+ 0xe0,
+ 0xf7,
+ 0xfa,
+ 0xb7,
+ 0xba,
+ 0xad,
+ 0xa0,
+ 0x83,
+ 0x8e,
+ 0x99,
+ 0x94,
+ 0xdf,
+ 0xd2,
+ 0xc5,
+ 0xc8,
+ 0xeb,
+ 0xe6,
+ 0xf1,
+ 0xfc,
+ 0x67,
+ 0x6a,
+ 0x7d,
+ 0x70,
+ 0x53,
+ 0x5e,
+ 0x49,
+ 0x44,
+ 0x0f,
+ 0x02,
+ 0x15,
+ 0x18,
+ 0x3b,
+ 0x36,
+ 0x21,
+ 0x2c,
+ 0x0c,
+ 0x01,
+ 0x16,
+ 0x1b,
+ 0x38,
+ 0x35,
+ 0x22,
+ 0x2f,
+ 0x64,
+ 0x69,
+ 0x7e,
+ 0x73,
+ 0x50,
+ 0x5d,
+ 0x4a,
+ 0x47,
+ 0xdc,
+ 0xd1,
+ 0xc6,
+ 0xcb,
+ 0xe8,
+ 0xe5,
+ 0xf2,
+ 0xff,
+ 0xb4,
+ 0xb9,
+ 0xae,
+ 0xa3,
+ 0x80,
+ 0x8d,
+ 0x9a,
+ 0x97,
+ };
+
+ /**
+ * Precalculated lookup table for galois field multiplication by 14 used in
+ * the MixColums step during decryption.
+ */
+ private static final int[] MULT14 = {
+ 0x00,
+ 0x0e,
+ 0x1c,
+ 0x12,
+ 0x38,
+ 0x36,
+ 0x24,
+ 0x2a,
+ 0x70,
+ 0x7e,
+ 0x6c,
+ 0x62,
+ 0x48,
+ 0x46,
+ 0x54,
+ 0x5a,
+ 0xe0,
+ 0xee,
+ 0xfc,
+ 0xf2,
+ 0xd8,
+ 0xd6,
+ 0xc4,
+ 0xca,
+ 0x90,
+ 0x9e,
+ 0x8c,
+ 0x82,
+ 0xa8,
+ 0xa6,
+ 0xb4,
+ 0xba,
+ 0xdb,
+ 0xd5,
+ 0xc7,
+ 0xc9,
+ 0xe3,
+ 0xed,
+ 0xff,
+ 0xf1,
+ 0xab,
+ 0xa5,
+ 0xb7,
+ 0xb9,
+ 0x93,
+ 0x9d,
+ 0x8f,
+ 0x81,
+ 0x3b,
+ 0x35,
+ 0x27,
+ 0x29,
+ 0x03,
+ 0x0d,
+ 0x1f,
+ 0x11,
+ 0x4b,
+ 0x45,
+ 0x57,
+ 0x59,
+ 0x73,
+ 0x7d,
+ 0x6f,
+ 0x61,
+ 0xad,
+ 0xa3,
+ 0xb1,
+ 0xbf,
+ 0x95,
+ 0x9b,
+ 0x89,
+ 0x87,
+ 0xdd,
+ 0xd3,
+ 0xc1,
+ 0xcf,
+ 0xe5,
+ 0xeb,
+ 0xf9,
+ 0xf7,
+ 0x4d,
+ 0x43,
+ 0x51,
+ 0x5f,
+ 0x75,
+ 0x7b,
+ 0x69,
+ 0x67,
+ 0x3d,
+ 0x33,
+ 0x21,
+ 0x2f,
+ 0x05,
+ 0x0b,
+ 0x19,
+ 0x17,
+ 0x76,
+ 0x78,
+ 0x6a,
+ 0x64,
+ 0x4e,
+ 0x40,
+ 0x52,
+ 0x5c,
+ 0x06,
+ 0x08,
+ 0x1a,
+ 0x14,
+ 0x3e,
+ 0x30,
+ 0x22,
+ 0x2c,
+ 0x96,
+ 0x98,
+ 0x8a,
+ 0x84,
+ 0xae,
+ 0xa0,
+ 0xb2,
+ 0xbc,
+ 0xe6,
+ 0xe8,
+ 0xfa,
+ 0xf4,
+ 0xde,
+ 0xd0,
+ 0xc2,
+ 0xcc,
+ 0x41,
+ 0x4f,
+ 0x5d,
+ 0x53,
+ 0x79,
+ 0x77,
+ 0x65,
+ 0x6b,
+ 0x31,
+ 0x3f,
+ 0x2d,
+ 0x23,
+ 0x09,
+ 0x07,
+ 0x15,
+ 0x1b,
+ 0xa1,
+ 0xaf,
+ 0xbd,
+ 0xb3,
+ 0x99,
+ 0x97,
+ 0x85,
+ 0x8b,
+ 0xd1,
+ 0xdf,
+ 0xcd,
+ 0xc3,
+ 0xe9,
+ 0xe7,
+ 0xf5,
+ 0xfb,
+ 0x9a,
+ 0x94,
+ 0x86,
+ 0x88,
+ 0xa2,
+ 0xac,
+ 0xbe,
+ 0xb0,
+ 0xea,
+ 0xe4,
+ 0xf6,
+ 0xf8,
+ 0xd2,
+ 0xdc,
+ 0xce,
+ 0xc0,
+ 0x7a,
+ 0x74,
+ 0x66,
+ 0x68,
+ 0x42,
+ 0x4c,
+ 0x5e,
+ 0x50,
+ 0x0a,
+ 0x04,
+ 0x16,
+ 0x18,
+ 0x32,
+ 0x3c,
+ 0x2e,
+ 0x20,
+ 0xec,
+ 0xe2,
+ 0xf0,
+ 0xfe,
+ 0xd4,
+ 0xda,
+ 0xc8,
+ 0xc6,
+ 0x9c,
+ 0x92,
+ 0x80,
+ 0x8e,
+ 0xa4,
+ 0xaa,
+ 0xb8,
+ 0xb6,
+ 0x0c,
+ 0x02,
+ 0x10,
+ 0x1e,
+ 0x34,
+ 0x3a,
+ 0x28,
+ 0x26,
+ 0x7c,
+ 0x72,
+ 0x60,
+ 0x6e,
+ 0x44,
+ 0x4a,
+ 0x58,
+ 0x56,
+ 0x37,
+ 0x39,
+ 0x2b,
+ 0x25,
+ 0x0f,
+ 0x01,
+ 0x13,
+ 0x1d,
+ 0x47,
+ 0x49,
+ 0x5b,
+ 0x55,
+ 0x7f,
+ 0x71,
+ 0x63,
+ 0x6d,
+ 0xd7,
+ 0xd9,
+ 0xcb,
+ 0xc5,
+ 0xef,
+ 0xe1,
+ 0xf3,
+ 0xfd,
+ 0xa7,
+ 0xa9,
+ 0xbb,
+ 0xb5,
+ 0x9f,
+ 0x91,
+ 0x83,
+ 0x8d,
+ };
+
+ /**
+ * Subroutine of the Rijndael key expansion.
+ */
+ public static BigInteger scheduleCore(BigInteger t, int rconCounter) {
+ StringBuilder rBytes = new StringBuilder(t.toString(16));
+
+ // Add zero padding
+ while (rBytes.length() < 8) {
+ rBytes.insert(0, "0");
+ }
+
+ // rotate the first 16 bits to the back
+ String rotatingBytes = rBytes.substring(0, 2);
+ String fixedBytes = rBytes.substring(2);
+
+ rBytes = new StringBuilder(fixedBytes + rotatingBytes);
+
+ // apply S-Box to all 8-Bit Substrings
+ for (int i = 0; i < 4; i++) {
+ StringBuilder currentByteBits = new StringBuilder(rBytes.substring(i * 2, (i + 1) * 2));
+
+ int currentByte = Integer.parseInt(currentByteBits.toString(), 16);
+ currentByte = SBOX[currentByte];
+
+ // add the current RCON value to the first byte
+ if (i == 0) {
+ currentByte = currentByte ^ RCON[rconCounter];
+ }
+
+ currentByteBits = new StringBuilder(Integer.toHexString(currentByte));
+
+ // Add zero padding
+ while (currentByteBits.length() < 2) {
+ currentByteBits.insert(0, '0');
+ }
+
+ // replace bytes in original string
+ rBytes = new StringBuilder(rBytes.substring(0, i * 2) + currentByteBits + rBytes.substring((i + 1) * 2));
+ }
+
+ return new BigInteger(rBytes.toString(), 16);
+ }
+
+ /**
+ * Returns an array of 10 + 1 round keys that are calculated by using
+ * Rijndael key schedule
+ *
+ * @return array of 10 + 1 round keys
+ */
+ public static BigInteger[] keyExpansion(BigInteger initialKey) {
+ BigInteger[] roundKeys = {
+ initialKey,
+ BigInteger.ZERO,
+ BigInteger.ZERO,
+ BigInteger.ZERO,
+ BigInteger.ZERO,
+ BigInteger.ZERO,
+ BigInteger.ZERO,
+ BigInteger.ZERO,
+ BigInteger.ZERO,
+ BigInteger.ZERO,
+ BigInteger.ZERO,
+ };
+
+ // initialize rcon iteration
+ int rconCounter = 1;
+
+ for (int i = 1; i < 11; i++) {
+ // get the previous 32 bits the key
+ BigInteger t = roundKeys[i - 1].remainder(new BigInteger("100000000", 16));
+
+ // split previous key into 8-bit segments
+ BigInteger[] prevKey = {
+ roundKeys[i - 1].remainder(new BigInteger("100000000", 16)),
+ roundKeys[i - 1].remainder(new BigInteger("10000000000000000", 16)).divide(new BigInteger("100000000", 16)),
+ roundKeys[i - 1].remainder(new BigInteger("1000000000000000000000000", 16)).divide(new BigInteger("10000000000000000", 16)),
+ roundKeys[i - 1].divide(new BigInteger("1000000000000000000000000", 16)),
+ };
+
+ // run schedule core
+ t = scheduleCore(t, rconCounter);
+ rconCounter += 1;
+
+ // Calculate partial round key
+ BigInteger t0 = t.xor(prevKey[3]);
+ BigInteger t1 = t0.xor(prevKey[2]);
+ BigInteger t2 = t1.xor(prevKey[1]);
+ BigInteger t3 = t2.xor(prevKey[0]);
+
+ // Join round key segments
+ t2 = t2.multiply(new BigInteger("100000000", 16));
+ t1 = t1.multiply(new BigInteger("10000000000000000", 16));
+ t0 = t0.multiply(new BigInteger("1000000000000000000000000", 16));
+ roundKeys[i] = t0.add(t1).add(t2).add(t3);
+ }
+ return roundKeys;
+ }
+
+ /**
+ * representation of the input 128-bit block as an array of 8-bit integers.
+ *
+ * @param block of 128-bit integers
+ * @return array of 8-bit integers
+ */
+ public static int[] splitBlockIntoCells(BigInteger block) {
+ int[] cells = new int[16];
+ StringBuilder blockBits = new StringBuilder(block.toString(2));
+
+ // Append leading 0 for full "128-bit" string
+ while (blockBits.length() < 128) {
+ blockBits.insert(0, '0');
+ }
+
+ // split 128 to 8 bit cells
+ for (int i = 0; i < cells.length; i++) {
+ String cellBits = blockBits.substring(8 * i, 8 * (i + 1));
+ cells[i] = Integer.parseInt(cellBits, 2);
+ }
+
+ return cells;
+ }
+
+ /**
+ * Returns the 128-bit BigInteger representation of the input of an array of
+ * 8-bit integers.
+ *
+ * @param cells that we need to merge
+ * @return block of merged cells
+ */
+ public static BigInteger mergeCellsIntoBlock(int[] cells) {
+ StringBuilder blockBits = new StringBuilder();
+ for (int i = 0; i < 16; i++) {
+ StringBuilder cellBits = new StringBuilder(Integer.toBinaryString(cells[i]));
+
+ // Append leading 0 for full "8-bit" strings
+ while (cellBits.length() < 8) {
+ cellBits.insert(0, '0');
+ }
+
+ blockBits.append(cellBits);
+ }
+
+ return new BigInteger(blockBits.toString(), 2);
+ }
+
+ /**
+ * @return ciphertext XOR key
+ */
+ public static BigInteger addRoundKey(BigInteger ciphertext, BigInteger key) {
+ return ciphertext.xor(key);
+ }
+
+ /**
+ * substitutes 8-Bit long substrings of the input using the S-Box and
+ * returns the result.
+ *
+ * @return subtraction Output
+ */
+ public static BigInteger subBytes(BigInteger ciphertext) {
+ int[] cells = splitBlockIntoCells(ciphertext);
+
+ for (int i = 0; i < 16; i++) {
+ cells[i] = SBOX[cells[i]];
+ }
+
+ return mergeCellsIntoBlock(cells);
+ }
+
+ /**
+ * substitutes 8-Bit long substrings of the input using the inverse S-Box
+ * for decryption and returns the result.
+ *
+ * @return subtraction Output
+ */
+ public static BigInteger subBytesDec(BigInteger ciphertext) {
+ int[] cells = splitBlockIntoCells(ciphertext);
+
+ for (int i = 0; i < 16; i++) {
+ cells[i] = INVERSE_SBOX[cells[i]];
+ }
+
+ return mergeCellsIntoBlock(cells);
+ }
+
+ /**
+ * Cell permutation step. Shifts cells within the rows of the input and
+ * returns the result.
+ */
+ public static BigInteger shiftRows(BigInteger ciphertext) {
+ int[] cells = splitBlockIntoCells(ciphertext);
+ int[] output = new int[16];
+
+ // do nothing in the first row
+ output[0] = cells[0];
+ output[4] = cells[4];
+ output[8] = cells[8];
+ output[12] = cells[12];
+
+ // shift the second row backwards by one cell
+ output[1] = cells[5];
+ output[5] = cells[9];
+ output[9] = cells[13];
+ output[13] = cells[1];
+
+ // shift the third row backwards by two cell
+ output[2] = cells[10];
+ output[6] = cells[14];
+ output[10] = cells[2];
+ output[14] = cells[6];
+
+ // shift the forth row backwards by tree cell
+ output[3] = cells[15];
+ output[7] = cells[3];
+ output[11] = cells[7];
+ output[15] = cells[11];
+
+ return mergeCellsIntoBlock(output);
+ }
+
+ /**
+ * Cell permutation step for decryption . Shifts cells within the rows of
+ * the input and returns the result.
+ */
+ public static BigInteger shiftRowsDec(BigInteger ciphertext) {
+ int[] cells = splitBlockIntoCells(ciphertext);
+ int[] output = new int[16];
+
+ // do nothing in the first row
+ output[0] = cells[0];
+ output[4] = cells[4];
+ output[8] = cells[8];
+ output[12] = cells[12];
+
+ // shift the second row forwards by one cell
+ output[1] = cells[13];
+ output[5] = cells[1];
+ output[9] = cells[5];
+ output[13] = cells[9];
+
+ // shift the third row forwards by two cell
+ output[2] = cells[10];
+ output[6] = cells[14];
+ output[10] = cells[2];
+ output[14] = cells[6];
+
+ // shift the forth row forwards by tree cell
+ output[3] = cells[7];
+ output[7] = cells[11];
+ output[11] = cells[15];
+ output[15] = cells[3];
+
+ return mergeCellsIntoBlock(output);
+ }
+
+ /**
+ * Applies the Rijndael MixColumns to the input and returns the result.
+ */
+ public static BigInteger mixColumns(BigInteger ciphertext) {
+ int[] cells = splitBlockIntoCells(ciphertext);
+ int[] outputCells = new int[16];
+
+ for (int i = 0; i < 4; i++) {
+ int[] row = {
+ cells[i * 4],
+ cells[i * 4 + 1],
+ cells[i * 4 + 2],
+ cells[i * 4 + 3],
+ };
+
+ outputCells[i * 4] = MULT2[row[0]] ^ MULT3[row[1]] ^ row[2] ^ row[3];
+ outputCells[i * 4 + 1] = row[0] ^ MULT2[row[1]] ^ MULT3[row[2]] ^ row[3];
+ outputCells[i * 4 + 2] = row[0] ^ row[1] ^ MULT2[row[2]] ^ MULT3[row[3]];
+ outputCells[i * 4 + 3] = MULT3[row[0]] ^ row[1] ^ row[2] ^ MULT2[row[3]];
+ }
+ return mergeCellsIntoBlock(outputCells);
+ }
+
+ /**
+ * Applies the inverse Rijndael MixColumns for decryption to the input and
+ * returns the result.
+ */
+ public static BigInteger mixColumnsDec(BigInteger ciphertext) {
+ int[] cells = splitBlockIntoCells(ciphertext);
+ int[] outputCells = new int[16];
+
+ for (int i = 0; i < 4; i++) {
+ int[] row = {
+ cells[i * 4],
+ cells[i * 4 + 1],
+ cells[i * 4 + 2],
+ cells[i * 4 + 3],
+ };
+
+ outputCells[i * 4] = MULT14[row[0]] ^ MULT11[row[1]] ^ MULT13[row[2]] ^ MULT9[row[3]];
+ outputCells[i * 4 + 1] = MULT9[row[0]] ^ MULT14[row[1]] ^ MULT11[row[2]] ^ MULT13[row[3]];
+ outputCells[i * 4 + 2] = MULT13[row[0]] ^ MULT9[row[1]] ^ MULT14[row[2]] ^ MULT11[row[3]];
+ outputCells[i * 4 + 3] = MULT11[row[0]] ^ MULT13[row[1]] ^ MULT9[row[2]] ^ MULT14[row[3]];
+ }
+ return mergeCellsIntoBlock(outputCells);
+ }
+
+ /**
+ * Encrypts the plaintext with the key and returns the result
+ *
+ * @param plainText which we want to encrypt
+ * @param key the key for encrypt
+ * @return EncryptedText
+ */
+ public static BigInteger encrypt(BigInteger plainText, BigInteger key) {
+ BigInteger[] roundKeys = keyExpansion(key);
+
+ // Initial round
+ plainText = addRoundKey(plainText, roundKeys[0]);
+
+ // Main rounds
+ for (int i = 1; i < 10; i++) {
+ plainText = subBytes(plainText);
+ plainText = shiftRows(plainText);
+ plainText = mixColumns(plainText);
+ plainText = addRoundKey(plainText, roundKeys[i]);
+ }
+
+ // Final round
+ plainText = subBytes(plainText);
+ plainText = shiftRows(plainText);
+ plainText = addRoundKey(plainText, roundKeys[10]);
+
+ return plainText;
+ }
+
+ /**
+ * Decrypts the ciphertext with the key and returns the result
+ *
+ * @param cipherText The Encrypted text which we want to decrypt
+ * @return decryptedText
+ */
+ public static BigInteger decrypt(BigInteger cipherText, BigInteger key) {
+ BigInteger[] roundKeys = keyExpansion(key);
+
+ // Invert final round
+ cipherText = addRoundKey(cipherText, roundKeys[10]);
+ cipherText = shiftRowsDec(cipherText);
+ cipherText = subBytesDec(cipherText);
+
+ // Invert main rounds
+ for (int i = 9; i > 0; i--) {
+ cipherText = addRoundKey(cipherText, roundKeys[i]);
+ cipherText = mixColumnsDec(cipherText);
+ cipherText = shiftRowsDec(cipherText);
+ cipherText = subBytesDec(cipherText);
+ }
+
+ // Invert initial round
+ cipherText = addRoundKey(cipherText, roundKeys[0]);
+
+ return cipherText;
+ }
+
+ public static void main(String[] args) {
+ try (Scanner input = new Scanner(System.in)) {
+ System.out.println("Enter (e) letter for encrypt or (d) letter for decrypt :");
+ char choice = input.nextLine().charAt(0);
+ String in;
+ switch (choice) {
+ case 'E', 'e' -> {
+ System.out.println(
+ "Choose a plaintext block (128-Bit Integer in base 16):"
+ );
+ in = input.nextLine();
+ BigInteger plaintext = new BigInteger(in, 16);
+ System.out.println(
+ "Choose a Key (128-Bit Integer in base 16):"
+ );
+ in = input.nextLine();
+ BigInteger encryptionKey = new BigInteger(in, 16);
+ System.out.println(
+ "The encrypted message is: \n"
+ + encrypt(plaintext, encryptionKey).toString(16)
+ );
+ }
+ case 'D', 'd' -> {
+ System.out.println(
+ "Enter your ciphertext block (128-Bit Integer in base 16):"
+ );
+ in = input.nextLine();
+ BigInteger ciphertext = new BigInteger(in, 16);
+ System.out.println(
+ "Choose a Key (128-Bit Integer in base 16):"
+ );
+ in = input.nextLine();
+ BigInteger decryptionKey = new BigInteger(in, 16);
+ System.out.println(
+ "The deciphered message is:\n"
+ + decrypt(ciphertext, decryptionKey).toString(16)
+ );
+ }
+ default -> System.out.println("** End **");
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/thealgorithms/ciphers/AESEncryption.java b/src/main/java/com/thealgorithms/ciphers/AESEncryption.java
index 14582205442f..89c34b016f0c 100644
--- a/src/main/java/com/thealgorithms/ciphers/AESEncryption.java
+++ b/src/main/java/com/thealgorithms/ciphers/AESEncryption.java
@@ -1,104 +1,104 @@
-package com.thealgorithms.ciphers;
-
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.KeyGenerator;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.GCMParameterSpec;
-
-/**
- * This example program shows how AES encryption and decryption can be done in
- * Java. Please note that secret key and encrypted text is unreadable binary and
- * hence in the following program we display it in hexadecimal format of the
- * underlying bytes.
- */
-public final class AESEncryption {
- private AESEncryption() {
- }
-
- private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
- private static Cipher aesCipher;
-
- /**
- * 1. Generate a plain text for encryption 2. Get a secret key (printed in
- * hexadecimal form). In actual use this must be encrypted and kept safe.
- * The same key is required for decryption.
- */
- public static void main(String[] args) throws Exception {
- String plainText = "Hello World";
- SecretKey secKey = getSecretEncryptionKey();
- byte[] cipherText = encryptText(plainText, secKey);
- String decryptedText = decryptText(cipherText, secKey);
-
- System.out.println("Original Text:" + plainText);
- System.out.println("AES Key (Hex Form):" + bytesToHex(secKey.getEncoded()));
- System.out.println("Encrypted Text (Hex Form):" + bytesToHex(cipherText));
- System.out.println("Descrypted Text:" + decryptedText);
- }
-
- /**
- * gets the AES encryption key. In your actual programs, this should be
- * safely stored.
- *
- * @return secKey (Secret key that we encrypt using it)
- * @throws NoSuchAlgorithmException (from KeyGenrator)
- */
- public static SecretKey getSecretEncryptionKey() throws NoSuchAlgorithmException {
- KeyGenerator aesKeyGenerator = KeyGenerator.getInstance("AES");
- aesKeyGenerator.init(128); // The AES key size in number of bits
- return aesKeyGenerator.generateKey();
- }
-
- /**
- * Encrypts plainText in AES using the secret key
- *
- * @return byteCipherText (The encrypted text)
- * @throws NoSuchPaddingException (from Cipher)
- * @throws NoSuchAlgorithmException (from Cipher)
- * @throws InvalidKeyException (from Cipher)
- * @throws BadPaddingException (from Cipher)
- * @throws IllegalBlockSizeException (from Cipher)
- */
- public static byte[] encryptText(String plainText, SecretKey secKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
- // AES defaults to AES/ECB/PKCS5Padding in Java 7
- aesCipher = Cipher.getInstance("AES/GCM/NoPadding");
- aesCipher.init(Cipher.ENCRYPT_MODE, secKey);
- return aesCipher.doFinal(plainText.getBytes());
- }
-
- /**
- * Decrypts encrypted byte array using the key used for encryption.
- *
- * @return plainText
- */
- public static String decryptText(byte[] byteCipherText, SecretKey secKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException {
- // AES defaults to AES/ECB/PKCS5Padding in Java 7
- Cipher decryptionCipher = Cipher.getInstance("AES/GCM/NoPadding");
- GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, aesCipher.getIV());
- decryptionCipher.init(Cipher.DECRYPT_MODE, secKey, gcmParameterSpec);
- byte[] bytePlainText = decryptionCipher.doFinal(byteCipherText);
- return new String(bytePlainText);
- }
-
- /**
- * Convert a binary byte array into readable hex form Old library is
- * deprecated on OpenJdk 11 and this is faster regarding other solution is
- * using StringBuilder
- *
- * @return hexHash
- */
- public static String bytesToHex(byte[] bytes) {
- char[] hexChars = new char[bytes.length * 2];
- for (int j = 0; j < bytes.length; j++) {
- int v = bytes[j] & 0xFF;
- hexChars[j * 2] = HEX_ARRAY[v >>> 4];
- hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
- }
- return new String(hexChars);
- }
-}
+package com.thealgorithms.ciphers;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyGenerator;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.GCMParameterSpec;
+
+/**
+ * This example program shows how AES encryption and decryption can be done in
+ * Java. Please note that secret key and encrypted text is unreadable binary and
+ * hence in the following program we display it in hexadecimal format of the
+ * underlying bytes.
+ */
+public final class AESEncryption {
+ private AESEncryption() {
+ }
+
+ private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
+ private static Cipher aesCipher;
+
+ /**
+ * 1. Generate a plain text for encryption 2. Get a secret key (printed in
+ * hexadecimal form). In actual use this must be encrypted and kept safe.
+ * The same key is required for decryption.
+ */
+ public static void main(String[] args) throws Exception {
+ String plainText = "Hello World";
+ SecretKey secKey = getSecretEncryptionKey();
+ byte[] cipherText = encryptText(plainText, secKey);
+ String decryptedText = decryptText(cipherText, secKey);
+
+ System.out.println("Original Text:" + plainText);
+ System.out.println("AES Key (Hex Form):" + bytesToHex(secKey.getEncoded()));
+ System.out.println("Encrypted Text (Hex Form):" + bytesToHex(cipherText));
+ System.out.println("Descrypted Text:" + decryptedText);
+ }
+
+ /**
+ * gets the AES encryption key. In your actual programs, this should be
+ * safely stored.
+ *
+ * @return secKey (Secret key that we encrypt using it)
+ * @throws NoSuchAlgorithmException (from KeyGenrator)
+ */
+ public static SecretKey getSecretEncryptionKey() throws NoSuchAlgorithmException {
+ KeyGenerator aesKeyGenerator = KeyGenerator.getInstance("AES");
+ aesKeyGenerator.init(128); // The AES key size in number of bits
+ return aesKeyGenerator.generateKey();
+ }
+
+ /**
+ * Encrypts plainText in AES using the secret key
+ *
+ * @return byteCipherText (The encrypted text)
+ * @throws NoSuchPaddingException (from Cipher)
+ * @throws NoSuchAlgorithmException (from Cipher)
+ * @throws InvalidKeyException (from Cipher)
+ * @throws BadPaddingException (from Cipher)
+ * @throws IllegalBlockSizeException (from Cipher)
+ */
+ public static byte[] encryptText(String plainText, SecretKey secKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
+ // AES defaults to AES/ECB/PKCS5Padding in Java 7
+ aesCipher = Cipher.getInstance("AES/GCM/NoPadding");
+ aesCipher.init(Cipher.ENCRYPT_MODE, secKey);
+ return aesCipher.doFinal(plainText.getBytes());
+ }
+
+ /**
+ * Decrypts encrypted byte array using the key used for encryption.
+ *
+ * @return plainText
+ */
+ public static String decryptText(byte[] byteCipherText, SecretKey secKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException {
+ // AES defaults to AES/ECB/PKCS5Padding in Java 7
+ Cipher decryptionCipher = Cipher.getInstance("AES/GCM/NoPadding");
+ GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, aesCipher.getIV());
+ decryptionCipher.init(Cipher.DECRYPT_MODE, secKey, gcmParameterSpec);
+ byte[] bytePlainText = decryptionCipher.doFinal(byteCipherText);
+ return new String(bytePlainText);
+ }
+
+ /**
+ * Convert a binary byte array into readable hex form Old library is
+ * deprecated on OpenJdk 11 and this is faster regarding other solution is
+ * using StringBuilder
+ *
+ * @return hexHash
+ */
+ public static String bytesToHex(byte[] bytes) {
+ char[] hexChars = new char[bytes.length * 2];
+ for (int j = 0; j < bytes.length; j++) {
+ int v = bytes[j] & 0xFF;
+ hexChars[j * 2] = HEX_ARRAY[v >>> 4];
+ hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
+ }
+ return new String(hexChars);
+ }
+}
diff --git a/src/main/java/com/thealgorithms/ciphers/AffineCipher.java b/src/main/java/com/thealgorithms/ciphers/AffineCipher.java
index 979f18532eaa..101c95d215b3 100644
--- a/src/main/java/com/thealgorithms/ciphers/AffineCipher.java
+++ b/src/main/java/com/thealgorithms/ciphers/AffineCipher.java
@@ -1,87 +1,87 @@
-package com.thealgorithms.ciphers;
-
-/**
- * The AffineCipher class implements the Affine cipher, a type of monoalphabetic substitution cipher.
- * It encrypts and decrypts messages using a linear transformation defined by the formula:
- *
- * E(x) = (a * x + b) mod m
- * D(y) = a^-1 * (y - b) mod m
- *
- * where:
- * - E(x) is the encrypted character,
- * - D(y) is the decrypted character,
- * - a is the multiplicative key (must be coprime to m),
- * - b is the additive key,
- * - x is the index of the plaintext character,
- * - y is the index of the ciphertext character,
- * - m is the size of the alphabet (26 for the English alphabet).
- *
- * The class provides methods for encrypting and decrypting messages, as well as a main method to demonstrate its usage.
- */
-final class AffineCipher {
- private AffineCipher() {
- }
-
- // Key values of a and b
- static int a = 17;
- static int b = 20;
-
- /**
- * Encrypts a message using the Affine cipher.
- *
- * @param msg the plaintext message as a character array
- * @return the encrypted ciphertext
- */
- static String encryptMessage(char[] msg) {
- // Cipher Text initially empty
- StringBuilder cipher = new StringBuilder();
- for (int i = 0; i < msg.length; i++) {
- // Avoid space to be encrypted
- /* applying encryption formula ( a * x + b ) mod m
- {here x is msg[i] and m is 26} and added 'A' to
- bring it in the range of ASCII alphabet [65-90 | A-Z] */
- if (msg[i] != ' ') {
- cipher.append((char) ((((a * (msg[i] - 'A')) + b) % 26) + 'A'));
- } else { // else simply append space character
- cipher.append(msg[i]);
- }
- }
- return cipher.toString();
- }
-
- /**
- * Decrypts a ciphertext using the Affine cipher.
- *
- * @param cipher the ciphertext to decrypt
- * @return the decrypted plaintext message
- */
- static String decryptCipher(String cipher) {
- StringBuilder msg = new StringBuilder();
- int aInv = 0;
- int flag;
-
- // Find a^-1 (the multiplicative inverse of a in the group of integers modulo m.)
- for (int i = 0; i < 26; i++) {
- flag = (a * i) % 26;
-
- // Check if (a * i) % 26 == 1,
- // then i will be the multiplicative inverse of a
- if (flag == 1) {
- aInv = i;
- break;
- }
- }
- for (int i = 0; i < cipher.length(); i++) {
- /* Applying decryption formula a^-1 * (x - b) mod m
- {here x is cipher[i] and m is 26} and added 'A'
- to bring it in the range of ASCII alphabet [65-90 | A-Z] */
- if (cipher.charAt(i) != ' ') {
- msg.append((char) (((aInv * ((cipher.charAt(i) - 'A') - b + 26)) % 26) + 'A'));
- } else { // else simply append space character
- msg.append(cipher.charAt(i));
- }
- }
-
- return msg.toString();
- }
-}
+package com.thealgorithms.ciphers;
+
+/**
+ * The AffineCipher class implements the Affine cipher, a type of monoalphabetic substitution cipher.
+ * It encrypts and decrypts messages using a linear transformation defined by the formula:
+ *
+ * E(x) = (a * x + b) mod m
+ * D(y) = a^-1 * (y - b) mod m
+ *
+ * where:
+ * - E(x) is the encrypted character,
+ * - D(y) is the decrypted character,
+ * - a is the multiplicative key (must be coprime to m),
+ * - b is the additive key,
+ * - x is the index of the plaintext character,
+ * - y is the index of the ciphertext character,
+ * - m is the size of the alphabet (26 for the English alphabet).
+ *
+ * The class provides methods for encrypting and decrypting messages, as well as a main method to demonstrate its usage.
+ */
+final class AffineCipher {
+ private AffineCipher() {
+ }
+
+ // Key values of a and b
+ static int a = 17;
+ static int b = 20;
+
+ /**
+ * Encrypts a message using the Affine cipher.
+ *
+ * @param msg the plaintext message as a character array
+ * @return the encrypted ciphertext
+ */
+ static String encryptMessage(char[] msg) {
+ // Cipher Text initially empty
+ StringBuilder cipher = new StringBuilder();
+ for (int i = 0; i < msg.length; i++) {
+ // Avoid space to be encrypted
+ /* applying encryption formula ( a * x + b ) mod m
+ {here x is msg[i] and m is 26} and added 'A' to
+ bring it in the range of ASCII alphabet [65-90 | A-Z] */
+ if (msg[i] != ' ') {
+ cipher.append((char) ((((a * (msg[i] - 'A')) + b) % 26) + 'A'));
+ } else { // else simply append space character
+ cipher.append(msg[i]);
+ }
+ }
+ return cipher.toString();
+ }
+
+ /**
+ * Decrypts a ciphertext using the Affine cipher.
+ *
+ * @param cipher the ciphertext to decrypt
+ * @return the decrypted plaintext message
+ */
+ static String decryptCipher(String cipher) {
+ StringBuilder msg = new StringBuilder();
+ int aInv = 0;
+ int flag;
+
+ // Find a^-1 (the multiplicative inverse of a in the group of integers modulo m.)
+ for (int i = 0; i < 26; i++) {
+ flag = (a * i) % 26;
+
+ // Check if (a * i) % 26 == 1,
+ // then i will be the multiplicative inverse of a
+ if (flag == 1) {
+ aInv = i;
+ break;
+ }
+ }
+ for (int i = 0; i < cipher.length(); i++) {
+ /* Applying decryption formula a^-1 * (x - b) mod m
+ {here x is cipher[i] and m is 26} and added 'A'
+ to bring it in the range of ASCII alphabet [65-90 | A-Z] */
+ if (cipher.charAt(i) != ' ') {
+ msg.append((char) (((aInv * ((cipher.charAt(i) - 'A') - b + 26)) % 26) + 'A'));
+ } else { // else simply append space character
+ msg.append(cipher.charAt(i));
+ }
+ }
+
+ return msg.toString();
+ }
+}
diff --git a/src/main/java/com/thealgorithms/ciphers/Autokey.java b/src/main/java/com/thealgorithms/ciphers/Autokey.java
index bb67f512accf..eaaadf382a42 100644
--- a/src/main/java/com/thealgorithms/ciphers/Autokey.java
+++ b/src/main/java/com/thealgorithms/ciphers/Autokey.java
@@ -1,55 +1,55 @@
-package com.thealgorithms.ciphers;
-
-/**
- * The Autokey Cipher is an interesting and historically significant encryption method,
- * as it improves upon the classic Vigenère Cipher by using the plaintext itself to
- * extend the key. This makes it harder to break using frequency analysis, as it
- * doesn’t rely solely on a repeated key.
- * https://en.wikipedia.org/wiki/Autokey_cipher
- *
- * @author bennybebo
- */
-public class Autokey {
-
- // Encrypts the plaintext using the Autokey cipher
- public String encrypt(String plaintext, String keyword) {
- plaintext = plaintext.toUpperCase().replaceAll("[^A-Z]", ""); // Sanitize input
- keyword = keyword.toUpperCase();
-
- StringBuilder extendedKey = new StringBuilder(keyword);
- extendedKey.append(plaintext); // Extend key with plaintext
-
- StringBuilder ciphertext = new StringBuilder();
-
- for (int i = 0; i < plaintext.length(); i++) {
- char plainChar = plaintext.charAt(i);
- char keyChar = extendedKey.charAt(i);
-
- int encryptedChar = (plainChar - 'A' + keyChar - 'A') % 26 + 'A';
- ciphertext.append((char) encryptedChar);
- }
-
- return ciphertext.toString();
- }
-
- // Decrypts the ciphertext using the Autokey cipher
- public String decrypt(String ciphertext, String keyword) {
- ciphertext = ciphertext.toUpperCase().replaceAll("[^A-Z]", ""); // Sanitize input
- keyword = keyword.toUpperCase();
-
- StringBuilder plaintext = new StringBuilder();
- StringBuilder extendedKey = new StringBuilder(keyword);
-
- for (int i = 0; i < ciphertext.length(); i++) {
- char cipherChar = ciphertext.charAt(i);
- char keyChar = extendedKey.charAt(i);
-
- int decryptedChar = (cipherChar - 'A' - (keyChar - 'A') + 26) % 26 + 'A';
- plaintext.append((char) decryptedChar);
-
- extendedKey.append((char) decryptedChar); // Extend key with each decrypted char
- }
-
- return plaintext.toString();
- }
-}
+package com.thealgorithms.ciphers;
+
+/**
+ * The Autokey Cipher is an interesting and historically significant encryption method,
+ * as it improves upon the classic Vigenère Cipher by using the plaintext itself to
+ * extend the key. This makes it harder to break using frequency analysis, as it
+ * doesn’t rely solely on a repeated key.
+ * https://en.wikipedia.org/wiki/Autokey_cipher
+ *
+ * @author bennybebo
+ */
+public class Autokey {
+
+ // Encrypts the plaintext using the Autokey cipher
+ public String encrypt(String plaintext, String keyword) {
+ plaintext = plaintext.toUpperCase().replaceAll("[^A-Z]", ""); // Sanitize input
+ keyword = keyword.toUpperCase();
+
+ StringBuilder extendedKey = new StringBuilder(keyword);
+ extendedKey.append(plaintext); // Extend key with plaintext
+
+ StringBuilder ciphertext = new StringBuilder();
+
+ for (int i = 0; i < plaintext.length(); i++) {
+ char plainChar = plaintext.charAt(i);
+ char keyChar = extendedKey.charAt(i);
+
+ int encryptedChar = (plainChar - 'A' + keyChar - 'A') % 26 + 'A';
+ ciphertext.append((char) encryptedChar);
+ }
+
+ return ciphertext.toString();
+ }
+
+ // Decrypts the ciphertext using the Autokey cipher
+ public String decrypt(String ciphertext, String keyword) {
+ ciphertext = ciphertext.toUpperCase().replaceAll("[^A-Z]", ""); // Sanitize input
+ keyword = keyword.toUpperCase();
+
+ StringBuilder plaintext = new StringBuilder();
+ StringBuilder extendedKey = new StringBuilder(keyword);
+
+ for (int i = 0; i < ciphertext.length(); i++) {
+ char cipherChar = ciphertext.charAt(i);
+ char keyChar = extendedKey.charAt(i);
+
+ int decryptedChar = (cipherChar - 'A' - (keyChar - 'A') + 26) % 26 + 'A';
+ plaintext.append((char) decryptedChar);
+
+ extendedKey.append((char) decryptedChar); // Extend key with each decrypted char
+ }
+
+ return plaintext.toString();
+ }
+}
diff --git a/src/main/java/com/thealgorithms/ciphers/BaconianCipher.java b/src/main/java/com/thealgorithms/ciphers/BaconianCipher.java
index 16dfd6e674af..32116a98bcd8 100644
--- a/src/main/java/com/thealgorithms/ciphers/BaconianCipher.java
+++ b/src/main/java/com/thealgorithms/ciphers/BaconianCipher.java
@@ -1,71 +1,71 @@
-package com.thealgorithms.ciphers;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * The Baconian Cipher is a substitution cipher where each letter is represented
- * by a group of five binary digits (A's and B's). It can also be used to hide
- * messages within other texts, making it a simple form of steganography.
- * https://en.wikipedia.org/wiki/Bacon%27s_cipher
- *
- * @author Bennybebo
- */
-public class BaconianCipher {
-
- private static final Map BACONIAN_MAP = new HashMap<>();
- private static final Map REVERSE_BACONIAN_MAP = new HashMap<>();
-
- static {
- // Initialize the Baconian cipher mappings
- String[] baconianAlphabet = {"AAAAA", "AAAAB", "AAABA", "AAABB", "AABAA", "AABAB", "AABBA", "AABBB", "ABAAA", "ABAAB", "ABABA", "ABABB", "ABBAA", "ABBAB", "ABBBA", "ABBBB", "BAAAA", "BAAAB", "BAABA", "BAABB", "BABAA", "BABAB", "BABBA", "BABBB", "BBAAA", "BBAAB"};
- char letter = 'A';
- for (String code : baconianAlphabet) {
- BACONIAN_MAP.put(letter, code);
- REVERSE_BACONIAN_MAP.put(code, letter);
- letter++;
- }
-
- // Handle I/J as the same letter
- BACONIAN_MAP.put('I', BACONIAN_MAP.get('J'));
- REVERSE_BACONIAN_MAP.put(BACONIAN_MAP.get('I'), 'I');
- }
-
- /**
- * Encrypts the given plaintext using the Baconian cipher.
- *
- * @param plaintext The plaintext message to encrypt.
- * @return The ciphertext as a binary (A/B) sequence.
- */
- public String encrypt(String plaintext) {
- StringBuilder ciphertext = new StringBuilder();
- plaintext = plaintext.toUpperCase().replaceAll("[^A-Z]", ""); // Remove non-letter characters
-
- for (char letter : plaintext.toCharArray()) {
- ciphertext.append(BACONIAN_MAP.get(letter));
- }
-
- return ciphertext.toString();
- }
-
- /**
- * Decrypts the given ciphertext encoded in binary (A/B) format using the Baconian cipher.
- *
- * @param ciphertext The ciphertext to decrypt.
- * @return The decrypted plaintext message.
- */
- public String decrypt(String ciphertext) {
- StringBuilder plaintext = new StringBuilder();
-
- for (int i = 0; i < ciphertext.length(); i += 5) {
- String code = ciphertext.substring(i, i + 5);
- if (REVERSE_BACONIAN_MAP.containsKey(code)) {
- plaintext.append(REVERSE_BACONIAN_MAP.get(code));
- } else {
- throw new IllegalArgumentException("Invalid Baconian code: " + code);
- }
- }
-
- return plaintext.toString();
- }
-}
+package com.thealgorithms.ciphers;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * The Baconian Cipher is a substitution cipher where each letter is represented
+ * by a group of five binary digits (A's and B's). It can also be used to hide
+ * messages within other texts, making it a simple form of steganography.
+ * https://en.wikipedia.org/wiki/Bacon%27s_cipher
+ *
+ * @author Bennybebo
+ */
+public class BaconianCipher {
+
+ private static final Map BACONIAN_MAP = new HashMap<>();
+ private static final Map REVERSE_BACONIAN_MAP = new HashMap<>();
+
+ static {
+ // Initialize the Baconian cipher mappings
+ String[] baconianAlphabet = {"AAAAA", "AAAAB", "AAABA", "AAABB", "AABAA", "AABAB", "AABBA", "AABBB", "ABAAA", "ABAAB", "ABABA", "ABABB", "ABBAA", "ABBAB", "ABBBA", "ABBBB", "BAAAA", "BAAAB", "BAABA", "BAABB", "BABAA", "BABAB", "BABBA", "BABBB", "BBAAA", "BBAAB"};
+ char letter = 'A';
+ for (String code : baconianAlphabet) {
+ BACONIAN_MAP.put(letter, code);
+ REVERSE_BACONIAN_MAP.put(code, letter);
+ letter++;
+ }
+
+ // Handle I/J as the same letter
+ BACONIAN_MAP.put('I', BACONIAN_MAP.get('J'));
+ REVERSE_BACONIAN_MAP.put(BACONIAN_MAP.get('I'), 'I');
+ }
+
+ /**
+ * Encrypts the given plaintext using the Baconian cipher.
+ *
+ * @param plaintext The plaintext message to encrypt.
+ * @return The ciphertext as a binary (A/B) sequence.
+ */
+ public String encrypt(String plaintext) {
+ StringBuilder ciphertext = new StringBuilder();
+ plaintext = plaintext.toUpperCase().replaceAll("[^A-Z]", ""); // Remove non-letter characters
+
+ for (char letter : plaintext.toCharArray()) {
+ ciphertext.append(BACONIAN_MAP.get(letter));
+ }
+
+ return ciphertext.toString();
+ }
+
+ /**
+ * Decrypts the given ciphertext encoded in binary (A/B) format using the Baconian cipher.
+ *
+ * @param ciphertext The ciphertext to decrypt.
+ * @return The decrypted plaintext message.
+ */
+ public String decrypt(String ciphertext) {
+ StringBuilder plaintext = new StringBuilder();
+
+ for (int i = 0; i < ciphertext.length(); i += 5) {
+ String code = ciphertext.substring(i, i + 5);
+ if (REVERSE_BACONIAN_MAP.containsKey(code)) {
+ plaintext.append(REVERSE_BACONIAN_MAP.get(code));
+ } else {
+ throw new IllegalArgumentException("Invalid Baconian code: " + code);
+ }
+ }
+
+ return plaintext.toString();
+ }
+}
diff --git a/src/main/java/com/thealgorithms/ciphers/Blowfish.java b/src/main/java/com/thealgorithms/ciphers/Blowfish.java
index ea1807e62710..f1d8fcf2452a 100644
--- a/src/main/java/com/thealgorithms/ciphers/Blowfish.java
+++ b/src/main/java/com/thealgorithms/ciphers/Blowfish.java
@@ -1,1244 +1,1244 @@
-package com.thealgorithms.ciphers;
-
-/*
- * Java program for Blowfish Algorithm
- * Wikipedia: https://en.wikipedia.org/wiki/Blowfish_(cipher)
- *
- * Author: Akshay Dubey (https://github.com/itsAkshayDubey)
- *
- * */
-
-public class Blowfish {
-
- // Initializing substitution boxes
- String[][] sBox = {
- {
- "d1310ba6",
- "98dfb5ac",
- "2ffd72db",
- "d01adfb7",
- "b8e1afed",
- "6a267e96",
- "ba7c9045",
- "f12c7f99",
- "24a19947",
- "b3916cf7",
- "0801f2e2",
- "858efc16",
- "636920d8",
- "71574e69",
- "a458fea3",
- "f4933d7e",
- "0d95748f",
- "728eb658",
- "718bcd58",
- "82154aee",
- "7b54a41d",
- "c25a59b5",
- "9c30d539",
- "2af26013",
- "c5d1b023",
- "286085f0",
- "ca417918",
- "b8db38ef",
- "8e79dcb0",
- "603a180e",
- "6c9e0e8b",
- "b01e8a3e",
- "d71577c1",
- "bd314b27",
- "78af2fda",
- "55605c60",
- "e65525f3",
- "aa55ab94",
- "57489862",
- "63e81440",
- "55ca396a",
- "2aab10b6",
- "b4cc5c34",
- "1141e8ce",
- "a15486af",
- "7c72e993",
- "b3ee1411",
- "636fbc2a",
- "2ba9c55d",
- "741831f6",
- "ce5c3e16",
- "9b87931e",
- "afd6ba33",
- "6c24cf5c",
- "7a325381",
- "28958677",
- "3b8f4898",
- "6b4bb9af",
- "c4bfe81b",
- "66282193",
- "61d809cc",
- "fb21a991",
- "487cac60",
- "5dec8032",
- "ef845d5d",
- "e98575b1",
- "dc262302",
- "eb651b88",
- "23893e81",
- "d396acc5",
- "0f6d6ff3",
- "83f44239",
- "2e0b4482",
- "a4842004",
- "69c8f04a",
- "9e1f9b5e",
- "21c66842",
- "f6e96c9a",
- "670c9c61",
- "abd388f0",
- "6a51a0d2",
- "d8542f68",
- "960fa728",
- "ab5133a3",
- "6eef0b6c",
- "137a3be4",
- "ba3bf050",
- "7efb2a98",
- "a1f1651d",
- "39af0176",
- "66ca593e",
- "82430e88",
- "8cee8619",
- "456f9fb4",
- "7d84a5c3",
- "3b8b5ebe",
- "e06f75d8",
- "85c12073",
- "401a449f",
- "56c16aa6",
- "4ed3aa62",
- "363f7706",
- "1bfedf72",
- "429b023d",
- "37d0d724",
- "d00a1248",
- "db0fead3",
- "49f1c09b",
- "075372c9",
- "80991b7b",
- "25d479d8",
- "f6e8def7",
- "e3fe501a",
- "b6794c3b",
- "976ce0bd",
- "04c006ba",
- "c1a94fb6",
- "409f60c4",
- "5e5c9ec2",
- "196a2463",
- "68fb6faf",
- "3e6c53b5",
- "1339b2eb",
- "3b52ec6f",
- "6dfc511f",
- "9b30952c",
- "cc814544",
- "af5ebd09",
- "bee3d004",
- "de334afd",
- "660f2807",
- "192e4bb3",
- "c0cba857",
- "45c8740f",
- "d20b5f39",
- "b9d3fbdb",
- "5579c0bd",
- "1a60320a",
- "d6a100c6",
- "402c7279",
- "679f25fe",
- "fb1fa3cc",
- "8ea5e9f8",
- "db3222f8",
- "3c7516df",
- "fd616b15",
- "2f501ec8",
- "ad0552ab",
- "323db5fa",
- "fd238760",
- "53317b48",
- "3e00df82",
- "9e5c57bb",
- "ca6f8ca0",
- "1a87562e",
- "df1769db",
- "d542a8f6",
- "287effc3",
- "ac6732c6",
- "8c4f5573",
- "695b27b0",
- "bbca58c8",
- "e1ffa35d",
- "b8f011a0",
- "10fa3d98",
- "fd2183b8",
- "4afcb56c",
- "2dd1d35b",
- "9a53e479",
- "b6f84565",
- "d28e49bc",
- "4bfb9790",
- "e1ddf2da",
- "a4cb7e33",
- "62fb1341",
- "cee4c6e8",
- "ef20cada",
- "36774c01",
- "d07e9efe",
- "2bf11fb4",
- "95dbda4d",
- "ae909198",
- "eaad8e71",
- "6b93d5a0",
- "d08ed1d0",
- "afc725e0",
- "8e3c5b2f",
- "8e7594b7",
- "8ff6e2fb",
- "f2122b64",
- "8888b812",
- "900df01c",
- "4fad5ea0",
- "688fc31c",
- "d1cff191",
- "b3a8c1ad",
- "2f2f2218",
- "be0e1777",
- "ea752dfe",
- "8b021fa1",
- "e5a0cc0f",
- "b56f74e8",
- "18acf3d6",
- "ce89e299",
- "b4a84fe0",
- "fd13e0b7",
- "7cc43b81",
- "d2ada8d9",
- "165fa266",
- "80957705",
- "93cc7314",
- "211a1477",
- "e6ad2065",
- "77b5fa86",
- "c75442f5",
- "fb9d35cf",
- "ebcdaf0c",
- "7b3e89a0",
- "d6411bd3",
- "ae1e7e49",
- "00250e2d",
- "2071b35e",
- "226800bb",
- "57b8e0af",
- "2464369b",
- "f009b91e",
- "5563911d",
- "59dfa6aa",
- "78c14389",
- "d95a537f",
- "207d5ba2",
- "02e5b9c5",
- "83260376",
- "6295cfa9",
- "11c81968",
- "4e734a41",
- "b3472dca",
- "7b14a94a",
- "1b510052",
- "9a532915",
- "d60f573f",
- "bc9bc6e4",
- "2b60a476",
- "81e67400",
- "08ba6fb5",
- "571be91f",
- "f296ec6b",
- "2a0dd915",
- "b6636521",
- "e7b9f9b6",
- "ff34052e",
- "c5855664",
- "53b02d5d",
- "a99f8fa1",
- "08ba4799",
- "6e85076a",
- },
- {
- "4b7a70e9",
- "b5b32944",
- "db75092e",
- "c4192623",
- "ad6ea6b0",
- "49a7df7d",
- "9cee60b8",
- "8fedb266",
- "ecaa8c71",
- "699a17ff",
- "5664526c",
- "c2b19ee1",
- "193602a5",
- "75094c29",
- "a0591340",
- "e4183a3e",
- "3f54989a",
- "5b429d65",
- "6b8fe4d6",
- "99f73fd6",
- "a1d29c07",
- "efe830f5",
- "4d2d38e6",
- "f0255dc1",
- "4cdd2086",
- "8470eb26",
- "6382e9c6",
- "021ecc5e",
- "09686b3f",
- "3ebaefc9",
- "3c971814",
- "6b6a70a1",
- "687f3584",
- "52a0e286",
- "b79c5305",
- "aa500737",
- "3e07841c",
- "7fdeae5c",
- "8e7d44ec",
- "5716f2b8",
- "b03ada37",
- "f0500c0d",
- "f01c1f04",
- "0200b3ff",
- "ae0cf51a",
- "3cb574b2",
- "25837a58",
- "dc0921bd",
- "d19113f9",
- "7ca92ff6",
- "94324773",
- "22f54701",
- "3ae5e581",
- "37c2dadc",
- "c8b57634",
- "9af3dda7",
- "a9446146",
- "0fd0030e",
- "ecc8c73e",
- "a4751e41",
- "e238cd99",
- "3bea0e2f",
- "3280bba1",
- "183eb331",
- "4e548b38",
- "4f6db908",
- "6f420d03",
- "f60a04bf",
- "2cb81290",
- "24977c79",
- "5679b072",
- "bcaf89af",
- "de9a771f",
- "d9930810",
- "b38bae12",
- "dccf3f2e",
- "5512721f",
- "2e6b7124",
- "501adde6",
- "9f84cd87",
- "7a584718",
- "7408da17",
- "bc9f9abc",
- "e94b7d8c",
- "ec7aec3a",
- "db851dfa",
- "63094366",
- "c464c3d2",
- "ef1c1847",
- "3215d908",
- "dd433b37",
- "24c2ba16",
- "12a14d43",
- "2a65c451",
- "50940002",
- "133ae4dd",
- "71dff89e",
- "10314e55",
- "81ac77d6",
- "5f11199b",
- "043556f1",
- "d7a3c76b",
- "3c11183b",
- "5924a509",
- "f28fe6ed",
- "97f1fbfa",
- "9ebabf2c",
- "1e153c6e",
- "86e34570",
- "eae96fb1",
- "860e5e0a",
- "5a3e2ab3",
- "771fe71c",
- "4e3d06fa",
- "2965dcb9",
- "99e71d0f",
- "803e89d6",
- "5266c825",
- "2e4cc978",
- "9c10b36a",
- "c6150eba",
- "94e2ea78",
- "a5fc3c53",
- "1e0a2df4",
- "f2f74ea7",
- "361d2b3d",
- "1939260f",
- "19c27960",
- "5223a708",
- "f71312b6",
- "ebadfe6e",
- "eac31f66",
- "e3bc4595",
- "a67bc883",
- "b17f37d1",
- "018cff28",
- "c332ddef",
- "be6c5aa5",
- "65582185",
- "68ab9802",
- "eecea50f",
- "db2f953b",
- "2aef7dad",
- "5b6e2f84",
- "1521b628",
- "29076170",
- "ecdd4775",
- "619f1510",
- "13cca830",
- "eb61bd96",
- "0334fe1e",
- "aa0363cf",
- "b5735c90",
- "4c70a239",
- "d59e9e0b",
- "cbaade14",
- "eecc86bc",
- "60622ca7",
- "9cab5cab",
- "b2f3846e",
- "648b1eaf",
- "19bdf0ca",
- "a02369b9",
- "655abb50",
- "40685a32",
- "3c2ab4b3",
- "319ee9d5",
- "c021b8f7",
- "9b540b19",
- "875fa099",
- "95f7997e",
- "623d7da8",
- "f837889a",
- "97e32d77",
- "11ed935f",
- "16681281",
- "0e358829",
- "c7e61fd6",
- "96dedfa1",
- "7858ba99",
- "57f584a5",
- "1b227263",
- "9b83c3ff",
- "1ac24696",
- "cdb30aeb",
- "532e3054",
- "8fd948e4",
- "6dbc3128",
- "58ebf2ef",
- "34c6ffea",
- "fe28ed61",
- "ee7c3c73",
- "5d4a14d9",
- "e864b7e3",
- "42105d14",
- "203e13e0",
- "45eee2b6",
- "a3aaabea",
- "db6c4f15",
- "facb4fd0",
- "c742f442",
- "ef6abbb5",
- "654f3b1d",
- "41cd2105",
- "d81e799e",
- "86854dc7",
- "e44b476a",
- "3d816250",
- "cf62a1f2",
- "5b8d2646",
- "fc8883a0",
- "c1c7b6a3",
- "7f1524c3",
- "69cb7492",
- "47848a0b",
- "5692b285",
- "095bbf00",
- "ad19489d",
- "1462b174",
- "23820e00",
- "58428d2a",
- "0c55f5ea",
- "1dadf43e",
- "233f7061",
- "3372f092",
- "8d937e41",
- "d65fecf1",
- "6c223bdb",
- "7cde3759",
- "cbee7460",
- "4085f2a7",
- "ce77326e",
- "a6078084",
- "19f8509e",
- "e8efd855",
- "61d99735",
- "a969a7aa",
- "c50c06c2",
- "5a04abfc",
- "800bcadc",
- "9e447a2e",
- "c3453484",
- "fdd56705",
- "0e1e9ec9",
- "db73dbd3",
- "105588cd",
- "675fda79",
- "e3674340",
- "c5c43465",
- "713e38d8",
- "3d28f89e",
- "f16dff20",
- "153e21e7",
- "8fb03d4a",
- "e6e39f2b",
- "db83adf7",
- },
- {
- "e93d5a68",
- "948140f7",
- "f64c261c",
- "94692934",
- "411520f7",
- "7602d4f7",
- "bcf46b2e",
- "d4a20068",
- "d4082471",
- "3320f46a",
- "43b7d4b7",
- "500061af",
- "1e39f62e",
- "97244546",
- "14214f74",
- "bf8b8840",
- "4d95fc1d",
- "96b591af",
- "70f4ddd3",
- "66a02f45",
- "bfbc09ec",
- "03bd9785",
- "7fac6dd0",
- "31cb8504",
- "96eb27b3",
- "55fd3941",
- "da2547e6",
- "abca0a9a",
- "28507825",
- "530429f4",
- "0a2c86da",
- "e9b66dfb",
- "68dc1462",
- "d7486900",
- "680ec0a4",
- "27a18dee",
- "4f3ffea2",
- "e887ad8c",
- "b58ce006",
- "7af4d6b6",
- "aace1e7c",
- "d3375fec",
- "ce78a399",
- "406b2a42",
- "20fe9e35",
- "d9f385b9",
- "ee39d7ab",
- "3b124e8b",
- "1dc9faf7",
- "4b6d1856",
- "26a36631",
- "eae397b2",
- "3a6efa74",
- "dd5b4332",
- "6841e7f7",
- "ca7820fb",
- "fb0af54e",
- "d8feb397",
- "454056ac",
- "ba489527",
- "55533a3a",
- "20838d87",
- "fe6ba9b7",
- "d096954b",
- "55a867bc",
- "a1159a58",
- "cca92963",
- "99e1db33",
- "a62a4a56",
- "3f3125f9",
- "5ef47e1c",
- "9029317c",
- "fdf8e802",
- "04272f70",
- "80bb155c",
- "05282ce3",
- "95c11548",
- "e4c66d22",
- "48c1133f",
- "c70f86dc",
- "07f9c9ee",
- "41041f0f",
- "404779a4",
- "5d886e17",
- "325f51eb",
- "d59bc0d1",
- "f2bcc18f",
- "41113564",
- "257b7834",
- "602a9c60",
- "dff8e8a3",
- "1f636c1b",
- "0e12b4c2",
- "02e1329e",
- "af664fd1",
- "cad18115",
- "6b2395e0",
- "333e92e1",
- "3b240b62",
- "eebeb922",
- "85b2a20e",
- "e6ba0d99",
- "de720c8c",
- "2da2f728",
- "d0127845",
- "95b794fd",
- "647d0862",
- "e7ccf5f0",
- "5449a36f",
- "877d48fa",
- "c39dfd27",
- "f33e8d1e",
- "0a476341",
- "992eff74",
- "3a6f6eab",
- "f4f8fd37",
- "a812dc60",
- "a1ebddf8",
- "991be14c",
- "db6e6b0d",
- "c67b5510",
- "6d672c37",
- "2765d43b",
- "dcd0e804",
- "f1290dc7",
- "cc00ffa3",
- "b5390f92",
- "690fed0b",
- "667b9ffb",
- "cedb7d9c",
- "a091cf0b",
- "d9155ea3",
- "bb132f88",
- "515bad24",
- "7b9479bf",
- "763bd6eb",
- "37392eb3",
- "cc115979",
- "8026e297",
- "f42e312d",
- "6842ada7",
- "c66a2b3b",
- "12754ccc",
- "782ef11c",
- "6a124237",
- "b79251e7",
- "06a1bbe6",
- "4bfb6350",
- "1a6b1018",
- "11caedfa",
- "3d25bdd8",
- "e2e1c3c9",
- "44421659",
- "0a121386",
- "d90cec6e",
- "d5abea2a",
- "64af674e",
- "da86a85f",
- "bebfe988",
- "64e4c3fe",
- "9dbc8057",
- "f0f7c086",
- "60787bf8",
- "6003604d",
- "d1fd8346",
- "f6381fb0",
- "7745ae04",
- "d736fccc",
- "83426b33",
- "f01eab71",
- "b0804187",
- "3c005e5f",
- "77a057be",
- "bde8ae24",
- "55464299",
- "bf582e61",
- "4e58f48f",
- "f2ddfda2",
- "f474ef38",
- "8789bdc2",
- "5366f9c3",
- "c8b38e74",
- "b475f255",
- "46fcd9b9",
- "7aeb2661",
- "8b1ddf84",
- "846a0e79",
- "915f95e2",
- "466e598e",
- "20b45770",
- "8cd55591",
- "c902de4c",
- "b90bace1",
- "bb8205d0",
- "11a86248",
- "7574a99e",
- "b77f19b6",
- "e0a9dc09",
- "662d09a1",
- "c4324633",
- "e85a1f02",
- "09f0be8c",
- "4a99a025",
- "1d6efe10",
- "1ab93d1d",
- "0ba5a4df",
- "a186f20f",
- "2868f169",
- "dcb7da83",
- "573906fe",
- "a1e2ce9b",
- "4fcd7f52",
- "50115e01",
- "a70683fa",
- "a002b5c4",
- "0de6d027",
- "9af88c27",
- "773f8641",
- "c3604c06",
- "61a806b5",
- "f0177a28",
- "c0f586e0",
- "006058aa",
- "30dc7d62",
- "11e69ed7",
- "2338ea63",
- "53c2dd94",
- "c2c21634",
- "bbcbee56",
- "90bcb6de",
- "ebfc7da1",
- "ce591d76",
- "6f05e409",
- "4b7c0188",
- "39720a3d",
- "7c927c24",
- "86e3725f",
- "724d9db9",
- "1ac15bb4",
- "d39eb8fc",
- "ed545578",
- "08fca5b5",
- "d83d7cd3",
- "4dad0fc4",
- "1e50ef5e",
- "b161e6f8",
- "a28514d9",
- "6c51133c",
- "6fd5c7e7",
- "56e14ec4",
- "362abfce",
- "ddc6c837",
- "d79a3234",
- "92638212",
- "670efa8e",
- "406000e0",
- },
- {
- "3a39ce37",
- "d3faf5cf",
- "abc27737",
- "5ac52d1b",
- "5cb0679e",
- "4fa33742",
- "d3822740",
- "99bc9bbe",
- "d5118e9d",
- "bf0f7315",
- "d62d1c7e",
- "c700c47b",
- "b78c1b6b",
- "21a19045",
- "b26eb1be",
- "6a366eb4",
- "5748ab2f",
- "bc946e79",
- "c6a376d2",
- "6549c2c8",
- "530ff8ee",
- "468dde7d",
- "d5730a1d",
- "4cd04dc6",
- "2939bbdb",
- "a9ba4650",
- "ac9526e8",
- "be5ee304",
- "a1fad5f0",
- "6a2d519a",
- "63ef8ce2",
- "9a86ee22",
- "c089c2b8",
- "43242ef6",
- "a51e03aa",
- "9cf2d0a4",
- "83c061ba",
- "9be96a4d",
- "8fe51550",
- "ba645bd6",
- "2826a2f9",
- "a73a3ae1",
- "4ba99586",
- "ef5562e9",
- "c72fefd3",
- "f752f7da",
- "3f046f69",
- "77fa0a59",
- "80e4a915",
- "87b08601",
- "9b09e6ad",
- "3b3ee593",
- "e990fd5a",
- "9e34d797",
- "2cf0b7d9",
- "022b8b51",
- "96d5ac3a",
- "017da67d",
- "d1cf3ed6",
- "7c7d2d28",
- "1f9f25cf",
- "adf2b89b",
- "5ad6b472",
- "5a88f54c",
- "e029ac71",
- "e019a5e6",
- "47b0acfd",
- "ed93fa9b",
- "e8d3c48d",
- "283b57cc",
- "f8d56629",
- "79132e28",
- "785f0191",
- "ed756055",
- "f7960e44",
- "e3d35e8c",
- "15056dd4",
- "88f46dba",
- "03a16125",
- "0564f0bd",
- "c3eb9e15",
- "3c9057a2",
- "97271aec",
- "a93a072a",
- "1b3f6d9b",
- "1e6321f5",
- "f59c66fb",
- "26dcf319",
- "7533d928",
- "b155fdf5",
- "03563482",
- "8aba3cbb",
- "28517711",
- "c20ad9f8",
- "abcc5167",
- "ccad925f",
- "4de81751",
- "3830dc8e",
- "379d5862",
- "9320f991",
- "ea7a90c2",
- "fb3e7bce",
- "5121ce64",
- "774fbe32",
- "a8b6e37e",
- "c3293d46",
- "48de5369",
- "6413e680",
- "a2ae0810",
- "dd6db224",
- "69852dfd",
- "09072166",
- "b39a460a",
- "6445c0dd",
- "586cdecf",
- "1c20c8ae",
- "5bbef7dd",
- "1b588d40",
- "ccd2017f",
- "6bb4e3bb",
- "dda26a7e",
- "3a59ff45",
- "3e350a44",
- "bcb4cdd5",
- "72eacea8",
- "fa6484bb",
- "8d6612ae",
- "bf3c6f47",
- "d29be463",
- "542f5d9e",
- "aec2771b",
- "f64e6370",
- "740e0d8d",
- "e75b1357",
- "f8721671",
- "af537d5d",
- "4040cb08",
- "4eb4e2cc",
- "34d2466a",
- "0115af84",
- "e1b00428",
- "95983a1d",
- "06b89fb4",
- "ce6ea048",
- "6f3f3b82",
- "3520ab82",
- "011a1d4b",
- "277227f8",
- "611560b1",
- "e7933fdc",
- "bb3a792b",
- "344525bd",
- "a08839e1",
- "51ce794b",
- "2f32c9b7",
- "a01fbac9",
- "e01cc87e",
- "bcc7d1f6",
- "cf0111c3",
- "a1e8aac7",
- "1a908749",
- "d44fbd9a",
- "d0dadecb",
- "d50ada38",
- "0339c32a",
- "c6913667",
- "8df9317c",
- "e0b12b4f",
- "f79e59b7",
- "43f5bb3a",
- "f2d519ff",
- "27d9459c",
- "bf97222c",
- "15e6fc2a",
- "0f91fc71",
- "9b941525",
- "fae59361",
- "ceb69ceb",
- "c2a86459",
- "12baa8d1",
- "b6c1075e",
- "e3056a0c",
- "10d25065",
- "cb03a442",
- "e0ec6e0e",
- "1698db3b",
- "4c98a0be",
- "3278e964",
- "9f1f9532",
- "e0d392df",
- "d3a0342b",
- "8971f21e",
- "1b0a7441",
- "4ba3348c",
- "c5be7120",
- "c37632d8",
- "df359f8d",
- "9b992f2e",
- "e60b6f47",
- "0fe3f11d",
- "e54cda54",
- "1edad891",
- "ce6279cf",
- "cd3e7e6f",
- "1618b166",
- "fd2c1d05",
- "848fd2c5",
- "f6fb2299",
- "f523f357",
- "a6327623",
- "93a83531",
- "56cccd02",
- "acf08162",
- "5a75ebb5",
- "6e163697",
- "88d273cc",
- "de966292",
- "81b949d0",
- "4c50901b",
- "71c65614",
- "e6c6c7bd",
- "327a140a",
- "45e1d006",
- "c3f27b9a",
- "c9aa53fd",
- "62a80f00",
- "bb25bfe2",
- "35bdd2f6",
- "71126905",
- "b2040222",
- "b6cbcf7c",
- "cd769c2b",
- "53113ec0",
- "1640e3d3",
- "38abbd60",
- "2547adf0",
- "ba38209c",
- "f746ce76",
- "77afa1c5",
- "20756060",
- "85cbfe4e",
- "8ae88dd8",
- "7aaaf9b0",
- "4cf9aa7e",
- "1948c25c",
- "02fb8a8c",
- "01c36ae4",
- "d6ebe1f9",
- "90d4f869",
- "a65cdea0",
- "3f09252d",
- "c208e69f",
- "b74e6132",
- "ce77e25b",
- "578fdfe3",
- "3ac372e6",
- },
- };
-
- // Initializing subkeys with digits of pi
- String[] subKeys = {
- "243f6a88",
- "85a308d3",
- "13198a2e",
- "03707344",
- "a4093822",
- "299f31d0",
- "082efa98",
- "ec4e6c89",
- "452821e6",
- "38d01377",
- "be5466cf",
- "34e90c6c",
- "c0ac29b7",
- "c97c50dd",
- "3f84d5b5",
- "b5470917",
- "9216d5d9",
- "8979fb1b",
- };
-
- // Initializing modVal to 2^32
- long modVal = 4294967296L;
-
- /**
- * This method returns binary representation of the hexadecimal number passed as parameter
- *
- * @param hex Number for which binary representation is required
- * @return String object which is a binary representation of the hex number passed as parameter
- */
- private String hexToBin(String hex) {
- StringBuilder binary = new StringBuilder();
- long num;
- String binary4B;
- int n = hex.length();
- for (int i = 0; i < n; i++) {
- num = Long.parseUnsignedLong(hex.charAt(i) + "", 16);
- binary4B = Long.toBinaryString(num);
-
- binary4B = "0000" + binary4B;
-
- binary4B = binary4B.substring(binary4B.length() - 4);
- binary.append(binary4B);
- }
- return binary.toString();
- }
-
- /**
- * This method returns hexadecimal representation of the binary number passed as parameter
- *
- * @param binary Number for which hexadecimal representation is required
- * @return String object which is a hexadecimal representation of the binary number passed as
- * parameter
- */
- private String binToHex(String binary) {
- long num = Long.parseUnsignedLong(binary, 2);
- StringBuilder hex = new StringBuilder(Long.toHexString(num));
- while (hex.length() < (binary.length() / 4)) {
- hex.insert(0, "0");
- }
-
- return hex.toString();
- }
-
- /**
- * This method returns a string obtained by XOR-ing two strings of same length passed a method
- * parameters
- *
- * @param String a and b are string objects which will be XORed and are to be of same length
- * @return String object obtained by XOR operation on String a and String b
- * */
- private String xor(String a, String b) {
- a = hexToBin(a);
- b = hexToBin(b);
- StringBuilder ans = new StringBuilder();
- for (int i = 0; i < a.length(); i++) {
- ans.append((char) (((a.charAt(i) - '0') ^ (b.charAt(i) - '0')) + '0'));
- }
- ans = new StringBuilder(binToHex(ans.toString()));
- return ans.toString();
- }
-
- /**
- * This method returns addition of two hexadecimal numbers passed as parameters and moded with
- * 2^32
- *
- * @param String a and b are hexadecimal numbers
- * @return String object which is a is addition that is then moded with 2^32 of hex numbers
- * passed as parameters
- */
- private String addBin(String a, String b) {
- String ans = "";
- long n1 = Long.parseUnsignedLong(a, 16);
- long n2 = Long.parseUnsignedLong(b, 16);
- n1 = (n1 + n2) % modVal;
- ans = Long.toHexString(n1);
- ans = "00000000" + ans;
- return ans.substring(ans.length() - 8);
- }
-
- /*F-function splits the 32-bit input into four 8-bit quarters
- and uses the quarters as input to the S-boxes.
- The S-boxes accept 8-bit input and produce 32-bit output.
- The outputs are added modulo 232 and XORed to produce the final 32-bit output
- */
- private String f(String plainText) {
- String[] a = new String[4];
- String ans = "";
- for (int i = 0; i < 8; i += 2) {
- // column number for S-box is a 8-bit value
- long col = Long.parseUnsignedLong(hexToBin(plainText.substring(i, i + 2)), 2);
- a[i / 2] = sBox[i / 2][(int) col];
- }
- ans = addBin(a[0], a[1]);
- ans = xor(ans, a[2]);
- ans = addBin(ans, a[3]);
- return ans;
- }
-
- // generate subkeys
- private void keyGenerate(String key) {
- int j = 0;
- for (int i = 0; i < subKeys.length; i++) {
- // XOR-ing 32-bit parts of the key with initial subkeys
- subKeys[i] = xor(subKeys[i], key.substring(j, j + 8));
-
- j = (j + 8) % key.length();
- }
- }
-
- // round function
- private String round(int time, String plainText) {
- String left;
- String right;
- left = plainText.substring(0, 8);
- right = plainText.substring(8, 16);
- left = xor(left, subKeys[time]);
-
- // output from F function
- String fOut = f(left);
-
- right = xor(fOut, right);
-
- // swap left and right
- return right + left;
- }
-
- /**
- * This method returns cipher text for the plaintext passed as the first parameter generated
- * using the key passed as the second parameter
- *
- * @param String plainText is the text which is to be encrypted
- * @param String key is the key which is to be used for generating cipher text
- * @return String cipherText is the encrypted value
- */
- String encrypt(String plainText, String key) {
- // generating key
- keyGenerate(key);
-
- for (int i = 0; i < 16; i++) {
- plainText = round(i, plainText);
- }
-
- // postprocessing
- String right = plainText.substring(0, 8);
- String left = plainText.substring(8, 16);
- right = xor(right, subKeys[16]);
- left = xor(left, subKeys[17]);
- return left + right;
- }
-
- /**
- * This method returns plaintext for the ciphertext passed as the first parameter decoded
- * using the key passed as the second parameter
- *
- * @param String ciphertext is the text which is to be decrypted
- * @param String key is the key which is to be used for generating cipher text
- * @return String plainText is the decrypted text
- */
- String decrypt(String cipherText, String key) {
- // generating key
- keyGenerate(key);
-
- for (int i = 17; i > 1; i--) {
- cipherText = round(i, cipherText);
- }
-
- // postprocessing
- String right = cipherText.substring(0, 8);
- String left = cipherText.substring(8, 16);
- right = xor(right, subKeys[1]);
- left = xor(left, subKeys[0]);
- return left + right;
- }
-}
+package com.thealgorithms.ciphers;
+
+/*
+ * Java program for Blowfish Algorithm
+ * Wikipedia: https://en.wikipedia.org/wiki/Blowfish_(cipher)
+ *
+ * Author: Akshay Dubey (https://github.com/itsAkshayDubey)
+ *
+ * */
+
+public class Blowfish {
+
+ // Initializing substitution boxes
+ String[][] sBox = {
+ {
+ "d1310ba6",
+ "98dfb5ac",
+ "2ffd72db",
+ "d01adfb7",
+ "b8e1afed",
+ "6a267e96",
+ "ba7c9045",
+ "f12c7f99",
+ "24a19947",
+ "b3916cf7",
+ "0801f2e2",
+ "858efc16",
+ "636920d8",
+ "71574e69",
+ "a458fea3",
+ "f4933d7e",
+ "0d95748f",
+ "728eb658",
+ "718bcd58",
+ "82154aee",
+ "7b54a41d",
+ "c25a59b5",
+ "9c30d539",
+ "2af26013",
+ "c5d1b023",
+ "286085f0",
+ "ca417918",
+ "b8db38ef",
+ "8e79dcb0",
+ "603a180e",
+ "6c9e0e8b",
+ "b01e8a3e",
+ "d71577c1",
+ "bd314b27",
+ "78af2fda",
+ "55605c60",
+ "e65525f3",
+ "aa55ab94",
+ "57489862",
+ "63e81440",
+ "55ca396a",
+ "2aab10b6",
+ "b4cc5c34",
+ "1141e8ce",
+ "a15486af",
+ "7c72e993",
+ "b3ee1411",
+ "636fbc2a",
+ "2ba9c55d",
+ "741831f6",
+ "ce5c3e16",
+ "9b87931e",
+ "afd6ba33",
+ "6c24cf5c",
+ "7a325381",
+ "28958677",
+ "3b8f4898",
+ "6b4bb9af",
+ "c4bfe81b",
+ "66282193",
+ "61d809cc",
+ "fb21a991",
+ "487cac60",
+ "5dec8032",
+ "ef845d5d",
+ "e98575b1",
+ "dc262302",
+ "eb651b88",
+ "23893e81",
+ "d396acc5",
+ "0f6d6ff3",
+ "83f44239",
+ "2e0b4482",
+ "a4842004",
+ "69c8f04a",
+ "9e1f9b5e",
+ "21c66842",
+ "f6e96c9a",
+ "670c9c61",
+ "abd388f0",
+ "6a51a0d2",
+ "d8542f68",
+ "960fa728",
+ "ab5133a3",
+ "6eef0b6c",
+ "137a3be4",
+ "ba3bf050",
+ "7efb2a98",
+ "a1f1651d",
+ "39af0176",
+ "66ca593e",
+ "82430e88",
+ "8cee8619",
+ "456f9fb4",
+ "7d84a5c3",
+ "3b8b5ebe",
+ "e06f75d8",
+ "85c12073",
+ "401a449f",
+ "56c16aa6",
+ "4ed3aa62",
+ "363f7706",
+ "1bfedf72",
+ "429b023d",
+ "37d0d724",
+ "d00a1248",
+ "db0fead3",
+ "49f1c09b",
+ "075372c9",
+ "80991b7b",
+ "25d479d8",
+ "f6e8def7",
+ "e3fe501a",
+ "b6794c3b",
+ "976ce0bd",
+ "04c006ba",
+ "c1a94fb6",
+ "409f60c4",
+ "5e5c9ec2",
+ "196a2463",
+ "68fb6faf",
+ "3e6c53b5",
+ "1339b2eb",
+ "3b52ec6f",
+ "6dfc511f",
+ "9b30952c",
+ "cc814544",
+ "af5ebd09",
+ "bee3d004",
+ "de334afd",
+ "660f2807",
+ "192e4bb3",
+ "c0cba857",
+ "45c8740f",
+ "d20b5f39",
+ "b9d3fbdb",
+ "5579c0bd",
+ "1a60320a",
+ "d6a100c6",
+ "402c7279",
+ "679f25fe",
+ "fb1fa3cc",
+ "8ea5e9f8",
+ "db3222f8",
+ "3c7516df",
+ "fd616b15",
+ "2f501ec8",
+ "ad0552ab",
+ "323db5fa",
+ "fd238760",
+ "53317b48",
+ "3e00df82",
+ "9e5c57bb",
+ "ca6f8ca0",
+ "1a87562e",
+ "df1769db",
+ "d542a8f6",
+ "287effc3",
+ "ac6732c6",
+ "8c4f5573",
+ "695b27b0",
+ "bbca58c8",
+ "e1ffa35d",
+ "b8f011a0",
+ "10fa3d98",
+ "fd2183b8",
+ "4afcb56c",
+ "2dd1d35b",
+ "9a53e479",
+ "b6f84565",
+ "d28e49bc",
+ "4bfb9790",
+ "e1ddf2da",
+ "a4cb7e33",
+ "62fb1341",
+ "cee4c6e8",
+ "ef20cada",
+ "36774c01",
+ "d07e9efe",
+ "2bf11fb4",
+ "95dbda4d",
+ "ae909198",
+ "eaad8e71",
+ "6b93d5a0",
+ "d08ed1d0",
+ "afc725e0",
+ "8e3c5b2f",
+ "8e7594b7",
+ "8ff6e2fb",
+ "f2122b64",
+ "8888b812",
+ "900df01c",
+ "4fad5ea0",
+ "688fc31c",
+ "d1cff191",
+ "b3a8c1ad",
+ "2f2f2218",
+ "be0e1777",
+ "ea752dfe",
+ "8b021fa1",
+ "e5a0cc0f",
+ "b56f74e8",
+ "18acf3d6",
+ "ce89e299",
+ "b4a84fe0",
+ "fd13e0b7",
+ "7cc43b81",
+ "d2ada8d9",
+ "165fa266",
+ "80957705",
+ "93cc7314",
+ "211a1477",
+ "e6ad2065",
+ "77b5fa86",
+ "c75442f5",
+ "fb9d35cf",
+ "ebcdaf0c",
+ "7b3e89a0",
+ "d6411bd3",
+ "ae1e7e49",
+ "00250e2d",
+ "2071b35e",
+ "226800bb",
+ "57b8e0af",
+ "2464369b",
+ "f009b91e",
+ "5563911d",
+ "59dfa6aa",
+ "78c14389",
+ "d95a537f",
+ "207d5ba2",
+ "02e5b9c5",
+ "83260376",
+ "6295cfa9",
+ "11c81968",
+ "4e734a41",
+ "b3472dca",
+ "7b14a94a",
+ "1b510052",
+ "9a532915",
+ "d60f573f",
+ "bc9bc6e4",
+ "2b60a476",
+ "81e67400",
+ "08ba6fb5",
+ "571be91f",
+ "f296ec6b",
+ "2a0dd915",
+ "b6636521",
+ "e7b9f9b6",
+ "ff34052e",
+ "c5855664",
+ "53b02d5d",
+ "a99f8fa1",
+ "08ba4799",
+ "6e85076a",
+ },
+ {
+ "4b7a70e9",
+ "b5b32944",
+ "db75092e",
+ "c4192623",
+ "ad6ea6b0",
+ "49a7df7d",
+ "9cee60b8",
+ "8fedb266",
+ "ecaa8c71",
+ "699a17ff",
+ "5664526c",
+ "c2b19ee1",
+ "193602a5",
+ "75094c29",
+ "a0591340",
+ "e4183a3e",
+ "3f54989a",
+ "5b429d65",
+ "6b8fe4d6",
+ "99f73fd6",
+ "a1d29c07",
+ "efe830f5",
+ "4d2d38e6",
+ "f0255dc1",
+ "4cdd2086",
+ "8470eb26",
+ "6382e9c6",
+ "021ecc5e",
+ "09686b3f",
+ "3ebaefc9",
+ "3c971814",
+ "6b6a70a1",
+ "687f3584",
+ "52a0e286",
+ "b79c5305",
+ "aa500737",
+ "3e07841c",
+ "7fdeae5c",
+ "8e7d44ec",
+ "5716f2b8",
+ "b03ada37",
+ "f0500c0d",
+ "f01c1f04",
+ "0200b3ff",
+ "ae0cf51a",
+ "3cb574b2",
+ "25837a58",
+ "dc0921bd",
+ "d19113f9",
+ "7ca92ff6",
+ "94324773",
+ "22f54701",
+ "3ae5e581",
+ "37c2dadc",
+ "c8b57634",
+ "9af3dda7",
+ "a9446146",
+ "0fd0030e",
+ "ecc8c73e",
+ "a4751e41",
+ "e238cd99",
+ "3bea0e2f",
+ "3280bba1",
+ "183eb331",
+ "4e548b38",
+ "4f6db908",
+ "6f420d03",
+ "f60a04bf",
+ "2cb81290",
+ "24977c79",
+ "5679b072",
+ "bcaf89af",
+ "de9a771f",
+ "d9930810",
+ "b38bae12",
+ "dccf3f2e",
+ "5512721f",
+ "2e6b7124",
+ "501adde6",
+ "9f84cd87",
+ "7a584718",
+ "7408da17",
+ "bc9f9abc",
+ "e94b7d8c",
+ "ec7aec3a",
+ "db851dfa",
+ "63094366",
+ "c464c3d2",
+ "ef1c1847",
+ "3215d908",
+ "dd433b37",
+ "24c2ba16",
+ "12a14d43",
+ "2a65c451",
+ "50940002",
+ "133ae4dd",
+ "71dff89e",
+ "10314e55",
+ "81ac77d6",
+ "5f11199b",
+ "043556f1",
+ "d7a3c76b",
+ "3c11183b",
+ "5924a509",
+ "f28fe6ed",
+ "97f1fbfa",
+ "9ebabf2c",
+ "1e153c6e",
+ "86e34570",
+ "eae96fb1",
+ "860e5e0a",
+ "5a3e2ab3",
+ "771fe71c",
+ "4e3d06fa",
+ "2965dcb9",
+ "99e71d0f",
+ "803e89d6",
+ "5266c825",
+ "2e4cc978",
+ "9c10b36a",
+ "c6150eba",
+ "94e2ea78",
+ "a5fc3c53",
+ "1e0a2df4",
+ "f2f74ea7",
+ "361d2b3d",
+ "1939260f",
+ "19c27960",
+ "5223a708",
+ "f71312b6",
+ "ebadfe6e",
+ "eac31f66",
+ "e3bc4595",
+ "a67bc883",
+ "b17f37d1",
+ "018cff28",
+ "c332ddef",
+ "be6c5aa5",
+ "65582185",
+ "68ab9802",
+ "eecea50f",
+ "db2f953b",
+ "2aef7dad",
+ "5b6e2f84",
+ "1521b628",
+ "29076170",
+ "ecdd4775",
+ "619f1510",
+ "13cca830",
+ "eb61bd96",
+ "0334fe1e",
+ "aa0363cf",
+ "b5735c90",
+ "4c70a239",
+ "d59e9e0b",
+ "cbaade14",
+ "eecc86bc",
+ "60622ca7",
+ "9cab5cab",
+ "b2f3846e",
+ "648b1eaf",
+ "19bdf0ca",
+ "a02369b9",
+ "655abb50",
+ "40685a32",
+ "3c2ab4b3",
+ "319ee9d5",
+ "c021b8f7",
+ "9b540b19",
+ "875fa099",
+ "95f7997e",
+ "623d7da8",
+ "f837889a",
+ "97e32d77",
+ "11ed935f",
+ "16681281",
+ "0e358829",
+ "c7e61fd6",
+ "96dedfa1",
+ "7858ba99",
+ "57f584a5",
+ "1b227263",
+ "9b83c3ff",
+ "1ac24696",
+ "cdb30aeb",
+ "532e3054",
+ "8fd948e4",
+ "6dbc3128",
+ "58ebf2ef",
+ "34c6ffea",
+ "fe28ed61",
+ "ee7c3c73",
+ "5d4a14d9",
+ "e864b7e3",
+ "42105d14",
+ "203e13e0",
+ "45eee2b6",
+ "a3aaabea",
+ "db6c4f15",
+ "facb4fd0",
+ "c742f442",
+ "ef6abbb5",
+ "654f3b1d",
+ "41cd2105",
+ "d81e799e",
+ "86854dc7",
+ "e44b476a",
+ "3d816250",
+ "cf62a1f2",
+ "5b8d2646",
+ "fc8883a0",
+ "c1c7b6a3",
+ "7f1524c3",
+ "69cb7492",
+ "47848a0b",
+ "5692b285",
+ "095bbf00",
+ "ad19489d",
+ "1462b174",
+ "23820e00",
+ "58428d2a",
+ "0c55f5ea",
+ "1dadf43e",
+ "233f7061",
+ "3372f092",
+ "8d937e41",
+ "d65fecf1",
+ "6c223bdb",
+ "7cde3759",
+ "cbee7460",
+ "4085f2a7",
+ "ce77326e",
+ "a6078084",
+ "19f8509e",
+ "e8efd855",
+ "61d99735",
+ "a969a7aa",
+ "c50c06c2",
+ "5a04abfc",
+ "800bcadc",
+ "9e447a2e",
+ "c3453484",
+ "fdd56705",
+ "0e1e9ec9",
+ "db73dbd3",
+ "105588cd",
+ "675fda79",
+ "e3674340",
+ "c5c43465",
+ "713e38d8",
+ "3d28f89e",
+ "f16dff20",
+ "153e21e7",
+ "8fb03d4a",
+ "e6e39f2b",
+ "db83adf7",
+ },
+ {
+ "e93d5a68",
+ "948140f7",
+ "f64c261c",
+ "94692934",
+ "411520f7",
+ "7602d4f7",
+ "bcf46b2e",
+ "d4a20068",
+ "d4082471",
+ "3320f46a",
+ "43b7d4b7",
+ "500061af",
+ "1e39f62e",
+ "97244546",
+ "14214f74",
+ "bf8b8840",
+ "4d95fc1d",
+ "96b591af",
+ "70f4ddd3",
+ "66a02f45",
+ "bfbc09ec",
+ "03bd9785",
+ "7fac6dd0",
+ "31cb8504",
+ "96eb27b3",
+ "55fd3941",
+ "da2547e6",
+ "abca0a9a",
+ "28507825",
+ "530429f4",
+ "0a2c86da",
+ "e9b66dfb",
+ "68dc1462",
+ "d7486900",
+ "680ec0a4",
+ "27a18dee",
+ "4f3ffea2",
+ "e887ad8c",
+ "b58ce006",
+ "7af4d6b6",
+ "aace1e7c",
+ "d3375fec",
+ "ce78a399",
+ "406b2a42",
+ "20fe9e35",
+ "d9f385b9",
+ "ee39d7ab",
+ "3b124e8b",
+ "1dc9faf7",
+ "4b6d1856",
+ "26a36631",
+ "eae397b2",
+ "3a6efa74",
+ "dd5b4332",
+ "6841e7f7",
+ "ca7820fb",
+ "fb0af54e",
+ "d8feb397",
+ "454056ac",
+ "ba489527",
+ "55533a3a",
+ "20838d87",
+ "fe6ba9b7",
+ "d096954b",
+ "55a867bc",
+ "a1159a58",
+ "cca92963",
+ "99e1db33",
+ "a62a4a56",
+ "3f3125f9",
+ "5ef47e1c",
+ "9029317c",
+ "fdf8e802",
+ "04272f70",
+ "80bb155c",
+ "05282ce3",
+ "95c11548",
+ "e4c66d22",
+ "48c1133f",
+ "c70f86dc",
+ "07f9c9ee",
+ "41041f0f",
+ "404779a4",
+ "5d886e17",
+ "325f51eb",
+ "d59bc0d1",
+ "f2bcc18f",
+ "41113564",
+ "257b7834",
+ "602a9c60",
+ "dff8e8a3",
+ "1f636c1b",
+ "0e12b4c2",
+ "02e1329e",
+ "af664fd1",
+ "cad18115",
+ "6b2395e0",
+ "333e92e1",
+ "3b240b62",
+ "eebeb922",
+ "85b2a20e",
+ "e6ba0d99",
+ "de720c8c",
+ "2da2f728",
+ "d0127845",
+ "95b794fd",
+ "647d0862",
+ "e7ccf5f0",
+ "5449a36f",
+ "877d48fa",
+ "c39dfd27",
+ "f33e8d1e",
+ "0a476341",
+ "992eff74",
+ "3a6f6eab",
+ "f4f8fd37",
+ "a812dc60",
+ "a1ebddf8",
+ "991be14c",
+ "db6e6b0d",
+ "c67b5510",
+ "6d672c37",
+ "2765d43b",
+ "dcd0e804",
+ "f1290dc7",
+ "cc00ffa3",
+ "b5390f92",
+ "690fed0b",
+ "667b9ffb",
+ "cedb7d9c",
+ "a091cf0b",
+ "d9155ea3",
+ "bb132f88",
+ "515bad24",
+ "7b9479bf",
+ "763bd6eb",
+ "37392eb3",
+ "cc115979",
+ "8026e297",
+ "f42e312d",
+ "6842ada7",
+ "c66a2b3b",
+ "12754ccc",
+ "782ef11c",
+ "6a124237",
+ "b79251e7",
+ "06a1bbe6",
+ "4bfb6350",
+ "1a6b1018",
+ "11caedfa",
+ "3d25bdd8",
+ "e2e1c3c9",
+ "44421659",
+ "0a121386",
+ "d90cec6e",
+ "d5abea2a",
+ "64af674e",
+ "da86a85f",
+ "bebfe988",
+ "64e4c3fe",
+ "9dbc8057",
+ "f0f7c086",
+ "60787bf8",
+ "6003604d",
+ "d1fd8346",
+ "f6381fb0",
+ "7745ae04",
+ "d736fccc",
+ "83426b33",
+ "f01eab71",
+ "b0804187",
+ "3c005e5f",
+ "77a057be",
+ "bde8ae24",
+ "55464299",
+ "bf582e61",
+ "4e58f48f",
+ "f2ddfda2",
+ "f474ef38",
+ "8789bdc2",
+ "5366f9c3",
+ "c8b38e74",
+ "b475f255",
+ "46fcd9b9",
+ "7aeb2661",
+ "8b1ddf84",
+ "846a0e79",
+ "915f95e2",
+ "466e598e",
+ "20b45770",
+ "8cd55591",
+ "c902de4c",
+ "b90bace1",
+ "bb8205d0",
+ "11a86248",
+ "7574a99e",
+ "b77f19b6",
+ "e0a9dc09",
+ "662d09a1",
+ "c4324633",
+ "e85a1f02",
+ "09f0be8c",
+ "4a99a025",
+ "1d6efe10",
+ "1ab93d1d",
+ "0ba5a4df",
+ "a186f20f",
+ "2868f169",
+ "dcb7da83",
+ "573906fe",
+ "a1e2ce9b",
+ "4fcd7f52",
+ "50115e01",
+ "a70683fa",
+ "a002b5c4",
+ "0de6d027",
+ "9af88c27",
+ "773f8641",
+ "c3604c06",
+ "61a806b5",
+ "f0177a28",
+ "c0f586e0",
+ "006058aa",
+ "30dc7d62",
+ "11e69ed7",
+ "2338ea63",
+ "53c2dd94",
+ "c2c21634",
+ "bbcbee56",
+ "90bcb6de",
+ "ebfc7da1",
+ "ce591d76",
+ "6f05e409",
+ "4b7c0188",
+ "39720a3d",
+ "7c927c24",
+ "86e3725f",
+ "724d9db9",
+ "1ac15bb4",
+ "d39eb8fc",
+ "ed545578",
+ "08fca5b5",
+ "d83d7cd3",
+ "4dad0fc4",
+ "1e50ef5e",
+ "b161e6f8",
+ "a28514d9",
+ "6c51133c",
+ "6fd5c7e7",
+ "56e14ec4",
+ "362abfce",
+ "ddc6c837",
+ "d79a3234",
+ "92638212",
+ "670efa8e",
+ "406000e0",
+ },
+ {
+ "3a39ce37",
+ "d3faf5cf",
+ "abc27737",
+ "5ac52d1b",
+ "5cb0679e",
+ "4fa33742",
+ "d3822740",
+ "99bc9bbe",
+ "d5118e9d",
+ "bf0f7315",
+ "d62d1c7e",
+ "c700c47b",
+ "b78c1b6b",
+ "21a19045",
+ "b26eb1be",
+ "6a366eb4",
+ "5748ab2f",
+ "bc946e79",
+ "c6a376d2",
+ "6549c2c8",
+ "530ff8ee",
+ "468dde7d",
+ "d5730a1d",
+ "4cd04dc6",
+ "2939bbdb",
+ "a9ba4650",
+ "ac9526e8",
+ "be5ee304",
+ "a1fad5f0",
+ "6a2d519a",
+ "63ef8ce2",
+ "9a86ee22",
+ "c089c2b8",
+ "43242ef6",
+ "a51e03aa",
+ "9cf2d0a4",
+ "83c061ba",
+ "9be96a4d",
+ "8fe51550",
+ "ba645bd6",
+ "2826a2f9",
+ "a73a3ae1",
+ "4ba99586",
+ "ef5562e9",
+ "c72fefd3",
+ "f752f7da",
+ "3f046f69",
+ "77fa0a59",
+ "80e4a915",
+ "87b08601",
+ "9b09e6ad",
+ "3b3ee593",
+ "e990fd5a",
+ "9e34d797",
+ "2cf0b7d9",
+ "022b8b51",
+ "96d5ac3a",
+ "017da67d",
+ "d1cf3ed6",
+ "7c7d2d28",
+ "1f9f25cf",
+ "adf2b89b",
+ "5ad6b472",
+ "5a88f54c",
+ "e029ac71",
+ "e019a5e6",
+ "47b0acfd",
+ "ed93fa9b",
+ "e8d3c48d",
+ "283b57cc",
+ "f8d56629",
+ "79132e28",
+ "785f0191",
+ "ed756055",
+ "f7960e44",
+ "e3d35e8c",
+ "15056dd4",
+ "88f46dba",
+ "03a16125",
+ "0564f0bd",
+ "c3eb9e15",
+ "3c9057a2",
+ "97271aec",
+ "a93a072a",
+ "1b3f6d9b",
+ "1e6321f5",
+ "f59c66fb",
+ "26dcf319",
+ "7533d928",
+ "b155fdf5",
+ "03563482",
+ "8aba3cbb",
+ "28517711",
+ "c20ad9f8",
+ "abcc5167",
+ "ccad925f",
+ "4de81751",
+ "3830dc8e",
+ "379d5862",
+ "9320f991",
+ "ea7a90c2",
+ "fb3e7bce",
+ "5121ce64",
+ "774fbe32",
+ "a8b6e37e",
+ "c3293d46",
+ "48de5369",
+ "6413e680",
+ "a2ae0810",
+ "dd6db224",
+ "69852dfd",
+ "09072166",
+ "b39a460a",
+ "6445c0dd",
+ "586cdecf",
+ "1c20c8ae",
+ "5bbef7dd",
+ "1b588d40",
+ "ccd2017f",
+ "6bb4e3bb",
+ "dda26a7e",
+ "3a59ff45",
+ "3e350a44",
+ "bcb4cdd5",
+ "72eacea8",
+ "fa6484bb",
+ "8d6612ae",
+ "bf3c6f47",
+ "d29be463",
+ "542f5d9e",
+ "aec2771b",
+ "f64e6370",
+ "740e0d8d",
+ "e75b1357",
+ "f8721671",
+ "af537d5d",
+ "4040cb08",
+ "4eb4e2cc",
+ "34d2466a",
+ "0115af84",
+ "e1b00428",
+ "95983a1d",
+ "06b89fb4",
+ "ce6ea048",
+ "6f3f3b82",
+ "3520ab82",
+ "011a1d4b",
+ "277227f8",
+ "611560b1",
+ "e7933fdc",
+ "bb3a792b",
+ "344525bd",
+ "a08839e1",
+ "51ce794b",
+ "2f32c9b7",
+ "a01fbac9",
+ "e01cc87e",
+ "bcc7d1f6",
+ "cf0111c3",
+ "a1e8aac7",
+ "1a908749",
+ "d44fbd9a",
+ "d0dadecb",
+ "d50ada38",
+ "0339c32a",
+ "c6913667",
+ "8df9317c",
+ "e0b12b4f",
+ "f79e59b7",
+ "43f5bb3a",
+ "f2d519ff",
+ "27d9459c",
+ "bf97222c",
+ "15e6fc2a",
+ "0f91fc71",
+ "9b941525",
+ "fae59361",
+ "ceb69ceb",
+ "c2a86459",
+ "12baa8d1",
+ "b6c1075e",
+ "e3056a0c",
+ "10d25065",
+ "cb03a442",
+ "e0ec6e0e",
+ "1698db3b",
+ "4c98a0be",
+ "3278e964",
+ "9f1f9532",
+ "e0d392df",
+ "d3a0342b",
+ "8971f21e",
+ "1b0a7441",
+ "4ba3348c",
+ "c5be7120",
+ "c37632d8",
+ "df359f8d",
+ "9b992f2e",
+ "e60b6f47",
+ "0fe3f11d",
+ "e54cda54",
+ "1edad891",
+ "ce6279cf",
+ "cd3e7e6f",
+ "1618b166",
+ "fd2c1d05",
+ "848fd2c5",
+ "f6fb2299",
+ "f523f357",
+ "a6327623",
+ "93a83531",
+ "56cccd02",
+ "acf08162",
+ "5a75ebb5",
+ "6e163697",
+ "88d273cc",
+ "de966292",
+ "81b949d0",
+ "4c50901b",
+ "71c65614",
+ "e6c6c7bd",
+ "327a140a",
+ "45e1d006",
+ "c3f27b9a",
+ "c9aa53fd",
+ "62a80f00",
+ "bb25bfe2",
+ "35bdd2f6",
+ "71126905",
+ "b2040222",
+ "b6cbcf7c",
+ "cd769c2b",
+ "53113ec0",
+ "1640e3d3",
+ "38abbd60",
+ "2547adf0",
+ "ba38209c",
+ "f746ce76",
+ "77afa1c5",
+ "20756060",
+ "85cbfe4e",
+ "8ae88dd8",
+ "7aaaf9b0",
+ "4cf9aa7e",
+ "1948c25c",
+ "02fb8a8c",
+ "01c36ae4",
+ "d6ebe1f9",
+ "90d4f869",
+ "a65cdea0",
+ "3f09252d",
+ "c208e69f",
+ "b74e6132",
+ "ce77e25b",
+ "578fdfe3",
+ "3ac372e6",
+ },
+ };
+
+ // Initializing subkeys with digits of pi
+ String[] subKeys = {
+ "243f6a88",
+ "85a308d3",
+ "13198a2e",
+ "03707344",
+ "a4093822",
+ "299f31d0",
+ "082efa98",
+ "ec4e6c89",
+ "452821e6",
+ "38d01377",
+ "be5466cf",
+ "34e90c6c",
+ "c0ac29b7",
+ "c97c50dd",
+ "3f84d5b5",
+ "b5470917",
+ "9216d5d9",
+ "8979fb1b",
+ };
+
+ // Initializing modVal to 2^32
+ long modVal = 4294967296L;
+
+ /**
+ * This method returns binary representation of the hexadecimal number passed as parameter
+ *
+ * @param hex Number for which binary representation is required
+ * @return String object which is a binary representation of the hex number passed as parameter
+ */
+ private String hexToBin(String hex) {
+ StringBuilder binary = new StringBuilder();
+ long num;
+ String binary4B;
+ int n = hex.length();
+ for (int i = 0; i < n; i++) {
+ num = Long.parseUnsignedLong(hex.charAt(i) + "", 16);
+ binary4B = Long.toBinaryString(num);
+
+ binary4B = "0000" + binary4B;
+
+ binary4B = binary4B.substring(binary4B.length() - 4);
+ binary.append(binary4B);
+ }
+ return binary.toString();
+ }
+
+ /**
+ * This method returns hexadecimal representation of the binary number passed as parameter
+ *
+ * @param binary Number for which hexadecimal representation is required
+ * @return String object which is a hexadecimal representation of the binary number passed as
+ * parameter
+ */
+ private String binToHex(String binary) {
+ long num = Long.parseUnsignedLong(binary, 2);
+ StringBuilder hex = new StringBuilder(Long.toHexString(num));
+ while (hex.length() < (binary.length() / 4)) {
+ hex.insert(0, "0");
+ }
+
+ return hex.toString();
+ }
+
+ /**
+ * This method returns a string obtained by XOR-ing two strings of same length passed a method
+ * parameters
+ *
+ * @param String a and b are string objects which will be XORed and are to be of same length
+ * @return String object obtained by XOR operation on String a and String b
+ * */
+ private String xor(String a, String b) {
+ a = hexToBin(a);
+ b = hexToBin(b);
+ StringBuilder ans = new StringBuilder();
+ for (int i = 0; i < a.length(); i++) {
+ ans.append((char) (((a.charAt(i) - '0') ^ (b.charAt(i) - '0')) + '0'));
+ }
+ ans = new StringBuilder(binToHex(ans.toString()));
+ return ans.toString();
+ }
+
+ /**
+ * This method returns addition of two hexadecimal numbers passed as parameters and moded with
+ * 2^32
+ *
+ * @param String a and b are hexadecimal numbers
+ * @return String object which is a is addition that is then moded with 2^32 of hex numbers
+ * passed as parameters
+ */
+ private String addBin(String a, String b) {
+ String ans = "";
+ long n1 = Long.parseUnsignedLong(a, 16);
+ long n2 = Long.parseUnsignedLong(b, 16);
+ n1 = (n1 + n2) % modVal;
+ ans = Long.toHexString(n1);
+ ans = "00000000" + ans;
+ return ans.substring(ans.length() - 8);
+ }
+
+ /*F-function splits the 32-bit input into four 8-bit quarters
+ and uses the quarters as input to the S-boxes.
+ The S-boxes accept 8-bit input and produce 32-bit output.
+ The outputs are added modulo 232 and XORed to produce the final 32-bit output
+ */
+ private String f(String plainText) {
+ String[] a = new String[4];
+ String ans = "";
+ for (int i = 0; i < 8; i += 2) {
+ // column number for S-box is a 8-bit value
+ long col = Long.parseUnsignedLong(hexToBin(plainText.substring(i, i + 2)), 2);
+ a[i / 2] = sBox[i / 2][(int) col];
+ }
+ ans = addBin(a[0], a[1]);
+ ans = xor(ans, a[2]);
+ ans = addBin(ans, a[3]);
+ return ans;
+ }
+
+ // generate subkeys
+ private void keyGenerate(String key) {
+ int j = 0;
+ for (int i = 0; i < subKeys.length; i++) {
+ // XOR-ing 32-bit parts of the key with initial subkeys
+ subKeys[i] = xor(subKeys[i], key.substring(j, j + 8));
+
+ j = (j + 8) % key.length();
+ }
+ }
+
+ // round function
+ private String round(int time, String plainText) {
+ String left;
+ String right;
+ left = plainText.substring(0, 8);
+ right = plainText.substring(8, 16);
+ left = xor(left, subKeys[time]);
+
+ // output from F function
+ String fOut = f(left);
+
+ right = xor(fOut, right);
+
+ // swap left and right
+ return right + left;
+ }
+
+ /**
+ * This method returns cipher text for the plaintext passed as the first parameter generated
+ * using the key passed as the second parameter
+ *
+ * @param String plainText is the text which is to be encrypted
+ * @param String key is the key which is to be used for generating cipher text
+ * @return String cipherText is the encrypted value
+ */
+ String encrypt(String plainText, String key) {
+ // generating key
+ keyGenerate(key);
+
+ for (int i = 0; i < 16; i++) {
+ plainText = round(i, plainText);
+ }
+
+ // postprocessing
+ String right = plainText.substring(0, 8);
+ String left = plainText.substring(8, 16);
+ right = xor(right, subKeys[16]);
+ left = xor(left, subKeys[17]);
+ return left + right;
+ }
+
+ /**
+ * This method returns plaintext for the ciphertext passed as the first parameter decoded
+ * using the key passed as the second parameter
+ *
+ * @param String ciphertext is the text which is to be decrypted
+ * @param String key is the key which is to be used for generating cipher text
+ * @return String plainText is the decrypted text
+ */
+ String decrypt(String cipherText, String key) {
+ // generating key
+ keyGenerate(key);
+
+ for (int i = 17; i > 1; i--) {
+ cipherText = round(i, cipherText);
+ }
+
+ // postprocessing
+ String right = cipherText.substring(0, 8);
+ String left = cipherText.substring(8, 16);
+ right = xor(right, subKeys[1]);
+ left = xor(left, subKeys[0]);
+ return left + right;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/ciphers/Caesar.java b/src/main/java/com/thealgorithms/ciphers/Caesar.java
index 23535bc2b5d2..c8fb091eee9f 100644
--- a/src/main/java/com/thealgorithms/ciphers/Caesar.java
+++ b/src/main/java/com/thealgorithms/ciphers/Caesar.java
@@ -1,99 +1,99 @@
-package com.thealgorithms.ciphers;
-
-/**
- * A Java implementation of Caesar Cipher. /It is a type of substitution cipher
- * in which each letter in the plaintext is replaced by a letter some fixed
- * number of positions down the alphabet. /
- *
- * @author FAHRI YARDIMCI
- * @author khalil2535
- */
-public class Caesar {
- private static char normalizeShift(final int shift) {
- return (char) (shift % 26);
- }
-
- /**
- * Encrypt text by shifting every Latin char by add number shift for ASCII
- * Example : A + 1 -> B
- *
- * @return Encrypted message
- */
- public String encode(String message, int shift) {
- StringBuilder encoded = new StringBuilder();
-
- final char shiftChar = normalizeShift(shift);
-
- final int length = message.length();
- for (int i = 0; i < length; i++) {
- // int current = message.charAt(i); //using char to shift characters because
- // ascii
- // is in-order latin alphabet
- char current = message.charAt(i); // Java law : char + int = char
-
- if (isCapitalLatinLetter(current)) {
- current += shiftChar;
- encoded.append((char) (current > 'Z' ? current - 26 : current)); // 26 = number of latin letters
- } else if (isSmallLatinLetter(current)) {
- current += shiftChar;
- encoded.append((char) (current > 'z' ? current - 26 : current)); // 26 = number of latin letters
- } else {
- encoded.append(current);
- }
- }
- return encoded.toString();
- }
-
- /**
- * Decrypt message by shifting back every Latin char to previous the ASCII
- * Example : B - 1 -> A
- *
- * @return message
- */
- public String decode(String encryptedMessage, int shift) {
- StringBuilder decoded = new StringBuilder();
-
- final char shiftChar = normalizeShift(shift);
-
- final int length = encryptedMessage.length();
- for (int i = 0; i < length; i++) {
- char current = encryptedMessage.charAt(i);
- if (isCapitalLatinLetter(current)) {
- current -= shiftChar;
- decoded.append((char) (current < 'A' ? current + 26 : current)); // 26 = number of latin letters
- } else if (isSmallLatinLetter(current)) {
- current -= shiftChar;
- decoded.append((char) (current < 'a' ? current + 26 : current)); // 26 = number of latin letters
- } else {
- decoded.append(current);
- }
- }
- return decoded.toString();
- }
-
- /**
- * @return true if character is capital Latin letter or false for others
- */
- private static boolean isCapitalLatinLetter(char c) {
- return c >= 'A' && c <= 'Z';
- }
-
- /**
- * @return true if character is small Latin letter or false for others
- */
- private static boolean isSmallLatinLetter(char c) {
- return c >= 'a' && c <= 'z';
- }
-
- /**
- * @return string array which contains all the possible decoded combination.
- */
- public String[] bruteforce(String encryptedMessage) {
- String[] listOfAllTheAnswers = new String[27];
- for (int i = 0; i <= 26; i++) {
- listOfAllTheAnswers[i] = decode(encryptedMessage, i);
- }
-
- return listOfAllTheAnswers;
- }
-}
+package com.thealgorithms.ciphers;
+
+/**
+ * A Java implementation of Caesar Cipher. /It is a type of substitution cipher
+ * in which each letter in the plaintext is replaced by a letter some fixed
+ * number of positions down the alphabet. /
+ *
+ * @author FAHRI YARDIMCI
+ * @author khalil2535
+ */
+public class Caesar {
+ private static char normalizeShift(final int shift) {
+ return (char) (shift % 26);
+ }
+
+ /**
+ * Encrypt text by shifting every Latin char by add number shift for ASCII
+ * Example : A + 1 -> B
+ *
+ * @return Encrypted message
+ */
+ public String encode(String message, int shift) {
+ StringBuilder encoded = new StringBuilder();
+
+ final char shiftChar = normalizeShift(shift);
+
+ final int length = message.length();
+ for (int i = 0; i < length; i++) {
+ // int current = message.charAt(i); //using char to shift characters because
+ // ascii
+ // is in-order latin alphabet
+ char current = message.charAt(i); // Java law : char + int = char
+
+ if (isCapitalLatinLetter(current)) {
+ current += shiftChar;
+ encoded.append((char) (current > 'Z' ? current - 26 : current)); // 26 = number of latin letters
+ } else if (isSmallLatinLetter(current)) {
+ current += shiftChar;
+ encoded.append((char) (current > 'z' ? current - 26 : current)); // 26 = number of latin letters
+ } else {
+ encoded.append(current);
+ }
+ }
+ return encoded.toString();
+ }
+
+ /**
+ * Decrypt message by shifting back every Latin char to previous the ASCII
+ * Example : B - 1 -> A
+ *
+ * @return message
+ */
+ public String decode(String encryptedMessage, int shift) {
+ StringBuilder decoded = new StringBuilder();
+
+ final char shiftChar = normalizeShift(shift);
+
+ final int length = encryptedMessage.length();
+ for (int i = 0; i < length; i++) {
+ char current = encryptedMessage.charAt(i);
+ if (isCapitalLatinLetter(current)) {
+ current -= shiftChar;
+ decoded.append((char) (current < 'A' ? current + 26 : current)); // 26 = number of latin letters
+ } else if (isSmallLatinLetter(current)) {
+ current -= shiftChar;
+ decoded.append((char) (current < 'a' ? current + 26 : current)); // 26 = number of latin letters
+ } else {
+ decoded.append(current);
+ }
+ }
+ return decoded.toString();
+ }
+
+ /**
+ * @return true if character is capital Latin letter or false for others
+ */
+ private static boolean isCapitalLatinLetter(char c) {
+ return c >= 'A' && c <= 'Z';
+ }
+
+ /**
+ * @return true if character is small Latin letter or false for others
+ */
+ private static boolean isSmallLatinLetter(char c) {
+ return c >= 'a' && c <= 'z';
+ }
+
+ /**
+ * @return string array which contains all the possible decoded combination.
+ */
+ public String[] bruteforce(String encryptedMessage) {
+ String[] listOfAllTheAnswers = new String[27];
+ for (int i = 0; i <= 26; i++) {
+ listOfAllTheAnswers[i] = decode(encryptedMessage, i);
+ }
+
+ return listOfAllTheAnswers;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/ciphers/ColumnarTranspositionCipher.java b/src/main/java/com/thealgorithms/ciphers/ColumnarTranspositionCipher.java
index b6b889b079ca..300b416585ac 100644
--- a/src/main/java/com/thealgorithms/ciphers/ColumnarTranspositionCipher.java
+++ b/src/main/java/com/thealgorithms/ciphers/ColumnarTranspositionCipher.java
@@ -1,186 +1,186 @@
-package com.thealgorithms.ciphers;
-
-import java.util.Objects;
-
-/**
- * Columnar Transposition Cipher Encryption and Decryption.
- *
- * @author freitzzz
- */
-public final class ColumnarTranspositionCipher {
- private ColumnarTranspositionCipher() {
- }
-
- private static String keyword;
- private static Object[][] table;
- private static String abecedarium;
- public static final String ABECEDARIUM = "abcdefghijklmnopqrstuvwxyzABCDEFG"
- + "HIJKLMNOPQRSTUVWXYZ0123456789,.;:-@";
- private static final String ENCRYPTION_FIELD = "≈";
- private static final char ENCRYPTION_FIELD_CHAR = '≈';
-
- /**
- * Encrypts a certain String with the Columnar Transposition Cipher Rule
- *
- * @param word Word being encrypted
- * @param keyword String with keyword being used
- * @return a String with the word encrypted by the Columnar Transposition
- * Cipher Rule
- */
- public static String encrypt(final String word, final String keyword) {
- ColumnarTranspositionCipher.keyword = keyword;
- abecedariumBuilder();
- table = tableBuilder(word);
- Object[][] sortedTable = sortTable(table);
- StringBuilder wordEncrypted = new StringBuilder();
- for (int i = 0; i < sortedTable[0].length; i++) {
- for (int j = 1; j < sortedTable.length; j++) {
- wordEncrypted.append(sortedTable[j][i]);
- }
- }
- return wordEncrypted.toString();
- }
-
- /**
- * Encrypts a certain String with the Columnar Transposition Cipher Rule
- *
- * @param word Word being encrypted
- * @param keyword String with keyword being used
- * @param abecedarium String with the abecedarium being used. null for
- * default one
- * @return a String with the word encrypted by the Columnar Transposition
- * Cipher Rule
- */
- public static String encrypt(String word, String keyword, String abecedarium) {
- ColumnarTranspositionCipher.keyword = keyword;
- ColumnarTranspositionCipher.abecedarium = Objects.requireNonNullElse(abecedarium, ABECEDARIUM);
- table = tableBuilder(word);
- Object[][] sortedTable = sortTable(table);
-
- StringBuilder wordEncrypted = new StringBuilder();
- for (int i = 0; i < sortedTable[0].length; i++) {
- for (int j = 1; j < sortedTable.length; j++) {
- wordEncrypted.append(sortedTable[j][i]);
- }
- }
- return wordEncrypted.toString();
- }
-
- /**
- * Decrypts a certain encrypted String with the Columnar Transposition
- * Cipher Rule
- *
- * @return a String decrypted with the word encrypted by the Columnar
- * Transposition Cipher Rule
- */
- public static String decrypt() {
- StringBuilder wordDecrypted = new StringBuilder();
- for (int i = 1; i < table.length; i++) {
- for (Object item : table[i]) {
- wordDecrypted.append(item);
- }
- }
- return wordDecrypted.toString().replaceAll(ENCRYPTION_FIELD, "");
- }
-
- /**
- * Builds a table with the word to be encrypted in rows by the Columnar
- * Transposition Cipher Rule
- *
- * @return An Object[][] with the word to be encrypted filled in rows and
- * columns
- */
- private static Object[][] tableBuilder(String word) {
- Object[][] table = new Object[numberOfRows(word) + 1][keyword.length()];
- char[] wordInChars = word.toCharArray();
- // Fills in the respective numbers for the column
- table[0] = findElements();
- int charElement = 0;
- for (int i = 1; i < table.length; i++) {
- for (int j = 0; j < table[i].length; j++) {
- if (charElement < wordInChars.length) {
- table[i][j] = wordInChars[charElement];
- charElement++;
- } else {
- table[i][j] = ENCRYPTION_FIELD_CHAR;
- }
- }
- }
- return table;
- }
-
- /**
- * Determines the number of rows the table should have regarding the
- * Columnar Transposition Cipher Rule
- *
- * @return an int with the number of rows that the table should have in
- * order to respect the Columnar Transposition Cipher Rule.
- */
- private static int numberOfRows(String word) {
- if (word.length() % keyword.length() != 0) {
- return (word.length() / keyword.length()) + 1;
- } else {
- return word.length() / keyword.length();
- }
- }
-
- /**
- * @return charValues
- */
- private static Object[] findElements() {
- Object[] charValues = new Object[keyword.length()];
- for (int i = 0; i < charValues.length; i++) {
- int charValueIndex = abecedarium.indexOf(keyword.charAt(i));
- charValues[i] = charValueIndex > -1 ? charValueIndex : null;
- }
- return charValues;
- }
-
- /**
- * @return tableSorted
- */
- private static Object[][] sortTable(Object[][] table) {
- Object[][] tableSorted = new Object[table.length][table[0].length];
- for (int i = 0; i < tableSorted.length; i++) {
- System.arraycopy(table[i], 0, tableSorted[i], 0, tableSorted[i].length);
- }
- for (int i = 0; i < tableSorted[0].length; i++) {
- for (int j = i + 1; j < tableSorted[0].length; j++) {
- if ((int) tableSorted[0][i] > (int) table[0][j]) {
- Object[] column = getColumn(tableSorted, tableSorted.length, i);
- switchColumns(tableSorted, j, i, column);
- }
- }
- }
- return tableSorted;
- }
-
- /**
- * @return columnArray
- */
- private static Object[] getColumn(Object[][] table, int rows, int column) {
- Object[] columnArray = new Object[rows];
- for (int i = 0; i < rows; i++) {
- columnArray[i] = table[i][column];
- }
- return columnArray;
- }
-
- private static void switchColumns(Object[][] table, int firstColumnIndex, int secondColumnIndex, Object[] columnToSwitch) {
- for (int i = 0; i < table.length; i++) {
- table[i][secondColumnIndex] = table[i][firstColumnIndex];
- table[i][firstColumnIndex] = columnToSwitch[i];
- }
- }
-
- /**
- * Creates an abecedarium with all available ascii values.
- */
- private static void abecedariumBuilder() {
- StringBuilder t = new StringBuilder();
- for (int i = 0; i < 256; i++) {
- t.append((char) i);
- }
- abecedarium = t.toString();
- }
-}
+package com.thealgorithms.ciphers;
+
+import java.util.Objects;
+
+/**
+ * Columnar Transposition Cipher Encryption and Decryption.
+ *
+ * @author freitzzz
+ */
+public final class ColumnarTranspositionCipher {
+ private ColumnarTranspositionCipher() {
+ }
+
+ private static String keyword;
+ private static Object[][] table;
+ private static String abecedarium;
+ public static final String ABECEDARIUM = "abcdefghijklmnopqrstuvwxyzABCDEFG"
+ + "HIJKLMNOPQRSTUVWXYZ0123456789,.;:-@";
+ private static final String ENCRYPTION_FIELD = "≈";
+ private static final char ENCRYPTION_FIELD_CHAR = '≈';
+
+ /**
+ * Encrypts a certain String with the Columnar Transposition Cipher Rule
+ *
+ * @param word Word being encrypted
+ * @param keyword String with keyword being used
+ * @return a String with the word encrypted by the Columnar Transposition
+ * Cipher Rule
+ */
+ public static String encrypt(final String word, final String keyword) {
+ ColumnarTranspositionCipher.keyword = keyword;
+ abecedariumBuilder();
+ table = tableBuilder(word);
+ Object[][] sortedTable = sortTable(table);
+ StringBuilder wordEncrypted = new StringBuilder();
+ for (int i = 0; i < sortedTable[0].length; i++) {
+ for (int j = 1; j < sortedTable.length; j++) {
+ wordEncrypted.append(sortedTable[j][i]);
+ }
+ }
+ return wordEncrypted.toString();
+ }
+
+ /**
+ * Encrypts a certain String with the Columnar Transposition Cipher Rule
+ *
+ * @param word Word being encrypted
+ * @param keyword String with keyword being used
+ * @param abecedarium String with the abecedarium being used. null for
+ * default one
+ * @return a String with the word encrypted by the Columnar Transposition
+ * Cipher Rule
+ */
+ public static String encrypt(String word, String keyword, String abecedarium) {
+ ColumnarTranspositionCipher.keyword = keyword;
+ ColumnarTranspositionCipher.abecedarium = Objects.requireNonNullElse(abecedarium, ABECEDARIUM);
+ table = tableBuilder(word);
+ Object[][] sortedTable = sortTable(table);
+
+ StringBuilder wordEncrypted = new StringBuilder();
+ for (int i = 0; i < sortedTable[0].length; i++) {
+ for (int j = 1; j < sortedTable.length; j++) {
+ wordEncrypted.append(sortedTable[j][i]);
+ }
+ }
+ return wordEncrypted.toString();
+ }
+
+ /**
+ * Decrypts a certain encrypted String with the Columnar Transposition
+ * Cipher Rule
+ *
+ * @return a String decrypted with the word encrypted by the Columnar
+ * Transposition Cipher Rule
+ */
+ public static String decrypt() {
+ StringBuilder wordDecrypted = new StringBuilder();
+ for (int i = 1; i < table.length; i++) {
+ for (Object item : table[i]) {
+ wordDecrypted.append(item);
+ }
+ }
+ return wordDecrypted.toString().replaceAll(ENCRYPTION_FIELD, "");
+ }
+
+ /**
+ * Builds a table with the word to be encrypted in rows by the Columnar
+ * Transposition Cipher Rule
+ *
+ * @return An Object[][] with the word to be encrypted filled in rows and
+ * columns
+ */
+ private static Object[][] tableBuilder(String word) {
+ Object[][] table = new Object[numberOfRows(word) + 1][keyword.length()];
+ char[] wordInChars = word.toCharArray();
+ // Fills in the respective numbers for the column
+ table[0] = findElements();
+ int charElement = 0;
+ for (int i = 1; i < table.length; i++) {
+ for (int j = 0; j < table[i].length; j++) {
+ if (charElement < wordInChars.length) {
+ table[i][j] = wordInChars[charElement];
+ charElement++;
+ } else {
+ table[i][j] = ENCRYPTION_FIELD_CHAR;
+ }
+ }
+ }
+ return table;
+ }
+
+ /**
+ * Determines the number of rows the table should have regarding the
+ * Columnar Transposition Cipher Rule
+ *
+ * @return an int with the number of rows that the table should have in
+ * order to respect the Columnar Transposition Cipher Rule.
+ */
+ private static int numberOfRows(String word) {
+ if (word.length() % keyword.length() != 0) {
+ return (word.length() / keyword.length()) + 1;
+ } else {
+ return word.length() / keyword.length();
+ }
+ }
+
+ /**
+ * @return charValues
+ */
+ private static Object[] findElements() {
+ Object[] charValues = new Object[keyword.length()];
+ for (int i = 0; i < charValues.length; i++) {
+ int charValueIndex = abecedarium.indexOf(keyword.charAt(i));
+ charValues[i] = charValueIndex > -1 ? charValueIndex : null;
+ }
+ return charValues;
+ }
+
+ /**
+ * @return tableSorted
+ */
+ private static Object[][] sortTable(Object[][] table) {
+ Object[][] tableSorted = new Object[table.length][table[0].length];
+ for (int i = 0; i < tableSorted.length; i++) {
+ System.arraycopy(table[i], 0, tableSorted[i], 0, tableSorted[i].length);
+ }
+ for (int i = 0; i < tableSorted[0].length; i++) {
+ for (int j = i + 1; j < tableSorted[0].length; j++) {
+ if ((int) tableSorted[0][i] > (int) table[0][j]) {
+ Object[] column = getColumn(tableSorted, tableSorted.length, i);
+ switchColumns(tableSorted, j, i, column);
+ }
+ }
+ }
+ return tableSorted;
+ }
+
+ /**
+ * @return columnArray
+ */
+ private static Object[] getColumn(Object[][] table, int rows, int column) {
+ Object[] columnArray = new Object[rows];
+ for (int i = 0; i < rows; i++) {
+ columnArray[i] = table[i][column];
+ }
+ return columnArray;
+ }
+
+ private static void switchColumns(Object[][] table, int firstColumnIndex, int secondColumnIndex, Object[] columnToSwitch) {
+ for (int i = 0; i < table.length; i++) {
+ table[i][secondColumnIndex] = table[i][firstColumnIndex];
+ table[i][firstColumnIndex] = columnToSwitch[i];
+ }
+ }
+
+ /**
+ * Creates an abecedarium with all available ascii values.
+ */
+ private static void abecedariumBuilder() {
+ StringBuilder t = new StringBuilder();
+ for (int i = 0; i < 256; i++) {
+ t.append((char) i);
+ }
+ abecedarium = t.toString();
+ }
+}
diff --git a/src/main/java/com/thealgorithms/ciphers/DES.java b/src/main/java/com/thealgorithms/ciphers/DES.java
index 7f3eed70f3c2..821a9f1acfbb 100644
--- a/src/main/java/com/thealgorithms/ciphers/DES.java
+++ b/src/main/java/com/thealgorithms/ciphers/DES.java
@@ -1,250 +1,250 @@
-package com.thealgorithms.ciphers;
-
-/**
- * This class is build to demonstrate the application of the DES-algorithm
- * (https://en.wikipedia.org/wiki/Data_Encryption_Standard) on a plain English message. The supplied
- * key must be in form of a 64 bit binary String.
- */
-public class DES {
-
- private String key;
- private final String[] subKeys;
-
- private void sanitize(String key) {
- int length = key.length();
- if (length != 64) {
- throw new IllegalArgumentException("DES key must be supplied as a 64 character binary string");
- }
- }
-
- DES(String key) {
- sanitize(key);
- this.key = key;
- subKeys = getSubkeys(key);
- }
-
- public String getKey() {
- return this.key;
- }
-
- public void setKey(String key) {
- sanitize(key);
- this.key = key;
- }
-
- // Permutation table to convert initial 64-bit key to 56 bit key
- private static final int[] PC1 = {57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4};
-
- // Lookup table used to shift the initial key, in order to generate the subkeys
- private static final int[] KEY_SHIFTS = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
-
- // Table to convert the 56 bit subkeys to 48 bit subkeys
- private static final int[] PC2 = {14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32};
-
- // Initial permutation of each 64 but message block
- private static final int[] IP = {58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7};
-
- // Expansion table to convert right half of message blocks from 32 bits to 48 bits
- private static final int[] EXPANSION = {32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25, 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1};
-
- // The eight substitution boxes are defined below
- private static final int[][] S1 = {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7}, {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8}, {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0}, {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}};
-
- private static final int[][] S2 = {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10}, {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5}, {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15}, {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}};
-
- private static final int[][] S3 = {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8}, {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1}, {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7}, {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}};
-
- private static final int[][] S4 = {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15}, {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9}, {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4}, {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}};
-
- private static final int[][] S5 = {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9}, {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6}, {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14}, {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}};
-
- private static final int[][] S6 = {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11}, {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8}, {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6}, {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}};
-
- private static final int[][] S7 = {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1}, {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6}, {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2}, {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}};
-
- private static final int[][] S8 = {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7}, {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2}, {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8}, {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}};
-
- private static final int[][][] S = {S1, S2, S3, S4, S5, S6, S7, S8};
-
- // Permutation table, used in the Feistel function post s-box usage
- static final int[] PERMUTATION = {16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25};
-
- // Table used for final inversion of the message box after 16 rounds of Feistel Function
- static final int[] IP_INVERSE = {40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25};
-
- private String[] getSubkeys(String originalKey) {
- StringBuilder permutedKey = new StringBuilder(); // Initial permutation of keys via pc1
- int i;
- int j;
- for (i = 0; i < 56; i++) {
- permutedKey.append(originalKey.charAt(PC1[i] - 1));
- }
- String[] subKeys = new String[16];
- String initialPermutedKey = permutedKey.toString();
- String c0 = initialPermutedKey.substring(0, 28);
- String d0 = initialPermutedKey.substring(28);
-
- // We will now operate on the left and right halves of the permutedKey
- for (i = 0; i < 16; i++) {
- String cN = c0.substring(KEY_SHIFTS[i]) + c0.substring(0, KEY_SHIFTS[i]);
- String dN = d0.substring(KEY_SHIFTS[i]) + d0.substring(0, KEY_SHIFTS[i]);
- subKeys[i] = cN + dN;
- c0 = cN; // Re-assign the values to create running permutation
- d0 = dN;
- }
-
- // Let us shrink the keys to 48 bits (well, characters here) using pc2
- for (i = 0; i < 16; i++) {
- String key = subKeys[i];
- permutedKey.setLength(0);
- for (j = 0; j < 48; j++) {
- permutedKey.append(key.charAt(PC2[j] - 1));
- }
- subKeys[i] = permutedKey.toString();
- }
-
- return subKeys;
- }
-
- private String xOR(String a, String b) {
- int i;
- int l = a.length();
- StringBuilder xor = new StringBuilder();
- for (i = 0; i < l; i++) {
- int firstBit = a.charAt(i) - 48; // 48 is '0' in ascii
- int secondBit = b.charAt(i) - 48;
- xor.append((firstBit ^ secondBit));
- }
- return xor.toString();
- }
-
- private String createPaddedString(String s, int desiredLength, char pad) {
- int i;
- int l = s.length();
- StringBuilder paddedString = new StringBuilder();
- int diff = desiredLength - l;
- for (i = 0; i < diff; i++) {
- paddedString.append(pad);
- }
- return paddedString.toString();
- }
-
- private String pad(String s, int desiredLength) {
- return createPaddedString(s, desiredLength, '0') + s;
- }
-
- private String padLast(String s, int desiredLength) {
- return s + createPaddedString(s, desiredLength, '\u0000');
- }
-
- private String feistel(String messageBlock, String key) {
- int i;
- StringBuilder expandedKey = new StringBuilder();
- for (i = 0; i < 48; i++) {
- expandedKey.append(messageBlock.charAt(EXPANSION[i] - 1));
- }
- String mixedKey = xOR(expandedKey.toString(), key);
- StringBuilder substitutedString = new StringBuilder();
-
- // Let us now use the s-boxes to transform each 6 bit (length here) block to 4 bits
- for (i = 0; i < 48; i += 6) {
- String block = mixedKey.substring(i, i + 6);
- int row = (block.charAt(0) - 48) * 2 + (block.charAt(5) - 48);
- int col = (block.charAt(1) - 48) * 8 + (block.charAt(2) - 48) * 4 + (block.charAt(3) - 48) * 2 + (block.charAt(4) - 48);
- String substitutedBlock = pad(Integer.toBinaryString(S[i / 6][row][col]), 4);
- substitutedString.append(substitutedBlock);
- }
-
- StringBuilder permutedString = new StringBuilder();
- for (i = 0; i < 32; i++) {
- permutedString.append(substitutedString.charAt(PERMUTATION[i] - 1));
- }
-
- return permutedString.toString();
- }
-
- private String encryptBlock(String message, String[] keys) {
- StringBuilder permutedMessage = new StringBuilder();
- int i;
- for (i = 0; i < 64; i++) {
- permutedMessage.append(message.charAt(IP[i] - 1));
- }
- String e0 = permutedMessage.substring(0, 32);
- String f0 = permutedMessage.substring(32);
-
- // Iterate 16 times
- for (i = 0; i < 16; i++) {
- String eN = f0; // Previous Right block
- String fN = xOR(e0, feistel(f0, keys[i]));
- e0 = eN;
- f0 = fN;
- }
-
- String combinedBlock = f0 + e0; // Reverse the 16th block
- permutedMessage.setLength(0);
- for (i = 0; i < 64; i++) {
- permutedMessage.append(combinedBlock.charAt(IP_INVERSE[i] - 1));
- }
- return permutedMessage.toString();
- }
-
- // To decode, we follow the same process as encoding, but with reversed keys
- private String decryptBlock(String message, String[] keys) {
- String[] reversedKeys = new String[keys.length];
- for (int i = 0; i < keys.length; i++) {
- reversedKeys[i] = keys[keys.length - i - 1];
- }
- return encryptBlock(message, reversedKeys);
- }
-
- /**
- * @param message Message to be encrypted
- * @return The encrypted message, as a binary string
- */
- public String encrypt(String message) {
- StringBuilder encryptedMessage = new StringBuilder();
- int l = message.length();
- int i;
- int j;
- if (l % 8 != 0) {
- int desiredLength = (l / 8 + 1) * 8;
- l = desiredLength;
- message = padLast(message, desiredLength);
- }
-
- for (i = 0; i < l; i += 8) {
- String block = message.substring(i, i + 8);
- StringBuilder bitBlock = new StringBuilder();
- byte[] bytes = block.getBytes();
- for (j = 0; j < 8; j++) {
- bitBlock.append(pad(Integer.toBinaryString(bytes[j]), 8));
- }
- encryptedMessage.append(encryptBlock(bitBlock.toString(), subKeys));
- }
- return encryptedMessage.toString();
- }
-
- /**
- * @param message The encrypted string. Expects it to be a multiple of 64 bits, in binary format
- * @return The decrypted String, in plain English
- */
- public String decrypt(String message) {
- StringBuilder decryptedMessage = new StringBuilder();
- int l = message.length();
- int i;
- int j;
- if (l % 64 != 0) {
- throw new IllegalArgumentException("Encrypted message should be a multiple of 64 characters in length");
- }
- for (i = 0; i < l; i += 64) {
- String block = message.substring(i, i + 64);
- String result = decryptBlock(block, subKeys);
- byte[] res = new byte[8];
- for (j = 0; j < 64; j += 8) {
- res[j / 8] = (byte) Integer.parseInt(result.substring(j, j + 8), 2);
- }
- decryptedMessage.append(new String(res));
- }
- return decryptedMessage.toString().replace("\0", ""); // Get rid of the null bytes used for padding
- }
-}
+package com.thealgorithms.ciphers;
+
+/**
+ * This class is build to demonstrate the application of the DES-algorithm
+ * (https://en.wikipedia.org/wiki/Data_Encryption_Standard) on a plain English message. The supplied
+ * key must be in form of a 64 bit binary String.
+ */
+public class DES {
+
+ private String key;
+ private final String[] subKeys;
+
+ private void sanitize(String key) {
+ int length = key.length();
+ if (length != 64) {
+ throw new IllegalArgumentException("DES key must be supplied as a 64 character binary string");
+ }
+ }
+
+ DES(String key) {
+ sanitize(key);
+ this.key = key;
+ subKeys = getSubkeys(key);
+ }
+
+ public String getKey() {
+ return this.key;
+ }
+
+ public void setKey(String key) {
+ sanitize(key);
+ this.key = key;
+ }
+
+ // Permutation table to convert initial 64-bit key to 56 bit key
+ private static final int[] PC1 = {57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4};
+
+ // Lookup table used to shift the initial key, in order to generate the subkeys
+ private static final int[] KEY_SHIFTS = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
+
+ // Table to convert the 56 bit subkeys to 48 bit subkeys
+ private static final int[] PC2 = {14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32};
+
+ // Initial permutation of each 64 but message block
+ private static final int[] IP = {58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7};
+
+ // Expansion table to convert right half of message blocks from 32 bits to 48 bits
+ private static final int[] EXPANSION = {32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25, 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1};
+
+ // The eight substitution boxes are defined below
+ private static final int[][] S1 = {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7}, {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8}, {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0}, {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}};
+
+ private static final int[][] S2 = {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10}, {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5}, {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15}, {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}};
+
+ private static final int[][] S3 = {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8}, {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1}, {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7}, {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}};
+
+ private static final int[][] S4 = {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15}, {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9}, {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4}, {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}};
+
+ private static final int[][] S5 = {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9}, {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6}, {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14}, {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}};
+
+ private static final int[][] S6 = {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11}, {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8}, {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6}, {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}};
+
+ private static final int[][] S7 = {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1}, {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6}, {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2}, {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}};
+
+ private static final int[][] S8 = {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7}, {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2}, {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8}, {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}};
+
+ private static final int[][][] S = {S1, S2, S3, S4, S5, S6, S7, S8};
+
+ // Permutation table, used in the Feistel function post s-box usage
+ static final int[] PERMUTATION = {16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25};
+
+ // Table used for final inversion of the message box after 16 rounds of Feistel Function
+ static final int[] IP_INVERSE = {40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25};
+
+ private String[] getSubkeys(String originalKey) {
+ StringBuilder permutedKey = new StringBuilder(); // Initial permutation of keys via pc1
+ int i;
+ int j;
+ for (i = 0; i < 56; i++) {
+ permutedKey.append(originalKey.charAt(PC1[i] - 1));
+ }
+ String[] subKeys = new String[16];
+ String initialPermutedKey = permutedKey.toString();
+ String c0 = initialPermutedKey.substring(0, 28);
+ String d0 = initialPermutedKey.substring(28);
+
+ // We will now operate on the left and right halves of the permutedKey
+ for (i = 0; i < 16; i++) {
+ String cN = c0.substring(KEY_SHIFTS[i]) + c0.substring(0, KEY_SHIFTS[i]);
+ String dN = d0.substring(KEY_SHIFTS[i]) + d0.substring(0, KEY_SHIFTS[i]);
+ subKeys[i] = cN + dN;
+ c0 = cN; // Re-assign the values to create running permutation
+ d0 = dN;
+ }
+
+ // Let us shrink the keys to 48 bits (well, characters here) using pc2
+ for (i = 0; i < 16; i++) {
+ String key = subKeys[i];
+ permutedKey.setLength(0);
+ for (j = 0; j < 48; j++) {
+ permutedKey.append(key.charAt(PC2[j] - 1));
+ }
+ subKeys[i] = permutedKey.toString();
+ }
+
+ return subKeys;
+ }
+
+ private String xOR(String a, String b) {
+ int i;
+ int l = a.length();
+ StringBuilder xor = new StringBuilder();
+ for (i = 0; i < l; i++) {
+ int firstBit = a.charAt(i) - 48; // 48 is '0' in ascii
+ int secondBit = b.charAt(i) - 48;
+ xor.append((firstBit ^ secondBit));
+ }
+ return xor.toString();
+ }
+
+ private String createPaddedString(String s, int desiredLength, char pad) {
+ int i;
+ int l = s.length();
+ StringBuilder paddedString = new StringBuilder();
+ int diff = desiredLength - l;
+ for (i = 0; i < diff; i++) {
+ paddedString.append(pad);
+ }
+ return paddedString.toString();
+ }
+
+ private String pad(String s, int desiredLength) {
+ return createPaddedString(s, desiredLength, '0') + s;
+ }
+
+ private String padLast(String s, int desiredLength) {
+ return s + createPaddedString(s, desiredLength, '\u0000');
+ }
+
+ private String feistel(String messageBlock, String key) {
+ int i;
+ StringBuilder expandedKey = new StringBuilder();
+ for (i = 0; i < 48; i++) {
+ expandedKey.append(messageBlock.charAt(EXPANSION[i] - 1));
+ }
+ String mixedKey = xOR(expandedKey.toString(), key);
+ StringBuilder substitutedString = new StringBuilder();
+
+ // Let us now use the s-boxes to transform each 6 bit (length here) block to 4 bits
+ for (i = 0; i < 48; i += 6) {
+ String block = mixedKey.substring(i, i + 6);
+ int row = (block.charAt(0) - 48) * 2 + (block.charAt(5) - 48);
+ int col = (block.charAt(1) - 48) * 8 + (block.charAt(2) - 48) * 4 + (block.charAt(3) - 48) * 2 + (block.charAt(4) - 48);
+ String substitutedBlock = pad(Integer.toBinaryString(S[i / 6][row][col]), 4);
+ substitutedString.append(substitutedBlock);
+ }
+
+ StringBuilder permutedString = new StringBuilder();
+ for (i = 0; i < 32; i++) {
+ permutedString.append(substitutedString.charAt(PERMUTATION[i] - 1));
+ }
+
+ return permutedString.toString();
+ }
+
+ private String encryptBlock(String message, String[] keys) {
+ StringBuilder permutedMessage = new StringBuilder();
+ int i;
+ for (i = 0; i < 64; i++) {
+ permutedMessage.append(message.charAt(IP[i] - 1));
+ }
+ String e0 = permutedMessage.substring(0, 32);
+ String f0 = permutedMessage.substring(32);
+
+ // Iterate 16 times
+ for (i = 0; i < 16; i++) {
+ String eN = f0; // Previous Right block
+ String fN = xOR(e0, feistel(f0, keys[i]));
+ e0 = eN;
+ f0 = fN;
+ }
+
+ String combinedBlock = f0 + e0; // Reverse the 16th block
+ permutedMessage.setLength(0);
+ for (i = 0; i < 64; i++) {
+ permutedMessage.append(combinedBlock.charAt(IP_INVERSE[i] - 1));
+ }
+ return permutedMessage.toString();
+ }
+
+ // To decode, we follow the same process as encoding, but with reversed keys
+ private String decryptBlock(String message, String[] keys) {
+ String[] reversedKeys = new String[keys.length];
+ for (int i = 0; i < keys.length; i++) {
+ reversedKeys[i] = keys[keys.length - i - 1];
+ }
+ return encryptBlock(message, reversedKeys);
+ }
+
+ /**
+ * @param message Message to be encrypted
+ * @return The encrypted message, as a binary string
+ */
+ public String encrypt(String message) {
+ StringBuilder encryptedMessage = new StringBuilder();
+ int l = message.length();
+ int i;
+ int j;
+ if (l % 8 != 0) {
+ int desiredLength = (l / 8 + 1) * 8;
+ l = desiredLength;
+ message = padLast(message, desiredLength);
+ }
+
+ for (i = 0; i < l; i += 8) {
+ String block = message.substring(i, i + 8);
+ StringBuilder bitBlock = new StringBuilder();
+ byte[] bytes = block.getBytes();
+ for (j = 0; j < 8; j++) {
+ bitBlock.append(pad(Integer.toBinaryString(bytes[j]), 8));
+ }
+ encryptedMessage.append(encryptBlock(bitBlock.toString(), subKeys));
+ }
+ return encryptedMessage.toString();
+ }
+
+ /**
+ * @param message The encrypted string. Expects it to be a multiple of 64 bits, in binary format
+ * @return The decrypted String, in plain English
+ */
+ public String decrypt(String message) {
+ StringBuilder decryptedMessage = new StringBuilder();
+ int l = message.length();
+ int i;
+ int j;
+ if (l % 64 != 0) {
+ throw new IllegalArgumentException("Encrypted message should be a multiple of 64 characters in length");
+ }
+ for (i = 0; i < l; i += 64) {
+ String block = message.substring(i, i + 64);
+ String result = decryptBlock(block, subKeys);
+ byte[] res = new byte[8];
+ for (j = 0; j < 64; j += 8) {
+ res[j / 8] = (byte) Integer.parseInt(result.substring(j, j + 8), 2);
+ }
+ decryptedMessage.append(new String(res));
+ }
+ return decryptedMessage.toString().replace("\0", ""); // Get rid of the null bytes used for padding
+ }
+}
diff --git a/src/main/java/com/thealgorithms/ciphers/DiffieHellman.java b/src/main/java/com/thealgorithms/ciphers/DiffieHellman.java
index 7470b40e001a..e937887ccbff 100644
--- a/src/main/java/com/thealgorithms/ciphers/DiffieHellman.java
+++ b/src/main/java/com/thealgorithms/ciphers/DiffieHellman.java
@@ -1,36 +1,36 @@
-package com.thealgorithms.ciphers;
-
-import java.math.BigInteger;
-
-public final class DiffieHellman {
-
- private final BigInteger base;
- private final BigInteger secret;
- private final BigInteger prime;
-
- // Constructor to initialize base, secret, and prime
- public DiffieHellman(BigInteger base, BigInteger secret, BigInteger prime) {
- // Check for non-null and positive values
- if (base == null || secret == null || prime == null || base.signum() <= 0 || secret.signum() <= 0 || prime.signum() <= 0) {
- throw new IllegalArgumentException("Base, secret, and prime must be non-null and positive values.");
- }
- this.base = base;
- this.secret = secret;
- this.prime = prime;
- }
-
- // Method to calculate public value (g^x mod p)
- public BigInteger calculatePublicValue() {
- // Returns g^x mod p
- return base.modPow(secret, prime);
- }
-
- // Method to calculate the shared secret key (otherPublic^secret mod p)
- public BigInteger calculateSharedSecret(BigInteger otherPublicValue) {
- if (otherPublicValue == null || otherPublicValue.signum() <= 0) {
- throw new IllegalArgumentException("Other public value must be non-null and positive.");
- }
- // Returns b^x mod p or a^y mod p
- return otherPublicValue.modPow(secret, prime);
- }
-}
+package com.thealgorithms.ciphers;
+
+import java.math.BigInteger;
+
+public final class DiffieHellman {
+
+ private final BigInteger base;
+ private final BigInteger secret;
+ private final BigInteger prime;
+
+ // Constructor to initialize base, secret, and prime
+ public DiffieHellman(BigInteger base, BigInteger secret, BigInteger prime) {
+ // Check for non-null and positive values
+ if (base == null || secret == null || prime == null || base.signum() <= 0 || secret.signum() <= 0 || prime.signum() <= 0) {
+ throw new IllegalArgumentException("Base, secret, and prime must be non-null and positive values.");
+ }
+ this.base = base;
+ this.secret = secret;
+ this.prime = prime;
+ }
+
+ // Method to calculate public value (g^x mod p)
+ public BigInteger calculatePublicValue() {
+ // Returns g^x mod p
+ return base.modPow(secret, prime);
+ }
+
+ // Method to calculate the shared secret key (otherPublic^secret mod p)
+ public BigInteger calculateSharedSecret(BigInteger otherPublicValue) {
+ if (otherPublicValue == null || otherPublicValue.signum() <= 0) {
+ throw new IllegalArgumentException("Other public value must be non-null and positive.");
+ }
+ // Returns b^x mod p or a^y mod p
+ return otherPublicValue.modPow(secret, prime);
+ }
+}
diff --git a/src/main/java/com/thealgorithms/ciphers/ECC.java b/src/main/java/com/thealgorithms/ciphers/ECC.java
index 7b1e37f0e1e1..bea81c1ff80c 100644
--- a/src/main/java/com/thealgorithms/ciphers/ECC.java
+++ b/src/main/java/com/thealgorithms/ciphers/ECC.java
@@ -1,236 +1,236 @@
-package com.thealgorithms.ciphers;
-
-import java.math.BigInteger;
-import java.security.SecureRandom;
-
-/**
- * ECC - Elliptic Curve Cryptography
- * Elliptic Curve Cryptography is a public-key cryptography method that uses the algebraic structure of
- * elliptic curves over finite fields. ECC provides a higher level of security with smaller key sizes compared
- * to other public-key methods like RSA, making it particularly suitable for environments where computational
- * resources are limited, such as mobile devices and embedded systems.
- *
- * This class implements elliptic curve cryptography, providing encryption and decryption
- * functionalities based on public and private key pairs.
- *
- * @author xuyang
- */
-public class ECC {
-
- private BigInteger privateKey; // Private key used for decryption
- private ECPoint publicKey; // Public key used for encryption
- private EllipticCurve curve; // Elliptic curve used in cryptography
- private ECPoint basePoint; // Base point G on the elliptic curve
-
- public ECC(int bits) {
- generateKeys(bits); // Generates public-private key pair
- }
-
- public EllipticCurve getCurve() {
- return curve; // Returns the elliptic curve
- }
-
- public void setCurve(EllipticCurve curve) {
- this.curve = curve;
- }
-
- // Getter and Setter for private key
- public BigInteger getPrivateKey() {
- return privateKey;
- }
-
- public void setPrivateKey(BigInteger privateKey) {
- this.privateKey = privateKey;
- }
-
- /**
- * Encrypts the message using the public key.
- * The message is transformed into an ECPoint and encrypted with elliptic curve operations.
- *
- * @param message The plain message to be encrypted
- * @return The encrypted message as an array of ECPoints (R, S)
- */
- public ECPoint[] encrypt(String message) {
- BigInteger m = new BigInteger(message.getBytes()); // Convert message to BigInteger
- SecureRandom r = new SecureRandom(); // Generate random value for k
- BigInteger k = new BigInteger(curve.getFieldSize(), r); // Generate random scalar k
-
- // Calculate point r = k * G, where G is the base point
- ECPoint rPoint = basePoint.multiply(k, curve.getP(), curve.getA());
-
- // Calculate point s = k * publicKey + encodedMessage
- ECPoint sPoint = publicKey.multiply(k, curve.getP(), curve.getA()).add(curve.encodeMessage(m), curve.getP(), curve.getA());
-
- return new ECPoint[] {rPoint, sPoint}; // Return encrypted message as two ECPoints
- }
-
- /**
- * Decrypts the encrypted message using the private key.
- * The decryption process is the reverse of encryption, recovering the original message.
- *
- * @param encryptedMessage The encrypted message as an array of ECPoints (R, S)
- * @return The decrypted plain message as a String
- */
- public String decrypt(ECPoint[] encryptedMessage) {
- ECPoint rPoint = encryptedMessage[0]; // First part of ciphertext
- ECPoint sPoint = encryptedMessage[1]; // Second part of ciphertext
-
- // Perform decryption: s - r * privateKey
- ECPoint decodedMessage = sPoint.subtract(rPoint.multiply(privateKey, curve.getP(), curve.getA()), curve.getP(), curve.getA());
-
- BigInteger m = curve.decodeMessage(decodedMessage); // Decode the message from ECPoint
-
- return new String(m.toByteArray()); // Convert BigInteger back to String
- }
-
- /**
- * Generates a new public-private key pair for encryption and decryption.
- *
- * @param bits The size (in bits) of the keys to generate
- */
- public final void generateKeys(int bits) {
- SecureRandom r = new SecureRandom();
- curve = new EllipticCurve(bits); // Initialize a new elliptic curve
- basePoint = curve.getBasePoint(); // Set the base point G
-
- // Generate private key as a random BigInteger
- privateKey = new BigInteger(bits, r);
-
- // Generate public key as the point publicKey = privateKey * G
- publicKey = basePoint.multiply(privateKey, curve.getP(), curve.getA());
- }
-
- /**
- * Class representing an elliptic curve with the form y^2 = x^3 + ax + b.
- */
- public static class EllipticCurve {
- private final BigInteger a; // Coefficient a in the curve equation
- private final BigInteger b; // Coefficient b in the curve equation
- private final BigInteger p; // Prime number p, defining the finite field
- private final ECPoint basePoint; // Base point G on the curve
-
- // Constructor with explicit parameters for a, b, p, and base point
- public EllipticCurve(BigInteger a, BigInteger b, BigInteger p, ECPoint basePoint) {
- this.a = a;
- this.b = b;
- this.p = p;
- this.basePoint = basePoint;
- }
-
- // Constructor that randomly generates the curve parameters
- public EllipticCurve(int bits) {
- SecureRandom r = new SecureRandom();
- this.p = BigInteger.probablePrime(bits, r); // Random prime p
- this.a = new BigInteger(bits, r); // Random coefficient a
- this.b = new BigInteger(bits, r); // Random coefficient b
- this.basePoint = new ECPoint(BigInteger.valueOf(4), BigInteger.valueOf(8)); // Fixed base point G
- }
-
- public ECPoint getBasePoint() {
- return basePoint;
- }
-
- public BigInteger getP() {
- return p;
- }
-
- public BigInteger getA() {
- return a;
- }
-
- public BigInteger getB() {
- return b;
- }
-
- public int getFieldSize() {
- return p.bitLength();
- }
-
- public ECPoint encodeMessage(BigInteger message) {
- // Simple encoding of a message as an ECPoint (this is a simplified example)
- return new ECPoint(message, message);
- }
-
- public BigInteger decodeMessage(ECPoint point) {
- return point.getX(); // Decode the message from ECPoint (simplified)
- }
- }
-
- /**
- * Class representing a point on the elliptic curve.
- */
- public static class ECPoint {
- private final BigInteger x; // X-coordinate of the point
- private final BigInteger y; // Y-coordinate of the point
-
- public ECPoint(BigInteger x, BigInteger y) {
- this.x = x;
- this.y = y;
- }
-
- public BigInteger getX() {
- return x;
- }
-
- public BigInteger getY() {
- return y;
- }
-
- @Override
- public String toString() {
- return "ECPoint(x=" + x.toString() + ", y=" + y.toString() + ")";
- }
-
- /**
- * Add two points on the elliptic curve.
- */
- public ECPoint add(ECPoint other, BigInteger p, BigInteger a) {
- if (this.x.equals(BigInteger.ZERO) && this.y.equals(BigInteger.ZERO)) {
- return other; // If this point is the identity, return the other point
- }
- if (other.x.equals(BigInteger.ZERO) && other.y.equals(BigInteger.ZERO)) {
- return this; // If the other point is the identity, return this point
- }
-
- BigInteger lambda;
- if (this.equals(other)) {
- // Special case: point doubling
- lambda = this.x.pow(2).multiply(BigInteger.valueOf(3)).add(a).multiply(this.y.multiply(BigInteger.valueOf(2)).modInverse(p)).mod(p);
- } else {
- // General case: adding two different points
- lambda = other.y.subtract(this.y).multiply(other.x.subtract(this.x).modInverse(p)).mod(p);
- }
-
- BigInteger xr = lambda.pow(2).subtract(this.x).subtract(other.x).mod(p);
- BigInteger yr = lambda.multiply(this.x.subtract(xr)).subtract(this.y).mod(p);
-
- return new ECPoint(xr, yr);
- }
-
- /**
- * Subtract two points on the elliptic curve.
- */
- public ECPoint subtract(ECPoint other, BigInteger p, BigInteger a) {
- ECPoint negOther = new ECPoint(other.x, p.subtract(other.y)); // Negate the Y coordinate
- return this.add(negOther, p, a); // Add the negated point
- }
-
- /**
- * Multiply a point by a scalar (repeated addition).
- */
- public ECPoint multiply(BigInteger k, BigInteger p, BigInteger a) {
- ECPoint result = new ECPoint(BigInteger.ZERO, BigInteger.ZERO); // Identity point
- ECPoint addend = this;
-
- while (k.signum() > 0) {
- if (k.testBit(0)) {
- result = result.add(addend, p, a); // Add the current point
- }
- addend = addend.add(addend, p, a); // Double the point
- k = k.shiftRight(1); // Divide k by 2
- }
-
- return result;
- }
- }
-}
+package com.thealgorithms.ciphers;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+/**
+ * ECC - Elliptic Curve Cryptography
+ * Elliptic Curve Cryptography is a public-key cryptography method that uses the algebraic structure of
+ * elliptic curves over finite fields. ECC provides a higher level of security with smaller key sizes compared
+ * to other public-key methods like RSA, making it particularly suitable for environments where computational
+ * resources are limited, such as mobile devices and embedded systems.
+ *
+ * This class implements elliptic curve cryptography, providing encryption and decryption
+ * functionalities based on public and private key pairs.
+ *
+ * @author xuyang
+ */
+public class ECC {
+
+ private BigInteger privateKey; // Private key used for decryption
+ private ECPoint publicKey; // Public key used for encryption
+ private EllipticCurve curve; // Elliptic curve used in cryptography
+ private ECPoint basePoint; // Base point G on the elliptic curve
+
+ public ECC(int bits) {
+ generateKeys(bits); // Generates public-private key pair
+ }
+
+ public EllipticCurve getCurve() {
+ return curve; // Returns the elliptic curve
+ }
+
+ public void setCurve(EllipticCurve curve) {
+ this.curve = curve;
+ }
+
+ // Getter and Setter for private key
+ public BigInteger getPrivateKey() {
+ return privateKey;
+ }
+
+ public void setPrivateKey(BigInteger privateKey) {
+ this.privateKey = privateKey;
+ }
+
+ /**
+ * Encrypts the message using the public key.
+ * The message is transformed into an ECPoint and encrypted with elliptic curve operations.
+ *
+ * @param message The plain message to be encrypted
+ * @return The encrypted message as an array of ECPoints (R, S)
+ */
+ public ECPoint[] encrypt(String message) {
+ BigInteger m = new BigInteger(message.getBytes()); // Convert message to BigInteger
+ SecureRandom r = new SecureRandom(); // Generate random value for k
+ BigInteger k = new BigInteger(curve.getFieldSize(), r); // Generate random scalar k
+
+ // Calculate point r = k * G, where G is the base point
+ ECPoint rPoint = basePoint.multiply(k, curve.getP(), curve.getA());
+
+ // Calculate point s = k * publicKey + encodedMessage
+ ECPoint sPoint = publicKey.multiply(k, curve.getP(), curve.getA()).add(curve.encodeMessage(m), curve.getP(), curve.getA());
+
+ return new ECPoint[] {rPoint, sPoint}; // Return encrypted message as two ECPoints
+ }
+
+ /**
+ * Decrypts the encrypted message using the private key.
+ * The decryption process is the reverse of encryption, recovering the original message.
+ *
+ * @param encryptedMessage The encrypted message as an array of ECPoints (R, S)
+ * @return The decrypted plain message as a String
+ */
+ public String decrypt(ECPoint[] encryptedMessage) {
+ ECPoint rPoint = encryptedMessage[0]; // First part of ciphertext
+ ECPoint sPoint = encryptedMessage[1]; // Second part of ciphertext
+
+ // Perform decryption: s - r * privateKey
+ ECPoint decodedMessage = sPoint.subtract(rPoint.multiply(privateKey, curve.getP(), curve.getA()), curve.getP(), curve.getA());
+
+ BigInteger m = curve.decodeMessage(decodedMessage); // Decode the message from ECPoint
+
+ return new String(m.toByteArray()); // Convert BigInteger back to String
+ }
+
+ /**
+ * Generates a new public-private key pair for encryption and decryption.
+ *
+ * @param bits The size (in bits) of the keys to generate
+ */
+ public final void generateKeys(int bits) {
+ SecureRandom r = new SecureRandom();
+ curve = new EllipticCurve(bits); // Initialize a new elliptic curve
+ basePoint = curve.getBasePoint(); // Set the base point G
+
+ // Generate private key as a random BigInteger
+ privateKey = new BigInteger(bits, r);
+
+ // Generate public key as the point publicKey = privateKey * G
+ publicKey = basePoint.multiply(privateKey, curve.getP(), curve.getA());
+ }
+
+ /**
+ * Class representing an elliptic curve with the form y^2 = x^3 + ax + b.
+ */
+ public static class EllipticCurve {
+ private final BigInteger a; // Coefficient a in the curve equation
+ private final BigInteger b; // Coefficient b in the curve equation
+ private final BigInteger p; // Prime number p, defining the finite field
+ private final ECPoint basePoint; // Base point G on the curve
+
+ // Constructor with explicit parameters for a, b, p, and base point
+ public EllipticCurve(BigInteger a, BigInteger b, BigInteger p, ECPoint basePoint) {
+ this.a = a;
+ this.b = b;
+ this.p = p;
+ this.basePoint = basePoint;
+ }
+
+ // Constructor that randomly generates the curve parameters
+ public EllipticCurve(int bits) {
+ SecureRandom r = new SecureRandom();
+ this.p = BigInteger.probablePrime(bits, r); // Random prime p
+ this.a = new BigInteger(bits, r); // Random coefficient a
+ this.b = new BigInteger(bits, r); // Random coefficient b
+ this.basePoint = new ECPoint(BigInteger.valueOf(4), BigInteger.valueOf(8)); // Fixed base point G
+ }
+
+ public ECPoint getBasePoint() {
+ return basePoint;
+ }
+
+ public BigInteger getP() {
+ return p;
+ }
+
+ public BigInteger getA() {
+ return a;
+ }
+
+ public BigInteger getB() {
+ return b;
+ }
+
+ public int getFieldSize() {
+ return p.bitLength();
+ }
+
+ public ECPoint encodeMessage(BigInteger message) {
+ // Simple encoding of a message as an ECPoint (this is a simplified example)
+ return new ECPoint(message, message);
+ }
+
+ public BigInteger decodeMessage(ECPoint point) {
+ return point.getX(); // Decode the message from ECPoint (simplified)
+ }
+ }
+
+ /**
+ * Class representing a point on the elliptic curve.
+ */
+ public static class ECPoint {
+ private final BigInteger x; // X-coordinate of the point
+ private final BigInteger y; // Y-coordinate of the point
+
+ public ECPoint(BigInteger x, BigInteger y) {
+ this.x = x;
+ this.y = y;
+ }
+
+ public BigInteger getX() {
+ return x;
+ }
+
+ public BigInteger getY() {
+ return y;
+ }
+
+ @Override
+ public String toString() {
+ return "ECPoint(x=" + x.toString() + ", y=" + y.toString() + ")";
+ }
+
+ /**
+ * Add two points on the elliptic curve.
+ */
+ public ECPoint add(ECPoint other, BigInteger p, BigInteger a) {
+ if (this.x.equals(BigInteger.ZERO) && this.y.equals(BigInteger.ZERO)) {
+ return other; // If this point is the identity, return the other point
+ }
+ if (other.x.equals(BigInteger.ZERO) && other.y.equals(BigInteger.ZERO)) {
+ return this; // If the other point is the identity, return this point
+ }
+
+ BigInteger lambda;
+ if (this.equals(other)) {
+ // Special case: point doubling
+ lambda = this.x.pow(2).multiply(BigInteger.valueOf(3)).add(a).multiply(this.y.multiply(BigInteger.valueOf(2)).modInverse(p)).mod(p);
+ } else {
+ // General case: adding two different points
+ lambda = other.y.subtract(this.y).multiply(other.x.subtract(this.x).modInverse(p)).mod(p);
+ }
+
+ BigInteger xr = lambda.pow(2).subtract(this.x).subtract(other.x).mod(p);
+ BigInteger yr = lambda.multiply(this.x.subtract(xr)).subtract(this.y).mod(p);
+
+ return new ECPoint(xr, yr);
+ }
+
+ /**
+ * Subtract two points on the elliptic curve.
+ */
+ public ECPoint subtract(ECPoint other, BigInteger p, BigInteger a) {
+ ECPoint negOther = new ECPoint(other.x, p.subtract(other.y)); // Negate the Y coordinate
+ return this.add(negOther, p, a); // Add the negated point
+ }
+
+ /**
+ * Multiply a point by a scalar (repeated addition).
+ */
+ public ECPoint multiply(BigInteger k, BigInteger p, BigInteger a) {
+ ECPoint result = new ECPoint(BigInteger.ZERO, BigInteger.ZERO); // Identity point
+ ECPoint addend = this;
+
+ while (k.signum() > 0) {
+ if (k.testBit(0)) {
+ result = result.add(addend, p, a); // Add the current point
+ }
+ addend = addend.add(addend, p, a); // Double the point
+ k = k.shiftRight(1); // Divide k by 2
+ }
+
+ return result;
+ }
+ }
+}
diff --git a/src/main/java/com/thealgorithms/ciphers/ElGamalCipher.java b/src/main/java/com/thealgorithms/ciphers/ElGamalCipher.java
index 6383caa59b1f..fde0540b60b1 100644
--- a/src/main/java/com/thealgorithms/ciphers/ElGamalCipher.java
+++ b/src/main/java/com/thealgorithms/ciphers/ElGamalCipher.java
@@ -1,174 +1,174 @@
-package com.thealgorithms.ciphers;
-
-import java.math.BigInteger;
-import java.security.SecureRandom;
-
-/**
- * ElGamal Encryption Algorithm Implementation.
- *
- *
- * ElGamal is an asymmetric key encryption algorithm for public-key cryptography
- * based on the Diffie–Hellman key exchange. It relies on the difficulty
- * of computing discrete logarithms in a cyclic group.
- *
- *
- *
- * Key Features:
- *
- * - Uses Safe Primes (p = 2q + 1) to ensure group security.
- * - Verifies the generator is a primitive root modulo p.
- * - Stateless design using Java Records.
- * - SecureRandom for all cryptographic operations.
- *
- *
- *
- * @author Chahat Sandhu, singhc7
- * @see ElGamal Encryption (Wikipedia)
- * @see Safe Primes
- */
-public final class ElGamalCipher {
-
- private static final SecureRandom RANDOM = new SecureRandom();
- private static final int PRIME_CERTAINTY = 40;
- private static final int MIN_BIT_LENGTH = 256;
-
- private ElGamalCipher() {
- }
-
- /**
- * A container for the Public and Private keys.
- *
- * @param p The prime modulus.
- * @param g The generator (primitive root).
- * @param y The public key component (g^x mod p).
- * @param x The private key.
- */
- public record KeyPair(BigInteger p, BigInteger g, BigInteger y, BigInteger x) {
- }
-
- /**
- * Container for the encryption result.
- *
- * @param a The first component (g^k mod p).
- * @param b The second component (y^k * m mod p).
- */
- public record CipherText(BigInteger a, BigInteger b) {
- }
-
- /**
- * Generates a valid ElGamal KeyPair using a Safe Prime.
- *
- * @param bitLength The bit length of the prime modulus p. Must be at least 256.
- * @return A valid KeyPair (p, g, y, x).
- * @throws IllegalArgumentException if bitLength is too small.
- */
- public static KeyPair generateKeys(int bitLength) {
- if (bitLength < MIN_BIT_LENGTH) {
- throw new IllegalArgumentException("Bit length must be at least " + MIN_BIT_LENGTH + " for security.");
- }
-
- BigInteger p;
- BigInteger q;
- BigInteger g;
- BigInteger x;
- BigInteger y;
-
- // Generate Safe Prime p = 2q + 1
- do {
- q = new BigInteger(bitLength - 1, PRIME_CERTAINTY, RANDOM);
- p = q.multiply(BigInteger.TWO).add(BigInteger.ONE);
- } while (!p.isProbablePrime(PRIME_CERTAINTY));
-
- // Find a Generator g (Primitive Root modulo p)
- do {
- g = new BigInteger(bitLength, RANDOM).mod(p.subtract(BigInteger.TWO)).add(BigInteger.TWO);
- } while (!isValidGenerator(g, p, q));
-
- // Generate Private Key x in range [2, p-2]
- do {
- x = new BigInteger(bitLength, RANDOM);
- } while (x.compareTo(BigInteger.TWO) < 0 || x.compareTo(p.subtract(BigInteger.TWO)) > 0);
-
- // Compute Public Key y = g^x mod p
- y = g.modPow(x, p);
-
- return new KeyPair(p, g, y, x);
- }
-
- /**
- * Encrypts a message using the public key.
- *
- * @param message The message converted to BigInteger.
- * @param p The prime modulus.
- * @param g The generator.
- * @param y The public key component.
- * @return The CipherText pair (a, b).
- * @throws IllegalArgumentException if inputs are null, negative, or message >= p.
- */
- public static CipherText encrypt(BigInteger message, BigInteger p, BigInteger g, BigInteger y) {
- if (message == null || p == null || g == null || y == null) {
- throw new IllegalArgumentException("Inputs cannot be null.");
- }
- if (message.compareTo(BigInteger.ZERO) < 0) {
- throw new IllegalArgumentException("Message must be non-negative.");
- }
- if (message.compareTo(p) >= 0) {
- throw new IllegalArgumentException("Message must be smaller than the prime modulus p.");
- }
-
- BigInteger k;
- BigInteger pMinus1 = p.subtract(BigInteger.ONE);
-
- // Select ephemeral key k such that 1 < k < p-1 and gcd(k, p-1) = 1
- do {
- k = new BigInteger(p.bitLength(), RANDOM);
- } while (k.compareTo(BigInteger.ONE) <= 0 || k.compareTo(pMinus1) >= 0 || !k.gcd(pMinus1).equals(BigInteger.ONE));
-
- BigInteger a = g.modPow(k, p);
- BigInteger b = y.modPow(k, p).multiply(message).mod(p);
-
- return new CipherText(a, b);
- }
-
- /**
- * Decrypts a ciphertext using the private key.
- *
- * @param cipher The CipherText (a, b).
- * @param x The private key.
- * @param p The prime modulus.
- * @return The decrypted message as BigInteger.
- * @throws IllegalArgumentException if inputs are null.
- */
- public static BigInteger decrypt(CipherText cipher, BigInteger x, BigInteger p) {
- if (cipher == null || x == null || p == null) {
- throw new IllegalArgumentException("Inputs cannot be null.");
- }
-
- BigInteger a = cipher.a();
- BigInteger b = cipher.b();
-
- BigInteger s = a.modPow(x, p);
- BigInteger sInverse = s.modInverse(p);
-
- return b.multiply(sInverse).mod(p);
- }
-
- /**
- * Verifies if g is a valid generator for safe prime p = 2q + 1.
- *
- * @param g The candidate generator.
- * @param p The safe prime.
- * @param q The Sophie Germain prime (p-1)/2.
- * @return True if g is a primitive root, False otherwise.
- */
- private static boolean isValidGenerator(BigInteger g, BigInteger p, BigInteger q) {
- // Fix: Must use braces {} for all if statements
- if (g.equals(BigInteger.ONE)) {
- return false;
- }
- if (g.modPow(BigInteger.TWO, p).equals(BigInteger.ONE)) {
- return false;
- }
- return !g.modPow(q, p).equals(BigInteger.ONE);
- }
-}
+package com.thealgorithms.ciphers;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+/**
+ * ElGamal Encryption Algorithm Implementation.
+ *
+ *
+ * ElGamal is an asymmetric key encryption algorithm for public-key cryptography
+ * based on the Diffie–Hellman key exchange. It relies on the difficulty
+ * of computing discrete logarithms in a cyclic group.
+ *
+ *
+ *
+ * Key Features:
+ *
+ * - Uses Safe Primes (p = 2q + 1) to ensure group security.
+ * - Verifies the generator is a primitive root modulo p.
+ * - Stateless design using Java Records.
+ * - SecureRandom for all cryptographic operations.
+ *
+ *
+ *
+ * @author Chahat Sandhu, singhc7
+ * @see ElGamal Encryption (Wikipedia)
+ * @see Safe Primes
+ */
+public final class ElGamalCipher {
+
+ private static final SecureRandom RANDOM = new SecureRandom();
+ private static final int PRIME_CERTAINTY = 40;
+ private static final int MIN_BIT_LENGTH = 256;
+
+ private ElGamalCipher() {
+ }
+
+ /**
+ * A container for the Public and Private keys.
+ *
+ * @param p The prime modulus.
+ * @param g The generator (primitive root).
+ * @param y The public key component (g^x mod p).
+ * @param x The private key.
+ */
+ public record KeyPair(BigInteger p, BigInteger g, BigInteger y, BigInteger x) {
+ }
+
+ /**
+ * Container for the encryption result.
+ *
+ * @param a The first component (g^k mod p).
+ * @param b The second component (y^k * m mod p).
+ */
+ public record CipherText(BigInteger a, BigInteger b) {
+ }
+
+ /**
+ * Generates a valid ElGamal KeyPair using a Safe Prime.
+ *
+ * @param bitLength The bit length of the prime modulus p. Must be at least 256.
+ * @return A valid KeyPair (p, g, y, x).
+ * @throws IllegalArgumentException if bitLength is too small.
+ */
+ public static KeyPair generateKeys(int bitLength) {
+ if (bitLength < MIN_BIT_LENGTH) {
+ throw new IllegalArgumentException("Bit length must be at least " + MIN_BIT_LENGTH + " for security.");
+ }
+
+ BigInteger p;
+ BigInteger q;
+ BigInteger g;
+ BigInteger x;
+ BigInteger y;
+
+ // Generate Safe Prime p = 2q + 1
+ do {
+ q = new BigInteger(bitLength - 1, PRIME_CERTAINTY, RANDOM);
+ p = q.multiply(BigInteger.TWO).add(BigInteger.ONE);
+ } while (!p.isProbablePrime(PRIME_CERTAINTY));
+
+ // Find a Generator g (Primitive Root modulo p)
+ do {
+ g = new BigInteger(bitLength, RANDOM).mod(p.subtract(BigInteger.TWO)).add(BigInteger.TWO);
+ } while (!isValidGenerator(g, p, q));
+
+ // Generate Private Key x in range [2, p-2]
+ do {
+ x = new BigInteger(bitLength, RANDOM);
+ } while (x.compareTo(BigInteger.TWO) < 0 || x.compareTo(p.subtract(BigInteger.TWO)) > 0);
+
+ // Compute Public Key y = g^x mod p
+ y = g.modPow(x, p);
+
+ return new KeyPair(p, g, y, x);
+ }
+
+ /**
+ * Encrypts a message using the public key.
+ *
+ * @param message The message converted to BigInteger.
+ * @param p The prime modulus.
+ * @param g The generator.
+ * @param y The public key component.
+ * @return The CipherText pair (a, b).
+ * @throws IllegalArgumentException if inputs are null, negative, or message >= p.
+ */
+ public static CipherText encrypt(BigInteger message, BigInteger p, BigInteger g, BigInteger y) {
+ if (message == null || p == null || g == null || y == null) {
+ throw new IllegalArgumentException("Inputs cannot be null.");
+ }
+ if (message.compareTo(BigInteger.ZERO) < 0) {
+ throw new IllegalArgumentException("Message must be non-negative.");
+ }
+ if (message.compareTo(p) >= 0) {
+ throw new IllegalArgumentException("Message must be smaller than the prime modulus p.");
+ }
+
+ BigInteger k;
+ BigInteger pMinus1 = p.subtract(BigInteger.ONE);
+
+ // Select ephemeral key k such that 1 < k < p-1 and gcd(k, p-1) = 1
+ do {
+ k = new BigInteger(p.bitLength(), RANDOM);
+ } while (k.compareTo(BigInteger.ONE) <= 0 || k.compareTo(pMinus1) >= 0 || !k.gcd(pMinus1).equals(BigInteger.ONE));
+
+ BigInteger a = g.modPow(k, p);
+ BigInteger b = y.modPow(k, p).multiply(message).mod(p);
+
+ return new CipherText(a, b);
+ }
+
+ /**
+ * Decrypts a ciphertext using the private key.
+ *
+ * @param cipher The CipherText (a, b).
+ * @param x The private key.
+ * @param p The prime modulus.
+ * @return The decrypted message as BigInteger.
+ * @throws IllegalArgumentException if inputs are null.
+ */
+ public static BigInteger decrypt(CipherText cipher, BigInteger x, BigInteger p) {
+ if (cipher == null || x == null || p == null) {
+ throw new IllegalArgumentException("Inputs cannot be null.");
+ }
+
+ BigInteger a = cipher.a();
+ BigInteger b = cipher.b();
+
+ BigInteger s = a.modPow(x, p);
+ BigInteger sInverse = s.modInverse(p);
+
+ return b.multiply(sInverse).mod(p);
+ }
+
+ /**
+ * Verifies if g is a valid generator for safe prime p = 2q + 1.
+ *
+ * @param g The candidate generator.
+ * @param p The safe prime.
+ * @param q The Sophie Germain prime (p-1)/2.
+ * @return True if g is a primitive root, False otherwise.
+ */
+ private static boolean isValidGenerator(BigInteger g, BigInteger p, BigInteger q) {
+ // Fix: Must use braces {} for all if statements
+ if (g.equals(BigInteger.ONE)) {
+ return false;
+ }
+ if (g.modPow(BigInteger.TWO, p).equals(BigInteger.ONE)) {
+ return false;
+ }
+ return !g.modPow(q, p).equals(BigInteger.ONE);
+ }
+}
diff --git a/src/main/java/com/thealgorithms/ciphers/HillCipher.java b/src/main/java/com/thealgorithms/ciphers/HillCipher.java
index 01b1aeb8bc6c..551f0d66d1ce 100644
--- a/src/main/java/com/thealgorithms/ciphers/HillCipher.java
+++ b/src/main/java/com/thealgorithms/ciphers/HillCipher.java
@@ -1,103 +1,103 @@
-package com.thealgorithms.ciphers;
-
-public class HillCipher {
-
- // Encrypts the message using the key matrix
- public String encrypt(String message, int[][] keyMatrix) {
- message = message.toUpperCase().replaceAll("[^A-Z]", "");
- int matrixSize = keyMatrix.length;
- validateDeterminant(keyMatrix, matrixSize);
-
- StringBuilder cipherText = new StringBuilder();
- int[] messageVector = new int[matrixSize];
- int[] cipherVector = new int[matrixSize];
- int index = 0;
-
- while (index < message.length()) {
- for (int i = 0; i < matrixSize; i++) {
- if (index < message.length()) {
- messageVector[i] = message.charAt(index++) - 'A';
- } else {
- messageVector[i] = 'X' - 'A'; // Padding with 'X' if needed
- }
- }
-
- for (int i = 0; i < matrixSize; i++) {
- cipherVector[i] = 0;
- for (int j = 0; j < matrixSize; j++) {
- cipherVector[i] += keyMatrix[i][j] * messageVector[j];
- }
- cipherVector[i] = cipherVector[i] % 26;
- cipherText.append((char) (cipherVector[i] + 'A'));
- }
- }
-
- return cipherText.toString();
- }
-
- // Decrypts the message using the inverse key matrix
- public String decrypt(String message, int[][] inverseKeyMatrix) {
- message = message.toUpperCase().replaceAll("[^A-Z]", "");
- int matrixSize = inverseKeyMatrix.length;
- validateDeterminant(inverseKeyMatrix, matrixSize);
-
- StringBuilder plainText = new StringBuilder();
- int[] messageVector = new int[matrixSize];
- int[] plainVector = new int[matrixSize];
- int index = 0;
-
- while (index < message.length()) {
- for (int i = 0; i < matrixSize; i++) {
- if (index < message.length()) {
- messageVector[i] = message.charAt(index++) - 'A';
- } else {
- messageVector[i] = 'X' - 'A'; // Padding with 'X' if needed
- }
- }
-
- for (int i = 0; i < matrixSize; i++) {
- plainVector[i] = 0;
- for (int j = 0; j < matrixSize; j++) {
- plainVector[i] += inverseKeyMatrix[i][j] * messageVector[j];
- }
- plainVector[i] = plainVector[i] % 26;
- plainText.append((char) (plainVector[i] + 'A'));
- }
- }
-
- return plainText.toString();
- }
-
- // Validates that the determinant of the key matrix is not zero modulo 26
- private void validateDeterminant(int[][] keyMatrix, int n) {
- int det = determinant(keyMatrix, n) % 26;
- if (det == 0) {
- throw new IllegalArgumentException("Invalid key matrix. Determinant is zero modulo 26.");
- }
- }
-
- // Computes the determinant of a matrix recursively
- private int determinant(int[][] matrix, int n) {
- int det = 0;
- if (n == 1) {
- return matrix[0][0];
- }
- int sign = 1;
- int[][] subMatrix = new int[n - 1][n - 1];
- for (int x = 0; x < n; x++) {
- int subI = 0;
- for (int i = 1; i < n; i++) {
- int subJ = 0;
- for (int j = 0; j < n; j++) {
- if (j != x) {
- subMatrix[subI][subJ++] = matrix[i][j];
- }
- }
- subI++;
- }
- det += sign * matrix[0][x] * determinant(subMatrix, n - 1);
- sign = -sign;
- }
- return det;
- }
-}
+package com.thealgorithms.ciphers;
+
+public class HillCipher {
+
+ // Encrypts the message using the key matrix
+ public String encrypt(String message, int[][] keyMatrix) {
+ message = message.toUpperCase().replaceAll("[^A-Z]", "");
+ int matrixSize = keyMatrix.length;
+ validateDeterminant(keyMatrix, matrixSize);
+
+ StringBuilder cipherText = new StringBuilder();
+ int[] messageVector = new int[matrixSize];
+ int[] cipherVector = new int[matrixSize];
+ int index = 0;
+
+ while (index < message.length()) {
+ for (int i = 0; i < matrixSize; i++) {
+ if (index < message.length()) {
+ messageVector[i] = message.charAt(index++) - 'A';
+ } else {
+ messageVector[i] = 'X' - 'A'; // Padding with 'X' if needed
+ }
+ }
+
+ for (int i = 0; i < matrixSize; i++) {
+ cipherVector[i] = 0;
+ for (int j = 0; j < matrixSize; j++) {
+ cipherVector[i] += keyMatrix[i][j] * messageVector[j];
+ }
+ cipherVector[i] = cipherVector[i] % 26;
+ cipherText.append((char) (cipherVector[i] + 'A'));
+ }
+ }
+
+ return cipherText.toString();
+ }
+
+ // Decrypts the message using the inverse key matrix
+ public String decrypt(String message, int[][] inverseKeyMatrix) {
+ message = message.toUpperCase().replaceAll("[^A-Z]", "");
+ int matrixSize = inverseKeyMatrix.length;
+ validateDeterminant(inverseKeyMatrix, matrixSize);
+
+ StringBuilder plainText = new StringBuilder();
+ int[] messageVector = new int[matrixSize];
+ int[] plainVector = new int[matrixSize];
+ int index = 0;
+
+ while (index < message.length()) {
+ for (int i = 0; i < matrixSize; i++) {
+ if (index < message.length()) {
+ messageVector[i] = message.charAt(index++) - 'A';
+ } else {
+ messageVector[i] = 'X' - 'A'; // Padding with 'X' if needed
+ }
+ }
+
+ for (int i = 0; i < matrixSize; i++) {
+ plainVector[i] = 0;
+ for (int j = 0; j < matrixSize; j++) {
+ plainVector[i] += inverseKeyMatrix[i][j] * messageVector[j];
+ }
+ plainVector[i] = plainVector[i] % 26;
+ plainText.append((char) (plainVector[i] + 'A'));
+ }
+ }
+
+ return plainText.toString();
+ }
+
+ // Validates that the determinant of the key matrix is not zero modulo 26
+ private void validateDeterminant(int[][] keyMatrix, int n) {
+ int det = determinant(keyMatrix, n) % 26;
+ if (det == 0) {
+ throw new IllegalArgumentException("Invalid key matrix. Determinant is zero modulo 26.");
+ }
+ }
+
+ // Computes the determinant of a matrix recursively
+ private int determinant(int[][] matrix, int n) {
+ int det = 0;
+ if (n == 1) {
+ return matrix[0][0];
+ }
+ int sign = 1;
+ int[][] subMatrix = new int[n - 1][n - 1];
+ for (int x = 0; x < n; x++) {
+ int subI = 0;
+ for (int i = 1; i < n; i++) {
+ int subJ = 0;
+ for (int j = 0; j < n; j++) {
+ if (j != x) {
+ subMatrix[subI][subJ++] = matrix[i][j];
+ }
+ }
+ subI++;
+ }
+ det += sign * matrix[0][x] * determinant(subMatrix, n - 1);
+ sign = -sign;
+ }
+ return det;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/ciphers/MonoAlphabetic.java b/src/main/java/com/thealgorithms/ciphers/MonoAlphabetic.java
index 1d5b7110a6f3..e420b035d2fc 100644
--- a/src/main/java/com/thealgorithms/ciphers/MonoAlphabetic.java
+++ b/src/main/java/com/thealgorithms/ciphers/MonoAlphabetic.java
@@ -1,48 +1,48 @@
-package com.thealgorithms.ciphers;
-
-public final class MonoAlphabetic {
-
- private MonoAlphabetic() {
- throw new UnsupportedOperationException("Utility class");
- }
-
- // Encryption method
- public static String encrypt(String data, String key) {
- if (!data.matches("[A-Z]+")) {
- throw new IllegalArgumentException("Input data contains invalid characters. Only uppercase A-Z are allowed.");
- }
- StringBuilder sb = new StringBuilder();
-
- // Encrypt each character
- for (char c : data.toCharArray()) {
- int idx = charToPos(c); // Get the index of the character
- sb.append(key.charAt(idx)); // Map to the corresponding character in the key
- }
- return sb.toString();
- }
-
- // Decryption method
- public static String decrypt(String data, String key) {
- StringBuilder sb = new StringBuilder();
-
- // Decrypt each character
- for (char c : data.toCharArray()) {
- int idx = key.indexOf(c); // Find the index of the character in the key
- if (idx == -1) {
- throw new IllegalArgumentException("Input data contains invalid characters.");
- }
- sb.append(posToChar(idx)); // Convert the index back to the original character
- }
- return sb.toString();
- }
-
- // Helper method: Convert a character to its position in the alphabet
- private static int charToPos(char c) {
- return c - 'A'; // Subtract 'A' to get position (0 for A, 1 for B, etc.)
- }
-
- // Helper method: Convert a position in the alphabet to a character
- private static char posToChar(int pos) {
- return (char) (pos + 'A'); // Add 'A' to convert position back to character
- }
-}
+package com.thealgorithms.ciphers;
+
+public final class MonoAlphabetic {
+
+ private MonoAlphabetic() {
+ throw new UnsupportedOperationException("Utility class");
+ }
+
+ // Encryption method
+ public static String encrypt(String data, String key) {
+ if (!data.matches("[A-Z]+")) {
+ throw new IllegalArgumentException("Input data contains invalid characters. Only uppercase A-Z are allowed.");
+ }
+ StringBuilder sb = new StringBuilder();
+
+ // Encrypt each character
+ for (char c : data.toCharArray()) {
+ int idx = charToPos(c); // Get the index of the character
+ sb.append(key.charAt(idx)); // Map to the corresponding character in the key
+ }
+ return sb.toString();
+ }
+
+ // Decryption method
+ public static String decrypt(String data, String key) {
+ StringBuilder sb = new StringBuilder();
+
+ // Decrypt each character
+ for (char c : data.toCharArray()) {
+ int idx = key.indexOf(c); // Find the index of the character in the key
+ if (idx == -1) {
+ throw new IllegalArgumentException("Input data contains invalid characters.");
+ }
+ sb.append(posToChar(idx)); // Convert the index back to the original character
+ }
+ return sb.toString();
+ }
+
+ // Helper method: Convert a character to its position in the alphabet
+ private static int charToPos(char c) {
+ return c - 'A'; // Subtract 'A' to get position (0 for A, 1 for B, etc.)
+ }
+
+ // Helper method: Convert a position in the alphabet to a character
+ private static char posToChar(int pos) {
+ return (char) (pos + 'A'); // Add 'A' to convert position back to character
+ }
+}
diff --git a/src/main/java/com/thealgorithms/ciphers/OneTimePadCipher.java b/src/main/java/com/thealgorithms/ciphers/OneTimePadCipher.java
index 7733f5cb46f2..137ee6877725 100644
--- a/src/main/java/com/thealgorithms/ciphers/OneTimePadCipher.java
+++ b/src/main/java/com/thealgorithms/ciphers/OneTimePadCipher.java
@@ -1,89 +1,89 @@
-package com.thealgorithms.ciphers;
-
-import java.security.SecureRandom;
-import java.util.Objects;
-
-/**
- * One-Time Pad (OTP) cipher implementation.
- *
- * The One-Time Pad is information-theoretically secure if:
- *
- * - The key is truly random.
- * - The key length is at least as long as the plaintext.
- * - The key is used only once and kept secret.
- *
- *
- * This implementation is for educational purposes only and should not be
- * used in production systems.
- */
-public final class OneTimePadCipher {
-
- private static final SecureRandom RANDOM = new SecureRandom();
-
- private OneTimePadCipher() {
- // utility class
- }
-
- /**
- * Generates a random key of the given length in bytes.
- *
- * @param length the length of the key in bytes, must be non-negative
- * @return a new random key
- * @throws IllegalArgumentException if length is negative
- */
- public static byte[] generateKey(int length) {
- if (length < 0) {
- throw new IllegalArgumentException("length must be non-negative");
- }
- byte[] key = new byte[length];
- RANDOM.nextBytes(key);
- return key;
- }
-
- /**
- * Encrypts the given plaintext bytes using the provided key.
- *
The key length must be exactly the same as the plaintext length.
- *
- * @param plaintext the plaintext bytes, must not be {@code null}
- * @param key the one-time pad key bytes, must not be {@code null}
- * @return the ciphertext bytes
- * @throws IllegalArgumentException if the key length does not match plaintext length
- * @throws NullPointerException if plaintext or key is {@code null}
- */
- public static byte[] encrypt(byte[] plaintext, byte[] key) {
- validateInputs(plaintext, key);
- return xor(plaintext, key);
- }
-
- /**
- * Decrypts the given ciphertext bytes using the provided key.
- *
For a One-Time Pad, decryption is identical to encryption:
- * {@code plaintext = ciphertext XOR key}.
- *
- * @param ciphertext the ciphertext bytes, must not be {@code null}
- * @param key the one-time pad key bytes, must not be {@code null}
- * @return the decrypted plaintext bytes
- * @throws IllegalArgumentException if the key length does not match ciphertext length
- * @throws NullPointerException if ciphertext or key is {@code null}
- */
- public static byte[] decrypt(byte[] ciphertext, byte[] key) {
- validateInputs(ciphertext, key);
- return xor(ciphertext, key);
- }
-
- private static void validateInputs(byte[] input, byte[] key) {
- Objects.requireNonNull(input, "input must not be null");
- Objects.requireNonNull(key, "key must not be null");
- if (input.length != key.length) {
- throw new IllegalArgumentException("Key length must match input length");
- }
- }
-
- private static byte[] xor(byte[] data, byte[] key) {
- byte[] result = new byte[data.length];
- for (int i = 0; i < data.length; i++) {
- result[i] = (byte) (data[i] ^ key[i]);
- }
- return result;
- }
-}
+package com.thealgorithms.ciphers;
+
+import java.security.SecureRandom;
+import java.util.Objects;
+
+/**
+ * One-Time Pad (OTP) cipher implementation.
+ *
+ *
The One-Time Pad is information-theoretically secure if:
+ *
+ * - The key is truly random.
+ * - The key length is at least as long as the plaintext.
+ * - The key is used only once and kept secret.
+ *
+ *
+ * This implementation is for educational purposes only and should not be
+ * used in production systems.
+ */
+public final class OneTimePadCipher {
+
+ private static final SecureRandom RANDOM = new SecureRandom();
+
+ private OneTimePadCipher() {
+ // utility class
+ }
+
+ /**
+ * Generates a random key of the given length in bytes.
+ *
+ * @param length the length of the key in bytes, must be non-negative
+ * @return a new random key
+ * @throws IllegalArgumentException if length is negative
+ */
+ public static byte[] generateKey(int length) {
+ if (length < 0) {
+ throw new IllegalArgumentException("length must be non-negative");
+ }
+ byte[] key = new byte[length];
+ RANDOM.nextBytes(key);
+ return key;
+ }
+
+ /**
+ * Encrypts the given plaintext bytes using the provided key.
+ *
The key length must be exactly the same as the plaintext length.
+ *
+ * @param plaintext the plaintext bytes, must not be {@code null}
+ * @param key the one-time pad key bytes, must not be {@code null}
+ * @return the ciphertext bytes
+ * @throws IllegalArgumentException if the key length does not match plaintext length
+ * @throws NullPointerException if plaintext or key is {@code null}
+ */
+ public static byte[] encrypt(byte[] plaintext, byte[] key) {
+ validateInputs(plaintext, key);
+ return xor(plaintext, key);
+ }
+
+ /**
+ * Decrypts the given ciphertext bytes using the provided key.
+ *
For a One-Time Pad, decryption is identical to encryption:
+ * {@code plaintext = ciphertext XOR key}.
+ *
+ * @param ciphertext the ciphertext bytes, must not be {@code null}
+ * @param key the one-time pad key bytes, must not be {@code null}
+ * @return the decrypted plaintext bytes
+ * @throws IllegalArgumentException if the key length does not match ciphertext length
+ * @throws NullPointerException if ciphertext or key is {@code null}
+ */
+ public static byte[] decrypt(byte[] ciphertext, byte[] key) {
+ validateInputs(ciphertext, key);
+ return xor(ciphertext, key);
+ }
+
+ private static void validateInputs(byte[] input, byte[] key) {
+ Objects.requireNonNull(input, "input must not be null");
+ Objects.requireNonNull(key, "key must not be null");
+ if (input.length != key.length) {
+ throw new IllegalArgumentException("Key length must match input length");
+ }
+ }
+
+ private static byte[] xor(byte[] data, byte[] key) {
+ byte[] result = new byte[data.length];
+ for (int i = 0; i < data.length; i++) {
+ result[i] = (byte) (data[i] ^ key[i]);
+ }
+ return result;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/ciphers/PlayfairCipher.java b/src/main/java/com/thealgorithms/ciphers/PlayfairCipher.java
index 76ceb6dbce31..353eb2cc612b 100644
--- a/src/main/java/com/thealgorithms/ciphers/PlayfairCipher.java
+++ b/src/main/java/com/thealgorithms/ciphers/PlayfairCipher.java
@@ -1,128 +1,128 @@
-package com.thealgorithms.ciphers;
-
-public class PlayfairCipher {
-
- private char[][] matrix;
- private String key;
-
- public PlayfairCipher(String key) {
- this.key = key;
- generateMatrix();
- }
-
- public String encrypt(String plaintext) {
- plaintext = prepareText(plaintext.replace("J", "I"));
- StringBuilder ciphertext = new StringBuilder();
- for (int i = 0; i < plaintext.length(); i += 2) {
- char char1 = plaintext.charAt(i);
- char char2 = plaintext.charAt(i + 1);
- int[] pos1 = findPosition(char1);
- int[] pos2 = findPosition(char2);
- int row1 = pos1[0];
- int col1 = pos1[1];
- int row2 = pos2[0];
- int col2 = pos2[1];
- if (row1 == row2) {
- ciphertext.append(matrix[row1][(col1 + 1) % 5]);
- ciphertext.append(matrix[row2][(col2 + 1) % 5]);
- } else if (col1 == col2) {
- ciphertext.append(matrix[(row1 + 1) % 5][col1]);
- ciphertext.append(matrix[(row2 + 1) % 5][col2]);
- } else {
- ciphertext.append(matrix[row1][col2]);
- ciphertext.append(matrix[row2][col1]);
- }
- }
- return ciphertext.toString();
- }
-
- public String decrypt(String ciphertext) {
- StringBuilder plaintext = new StringBuilder();
- for (int i = 0; i < ciphertext.length(); i += 2) {
- char char1 = ciphertext.charAt(i);
- char char2 = ciphertext.charAt(i + 1);
- int[] pos1 = findPosition(char1);
- int[] pos2 = findPosition(char2);
- int row1 = pos1[0];
- int col1 = pos1[1];
- int row2 = pos2[0];
- int col2 = pos2[1];
- if (row1 == row2) {
- plaintext.append(matrix[row1][(col1 + 4) % 5]);
- plaintext.append(matrix[row2][(col2 + 4) % 5]);
- } else if (col1 == col2) {
- plaintext.append(matrix[(row1 + 4) % 5][col1]);
- plaintext.append(matrix[(row2 + 4) % 5][col2]);
- } else {
- plaintext.append(matrix[row1][col2]);
- plaintext.append(matrix[row2][col1]);
- }
- }
- return plaintext.toString();
- }
-
- private void generateMatrix() {
- String keyWithoutDuplicates = removeDuplicateChars(key + "ABCDEFGHIKLMNOPQRSTUVWXYZ");
- matrix = new char[5][5];
- int index = 0;
- for (int i = 0; i < 5; i++) {
- for (int j = 0; j < 5; j++) {
- matrix[i][j] = keyWithoutDuplicates.charAt(index);
- index++;
- }
- }
- }
-
- private String removeDuplicateChars(String str) {
- StringBuilder result = new StringBuilder();
- for (int i = 0; i < str.length(); i++) {
- if (result.indexOf(String.valueOf(str.charAt(i))) == -1) {
- result.append(str.charAt(i));
- }
- }
- return result.toString();
- }
-
- private String prepareText(String text) {
- text = text.toUpperCase().replaceAll("[^A-Z]", "");
- StringBuilder preparedText = new StringBuilder();
- char prevChar = '\0';
- for (char c : text.toCharArray()) {
- if (c != prevChar) {
- preparedText.append(c);
- prevChar = c;
- } else {
- preparedText.append('X').append(c);
- prevChar = '\0';
- }
- }
- if (preparedText.length() % 2 != 0) {
- preparedText.append('X');
- }
- return preparedText.toString();
- }
-
- private int[] findPosition(char c) {
- int[] pos = new int[2];
- for (int i = 0; i < 5; i++) {
- for (int j = 0; j < 5; j++) {
- if (matrix[i][j] == c) {
- pos[0] = i;
- pos[1] = j;
- return pos;
- }
- }
- }
- return pos;
- }
-
- public void printMatrix() {
- System.out.println("\nPlayfair Cipher Matrix:");
- for (int i = 0; i < 5; i++) {
- for (int j = 0; j < 5; j++) {
- System.out.print(matrix[i][j] + " ");
- }
- System.out.println();
- }
- }
-}
+package com.thealgorithms.ciphers;
+
+public class PlayfairCipher {
+
+ private char[][] matrix;
+ private String key;
+
+ public PlayfairCipher(String key) {
+ this.key = key;
+ generateMatrix();
+ }
+
+ public String encrypt(String plaintext) {
+ plaintext = prepareText(plaintext.replace("J", "I"));
+ StringBuilder ciphertext = new StringBuilder();
+ for (int i = 0; i < plaintext.length(); i += 2) {
+ char char1 = plaintext.charAt(i);
+ char char2 = plaintext.charAt(i + 1);
+ int[] pos1 = findPosition(char1);
+ int[] pos2 = findPosition(char2);
+ int row1 = pos1[0];
+ int col1 = pos1[1];
+ int row2 = pos2[0];
+ int col2 = pos2[1];
+ if (row1 == row2) {
+ ciphertext.append(matrix[row1][(col1 + 1) % 5]);
+ ciphertext.append(matrix[row2][(col2 + 1) % 5]);
+ } else if (col1 == col2) {
+ ciphertext.append(matrix[(row1 + 1) % 5][col1]);
+ ciphertext.append(matrix[(row2 + 1) % 5][col2]);
+ } else {
+ ciphertext.append(matrix[row1][col2]);
+ ciphertext.append(matrix[row2][col1]);
+ }
+ }
+ return ciphertext.toString();
+ }
+
+ public String decrypt(String ciphertext) {
+ StringBuilder plaintext = new StringBuilder();
+ for (int i = 0; i < ciphertext.length(); i += 2) {
+ char char1 = ciphertext.charAt(i);
+ char char2 = ciphertext.charAt(i + 1);
+ int[] pos1 = findPosition(char1);
+ int[] pos2 = findPosition(char2);
+ int row1 = pos1[0];
+ int col1 = pos1[1];
+ int row2 = pos2[0];
+ int col2 = pos2[1];
+ if (row1 == row2) {
+ plaintext.append(matrix[row1][(col1 + 4) % 5]);
+ plaintext.append(matrix[row2][(col2 + 4) % 5]);
+ } else if (col1 == col2) {
+ plaintext.append(matrix[(row1 + 4) % 5][col1]);
+ plaintext.append(matrix[(row2 + 4) % 5][col2]);
+ } else {
+ plaintext.append(matrix[row1][col2]);
+ plaintext.append(matrix[row2][col1]);
+ }
+ }
+ return plaintext.toString();
+ }
+
+ private void generateMatrix() {
+ String keyWithoutDuplicates = removeDuplicateChars(key + "ABCDEFGHIKLMNOPQRSTUVWXYZ");
+ matrix = new char[5][5];
+ int index = 0;
+ for (int i = 0; i < 5; i++) {
+ for (int j = 0; j < 5; j++) {
+ matrix[i][j] = keyWithoutDuplicates.charAt(index);
+ index++;
+ }
+ }
+ }
+
+ private String removeDuplicateChars(String str) {
+ StringBuilder result = new StringBuilder();
+ for (int i = 0; i < str.length(); i++) {
+ if (result.indexOf(String.valueOf(str.charAt(i))) == -1) {
+ result.append(str.charAt(i));
+ }
+ }
+ return result.toString();
+ }
+
+ private String prepareText(String text) {
+ text = text.toUpperCase().replaceAll("[^A-Z]", "");
+ StringBuilder preparedText = new StringBuilder();
+ char prevChar = '\0';
+ for (char c : text.toCharArray()) {
+ if (c != prevChar) {
+ preparedText.append(c);
+ prevChar = c;
+ } else {
+ preparedText.append('X').append(c);
+ prevChar = '\0';
+ }
+ }
+ if (preparedText.length() % 2 != 0) {
+ preparedText.append('X');
+ }
+ return preparedText.toString();
+ }
+
+ private int[] findPosition(char c) {
+ int[] pos = new int[2];
+ for (int i = 0; i < 5; i++) {
+ for (int j = 0; j < 5; j++) {
+ if (matrix[i][j] == c) {
+ pos[0] = i;
+ pos[1] = j;
+ return pos;
+ }
+ }
+ }
+ return pos;
+ }
+
+ public void printMatrix() {
+ System.out.println("\nPlayfair Cipher Matrix:");
+ for (int i = 0; i < 5; i++) {
+ for (int j = 0; j < 5; j++) {
+ System.out.print(matrix[i][j] + " ");
+ }
+ System.out.println();
+ }
+ }
+}
diff --git a/src/main/java/com/thealgorithms/ciphers/Polybius.java b/src/main/java/com/thealgorithms/ciphers/Polybius.java
index 6b3cd6ccae81..f9cba92ae6cc 100644
--- a/src/main/java/com/thealgorithms/ciphers/Polybius.java
+++ b/src/main/java/com/thealgorithms/ciphers/Polybius.java
@@ -1,62 +1,62 @@
-package com.thealgorithms.ciphers;
-
-/**
- * A Java implementation of Polybius Cipher
- * Polybius is a substitution cipher method
- * It was invented by a greek philosopher that name is Polybius
- * Letters in alphabet takes place to two dimension table.
- * Encrypted text is created according to row and column in two dimension table
- * Decrypted text is generated by looking at the row and column respectively
- * Additionally, some letters in english alphabet deliberately throws such as U because U is very
- * similar with V
- *
- * @author Hikmet ÇAKIR
- * @since 08-07-2022+03:00
- */
-public final class Polybius {
- private Polybius() {
- }
-
- private static final char[][] KEY = {
- // 0 1 2 3 4
- /* 0 */ {'A', 'B', 'C', 'D', 'E'},
- /* 1 */ {'F', 'G', 'H', 'I', 'J'},
- /* 2 */ {'K', 'L', 'M', 'N', 'O'},
- /* 3 */ {'P', 'Q', 'R', 'S', 'T'},
- /* 4 */ {'V', 'W', 'X', 'Y', 'Z'},
- };
-
- private static String findLocationByCharacter(final char character) {
- final StringBuilder location = new StringBuilder();
- for (int i = 0; i < KEY.length; i++) {
- for (int j = 0; j < KEY[i].length; j++) {
- if (character == KEY[i][j]) {
- location.append(i).append(j);
- break;
- }
- }
- }
- return location.toString();
- }
-
- public static String encrypt(final String plaintext) {
- final char[] chars = plaintext.toUpperCase().toCharArray();
- final StringBuilder ciphertext = new StringBuilder();
- for (char aChar : chars) {
- String location = findLocationByCharacter(aChar);
- ciphertext.append(location);
- }
- return ciphertext.toString();
- }
-
- public static String decrypt(final String ciphertext) {
- final char[] chars = ciphertext.toCharArray();
- final StringBuilder plaintext = new StringBuilder();
- for (int i = 0; i < chars.length; i += 2) {
- int pozitionX = Character.getNumericValue(chars[i]);
- int pozitionY = Character.getNumericValue(chars[i + 1]);
- plaintext.append(KEY[pozitionX][pozitionY]);
- }
- return plaintext.toString();
- }
-}
+package com.thealgorithms.ciphers;
+
+/**
+ * A Java implementation of Polybius Cipher
+ * Polybius is a substitution cipher method
+ * It was invented by a greek philosopher that name is Polybius
+ * Letters in alphabet takes place to two dimension table.
+ * Encrypted text is created according to row and column in two dimension table
+ * Decrypted text is generated by looking at the row and column respectively
+ * Additionally, some letters in english alphabet deliberately throws such as U because U is very
+ * similar with V
+ *
+ * @author Hikmet ÇAKIR
+ * @since 08-07-2022+03:00
+ */
+public final class Polybius {
+ private Polybius() {
+ }
+
+ private static final char[][] KEY = {
+ // 0 1 2 3 4
+ /* 0 */ {'A', 'B', 'C', 'D', 'E'},
+ /* 1 */ {'F', 'G', 'H', 'I', 'J'},
+ /* 2 */ {'K', 'L', 'M', 'N', 'O'},
+ /* 3 */ {'P', 'Q', 'R', 'S', 'T'},
+ /* 4 */ {'V', 'W', 'X', 'Y', 'Z'},
+ };
+
+ private static String findLocationByCharacter(final char character) {
+ final StringBuilder location = new StringBuilder();
+ for (int i = 0; i < KEY.length; i++) {
+ for (int j = 0; j < KEY[i].length; j++) {
+ if (character == KEY[i][j]) {
+ location.append(i).append(j);
+ break;
+ }
+ }
+ }
+ return location.toString();
+ }
+
+ public static String encrypt(final String plaintext) {
+ final char[] chars = plaintext.toUpperCase().toCharArray();
+ final StringBuilder ciphertext = new StringBuilder();
+ for (char aChar : chars) {
+ String location = findLocationByCharacter(aChar);
+ ciphertext.append(location);
+ }
+ return ciphertext.toString();
+ }
+
+ public static String decrypt(final String ciphertext) {
+ final char[] chars = ciphertext.toCharArray();
+ final StringBuilder plaintext = new StringBuilder();
+ for (int i = 0; i < chars.length; i += 2) {
+ int pozitionX = Character.getNumericValue(chars[i]);
+ int pozitionY = Character.getNumericValue(chars[i + 1]);
+ plaintext.append(KEY[pozitionX][pozitionY]);
+ }
+ return plaintext.toString();
+ }
+}
diff --git a/src/main/java/com/thealgorithms/ciphers/ProductCipher.java b/src/main/java/com/thealgorithms/ciphers/ProductCipher.java
index d7eaea757001..debd9e06c032 100644
--- a/src/main/java/com/thealgorithms/ciphers/ProductCipher.java
+++ b/src/main/java/com/thealgorithms/ciphers/ProductCipher.java
@@ -1,73 +1,73 @@
-package com.thealgorithms.ciphers;
-
-import java.util.Scanner;
-
-final class ProductCipher {
- private ProductCipher() {
- }
-
- public static void main(String[] args) {
- try (Scanner sc = new Scanner(System.in)) {
- System.out.println("Enter the input to be encrypted: ");
- String substitutionInput = sc.nextLine();
- System.out.println(" ");
- System.out.println("Enter a number: ");
- int n = sc.nextInt();
-
- // Substitution encryption
- StringBuffer substitutionOutput = new StringBuffer();
- for (int i = 0; i < substitutionInput.length(); i++) {
- char c = substitutionInput.charAt(i);
- substitutionOutput.append((char) (c + 5));
- }
- System.out.println(" ");
- System.out.println("Substituted text: ");
- System.out.println(substitutionOutput);
-
- // Transposition encryption
- String transpositionInput = substitutionOutput.toString();
- int modulus = transpositionInput.length() % n;
- if (modulus != 0) {
- modulus = n - modulus;
-
- for (; modulus != 0; modulus--) {
- transpositionInput += "/";
- }
- }
- StringBuffer transpositionOutput = new StringBuffer();
- System.out.println(" ");
- System.out.println("Transposition Matrix: ");
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < transpositionInput.length() / n; j++) {
- char c = transpositionInput.charAt(i + (j * n));
- System.out.print(c);
- transpositionOutput.append(c);
- }
- System.out.println();
- }
- System.out.println(" ");
- System.out.println("Final encrypted text: ");
- System.out.println(transpositionOutput);
-
- // Transposition decryption
- n = transpositionOutput.length() / n;
- StringBuffer transpositionPlaintext = new StringBuffer();
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < transpositionOutput.length() / n; j++) {
- char c = transpositionOutput.charAt(i + (j * n));
- transpositionPlaintext.append(c);
- }
- }
-
- // Substitution decryption
- StringBuffer plaintext = new StringBuffer();
- for (int i = 0; i < transpositionPlaintext.length(); i++) {
- char c = transpositionPlaintext.charAt(i);
- plaintext.append((char) (c - 5));
- }
-
- System.out.println("Plaintext: ");
- System.out.println(plaintext);
- }
- }
-}
+package com.thealgorithms.ciphers;
+
+import java.util.Scanner;
+
+final class ProductCipher {
+ private ProductCipher() {
+ }
+
+ public static void main(String[] args) {
+ try (Scanner sc = new Scanner(System.in)) {
+ System.out.println("Enter the input to be encrypted: ");
+ String substitutionInput = sc.nextLine();
+ System.out.println(" ");
+ System.out.println("Enter a number: ");
+ int n = sc.nextInt();
+
+ // Substitution encryption
+ StringBuffer substitutionOutput = new StringBuffer();
+ for (int i = 0; i < substitutionInput.length(); i++) {
+ char c = substitutionInput.charAt(i);
+ substitutionOutput.append((char) (c + 5));
+ }
+ System.out.println(" ");
+ System.out.println("Substituted text: ");
+ System.out.println(substitutionOutput);
+
+ // Transposition encryption
+ String transpositionInput = substitutionOutput.toString();
+ int modulus = transpositionInput.length() % n;
+ if (modulus != 0) {
+ modulus = n - modulus;
+
+ for (; modulus != 0; modulus--) {
+ transpositionInput += "/";
+ }
+ }
+ StringBuffer transpositionOutput = new StringBuffer();
+ System.out.println(" ");
+ System.out.println("Transposition Matrix: ");
+ for (int i = 0; i < n; i++) {
+ for (int j = 0; j < transpositionInput.length() / n; j++) {
+ char c = transpositionInput.charAt(i + (j * n));
+ System.out.print(c);
+ transpositionOutput.append(c);
+ }
+ System.out.println();
+ }
+ System.out.println(" ");
+ System.out.println("Final encrypted text: ");
+ System.out.println(transpositionOutput);
+
+ // Transposition decryption
+ n = transpositionOutput.length() / n;
+ StringBuffer transpositionPlaintext = new StringBuffer();
+ for (int i = 0; i < n; i++) {
+ for (int j = 0; j < transpositionOutput.length() / n; j++) {
+ char c = transpositionOutput.charAt(i + (j * n));
+ transpositionPlaintext.append(c);
+ }
+ }
+
+ // Substitution decryption
+ StringBuffer plaintext = new StringBuffer();
+ for (int i = 0; i < transpositionPlaintext.length(); i++) {
+ char c = transpositionPlaintext.charAt(i);
+ plaintext.append((char) (c - 5));
+ }
+
+ System.out.println("Plaintext: ");
+ System.out.println(plaintext);
+ }
+ }
+}
diff --git a/src/main/java/com/thealgorithms/ciphers/RSA.java b/src/main/java/com/thealgorithms/ciphers/RSA.java
index 28af1a62032a..17ef45b41b83 100644
--- a/src/main/java/com/thealgorithms/ciphers/RSA.java
+++ b/src/main/java/com/thealgorithms/ciphers/RSA.java
@@ -1,119 +1,119 @@
-package com.thealgorithms.ciphers;
-
-import java.math.BigInteger;
-import java.security.SecureRandom;
-
-/**
- * RSA is an asymmetric cryptographic algorithm used for secure data encryption and decryption.
- * It relies on a pair of keys: a public key (used for encryption) and a private key
- * (used for decryption). The algorithm is based on the difficulty of factoring large prime numbers.
- *
- * This implementation includes key generation, encryption, and decryption methods that can handle both
- * text-based messages and BigInteger inputs. For more details on RSA:
- * RSA Cryptosystem - Wikipedia.
- *
- * Example Usage:
- *
- * RSA rsa = new RSA(1024);
- * String encryptedMessage = rsa.encrypt("Hello RSA!");
- * String decryptedMessage = rsa.decrypt(encryptedMessage);
- * System.out.println(decryptedMessage); // Output: Hello RSA!
- *
- *
- * Note: The key size directly affects the security and performance of the RSA algorithm.
- * Larger keys are more secure but slower to compute.
- *
- * @author Nguyen Duy Tiep
- * @version 23-Oct-17
- */
-public class RSA {
-
- private BigInteger modulus;
- private BigInteger privateKey;
- private BigInteger publicKey;
-
- /**
- * Constructor that generates RSA keys with the specified number of bits.
- *
- * @param bits The bit length of the keys to be generated. Common sizes include 512, 1024, 2048, etc.
- */
- public RSA(int bits) {
- generateKeys(bits);
- }
-
- /**
- * Encrypts a text message using the RSA public key.
- *
- * @param message The plaintext message to be encrypted.
- * @throws IllegalArgumentException If the message is empty.
- * @return The encrypted message represented as a String.
- */
- public synchronized String encrypt(String message) {
- if (message.isEmpty()) {
- throw new IllegalArgumentException("Message is empty");
- }
- return (new BigInteger(message.getBytes())).modPow(publicKey, modulus).toString();
- }
-
- /**
- * Encrypts a BigInteger message using the RSA public key.
- *
- * @param message The plaintext message as a BigInteger.
- * @return The encrypted message as a BigInteger.
- */
- public synchronized BigInteger encrypt(BigInteger message) {
- return message.modPow(publicKey, modulus);
- }
-
- /**
- * Decrypts an encrypted message (as String) using the RSA private key.
- *
- * @param encryptedMessage The encrypted message to be decrypted, represented as a String.
- * @throws IllegalArgumentException If the message is empty.
- * @return The decrypted plaintext message as a String.
- */
- public synchronized String decrypt(String encryptedMessage) {
- if (encryptedMessage.isEmpty()) {
- throw new IllegalArgumentException("Message is empty");
- }
- return new String((new BigInteger(encryptedMessage)).modPow(privateKey, modulus).toByteArray());
- }
-
- /**
- * Decrypts an encrypted BigInteger message using the RSA private key.
- *
- * @param encryptedMessage The encrypted message as a BigInteger.
- * @return The decrypted plaintext message as a BigInteger.
- */
- public synchronized BigInteger decrypt(BigInteger encryptedMessage) {
- return encryptedMessage.modPow(privateKey, modulus);
- }
-
- /**
- * Generates a new RSA key pair (public and private keys) with the specified bit length.
- * Steps:
- * 1. Generate two large prime numbers p and q.
- * 2. Compute the modulus n = p * q.
- * 3. Compute Euler's totient function: φ(n) = (p-1) * (q-1).
- * 4. Choose a public key e (starting from 3) that is coprime with φ(n).
- * 5. Compute the private key d as the modular inverse of e mod φ(n).
- * The public key is (e, n) and the private key is (d, n).
- *
- * @param bits The bit length of the keys to be generated.
- */
- public final synchronized void generateKeys(int bits) {
- SecureRandom random = new SecureRandom();
- BigInteger p = new BigInteger(bits / 2, 100, random);
- BigInteger q = new BigInteger(bits / 2, 100, random);
- modulus = p.multiply(q);
-
- BigInteger phi = (p.subtract(BigInteger.ONE)).multiply(q.subtract(BigInteger.ONE));
-
- publicKey = BigInteger.valueOf(3L);
- while (phi.gcd(publicKey).intValue() > 1) {
- publicKey = publicKey.add(BigInteger.TWO);
- }
-
- privateKey = publicKey.modInverse(phi);
- }
-}
+package com.thealgorithms.ciphers;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+/**
+ * RSA is an asymmetric cryptographic algorithm used for secure data encryption and decryption.
+ * It relies on a pair of keys: a public key (used for encryption) and a private key
+ * (used for decryption). The algorithm is based on the difficulty of factoring large prime numbers.
+ *
+ * This implementation includes key generation, encryption, and decryption methods that can handle both
+ * text-based messages and BigInteger inputs. For more details on RSA:
+ * RSA Cryptosystem - Wikipedia.
+ *
+ * Example Usage:
+ *
+ * RSA rsa = new RSA(1024);
+ * String encryptedMessage = rsa.encrypt("Hello RSA!");
+ * String decryptedMessage = rsa.decrypt(encryptedMessage);
+ * System.out.println(decryptedMessage); // Output: Hello RSA!
+ *
+ *
+ * Note: The key size directly affects the security and performance of the RSA algorithm.
+ * Larger keys are more secure but slower to compute.
+ *
+ * @author Nguyen Duy Tiep
+ * @version 23-Oct-17
+ */
+public class RSA {
+
+ private BigInteger modulus;
+ private BigInteger privateKey;
+ private BigInteger publicKey;
+
+ /**
+ * Constructor that generates RSA keys with the specified number of bits.
+ *
+ * @param bits The bit length of the keys to be generated. Common sizes include 512, 1024, 2048, etc.
+ */
+ public RSA(int bits) {
+ generateKeys(bits);
+ }
+
+ /**
+ * Encrypts a text message using the RSA public key.
+ *
+ * @param message The plaintext message to be encrypted.
+ * @throws IllegalArgumentException If the message is empty.
+ * @return The encrypted message represented as a String.
+ */
+ public synchronized String encrypt(String message) {
+ if (message.isEmpty()) {
+ throw new IllegalArgumentException("Message is empty");
+ }
+ return (new BigInteger(message.getBytes())).modPow(publicKey, modulus).toString();
+ }
+
+ /**
+ * Encrypts a BigInteger message using the RSA public key.
+ *
+ * @param message The plaintext message as a BigInteger.
+ * @return The encrypted message as a BigInteger.
+ */
+ public synchronized BigInteger encrypt(BigInteger message) {
+ return message.modPow(publicKey, modulus);
+ }
+
+ /**
+ * Decrypts an encrypted message (as String) using the RSA private key.
+ *
+ * @param encryptedMessage The encrypted message to be decrypted, represented as a String.
+ * @throws IllegalArgumentException If the message is empty.
+ * @return The decrypted plaintext message as a String.
+ */
+ public synchronized String decrypt(String encryptedMessage) {
+ if (encryptedMessage.isEmpty()) {
+ throw new IllegalArgumentException("Message is empty");
+ }
+ return new String((new BigInteger(encryptedMessage)).modPow(privateKey, modulus).toByteArray());
+ }
+
+ /**
+ * Decrypts an encrypted BigInteger message using the RSA private key.
+ *
+ * @param encryptedMessage The encrypted message as a BigInteger.
+ * @return The decrypted plaintext message as a BigInteger.
+ */
+ public synchronized BigInteger decrypt(BigInteger encryptedMessage) {
+ return encryptedMessage.modPow(privateKey, modulus);
+ }
+
+ /**
+ * Generates a new RSA key pair (public and private keys) with the specified bit length.
+ * Steps:
+ * 1. Generate two large prime numbers p and q.
+ * 2. Compute the modulus n = p * q.
+ * 3. Compute Euler's totient function: φ(n) = (p-1) * (q-1).
+ * 4. Choose a public key e (starting from 3) that is coprime with φ(n).
+ * 5. Compute the private key d as the modular inverse of e mod φ(n).
+ * The public key is (e, n) and the private key is (d, n).
+ *
+ * @param bits The bit length of the keys to be generated.
+ */
+ public final synchronized void generateKeys(int bits) {
+ SecureRandom random = new SecureRandom();
+ BigInteger p = new BigInteger(bits / 2, 100, random);
+ BigInteger q = new BigInteger(bits / 2, 100, random);
+ modulus = p.multiply(q);
+
+ BigInteger phi = (p.subtract(BigInteger.ONE)).multiply(q.subtract(BigInteger.ONE));
+
+ publicKey = BigInteger.valueOf(3L);
+ while (phi.gcd(publicKey).intValue() > 1) {
+ publicKey = publicKey.add(BigInteger.TWO);
+ }
+
+ privateKey = publicKey.modInverse(phi);
+ }
+}
diff --git a/src/main/java/com/thealgorithms/ciphers/SimpleSubCipher.java b/src/main/java/com/thealgorithms/ciphers/SimpleSubCipher.java
index f6c88ef730ec..7c7f0ff805b8 100644
--- a/src/main/java/com/thealgorithms/ciphers/SimpleSubCipher.java
+++ b/src/main/java/com/thealgorithms/ciphers/SimpleSubCipher.java
@@ -1,85 +1,85 @@
-package com.thealgorithms.ciphers;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * The simple substitution cipher is a cipher that has been in use for many
- * hundreds of years (an excellent history is given in Simon Singhs 'the Code
- * Book'). It basically consists of substituting every plaintext character for a
- * different ciphertext character. It differs from the Caesar cipher in that the
- * cipher alphabet is not simply the alphabet shifted, it is completely jumbled.
- */
-public class SimpleSubCipher {
-
- /**
- * Encrypt text by replacing each element with its opposite character.
- *
- * @param message
- * @param cipherSmall
- * @return Encrypted message
- */
- public String encode(String message, String cipherSmall) {
- StringBuilder encoded = new StringBuilder();
-
- // This map is used to encode
- Map cipherMap = new HashMap<>();
-
- char beginSmallLetter = 'a';
- char beginCapitalLetter = 'A';
-
- cipherSmall = cipherSmall.toLowerCase();
- String cipherCapital = cipherSmall.toUpperCase();
-
- // To handle Small and Capital letters
- for (int i = 0; i < cipherSmall.length(); i++) {
- cipherMap.put(beginSmallLetter++, cipherSmall.charAt(i));
- cipherMap.put(beginCapitalLetter++, cipherCapital.charAt(i));
- }
-
- for (int i = 0; i < message.length(); i++) {
- if (Character.isAlphabetic(message.charAt(i))) {
- encoded.append(cipherMap.get(message.charAt(i)));
- } else {
- encoded.append(message.charAt(i));
- }
- }
-
- return encoded.toString();
- }
-
- /**
- * Decrypt message by replacing each element with its opposite character in
- * cipher.
- *
- * @param encryptedMessage
- * @param cipherSmall
- * @return message
- */
- public String decode(String encryptedMessage, String cipherSmall) {
- StringBuilder decoded = new StringBuilder();
-
- Map cipherMap = new HashMap<>();
-
- char beginSmallLetter = 'a';
- char beginCapitalLetter = 'A';
-
- cipherSmall = cipherSmall.toLowerCase();
- String cipherCapital = cipherSmall.toUpperCase();
-
- for (int i = 0; i < cipherSmall.length(); i++) {
- cipherMap.put(cipherSmall.charAt(i), beginSmallLetter++);
- cipherMap.put(cipherCapital.charAt(i), beginCapitalLetter++);
- }
-
- for (int i = 0; i < encryptedMessage.length(); i++) {
- if (Character.isAlphabetic(encryptedMessage.charAt(i))) {
- decoded.append(cipherMap.get(encryptedMessage.charAt(i)));
- } else {
- decoded.append(encryptedMessage.charAt(i));
- }
- }
-
- return decoded.toString();
- }
-}
+package com.thealgorithms.ciphers;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * The simple substitution cipher is a cipher that has been in use for many
+ * hundreds of years (an excellent history is given in Simon Singhs 'the Code
+ * Book'). It basically consists of substituting every plaintext character for a
+ * different ciphertext character. It differs from the Caesar cipher in that the
+ * cipher alphabet is not simply the alphabet shifted, it is completely jumbled.
+ */
+public class SimpleSubCipher {
+
+ /**
+ * Encrypt text by replacing each element with its opposite character.
+ *
+ * @param message
+ * @param cipherSmall
+ * @return Encrypted message
+ */
+ public String encode(String message, String cipherSmall) {
+ StringBuilder encoded = new StringBuilder();
+
+ // This map is used to encode
+ Map cipherMap = new HashMap<>();
+
+ char beginSmallLetter = 'a';
+ char beginCapitalLetter = 'A';
+
+ cipherSmall = cipherSmall.toLowerCase();
+ String cipherCapital = cipherSmall.toUpperCase();
+
+ // To handle Small and Capital letters
+ for (int i = 0; i < cipherSmall.length(); i++) {
+ cipherMap.put(beginSmallLetter++, cipherSmall.charAt(i));
+ cipherMap.put(beginCapitalLetter++, cipherCapital.charAt(i));
+ }
+
+ for (int i = 0; i < message.length(); i++) {
+ if (Character.isAlphabetic(message.charAt(i))) {
+ encoded.append(cipherMap.get(message.charAt(i)));
+ } else {
+ encoded.append(message.charAt(i));
+ }
+ }
+
+ return encoded.toString();
+ }
+
+ /**
+ * Decrypt message by replacing each element with its opposite character in
+ * cipher.
+ *
+ * @param encryptedMessage
+ * @param cipherSmall
+ * @return message
+ */
+ public String decode(String encryptedMessage, String cipherSmall) {
+ StringBuilder decoded = new StringBuilder();
+
+ Map cipherMap = new HashMap<>();
+
+ char beginSmallLetter = 'a';
+ char beginCapitalLetter = 'A';
+
+ cipherSmall = cipherSmall.toLowerCase();
+ String cipherCapital = cipherSmall.toUpperCase();
+
+ for (int i = 0; i < cipherSmall.length(); i++) {
+ cipherMap.put(cipherSmall.charAt(i), beginSmallLetter++);
+ cipherMap.put(cipherCapital.charAt(i), beginCapitalLetter++);
+ }
+
+ for (int i = 0; i < encryptedMessage.length(); i++) {
+ if (Character.isAlphabetic(encryptedMessage.charAt(i))) {
+ decoded.append(cipherMap.get(encryptedMessage.charAt(i)));
+ } else {
+ decoded.append(encryptedMessage.charAt(i));
+ }
+ }
+
+ return decoded.toString();
+ }
+}
diff --git a/src/main/java/com/thealgorithms/ciphers/Vigenere.java b/src/main/java/com/thealgorithms/ciphers/Vigenere.java
index 0f117853bb85..f8e3f536465a 100644
--- a/src/main/java/com/thealgorithms/ciphers/Vigenere.java
+++ b/src/main/java/com/thealgorithms/ciphers/Vigenere.java
@@ -1,106 +1,106 @@
-package com.thealgorithms.ciphers;
-
-/**
- * A Java implementation of the Vigenère Cipher.
- *
- * The Vigenère Cipher is a polyalphabetic substitution cipher that uses a
- * keyword to shift letters in the plaintext by different amounts, depending
- * on the corresponding character in the keyword. It wraps around the alphabet,
- * ensuring the shifts are within 'A'-'Z' or 'a'-'z'.
- *
- * Non-alphabetic characters (like spaces, punctuation) are kept unchanged.
- *
- * Encryption Example:
- * - Plaintext: "Hello World!"
- * - Key: "suchsecret"
- * - Encrypted Text: "Zynsg Yfvev!"
- *
- * Decryption Example:
- * - Ciphertext: "Zynsg Yfvev!"
- * - Key: "suchsecret"
- * - Decrypted Text: "Hello World!"
- *
- * Wikipedia Reference:
- * Vigenère Cipher - Wikipedia
- *
- * @author straiffix
- * @author beingmartinbmc
- */
-public class Vigenere {
-
- /**
- * Encrypts a given message using the Vigenère Cipher with the specified key.
- * Steps:
- * 1. Iterate over each character in the message.
- * 2. If the character is a letter, shift it by the corresponding character in the key.
- * 3. Preserve the case of the letter.
- * 4. Preserve non-alphabetic characters.
- * 5. Move to the next character in the key (cyclic).
- * 6. Return the encrypted message.
- *
- * @param message The plaintext message to encrypt.
- * @param key The keyword used for encryption.
- * @throws IllegalArgumentException if the key is empty.
- * @return The encrypted message.
- */
- public String encrypt(final String message, final String key) {
- if (key.isEmpty()) {
- throw new IllegalArgumentException("Key cannot be empty.");
- }
-
- StringBuilder result = new StringBuilder();
- int j = 0;
- for (int i = 0; i < message.length(); i++) {
- char c = message.charAt(i);
- if (Character.isLetter(c)) {
- if (Character.isUpperCase(c)) {
- result.append((char) ((c + key.toUpperCase().charAt(j) - 2 * 'A') % 26 + 'A'));
- } else {
- result.append((char) ((c + key.toLowerCase().charAt(j) - 2 * 'a') % 26 + 'a'));
- }
- j = ++j % key.length();
- } else {
- result.append(c);
- }
- }
- return result.toString();
- }
-
- /**
- * Decrypts a given message encrypted with the Vigenère Cipher using the specified key.
- * Steps:
- * 1. Iterate over each character in the message.
- * 2. If the character is a letter, shift it back by the corresponding character in the key.
- * 3. Preserve the case of the letter.
- * 4. Preserve non-alphabetic characters.
- * 5. Move to the next character in the key (cyclic).
- * 6. Return the decrypted message.
- *
- * @param message The encrypted message to decrypt.
- * @param key The keyword used for decryption.
- * @throws IllegalArgumentException if the key is empty.
- * @return The decrypted plaintext message.
- */
- public String decrypt(final String message, final String key) {
- if (key.isEmpty()) {
- throw new IllegalArgumentException("Key cannot be empty.");
- }
-
- StringBuilder result = new StringBuilder();
- int j = 0;
- for (int i = 0; i < message.length(); i++) {
- char c = message.charAt(i);
- if (Character.isLetter(c)) {
- if (Character.isUpperCase(c)) {
- result.append((char) ('Z' - (25 - (c - key.toUpperCase().charAt(j))) % 26));
- } else {
- result.append((char) ('z' - (25 - (c - key.toLowerCase().charAt(j))) % 26));
- }
- j = ++j % key.length();
- } else {
- result.append(c);
- }
- }
- return result.toString();
- }
-}
+package com.thealgorithms.ciphers;
+
+/**
+ * A Java implementation of the Vigenère Cipher.
+ *
+ * The Vigenère Cipher is a polyalphabetic substitution cipher that uses a
+ * keyword to shift letters in the plaintext by different amounts, depending
+ * on the corresponding character in the keyword. It wraps around the alphabet,
+ * ensuring the shifts are within 'A'-'Z' or 'a'-'z'.
+ *
+ * Non-alphabetic characters (like spaces, punctuation) are kept unchanged.
+ *
+ * Encryption Example:
+ * - Plaintext: "Hello World!"
+ * - Key: "suchsecret"
+ * - Encrypted Text: "Zynsg Yfvev!"
+ *
+ * Decryption Example:
+ * - Ciphertext: "Zynsg Yfvev!"
+ * - Key: "suchsecret"
+ * - Decrypted Text: "Hello World!"
+ *
+ * Wikipedia Reference:
+ * Vigenère Cipher - Wikipedia
+ *
+ * @author straiffix
+ * @author beingmartinbmc
+ */
+public class Vigenere {
+
+ /**
+ * Encrypts a given message using the Vigenère Cipher with the specified key.
+ * Steps:
+ * 1. Iterate over each character in the message.
+ * 2. If the character is a letter, shift it by the corresponding character in the key.
+ * 3. Preserve the case of the letter.
+ * 4. Preserve non-alphabetic characters.
+ * 5. Move to the next character in the key (cyclic).
+ * 6. Return the encrypted message.
+ *
+ * @param message The plaintext message to encrypt.
+ * @param key The keyword used for encryption.
+ * @throws IllegalArgumentException if the key is empty.
+ * @return The encrypted message.
+ */
+ public String encrypt(final String message, final String key) {
+ if (key.isEmpty()) {
+ throw new IllegalArgumentException("Key cannot be empty.");
+ }
+
+ StringBuilder result = new StringBuilder();
+ int j = 0;
+ for (int i = 0; i < message.length(); i++) {
+ char c = message.charAt(i);
+ if (Character.isLetter(c)) {
+ if (Character.isUpperCase(c)) {
+ result.append((char) ((c + key.toUpperCase().charAt(j) - 2 * 'A') % 26 + 'A'));
+ } else {
+ result.append((char) ((c + key.toLowerCase().charAt(j) - 2 * 'a') % 26 + 'a'));
+ }
+ j = ++j % key.length();
+ } else {
+ result.append(c);
+ }
+ }
+ return result.toString();
+ }
+
+ /**
+ * Decrypts a given message encrypted with the Vigenère Cipher using the specified key.
+ * Steps:
+ * 1. Iterate over each character in the message.
+ * 2. If the character is a letter, shift it back by the corresponding character in the key.
+ * 3. Preserve the case of the letter.
+ * 4. Preserve non-alphabetic characters.
+ * 5. Move to the next character in the key (cyclic).
+ * 6. Return the decrypted message.
+ *
+ * @param message The encrypted message to decrypt.
+ * @param key The keyword used for decryption.
+ * @throws IllegalArgumentException if the key is empty.
+ * @return The decrypted plaintext message.
+ */
+ public String decrypt(final String message, final String key) {
+ if (key.isEmpty()) {
+ throw new IllegalArgumentException("Key cannot be empty.");
+ }
+
+ StringBuilder result = new StringBuilder();
+ int j = 0;
+ for (int i = 0; i < message.length(); i++) {
+ char c = message.charAt(i);
+ if (Character.isLetter(c)) {
+ if (Character.isUpperCase(c)) {
+ result.append((char) ('Z' - (25 - (c - key.toUpperCase().charAt(j))) % 26));
+ } else {
+ result.append((char) ('z' - (25 - (c - key.toLowerCase().charAt(j))) % 26));
+ }
+ j = ++j % key.length();
+ } else {
+ result.append(c);
+ }
+ }
+ return result.toString();
+ }
+}
diff --git a/src/main/java/com/thealgorithms/ciphers/XORCipher.java b/src/main/java/com/thealgorithms/ciphers/XORCipher.java
index a612ccfbcdef..41573da774da 100644
--- a/src/main/java/com/thealgorithms/ciphers/XORCipher.java
+++ b/src/main/java/com/thealgorithms/ciphers/XORCipher.java
@@ -1,95 +1,95 @@
-package com.thealgorithms.ciphers;
-
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import java.util.HexFormat;
-
-/**
- * A simple implementation of the XOR cipher that allows both encryption and decryption
- * using a given key. This cipher works by applying the XOR bitwise operation between
- * the bytes of the input text and the corresponding bytes of the key (repeating the key
- * if necessary).
- *
- * Usage:
- * - Encryption: Converts plaintext into a hexadecimal-encoded ciphertext.
- * - Decryption: Converts the hexadecimal ciphertext back into plaintext.
- *
- * Characteristics:
- * - Symmetric: The same key is used for both encryption and decryption.
- * - Simple but vulnerable: XOR encryption is insecure for real-world cryptography,
- * especially when the same key is reused.
- *
- * Example:
- * Plaintext: "Hello!"
- * Key: "key"
- * Encrypted: "27090c03120b"
- * Decrypted: "Hello!"
- *
- * Reference: XOR Cipher - Wikipedia
- *
- * @author lcsjunior
- */
-public final class XORCipher {
-
- // Default character encoding for string conversion
- private static final Charset CS_DEFAULT = StandardCharsets.UTF_8;
-
- private XORCipher() {
- }
-
- /**
- * Applies the XOR operation between the input bytes and the key bytes.
- * If the key is shorter than the input, it wraps around (cyclically).
- *
- * @param inputBytes The input byte array (plaintext or ciphertext).
- * @param keyBytes The key byte array used for XOR operation.
- * @return A new byte array containing the XOR result.
- */
- public static byte[] xor(final byte[] inputBytes, final byte[] keyBytes) {
- byte[] outputBytes = new byte[inputBytes.length];
- for (int i = 0; i < inputBytes.length; ++i) {
- outputBytes[i] = (byte) (inputBytes[i] ^ keyBytes[i % keyBytes.length]);
- }
- return outputBytes;
- }
-
- /**
- * Encrypts the given plaintext using the XOR cipher with the specified key.
- * The result is a hexadecimal-encoded string representing the ciphertext.
- *
- * @param plainText The input plaintext to encrypt.
- * @param key The encryption key.
- * @throws IllegalArgumentException if the key is empty.
- * @return A hexadecimal string representing the encrypted text.
- */
- public static String encrypt(final String plainText, final String key) {
- if (key.isEmpty()) {
- throw new IllegalArgumentException("Key must not be empty");
- }
-
- byte[] plainTextBytes = plainText.getBytes(CS_DEFAULT);
- byte[] keyBytes = key.getBytes(CS_DEFAULT);
- byte[] xorResult = xor(plainTextBytes, keyBytes);
- return HexFormat.of().formatHex(xorResult);
- }
-
- /**
- * Decrypts the given ciphertext (in hexadecimal format) using the XOR cipher
- * with the specified key. The result is the original plaintext.
- *
- * @param cipherText The hexadecimal string representing the encrypted text.
- * @param key The decryption key (must be the same as the encryption key).
- * @throws IllegalArgumentException if the key is empty.
- * @return The decrypted plaintext.
- */
- public static String decrypt(final String cipherText, final String key) {
- if (key.isEmpty()) {
- throw new IllegalArgumentException("Key must not be empty");
- }
-
- byte[] cipherBytes = HexFormat.of().parseHex(cipherText);
- byte[] keyBytes = key.getBytes(CS_DEFAULT);
- byte[] xorResult = xor(cipherBytes, keyBytes);
- return new String(xorResult, CS_DEFAULT);
- }
-}
+package com.thealgorithms.ciphers;
+
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.HexFormat;
+
+/**
+ * A simple implementation of the XOR cipher that allows both encryption and decryption
+ * using a given key. This cipher works by applying the XOR bitwise operation between
+ * the bytes of the input text and the corresponding bytes of the key (repeating the key
+ * if necessary).
+ *
+ * Usage:
+ * - Encryption: Converts plaintext into a hexadecimal-encoded ciphertext.
+ * - Decryption: Converts the hexadecimal ciphertext back into plaintext.
+ *
+ * Characteristics:
+ * - Symmetric: The same key is used for both encryption and decryption.
+ * - Simple but vulnerable: XOR encryption is insecure for real-world cryptography,
+ * especially when the same key is reused.
+ *
+ * Example:
+ * Plaintext: "Hello!"
+ * Key: "key"
+ * Encrypted: "27090c03120b"
+ * Decrypted: "Hello!"
+ *
+ * Reference: XOR Cipher - Wikipedia
+ *
+ * @author lcsjunior
+ */
+public final class XORCipher {
+
+ // Default character encoding for string conversion
+ private static final Charset CS_DEFAULT = StandardCharsets.UTF_8;
+
+ private XORCipher() {
+ }
+
+ /**
+ * Applies the XOR operation between the input bytes and the key bytes.
+ * If the key is shorter than the input, it wraps around (cyclically).
+ *
+ * @param inputBytes The input byte array (plaintext or ciphertext).
+ * @param keyBytes The key byte array used for XOR operation.
+ * @return A new byte array containing the XOR result.
+ */
+ public static byte[] xor(final byte[] inputBytes, final byte[] keyBytes) {
+ byte[] outputBytes = new byte[inputBytes.length];
+ for (int i = 0; i < inputBytes.length; ++i) {
+ outputBytes[i] = (byte) (inputBytes[i] ^ keyBytes[i % keyBytes.length]);
+ }
+ return outputBytes;
+ }
+
+ /**
+ * Encrypts the given plaintext using the XOR cipher with the specified key.
+ * The result is a hexadecimal-encoded string representing the ciphertext.
+ *
+ * @param plainText The input plaintext to encrypt.
+ * @param key The encryption key.
+ * @throws IllegalArgumentException if the key is empty.
+ * @return A hexadecimal string representing the encrypted text.
+ */
+ public static String encrypt(final String plainText, final String key) {
+ if (key.isEmpty()) {
+ throw new IllegalArgumentException("Key must not be empty");
+ }
+
+ byte[] plainTextBytes = plainText.getBytes(CS_DEFAULT);
+ byte[] keyBytes = key.getBytes(CS_DEFAULT);
+ byte[] xorResult = xor(plainTextBytes, keyBytes);
+ return HexFormat.of().formatHex(xorResult);
+ }
+
+ /**
+ * Decrypts the given ciphertext (in hexadecimal format) using the XOR cipher
+ * with the specified key. The result is the original plaintext.
+ *
+ * @param cipherText The hexadecimal string representing the encrypted text.
+ * @param key The decryption key (must be the same as the encryption key).
+ * @throws IllegalArgumentException if the key is empty.
+ * @return The decrypted plaintext.
+ */
+ public static String decrypt(final String cipherText, final String key) {
+ if (key.isEmpty()) {
+ throw new IllegalArgumentException("Key must not be empty");
+ }
+
+ byte[] cipherBytes = HexFormat.of().parseHex(cipherText);
+ byte[] keyBytes = key.getBytes(CS_DEFAULT);
+ byte[] xorResult = xor(cipherBytes, keyBytes);
+ return new String(xorResult, CS_DEFAULT);
+ }
+}
diff --git a/src/main/java/com/thealgorithms/ciphers/a5/A5Cipher.java b/src/main/java/com/thealgorithms/ciphers/a5/A5Cipher.java
index cc2e9105229a..5fa1da513121 100644
--- a/src/main/java/com/thealgorithms/ciphers/a5/A5Cipher.java
+++ b/src/main/java/com/thealgorithms/ciphers/a5/A5Cipher.java
@@ -1,63 +1,63 @@
-package com.thealgorithms.ciphers.a5;
-
-import java.util.BitSet;
-
-/**
- * The A5Cipher class implements the A5/1 stream cipher, which is a widely used
- * encryption algorithm, particularly in mobile communications.
- *
- * This implementation uses a key stream generator to produce a stream of bits
- * that are XORed with the plaintext bits to produce the ciphertext.
- *
- *
- * For more details about the A5/1 algorithm, refer to
- * Wikipedia.
- *
- */
-public class A5Cipher {
-
- private final A5KeyStreamGenerator keyStreamGenerator;
- private static final int KEY_STREAM_LENGTH = 228; // Length of the key stream in bits (28.5 bytes)
-
- /**
- * Constructs an A5Cipher instance with the specified session key and frame counter.
- *
- * @param sessionKey a BitSet representing the session key used for encryption.
- * @param frameCounter a BitSet representing the frame counter that helps in key stream generation.
- */
- public A5Cipher(BitSet sessionKey, BitSet frameCounter) {
- keyStreamGenerator = new A5KeyStreamGenerator();
- keyStreamGenerator.initialize(sessionKey, frameCounter);
- }
-
- /**
- * Encrypts the given plaintext bits using the A5/1 cipher algorithm.
- *
- * This method generates a key stream and XORs it with the provided plaintext
- * bits to produce the ciphertext.
- *
- * @param plainTextBits a BitSet representing the plaintext bits to be encrypted.
- * @return a BitSet containing the encrypted ciphertext bits.
- */
- public BitSet encrypt(BitSet plainTextBits) {
- // create a copy
- var result = new BitSet(KEY_STREAM_LENGTH);
- result.xor(plainTextBits);
-
- var key = keyStreamGenerator.getNextKeyStream();
- result.xor(key);
-
- return result;
- }
-
- /**
- * Resets the internal counter of the key stream generator.
- *
- * This method can be called to re-initialize the state of the key stream
- * generator, allowing for new key streams to be generated for subsequent
- * encryptions.
- */
- public void resetCounter() {
- keyStreamGenerator.reInitialize();
- }
-}
+package com.thealgorithms.ciphers.a5;
+
+import java.util.BitSet;
+
+/**
+ * The A5Cipher class implements the A5/1 stream cipher, which is a widely used
+ * encryption algorithm, particularly in mobile communications.
+ *
+ * This implementation uses a key stream generator to produce a stream of bits
+ * that are XORed with the plaintext bits to produce the ciphertext.
+ *
+ *
+ * For more details about the A5/1 algorithm, refer to
+ * Wikipedia.
+ *
+ */
+public class A5Cipher {
+
+ private final A5KeyStreamGenerator keyStreamGenerator;
+ private static final int KEY_STREAM_LENGTH = 228; // Length of the key stream in bits (28.5 bytes)
+
+ /**
+ * Constructs an A5Cipher instance with the specified session key and frame counter.
+ *
+ * @param sessionKey a BitSet representing the session key used for encryption.
+ * @param frameCounter a BitSet representing the frame counter that helps in key stream generation.
+ */
+ public A5Cipher(BitSet sessionKey, BitSet frameCounter) {
+ keyStreamGenerator = new A5KeyStreamGenerator();
+ keyStreamGenerator.initialize(sessionKey, frameCounter);
+ }
+
+ /**
+ * Encrypts the given plaintext bits using the A5/1 cipher algorithm.
+ *
+ * This method generates a key stream and XORs it with the provided plaintext
+ * bits to produce the ciphertext.
+ *
+ * @param plainTextBits a BitSet representing the plaintext bits to be encrypted.
+ * @return a BitSet containing the encrypted ciphertext bits.
+ */
+ public BitSet encrypt(BitSet plainTextBits) {
+ // create a copy
+ var result = new BitSet(KEY_STREAM_LENGTH);
+ result.xor(plainTextBits);
+
+ var key = keyStreamGenerator.getNextKeyStream();
+ result.xor(key);
+
+ return result;
+ }
+
+ /**
+ * Resets the internal counter of the key stream generator.
+ *
+ * This method can be called to re-initialize the state of the key stream
+ * generator, allowing for new key streams to be generated for subsequent
+ * encryptions.
+ */
+ public void resetCounter() {
+ keyStreamGenerator.reInitialize();
+ }
+}
diff --git a/src/main/java/com/thealgorithms/ciphers/a5/A5KeyStreamGenerator.java b/src/main/java/com/thealgorithms/ciphers/a5/A5KeyStreamGenerator.java
index ee837ef4241a..de29845fa75c 100644
--- a/src/main/java/com/thealgorithms/ciphers/a5/A5KeyStreamGenerator.java
+++ b/src/main/java/com/thealgorithms/ciphers/a5/A5KeyStreamGenerator.java
@@ -1,121 +1,121 @@
-package com.thealgorithms.ciphers.a5;
-
-import java.util.BitSet;
-
-/**
- * The A5KeyStreamGenerator class is responsible for generating key streams
- * for the A5/1 encryption algorithm using a combination of Linear Feedback Shift Registers (LFSRs).
- *
- *
- * This class extends the CompositeLFSR and initializes a set of LFSRs with
- * a session key and a frame counter to produce a pseudo-random key stream.
- *
- *
- *
- * Note: Proper exception handling for invalid usage is to be implemented.
- *
- */
-public class A5KeyStreamGenerator extends CompositeLFSR {
-
- private BitSet initialFrameCounter;
- private BitSet frameCounter;
- private BitSet sessionKey;
- private static final int INITIAL_CLOCKING_CYCLES = 100;
- private static final int KEY_STREAM_LENGTH = 228;
-
- /**
- * Initializes the A5KeyStreamGenerator with the specified session key and frame counter.
- *
- *
- * This method sets up the internal state of the LFSRs using the provided
- * session key and frame counter. It creates three LFSRs with specific
- * configurations and initializes them.
- *
- *
- * @param sessionKey a BitSet representing the session key used for key stream generation.
- * @param frameCounter a BitSet representing the frame counter that influences the key stream.
- */
- @Override
- public void initialize(BitSet sessionKey, BitSet frameCounter) {
- this.sessionKey = sessionKey;
- this.frameCounter = (BitSet) frameCounter.clone();
- this.initialFrameCounter = (BitSet) frameCounter.clone();
- registers.clear();
- LFSR lfsr1 = new LFSR(19, 8, new int[] {13, 16, 17, 18});
- LFSR lfsr2 = new LFSR(22, 10, new int[] {20, 21});
- LFSR lfsr3 = new LFSR(23, 10, new int[] {7, 20, 21, 22});
- registers.add(lfsr1);
- registers.add(lfsr2);
- registers.add(lfsr3);
- registers.forEach(lfsr -> lfsr.initialize(sessionKey, frameCounter));
- }
-
- /**
- * Re-initializes the key stream generator with the original session key
- * and frame counter. This method restores the generator to its initial
- * state.
- */
- public void reInitialize() {
- this.initialize(sessionKey, initialFrameCounter);
- }
-
- /**
- * Generates the next key stream of bits.
- *
- *
- * This method performs an initial set of clocking cycles and then retrieves
- * a key stream of the specified length. After generation, it re-initializes
- * the internal registers.
- *
- *
- * @return a BitSet containing the generated key stream bits.
- */
- public BitSet getNextKeyStream() {
- for (int cycle = 1; cycle <= INITIAL_CLOCKING_CYCLES; ++cycle) {
- this.clock();
- }
-
- BitSet result = new BitSet(KEY_STREAM_LENGTH);
- for (int cycle = 1; cycle <= KEY_STREAM_LENGTH; ++cycle) {
- boolean outputBit = this.clock();
- result.set(cycle - 1, outputBit);
- }
-
- reInitializeRegisters();
- return result;
- }
-
- /**
- * Re-initializes the registers for the LFSRs.
- *
- *
- * This method increments the frame counter and re-initializes each LFSR
- * with the current session key and frame counter.
- *
- */
- private void reInitializeRegisters() {
- incrementFrameCounter();
- registers.forEach(lfsr -> lfsr.initialize(sessionKey, frameCounter));
- }
-
- /**
- * Increments the current frame counter.
- *
- *
- * This method uses a utility function to increment the frame counter,
- * which influences the key stream generation process.
- *
- */
- private void incrementFrameCounter() {
- Utils.increment(frameCounter, FRAME_COUNTER_LENGTH);
- }
-
- /**
- * Retrieves the current frame counter.
- *
- * @return a BitSet representing the current state of the frame counter.
- */
- public BitSet getFrameCounter() {
- return frameCounter;
- }
-}
+package com.thealgorithms.ciphers.a5;
+
+import java.util.BitSet;
+
+/**
+ * The A5KeyStreamGenerator class is responsible for generating key streams
+ * for the A5/1 encryption algorithm using a combination of Linear Feedback Shift Registers (LFSRs).
+ *
+ *
+ * This class extends the CompositeLFSR and initializes a set of LFSRs with
+ * a session key and a frame counter to produce a pseudo-random key stream.
+ *
+ *
+ *
+ * Note: Proper exception handling for invalid usage is to be implemented.
+ *
+ */
+public class A5KeyStreamGenerator extends CompositeLFSR {
+
+ private BitSet initialFrameCounter;
+ private BitSet frameCounter;
+ private BitSet sessionKey;
+ private static final int INITIAL_CLOCKING_CYCLES = 100;
+ private static final int KEY_STREAM_LENGTH = 228;
+
+ /**
+ * Initializes the A5KeyStreamGenerator with the specified session key and frame counter.
+ *
+ *
+ * This method sets up the internal state of the LFSRs using the provided
+ * session key and frame counter. It creates three LFSRs with specific
+ * configurations and initializes them.
+ *
+ *
+ * @param sessionKey a BitSet representing the session key used for key stream generation.
+ * @param frameCounter a BitSet representing the frame counter that influences the key stream.
+ */
+ @Override
+ public void initialize(BitSet sessionKey, BitSet frameCounter) {
+ this.sessionKey = sessionKey;
+ this.frameCounter = (BitSet) frameCounter.clone();
+ this.initialFrameCounter = (BitSet) frameCounter.clone();
+ registers.clear();
+ LFSR lfsr1 = new LFSR(19, 8, new int[] {13, 16, 17, 18});
+ LFSR lfsr2 = new LFSR(22, 10, new int[] {20, 21});
+ LFSR lfsr3 = new LFSR(23, 10, new int[] {7, 20, 21, 22});
+ registers.add(lfsr1);
+ registers.add(lfsr2);
+ registers.add(lfsr3);
+ registers.forEach(lfsr -> lfsr.initialize(sessionKey, frameCounter));
+ }
+
+ /**
+ * Re-initializes the key stream generator with the original session key
+ * and frame counter. This method restores the generator to its initial
+ * state.
+ */
+ public void reInitialize() {
+ this.initialize(sessionKey, initialFrameCounter);
+ }
+
+ /**
+ * Generates the next key stream of bits.
+ *
+ *
+ * This method performs an initial set of clocking cycles and then retrieves
+ * a key stream of the specified length. After generation, it re-initializes
+ * the internal registers.
+ *
+ *
+ * @return a BitSet containing the generated key stream bits.
+ */
+ public BitSet getNextKeyStream() {
+ for (int cycle = 1; cycle <= INITIAL_CLOCKING_CYCLES; ++cycle) {
+ this.clock();
+ }
+
+ BitSet result = new BitSet(KEY_STREAM_LENGTH);
+ for (int cycle = 1; cycle <= KEY_STREAM_LENGTH; ++cycle) {
+ boolean outputBit = this.clock();
+ result.set(cycle - 1, outputBit);
+ }
+
+ reInitializeRegisters();
+ return result;
+ }
+
+ /**
+ * Re-initializes the registers for the LFSRs.
+ *
+ *
+ * This method increments the frame counter and re-initializes each LFSR
+ * with the current session key and frame counter.
+ *
+ */
+ private void reInitializeRegisters() {
+ incrementFrameCounter();
+ registers.forEach(lfsr -> lfsr.initialize(sessionKey, frameCounter));
+ }
+
+ /**
+ * Increments the current frame counter.
+ *
+ *
+ * This method uses a utility function to increment the frame counter,
+ * which influences the key stream generation process.
+ *
+ */
+ private void incrementFrameCounter() {
+ Utils.increment(frameCounter, FRAME_COUNTER_LENGTH);
+ }
+
+ /**
+ * Retrieves the current frame counter.
+ *
+ * @return a BitSet representing the current state of the frame counter.
+ */
+ public BitSet getFrameCounter() {
+ return frameCounter;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/ciphers/a5/BaseLFSR.java b/src/main/java/com/thealgorithms/ciphers/a5/BaseLFSR.java
index 18ad913784dc..4a1fadd3a83f 100644
--- a/src/main/java/com/thealgorithms/ciphers/a5/BaseLFSR.java
+++ b/src/main/java/com/thealgorithms/ciphers/a5/BaseLFSR.java
@@ -1,10 +1,10 @@
-package com.thealgorithms.ciphers.a5;
-
-import java.util.BitSet;
-
-public interface BaseLFSR {
- void initialize(BitSet sessionKey, BitSet frameCounter);
- boolean clock();
- int SESSION_KEY_LENGTH = 64;
- int FRAME_COUNTER_LENGTH = 22;
-}
+package com.thealgorithms.ciphers.a5;
+
+import java.util.BitSet;
+
+public interface BaseLFSR {
+ void initialize(BitSet sessionKey, BitSet frameCounter);
+ boolean clock();
+ int SESSION_KEY_LENGTH = 64;
+ int FRAME_COUNTER_LENGTH = 22;
+}
diff --git a/src/main/java/com/thealgorithms/ciphers/a5/CompositeLFSR.java b/src/main/java/com/thealgorithms/ciphers/a5/CompositeLFSR.java
index 029a93848c28..164699b3d77c 100644
--- a/src/main/java/com/thealgorithms/ciphers/a5/CompositeLFSR.java
+++ b/src/main/java/com/thealgorithms/ciphers/a5/CompositeLFSR.java
@@ -1,69 +1,69 @@
-package com.thealgorithms.ciphers.a5;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
-
-/**
- * The CompositeLFSR class represents a composite implementation of
- * Linear Feedback Shift Registers (LFSRs) for cryptographic purposes.
- *
- *
- * This abstract class manages a collection of LFSR instances and
- * provides a mechanism for irregular clocking based on the
- * majority bit among the registers. It implements the BaseLFSR
- * interface, requiring subclasses to define specific LFSR behaviors.
- *
- */
-public abstract class CompositeLFSR implements BaseLFSR {
-
- protected final List registers = new ArrayList<>();
-
- /**
- * Performs a clocking operation on the composite LFSR.
- *
- *
- * This method determines the majority bit across all registers and
- * clocks each register based on its clock bit. If a register's
- * clock bit matches the majority bit, it is clocked (shifted).
- * The method also computes and returns the XOR of the last bits
- * of all registers.
- *
- *
- * @return the XOR value of the last bits of all registers.
- */
- @Override
- public boolean clock() {
- boolean majorityBit = getMajorityBit();
- boolean result = false;
- for (var register : registers) {
- result ^= register.getLastBit();
- if (register.getClockBit() == majorityBit) {
- register.clock();
- }
- }
- return result;
- }
-
- /**
- * Calculates the majority bit among all registers.
- *
- *
- * This private method counts the number of true and false clock bits
- * across all LFSR registers. It returns true if the count of true
- * bits is greater than or equal to the count of false bits; otherwise,
- * it returns false.
- *
- *
- * @return true if the majority clock bits are true; false otherwise.
- */
- private boolean getMajorityBit() {
- Map bitCount = new TreeMap<>();
- bitCount.put(Boolean.FALSE, 0);
- bitCount.put(Boolean.TRUE, 0);
-
- registers.forEach(lfsr -> bitCount.put(lfsr.getClockBit(), bitCount.get(lfsr.getClockBit()) + 1));
- return bitCount.get(Boolean.FALSE) <= bitCount.get(Boolean.TRUE);
- }
-}
+package com.thealgorithms.ciphers.a5;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * The CompositeLFSR class represents a composite implementation of
+ * Linear Feedback Shift Registers (LFSRs) for cryptographic purposes.
+ *
+ *
+ * This abstract class manages a collection of LFSR instances and
+ * provides a mechanism for irregular clocking based on the
+ * majority bit among the registers. It implements the BaseLFSR
+ * interface, requiring subclasses to define specific LFSR behaviors.
+ *
+ */
+public abstract class CompositeLFSR implements BaseLFSR {
+
+ protected final List registers = new ArrayList<>();
+
+ /**
+ * Performs a clocking operation on the composite LFSR.
+ *
+ *
+ * This method determines the majority bit across all registers and
+ * clocks each register based on its clock bit. If a register's
+ * clock bit matches the majority bit, it is clocked (shifted).
+ * The method also computes and returns the XOR of the last bits
+ * of all registers.
+ *
+ *
+ * @return the XOR value of the last bits of all registers.
+ */
+ @Override
+ public boolean clock() {
+ boolean majorityBit = getMajorityBit();
+ boolean result = false;
+ for (var register : registers) {
+ result ^= register.getLastBit();
+ if (register.getClockBit() == majorityBit) {
+ register.clock();
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Calculates the majority bit among all registers.
+ *
+ *
+ * This private method counts the number of true and false clock bits
+ * across all LFSR registers. It returns true if the count of true
+ * bits is greater than or equal to the count of false bits; otherwise,
+ * it returns false.
+ *
+ *
+ * @return true if the majority clock bits are true; false otherwise.
+ */
+ private boolean getMajorityBit() {
+ Map bitCount = new TreeMap<>();
+ bitCount.put(Boolean.FALSE, 0);
+ bitCount.put(Boolean.TRUE, 0);
+
+ registers.forEach(lfsr -> bitCount.put(lfsr.getClockBit(), bitCount.get(lfsr.getClockBit()) + 1));
+ return bitCount.get(Boolean.FALSE) <= bitCount.get(Boolean.TRUE);
+ }
+}
diff --git a/src/main/java/com/thealgorithms/ciphers/a5/LFSR.java b/src/main/java/com/thealgorithms/ciphers/a5/LFSR.java
index dc42ae0a7a5e..f8e213398d4e 100644
--- a/src/main/java/com/thealgorithms/ciphers/a5/LFSR.java
+++ b/src/main/java/com/thealgorithms/ciphers/a5/LFSR.java
@@ -1,79 +1,79 @@
-package com.thealgorithms.ciphers.a5;
-
-import java.util.BitSet;
-
-public class LFSR implements BaseLFSR {
-
- private final BitSet register;
- private final int length;
- private final int clockBitIndex;
- private final int[] tappingBitsIndices;
-
- public LFSR(int length, int clockBitIndex, int[] tappingBitsIndices) {
- this.length = length;
- this.clockBitIndex = clockBitIndex;
- this.tappingBitsIndices = tappingBitsIndices;
- register = new BitSet(length);
- }
-
- @Override
- public void initialize(BitSet sessionKey, BitSet frameCounter) {
- register.clear();
- clock(sessionKey, SESSION_KEY_LENGTH);
- clock(frameCounter, FRAME_COUNTER_LENGTH);
- }
-
- private void clock(BitSet key, int keyLength) {
- // We start from reverse because LFSR 0 index is the left most bit
- // while key 0 index is right most bit, so we reverse it
- for (int i = keyLength - 1; i >= 0; --i) {
- var newBit = key.get(i) ^ xorTappingBits();
- pushBit(newBit);
- }
- }
-
- @Override
- public boolean clock() {
- return pushBit(xorTappingBits());
- }
-
- public boolean getClockBit() {
- return register.get(clockBitIndex);
- }
-
- public boolean get(int bitIndex) {
- return register.get(bitIndex);
- }
-
- public boolean getLastBit() {
- return register.get(length - 1);
- }
-
- private boolean xorTappingBits() {
- boolean result = false;
- for (int i : tappingBitsIndices) {
- result ^= register.get(i);
- }
- return result;
- }
-
- private boolean pushBit(boolean bit) {
- boolean discardedBit = rightShift();
- register.set(0, bit);
- return discardedBit;
- }
-
- private boolean rightShift() {
- boolean discardedBit = get(length - 1);
- for (int i = length - 1; i > 0; --i) {
- register.set(i, get(i - 1));
- }
- register.set(0, false);
- return discardedBit;
- }
-
- @Override
- public String toString() {
- return register.toString();
- }
-}
+package com.thealgorithms.ciphers.a5;
+
+import java.util.BitSet;
+
+public class LFSR implements BaseLFSR {
+
+ private final BitSet register;
+ private final int length;
+ private final int clockBitIndex;
+ private final int[] tappingBitsIndices;
+
+ public LFSR(int length, int clockBitIndex, int[] tappingBitsIndices) {
+ this.length = length;
+ this.clockBitIndex = clockBitIndex;
+ this.tappingBitsIndices = tappingBitsIndices;
+ register = new BitSet(length);
+ }
+
+ @Override
+ public void initialize(BitSet sessionKey, BitSet frameCounter) {
+ register.clear();
+ clock(sessionKey, SESSION_KEY_LENGTH);
+ clock(frameCounter, FRAME_COUNTER_LENGTH);
+ }
+
+ private void clock(BitSet key, int keyLength) {
+ // We start from reverse because LFSR 0 index is the left most bit
+ // while key 0 index is right most bit, so we reverse it
+ for (int i = keyLength - 1; i >= 0; --i) {
+ var newBit = key.get(i) ^ xorTappingBits();
+ pushBit(newBit);
+ }
+ }
+
+ @Override
+ public boolean clock() {
+ return pushBit(xorTappingBits());
+ }
+
+ public boolean getClockBit() {
+ return register.get(clockBitIndex);
+ }
+
+ public boolean get(int bitIndex) {
+ return register.get(bitIndex);
+ }
+
+ public boolean getLastBit() {
+ return register.get(length - 1);
+ }
+
+ private boolean xorTappingBits() {
+ boolean result = false;
+ for (int i : tappingBitsIndices) {
+ result ^= register.get(i);
+ }
+ return result;
+ }
+
+ private boolean pushBit(boolean bit) {
+ boolean discardedBit = rightShift();
+ register.set(0, bit);
+ return discardedBit;
+ }
+
+ private boolean rightShift() {
+ boolean discardedBit = get(length - 1);
+ for (int i = length - 1; i > 0; --i) {
+ register.set(i, get(i - 1));
+ }
+ register.set(0, false);
+ return discardedBit;
+ }
+
+ @Override
+ public String toString() {
+ return register.toString();
+ }
+}
diff --git a/src/main/java/com/thealgorithms/ciphers/a5/Utils.java b/src/main/java/com/thealgorithms/ciphers/a5/Utils.java
index b4addf18dd9d..d67eaebe97c5 100644
--- a/src/main/java/com/thealgorithms/ciphers/a5/Utils.java
+++ b/src/main/java/com/thealgorithms/ciphers/a5/Utils.java
@@ -1,25 +1,25 @@
-package com.thealgorithms.ciphers.a5;
-
-// Source
-// http://www.java2s.com/example/java-utility-method/bitset/increment-bitset-bits-int-size-9fd84.html
-// package com.java2s;
-// License from project: Open Source License
-
-import java.util.BitSet;
-
-public final class Utils {
- private Utils() {
- }
-
- public static boolean increment(BitSet bits, int size) {
- int i = size - 1;
- while (i >= 0 && bits.get(i)) {
- bits.set(i--, false); /*from w w w . j a v a 2s .c o m*/
- }
- if (i < 0) {
- return false;
- }
- bits.set(i, true);
- return true;
- }
-}
+package com.thealgorithms.ciphers.a5;
+
+// Source
+// http://www.java2s.com/example/java-utility-method/bitset/increment-bitset-bits-int-size-9fd84.html
+// package com.java2s;
+// License from project: Open Source License
+
+import java.util.BitSet;
+
+public final class Utils {
+ private Utils() {
+ }
+
+ public static boolean increment(BitSet bits, int size) {
+ int i = size - 1;
+ while (i >= 0 && bits.get(i)) {
+ bits.set(i--, false); /*from w w w . j a v a 2s .c o m*/
+ }
+ if (i < 0) {
+ return false;
+ }
+ bits.set(i, true);
+ return true;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/compression/ArithmeticCoding.java b/src/main/java/com/thealgorithms/compression/ArithmeticCoding.java
index b5ccf359d1be..8c825b45f3da 100644
--- a/src/main/java/com/thealgorithms/compression/ArithmeticCoding.java
+++ b/src/main/java/com/thealgorithms/compression/ArithmeticCoding.java
@@ -1,157 +1,157 @@
-package com.thealgorithms.compression;
-
-import java.math.BigDecimal;
-import java.math.MathContext;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * An implementation of the Arithmetic Coding algorithm.
- *
- *
- * Arithmetic coding is a form of entropy encoding used in lossless data
- * compression. It encodes an entire message into a single number, a fraction n
- * where (0.0 <= n < 1.0). Unlike Huffman coding, which assigns a specific
- * bit sequence to each symbol, arithmetic coding represents the message as a
- * sub-interval of the [0, 1) interval.
- *
- *
- *
- * This implementation uses BigDecimal for precision to handle the shrinking
- * intervals, making it suitable for educational purposes to demonstrate the
- * core logic.
- *
- *
- *
- * Time Complexity: O(n*m) for compression and decompression where n is the
- * length of the input and m is the number of unique symbols, due to the need
- * to calculate symbol probabilities.
- *
- *
- *
- * References:
- *
- *
- */
-public final class ArithmeticCoding {
-
- private ArithmeticCoding() {
- }
-
- /**
- * Compresses a string using the Arithmetic Coding algorithm.
- *
- * @param uncompressed The string to be compressed.
- * @return The compressed representation as a BigDecimal number.
- * @throws IllegalArgumentException if the input string is null or empty.
- */
- public static BigDecimal compress(String uncompressed) {
- if (uncompressed == null || uncompressed.isEmpty()) {
- throw new IllegalArgumentException("Input string cannot be null or empty.");
- }
-
- Map probabilityTable = calculateProbabilities(uncompressed);
-
- BigDecimal low = BigDecimal.ZERO;
- BigDecimal high = BigDecimal.ONE;
-
- for (char symbol : uncompressed.toCharArray()) {
- BigDecimal range = high.subtract(low);
- Symbol sym = probabilityTable.get(symbol);
-
- high = low.add(range.multiply(sym.high()));
- low = low.add(range.multiply(sym.low()));
- }
-
- return low; // Return the lower bound of the final interval
- }
-
- /**
- * Decompresses a BigDecimal number back into the original string.
- *
- * @param compressed The compressed BigDecimal number.
- * @param length The length of the original uncompressed string.
- * @param probabilityTable The probability table used during compression.
- * @return The original, uncompressed string.
- */
- public static String decompress(BigDecimal compressed, int length, Map probabilityTable) {
- StringBuilder decompressed = new StringBuilder();
-
- // Create a sorted list of symbols for deterministic decompression, matching the
- // order used in calculateProbabilities
- List> sortedSymbols = new ArrayList<>(probabilityTable.entrySet());
- sortedSymbols.sort(Map.Entry.comparingByKey());
-
- BigDecimal low = BigDecimal.ZERO;
- BigDecimal high = BigDecimal.ONE;
-
- for (int i = 0; i < length; i++) {
- BigDecimal range = high.subtract(low);
-
- // Find which symbol the compressed value falls into
- for (Map.Entry entry : sortedSymbols) {
- Symbol sym = entry.getValue();
-
- // Calculate the actual range for this symbol in the current interval
- BigDecimal symLow = low.add(range.multiply(sym.low()));
- BigDecimal symHigh = low.add(range.multiply(sym.high()));
-
- // Check if the compressed value falls within this symbol's range
- if (compressed.compareTo(symLow) >= 0 && compressed.compareTo(symHigh) < 0) {
- decompressed.append(entry.getKey());
-
- // Update the interval for the next iteration
- low = symLow;
- high = symHigh;
- break;
- }
- }
- }
-
- return decompressed.toString();
- }
-
- /**
- * Calculates the frequency and probability range for each character in the
- * input string in a deterministic order.
- *
- * @param text The input string.
- * @return A map from each character to a Symbol object containing its
- * probability range.
- */
- public static Map calculateProbabilities(String text) {
- Map frequencies = new HashMap<>();
- for (char c : text.toCharArray()) {
- frequencies.put(c, frequencies.getOrDefault(c, 0) + 1);
- }
-
- // Sort the characters to ensure a deterministic order for the probability table
- List sortedKeys = new ArrayList<>(frequencies.keySet());
- Collections.sort(sortedKeys);
-
- Map probabilityTable = new HashMap<>();
- BigDecimal currentLow = BigDecimal.ZERO;
- int total = text.length();
-
- for (char symbol : sortedKeys) {
- BigDecimal probability = BigDecimal.valueOf(frequencies.get(symbol)).divide(BigDecimal.valueOf(total), MathContext.DECIMAL128);
- BigDecimal high = currentLow.add(probability);
- probabilityTable.put(symbol, new Symbol(currentLow, high));
- currentLow = high;
- }
-
- return probabilityTable;
- }
-
- /**
- * Helper class to store the probability range [low, high) for a symbol.
- */
- public record Symbol(BigDecimal low, BigDecimal high) {
- }
-}
+package com.thealgorithms.compression;
+
+import java.math.BigDecimal;
+import java.math.MathContext;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * An implementation of the Arithmetic Coding algorithm.
+ *
+ *
+ * Arithmetic coding is a form of entropy encoding used in lossless data
+ * compression. It encodes an entire message into a single number, a fraction n
+ * where (0.0 <= n < 1.0). Unlike Huffman coding, which assigns a specific
+ * bit sequence to each symbol, arithmetic coding represents the message as a
+ * sub-interval of the [0, 1) interval.
+ *
+ *
+ *
+ * This implementation uses BigDecimal for precision to handle the shrinking
+ * intervals, making it suitable for educational purposes to demonstrate the
+ * core logic.
+ *
+ *
+ *
+ * Time Complexity: O(n*m) for compression and decompression where n is the
+ * length of the input and m is the number of unique symbols, due to the need
+ * to calculate symbol probabilities.
+ *
+ *
+ *
+ * References:
+ *
+ *
+ */
+public final class ArithmeticCoding {
+
+ private ArithmeticCoding() {
+ }
+
+ /**
+ * Compresses a string using the Arithmetic Coding algorithm.
+ *
+ * @param uncompressed The string to be compressed.
+ * @return The compressed representation as a BigDecimal number.
+ * @throws IllegalArgumentException if the input string is null or empty.
+ */
+ public static BigDecimal compress(String uncompressed) {
+ if (uncompressed == null || uncompressed.isEmpty()) {
+ throw new IllegalArgumentException("Input string cannot be null or empty.");
+ }
+
+ Map probabilityTable = calculateProbabilities(uncompressed);
+
+ BigDecimal low = BigDecimal.ZERO;
+ BigDecimal high = BigDecimal.ONE;
+
+ for (char symbol : uncompressed.toCharArray()) {
+ BigDecimal range = high.subtract(low);
+ Symbol sym = probabilityTable.get(symbol);
+
+ high = low.add(range.multiply(sym.high()));
+ low = low.add(range.multiply(sym.low()));
+ }
+
+ return low; // Return the lower bound of the final interval
+ }
+
+ /**
+ * Decompresses a BigDecimal number back into the original string.
+ *
+ * @param compressed The compressed BigDecimal number.
+ * @param length The length of the original uncompressed string.
+ * @param probabilityTable The probability table used during compression.
+ * @return The original, uncompressed string.
+ */
+ public static String decompress(BigDecimal compressed, int length, Map probabilityTable) {
+ StringBuilder decompressed = new StringBuilder();
+
+ // Create a sorted list of symbols for deterministic decompression, matching the
+ // order used in calculateProbabilities
+ List> sortedSymbols = new ArrayList<>(probabilityTable.entrySet());
+ sortedSymbols.sort(Map.Entry.comparingByKey());
+
+ BigDecimal low = BigDecimal.ZERO;
+ BigDecimal high = BigDecimal.ONE;
+
+ for (int i = 0; i < length; i++) {
+ BigDecimal range = high.subtract(low);
+
+ // Find which symbol the compressed value falls into
+ for (Map.Entry entry : sortedSymbols) {
+ Symbol sym = entry.getValue();
+
+ // Calculate the actual range for this symbol in the current interval
+ BigDecimal symLow = low.add(range.multiply(sym.low()));
+ BigDecimal symHigh = low.add(range.multiply(sym.high()));
+
+ // Check if the compressed value falls within this symbol's range
+ if (compressed.compareTo(symLow) >= 0 && compressed.compareTo(symHigh) < 0) {
+ decompressed.append(entry.getKey());
+
+ // Update the interval for the next iteration
+ low = symLow;
+ high = symHigh;
+ break;
+ }
+ }
+ }
+
+ return decompressed.toString();
+ }
+
+ /**
+ * Calculates the frequency and probability range for each character in the
+ * input string in a deterministic order.
+ *
+ * @param text The input string.
+ * @return A map from each character to a Symbol object containing its
+ * probability range.
+ */
+ public static Map calculateProbabilities(String text) {
+ Map frequencies = new HashMap<>();
+ for (char c : text.toCharArray()) {
+ frequencies.put(c, frequencies.getOrDefault(c, 0) + 1);
+ }
+
+ // Sort the characters to ensure a deterministic order for the probability table
+ List sortedKeys = new ArrayList<>(frequencies.keySet());
+ Collections.sort(sortedKeys);
+
+ Map probabilityTable = new HashMap<>();
+ BigDecimal currentLow = BigDecimal.ZERO;
+ int total = text.length();
+
+ for (char symbol : sortedKeys) {
+ BigDecimal probability = BigDecimal.valueOf(frequencies.get(symbol)).divide(BigDecimal.valueOf(total), MathContext.DECIMAL128);
+ BigDecimal high = currentLow.add(probability);
+ probabilityTable.put(symbol, new Symbol(currentLow, high));
+ currentLow = high;
+ }
+
+ return probabilityTable;
+ }
+
+ /**
+ * Helper class to store the probability range [low, high) for a symbol.
+ */
+ public record Symbol(BigDecimal low, BigDecimal high) {
+ }
+}
diff --git a/src/main/java/com/thealgorithms/compression/BurrowsWheelerTransform.java b/src/main/java/com/thealgorithms/compression/BurrowsWheelerTransform.java
index a148517e5b55..8d6c84eaa2e0 100644
--- a/src/main/java/com/thealgorithms/compression/BurrowsWheelerTransform.java
+++ b/src/main/java/com/thealgorithms/compression/BurrowsWheelerTransform.java
@@ -1,220 +1,220 @@
-package com.thealgorithms.compression;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Implementation of the Burrows-Wheeler Transform (BWT) and its inverse.
- *
- * BWT is a reversible data transformation algorithm that rearranges a string into runs of
- * similar characters. While not a compression algorithm itself, it significantly improves
- * the compressibility of data for subsequent algorithms like Move-to-Front encoding and
- * Run-Length Encoding.
- *
- *
- * The transform works by:
- *
- * - Generating all rotations of the input string
- * - Sorting these rotations lexicographically
- * - Taking the last column of the sorted matrix as output
- * - Recording the index of the original string in the sorted matrix
- *
- *
- *
- * Important: The input string should end with a unique end-of-string marker
- * (typically '$') that:
- *
- * - Does not appear anywhere else in the text
- * - Is lexicographically smaller than all other characters
- * - Ensures unique rotations and enables correct inverse transformation
- *
- * Without this marker, the inverse transform may not correctly reconstruct the original string.
- *
- *
- * Time Complexity:
- *
- * - Forward transform: O(n² log n) where n is the string length
- * - Inverse transform: O(n) using the LF-mapping technique
- *
- *
- *
- * Example:
- *
- * Input: "banana$"
- * Output: BWTResult("annb$aa", 4)
- * - "annb$aa" is the transformed string (groups similar characters)
- * - 4 is the index of the original string in the sorted rotations
- *
- *
- * @see Burrows–Wheeler transform (Wikipedia)
- */
-public final class BurrowsWheelerTransform {
-
- private BurrowsWheelerTransform() {
- }
-
- /**
- * A container for the result of the forward BWT.
- *
- * Contains the transformed string and the index of the original string
- * in the sorted rotations matrix, both of which are required for the
- * inverse transformation.
- *
- */
- public static class BWTResult {
- /** The transformed string (last column of the sorted rotation matrix) */
- public final String transformed;
-
- /** The index of the original string in the sorted rotations matrix */
- public final int originalIndex;
-
- /**
- * Constructs a BWTResult with the transformed string and original index.
- *
- * @param transformed the transformed string (L-column)
- * @param originalIndex the index of the original string in sorted rotations
- */
- public BWTResult(String transformed, int originalIndex) {
- this.transformed = transformed;
- this.originalIndex = originalIndex;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null || getClass() != obj.getClass()) {
- return false;
- }
- BWTResult bwtResult = (BWTResult) obj;
- return originalIndex == bwtResult.originalIndex && transformed.equals(bwtResult.transformed);
- }
-
- @Override
- public int hashCode() {
- return 31 * transformed.hashCode() + originalIndex;
- }
-
- @Override
- public String toString() {
- return "BWTResult[transformed=" + transformed + ", originalIndex=" + originalIndex + "]";
- }
- }
-
- /**
- * Performs the forward Burrows-Wheeler Transform on the input string.
- *
- * The algorithm generates all cyclic rotations of the input, sorts them
- * lexicographically, and returns the last column of this sorted matrix
- * along with the position of the original string.
- *
- *
- * Note: It is strongly recommended that the input string ends with
- * a unique end-of-string marker (e.g., '$') that is lexicographically smaller
- * than any other character in the string. This ensures correct inversion.
- *
- * @param text the input string to transform; must not be {@code null}
- * @return a {@link BWTResult} object containing the transformed string (L-column)
- * and the index of the original string in the sorted rotations matrix;
- * returns {@code BWTResult("", -1)} for empty input
- * @throws NullPointerException if {@code text} is {@code null}
- */
- public static BWTResult transform(String text) {
- if (text == null || text.isEmpty()) {
- return new BWTResult("", -1);
- }
-
- int n = text.length();
-
- // Generate all rotations of the input string
- String[] rotations = new String[n];
- for (int i = 0; i < n; i++) {
- rotations[i] = text.substring(i) + text.substring(0, i);
- }
-
- // Sort rotations lexicographically
- Arrays.sort(rotations);
- int originalIndex = Arrays.binarySearch(rotations, text);
- StringBuilder lastColumn = new StringBuilder(n);
- for (int i = 0; i < n; i++) {
- lastColumn.append(rotations[i].charAt(n - 1));
- }
-
- return new BWTResult(lastColumn.toString(), originalIndex);
- }
-
- /**
- * Performs the inverse Burrows-Wheeler Transform using the LF-mapping technique.
- *
- * The LF-mapping (Last-First mapping) is an efficient method to reconstruct
- * the original string from the BWT output without explicitly reconstructing
- * the entire sorted rotations matrix.
- *
- *
- * The algorithm works by:
- *
- * - Creating the first column by sorting the BWT string
- * - Building a mapping from first column indices to last column indices
- * - Following this mapping starting from the original index to reconstruct the string
- *
- *
- *
- * @param bwtString the transformed string (L-column) from the forward transform; must not be {@code null}
- * @param originalIndex the index of the original string row from the forward transform;
- * use -1 for empty strings
- * @return the original, untransformed string; returns empty string if input is empty or {@code originalIndex} is -1
- * @throws NullPointerException if {@code bwtString} is {@code null}
- * @throws IllegalArgumentException if {@code originalIndex} is out of valid range (except -1)
- */
- public static String inverseTransform(String bwtString, int originalIndex) {
- if (bwtString == null || bwtString.isEmpty() || originalIndex == -1) {
- return "";
- }
-
- int n = bwtString.length();
- if (originalIndex < 0 || originalIndex >= n) {
- throw new IllegalArgumentException("Original index must be between 0 and " + (n - 1) + ", got: " + originalIndex);
- }
-
- char[] lastColumn = bwtString.toCharArray();
- char[] firstColumn = bwtString.toCharArray();
- Arrays.sort(firstColumn);
-
- // Create the "next" array for LF-mapping.
- // next[i] stores the row index in the last column that corresponds to firstColumn[i]
- int[] next = new int[n];
-
- // Track the count of each character seen so far in the last column
- Map countMap = new HashMap<>();
-
- // Store the first occurrence index of each character in the first column
- Map firstOccurrence = new HashMap<>();
-
- for (int i = 0; i < n; i++) {
- if (!firstOccurrence.containsKey(firstColumn[i])) {
- firstOccurrence.put(firstColumn[i], i);
- }
- }
-
- // Build the LF-mapping
- for (int i = 0; i < n; i++) {
- char c = lastColumn[i];
- int count = countMap.getOrDefault(c, 0);
- int firstIndex = firstOccurrence.get(c);
- next[firstIndex + count] = i;
- countMap.put(c, count + 1);
- }
-
- // Reconstruct the original string by following the LF-mapping
- StringBuilder originalString = new StringBuilder(n);
- int currentRow = originalIndex;
- for (int i = 0; i < n; i++) {
- originalString.append(firstColumn[currentRow]);
- currentRow = next[currentRow];
- }
-
- return originalString.toString();
- }
-}
+package com.thealgorithms.compression;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Implementation of the Burrows-Wheeler Transform (BWT) and its inverse.
+ *
+ * BWT is a reversible data transformation algorithm that rearranges a string into runs of
+ * similar characters. While not a compression algorithm itself, it significantly improves
+ * the compressibility of data for subsequent algorithms like Move-to-Front encoding and
+ * Run-Length Encoding.
+ *
+ *
+ * The transform works by:
+ *
+ * - Generating all rotations of the input string
+ * - Sorting these rotations lexicographically
+ * - Taking the last column of the sorted matrix as output
+ * - Recording the index of the original string in the sorted matrix
+ *
+ *
+ *
+ * Important: The input string should end with a unique end-of-string marker
+ * (typically '$') that:
+ *
+ * - Does not appear anywhere else in the text
+ * - Is lexicographically smaller than all other characters
+ * - Ensures unique rotations and enables correct inverse transformation
+ *
+ * Without this marker, the inverse transform may not correctly reconstruct the original string.
+ *
+ *
+ * Time Complexity:
+ *
+ * - Forward transform: O(n² log n) where n is the string length
+ * - Inverse transform: O(n) using the LF-mapping technique
+ *
+ *
+ *
+ * Example:
+ *
+ * Input: "banana$"
+ * Output: BWTResult("annb$aa", 4)
+ * - "annb$aa" is the transformed string (groups similar characters)
+ * - 4 is the index of the original string in the sorted rotations
+ *
+ *
+ * @see Burrows–Wheeler transform (Wikipedia)
+ */
+public final class BurrowsWheelerTransform {
+
+ private BurrowsWheelerTransform() {
+ }
+
+ /**
+ * A container for the result of the forward BWT.
+ *
+ * Contains the transformed string and the index of the original string
+ * in the sorted rotations matrix, both of which are required for the
+ * inverse transformation.
+ *
+ */
+ public static class BWTResult {
+ /** The transformed string (last column of the sorted rotation matrix) */
+ public final String transformed;
+
+ /** The index of the original string in the sorted rotations matrix */
+ public final int originalIndex;
+
+ /**
+ * Constructs a BWTResult with the transformed string and original index.
+ *
+ * @param transformed the transformed string (L-column)
+ * @param originalIndex the index of the original string in sorted rotations
+ */
+ public BWTResult(String transformed, int originalIndex) {
+ this.transformed = transformed;
+ this.originalIndex = originalIndex;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ BWTResult bwtResult = (BWTResult) obj;
+ return originalIndex == bwtResult.originalIndex && transformed.equals(bwtResult.transformed);
+ }
+
+ @Override
+ public int hashCode() {
+ return 31 * transformed.hashCode() + originalIndex;
+ }
+
+ @Override
+ public String toString() {
+ return "BWTResult[transformed=" + transformed + ", originalIndex=" + originalIndex + "]";
+ }
+ }
+
+ /**
+ * Performs the forward Burrows-Wheeler Transform on the input string.
+ *
+ * The algorithm generates all cyclic rotations of the input, sorts them
+ * lexicographically, and returns the last column of this sorted matrix
+ * along with the position of the original string.
+ *
+ *
+ * Note: It is strongly recommended that the input string ends with
+ * a unique end-of-string marker (e.g., '$') that is lexicographically smaller
+ * than any other character in the string. This ensures correct inversion.
+ *
+ * @param text the input string to transform; must not be {@code null}
+ * @return a {@link BWTResult} object containing the transformed string (L-column)
+ * and the index of the original string in the sorted rotations matrix;
+ * returns {@code BWTResult("", -1)} for empty input
+ * @throws NullPointerException if {@code text} is {@code null}
+ */
+ public static BWTResult transform(String text) {
+ if (text == null || text.isEmpty()) {
+ return new BWTResult("", -1);
+ }
+
+ int n = text.length();
+
+ // Generate all rotations of the input string
+ String[] rotations = new String[n];
+ for (int i = 0; i < n; i++) {
+ rotations[i] = text.substring(i) + text.substring(0, i);
+ }
+
+ // Sort rotations lexicographically
+ Arrays.sort(rotations);
+ int originalIndex = Arrays.binarySearch(rotations, text);
+ StringBuilder lastColumn = new StringBuilder(n);
+ for (int i = 0; i < n; i++) {
+ lastColumn.append(rotations[i].charAt(n - 1));
+ }
+
+ return new BWTResult(lastColumn.toString(), originalIndex);
+ }
+
+ /**
+ * Performs the inverse Burrows-Wheeler Transform using the LF-mapping technique.
+ *
+ * The LF-mapping (Last-First mapping) is an efficient method to reconstruct
+ * the original string from the BWT output without explicitly reconstructing
+ * the entire sorted rotations matrix.
+ *
+ *
+ * The algorithm works by:
+ *
+ * - Creating the first column by sorting the BWT string
+ * - Building a mapping from first column indices to last column indices
+ * - Following this mapping starting from the original index to reconstruct the string
+ *
+ *
+ *
+ * @param bwtString the transformed string (L-column) from the forward transform; must not be {@code null}
+ * @param originalIndex the index of the original string row from the forward transform;
+ * use -1 for empty strings
+ * @return the original, untransformed string; returns empty string if input is empty or {@code originalIndex} is -1
+ * @throws NullPointerException if {@code bwtString} is {@code null}
+ * @throws IllegalArgumentException if {@code originalIndex} is out of valid range (except -1)
+ */
+ public static String inverseTransform(String bwtString, int originalIndex) {
+ if (bwtString == null || bwtString.isEmpty() || originalIndex == -1) {
+ return "";
+ }
+
+ int n = bwtString.length();
+ if (originalIndex < 0 || originalIndex >= n) {
+ throw new IllegalArgumentException("Original index must be between 0 and " + (n - 1) + ", got: " + originalIndex);
+ }
+
+ char[] lastColumn = bwtString.toCharArray();
+ char[] firstColumn = bwtString.toCharArray();
+ Arrays.sort(firstColumn);
+
+ // Create the "next" array for LF-mapping.
+ // next[i] stores the row index in the last column that corresponds to firstColumn[i]
+ int[] next = new int[n];
+
+ // Track the count of each character seen so far in the last column
+ Map countMap = new HashMap<>();
+
+ // Store the first occurrence index of each character in the first column
+ Map firstOccurrence = new HashMap<>();
+
+ for (int i = 0; i < n; i++) {
+ if (!firstOccurrence.containsKey(firstColumn[i])) {
+ firstOccurrence.put(firstColumn[i], i);
+ }
+ }
+
+ // Build the LF-mapping
+ for (int i = 0; i < n; i++) {
+ char c = lastColumn[i];
+ int count = countMap.getOrDefault(c, 0);
+ int firstIndex = firstOccurrence.get(c);
+ next[firstIndex + count] = i;
+ countMap.put(c, count + 1);
+ }
+
+ // Reconstruct the original string by following the LF-mapping
+ StringBuilder originalString = new StringBuilder(n);
+ int currentRow = originalIndex;
+ for (int i = 0; i < n; i++) {
+ originalString.append(firstColumn[currentRow]);
+ currentRow = next[currentRow];
+ }
+
+ return originalString.toString();
+ }
+}
diff --git a/src/main/java/com/thealgorithms/compression/LZ77.java b/src/main/java/com/thealgorithms/compression/LZ77.java
index d02307aa57b5..7d95ce54d959 100644
--- a/src/main/java/com/thealgorithms/compression/LZ77.java
+++ b/src/main/java/com/thealgorithms/compression/LZ77.java
@@ -1,168 +1,168 @@
-package com.thealgorithms.compression;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * An implementation of the Lempel-Ziv 77 (LZ77) compression algorithm.
- *
- * LZ77 is a lossless data compression algorithm that works by finding repeated
- * occurrences of data in a sliding window. It replaces subsequent occurrences
- * with references (offset, length) to the first occurrence within the window.
- *
- *
- * This implementation uses a simple sliding window and lookahead buffer approach.
- * Output format is a sequence of tuples (offset, length, next_character).
- *
- *
- * Time Complexity: O(n*W) in this naive implementation, where n is the input length
- * and W is the window size, due to the search for the longest match. More advanced
- * data structures (like suffix trees) can improve this.
- *
- *
- * References:
- *
- *
- */
-public final class LZ77 {
-
- private static final int DEFAULT_WINDOW_SIZE = 4096;
- private static final int DEFAULT_LOOKAHEAD_BUFFER_SIZE = 16;
- private static final char END_OF_STREAM = '\u0000';
- private LZ77() {
- }
-
- /**
- * Represents a token in the LZ77 compressed output.
- * Stores the offset back into the window, the length of the match,
- * and the next character after the match (or END_OF_STREAM if at end).
- */
- public record Token(int offset, int length, char nextChar) {
- }
-
- /**
- * Compresses the input text using the LZ77 algorithm.
- *
- * @param text The input string to compress. Must not be null.
- * @param windowSize The size of the sliding window (search buffer). Must be positive.
- * @param lookaheadBufferSize The size of the lookahead buffer. Must be positive.
- * @return A list of {@link Token} objects representing the compressed data.
- * @throws IllegalArgumentException if windowSize or lookaheadBufferSize are not positive.
- */
- public static List compress(String text, int windowSize, int lookaheadBufferSize) {
- if (text == null) {
- return new ArrayList<>();
- }
- if (windowSize <= 0 || lookaheadBufferSize <= 0) {
- throw new IllegalArgumentException("Window size and lookahead buffer size must be positive.");
- }
-
- List compressedOutput = new ArrayList<>();
- int currentPosition = 0;
-
- while (currentPosition < text.length()) {
- int bestMatchDistance = 0;
- int bestMatchLength = 0;
-
- // Define the start of the search window
- int searchBufferStart = Math.max(0, currentPosition - windowSize);
- // Define the end of the lookahead buffer (don't go past text length)
- int lookaheadEnd = Math.min(currentPosition + lookaheadBufferSize, text.length());
-
- // Search for the longest match in the window
- for (int i = searchBufferStart; i < currentPosition; i++) {
- int currentMatchLength = 0;
-
- // Check how far the match extends into the lookahead buffer
- // This allows for overlapping matches (e.g., "aaa" can match with offset 1)
- while (currentPosition + currentMatchLength < lookaheadEnd) {
- int sourceIndex = i + currentMatchLength;
-
- // Handle overlapping matches (run-length encoding within LZ77)
- // When we've matched beyond our starting position, wrap around using modulo
- if (sourceIndex >= currentPosition) {
- int offset = currentPosition - i;
- sourceIndex = i + (currentMatchLength % offset);
- }
-
- if (text.charAt(sourceIndex) == text.charAt(currentPosition + currentMatchLength)) {
- currentMatchLength++;
- } else {
- break;
- }
- }
-
- // If this match is longer than the best found so far
- if (currentMatchLength > bestMatchLength) {
- bestMatchLength = currentMatchLength;
- bestMatchDistance = currentPosition - i; // Calculate offset from current position
- }
- }
-
- char nextChar;
- if (currentPosition + bestMatchLength < text.length()) {
- nextChar = text.charAt(currentPosition + bestMatchLength);
- } else {
- nextChar = END_OF_STREAM;
- }
-
- // Add the token to the output
- compressedOutput.add(new Token(bestMatchDistance, bestMatchLength, nextChar));
-
- // Move the current position forward
- // If we're at the end and had a match, just move by the match length
- if (nextChar == END_OF_STREAM) {
- currentPosition += bestMatchLength;
- } else {
- currentPosition += bestMatchLength + 1;
- }
- }
-
- return compressedOutput;
- }
-
- /**
- * Compresses the input text using the LZ77 algorithm with default buffer sizes.
- *
- * @param text The input string to compress. Must not be null.
- * @return A list of {@link Token} objects representing the compressed data.
- */
- public static List compress(String text) {
- return compress(text, DEFAULT_WINDOW_SIZE, DEFAULT_LOOKAHEAD_BUFFER_SIZE);
- }
-
- /**
- * Decompresses a list of LZ77 tokens back into the original string.
- *
- * @param compressedData The list of {@link Token} objects. Must not be null.
- * @return The original, uncompressed string.
- */
- public static String decompress(List compressedData) {
- if (compressedData == null) {
- return "";
- }
-
- StringBuilder decompressedText = new StringBuilder();
-
- for (Token token : compressedData) {
- // Copy matched characters from the sliding window
- if (token.length > 0) {
- int startIndex = decompressedText.length() - token.offset;
-
- // Handle overlapping matches (e.g., when length > offset)
- for (int i = 0; i < token.length; i++) {
- decompressedText.append(decompressedText.charAt(startIndex + i));
- }
- }
-
- // Append the next character (if not END_OF_STREAM)
- if (token.nextChar != END_OF_STREAM) {
- decompressedText.append(token.nextChar);
- }
- }
-
- return decompressedText.toString();
- }
-}
+package com.thealgorithms.compression;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * An implementation of the Lempel-Ziv 77 (LZ77) compression algorithm.
+ *
+ * LZ77 is a lossless data compression algorithm that works by finding repeated
+ * occurrences of data in a sliding window. It replaces subsequent occurrences
+ * with references (offset, length) to the first occurrence within the window.
+ *
+ *
+ * This implementation uses a simple sliding window and lookahead buffer approach.
+ * Output format is a sequence of tuples (offset, length, next_character).
+ *
+ *
+ * Time Complexity: O(n*W) in this naive implementation, where n is the input length
+ * and W is the window size, due to the search for the longest match. More advanced
+ * data structures (like suffix trees) can improve this.
+ *
+ *
+ * References:
+ *
+ *
+ */
+public final class LZ77 {
+
+ private static final int DEFAULT_WINDOW_SIZE = 4096;
+ private static final int DEFAULT_LOOKAHEAD_BUFFER_SIZE = 16;
+ private static final char END_OF_STREAM = '\u0000';
+ private LZ77() {
+ }
+
+ /**
+ * Represents a token in the LZ77 compressed output.
+ * Stores the offset back into the window, the length of the match,
+ * and the next character after the match (or END_OF_STREAM if at end).
+ */
+ public record Token(int offset, int length, char nextChar) {
+ }
+
+ /**
+ * Compresses the input text using the LZ77 algorithm.
+ *
+ * @param text The input string to compress. Must not be null.
+ * @param windowSize The size of the sliding window (search buffer). Must be positive.
+ * @param lookaheadBufferSize The size of the lookahead buffer. Must be positive.
+ * @return A list of {@link Token} objects representing the compressed data.
+ * @throws IllegalArgumentException if windowSize or lookaheadBufferSize are not positive.
+ */
+ public static List compress(String text, int windowSize, int lookaheadBufferSize) {
+ if (text == null) {
+ return new ArrayList<>();
+ }
+ if (windowSize <= 0 || lookaheadBufferSize <= 0) {
+ throw new IllegalArgumentException("Window size and lookahead buffer size must be positive.");
+ }
+
+ List compressedOutput = new ArrayList<>();
+ int currentPosition = 0;
+
+ while (currentPosition < text.length()) {
+ int bestMatchDistance = 0;
+ int bestMatchLength = 0;
+
+ // Define the start of the search window
+ int searchBufferStart = Math.max(0, currentPosition - windowSize);
+ // Define the end of the lookahead buffer (don't go past text length)
+ int lookaheadEnd = Math.min(currentPosition + lookaheadBufferSize, text.length());
+
+ // Search for the longest match in the window
+ for (int i = searchBufferStart; i < currentPosition; i++) {
+ int currentMatchLength = 0;
+
+ // Check how far the match extends into the lookahead buffer
+ // This allows for overlapping matches (e.g., "aaa" can match with offset 1)
+ while (currentPosition + currentMatchLength < lookaheadEnd) {
+ int sourceIndex = i + currentMatchLength;
+
+ // Handle overlapping matches (run-length encoding within LZ77)
+ // When we've matched beyond our starting position, wrap around using modulo
+ if (sourceIndex >= currentPosition) {
+ int offset = currentPosition - i;
+ sourceIndex = i + (currentMatchLength % offset);
+ }
+
+ if (text.charAt(sourceIndex) == text.charAt(currentPosition + currentMatchLength)) {
+ currentMatchLength++;
+ } else {
+ break;
+ }
+ }
+
+ // If this match is longer than the best found so far
+ if (currentMatchLength > bestMatchLength) {
+ bestMatchLength = currentMatchLength;
+ bestMatchDistance = currentPosition - i; // Calculate offset from current position
+ }
+ }
+
+ char nextChar;
+ if (currentPosition + bestMatchLength < text.length()) {
+ nextChar = text.charAt(currentPosition + bestMatchLength);
+ } else {
+ nextChar = END_OF_STREAM;
+ }
+
+ // Add the token to the output
+ compressedOutput.add(new Token(bestMatchDistance, bestMatchLength, nextChar));
+
+ // Move the current position forward
+ // If we're at the end and had a match, just move by the match length
+ if (nextChar == END_OF_STREAM) {
+ currentPosition += bestMatchLength;
+ } else {
+ currentPosition += bestMatchLength + 1;
+ }
+ }
+
+ return compressedOutput;
+ }
+
+ /**
+ * Compresses the input text using the LZ77 algorithm with default buffer sizes.
+ *
+ * @param text The input string to compress. Must not be null.
+ * @return A list of {@link Token} objects representing the compressed data.
+ */
+ public static List compress(String text) {
+ return compress(text, DEFAULT_WINDOW_SIZE, DEFAULT_LOOKAHEAD_BUFFER_SIZE);
+ }
+
+ /**
+ * Decompresses a list of LZ77 tokens back into the original string.
+ *
+ * @param compressedData The list of {@link Token} objects. Must not be null.
+ * @return The original, uncompressed string.
+ */
+ public static String decompress(List compressedData) {
+ if (compressedData == null) {
+ return "";
+ }
+
+ StringBuilder decompressedText = new StringBuilder();
+
+ for (Token token : compressedData) {
+ // Copy matched characters from the sliding window
+ if (token.length > 0) {
+ int startIndex = decompressedText.length() - token.offset;
+
+ // Handle overlapping matches (e.g., when length > offset)
+ for (int i = 0; i < token.length; i++) {
+ decompressedText.append(decompressedText.charAt(startIndex + i));
+ }
+ }
+
+ // Append the next character (if not END_OF_STREAM)
+ if (token.nextChar != END_OF_STREAM) {
+ decompressedText.append(token.nextChar);
+ }
+ }
+
+ return decompressedText.toString();
+ }
+}
diff --git a/src/main/java/com/thealgorithms/compression/LZ78.java b/src/main/java/com/thealgorithms/compression/LZ78.java
index 904c379cc2a2..ca7f58b08e5f 100644
--- a/src/main/java/com/thealgorithms/compression/LZ78.java
+++ b/src/main/java/com/thealgorithms/compression/LZ78.java
@@ -1,136 +1,136 @@
-package com.thealgorithms.compression;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * An implementation of the Lempel-Ziv 78 (LZ78) compression algorithm.
- *
- * LZ78 is a dictionary-based lossless data compression algorithm. It processes
- * input data sequentially, building a dictionary of phrases encountered so far.
- * It outputs pairs (dictionary_index, next_character), representing
- * the longest match found in the dictionary plus the character that follows it.
- *
- *
- * This implementation builds the dictionary dynamically during compression.
- * The dictionary index 0 represents the empty string (no prefix).
- *
- *
- * Time Complexity: O(n) on average for compression and decompression, assuming
- * efficient dictionary lookups (using a HashMap), where n is the
- * length of the input string.
- *
- *
- * References:
- *
- *
- */
-public final class LZ78 {
-
- /**
- * Special character used to mark end of stream when needed.
- */
- private static final char END_OF_STREAM = '\u0000';
-
- /**
- * Private constructor to prevent instantiation of this utility class.
- */
- private LZ78() {
- }
-
- /**
- * Represents a token in the LZ78 compressed output.
- * Stores the index of the matching prefix in the dictionary and the next character.
- * Index 0 represents the empty string (no prefix).
- */
- public record Token(int index, char nextChar) {
- }
-
- /**
- * A node in the dictionary trie structure.
- * Each node represents a phrase and can have child nodes for extended phrases.
- */
- private static final class TrieNode {
- Map children = new HashMap<>();
- int index = -1; // -1 means not assigned yet
- }
-
- /**
- * Compresses the input text using the LZ78 algorithm.
- *
- * @param text The input string to compress. Must not be null.
- * @return A list of {@link Token} objects representing the compressed data.
- */
- public static List compress(String text) {
- if (text == null || text.isEmpty()) {
- return new ArrayList<>();
- }
-
- List compressedOutput = new ArrayList<>();
- TrieNode root = new TrieNode();
- int nextDictionaryIndex = 1;
-
- TrieNode currentNode = root;
- int lastMatchedIndex = 0;
-
- for (int i = 0; i < text.length(); i++) {
- char currentChar = text.charAt(i);
-
- if (currentNode.children.containsKey(currentChar)) {
- currentNode = currentNode.children.get(currentChar);
- lastMatchedIndex = currentNode.index;
- } else {
- // Output: (index of longest matching prefix, current character)
- compressedOutput.add(new Token(lastMatchedIndex, currentChar));
-
- TrieNode newNode = new TrieNode();
- newNode.index = nextDictionaryIndex++;
- currentNode.children.put(currentChar, newNode);
-
- currentNode = root;
- lastMatchedIndex = 0;
- }
- }
-
- // Handle remaining phrase at end of input
- if (currentNode != root) {
- compressedOutput.add(new Token(lastMatchedIndex, END_OF_STREAM));
- }
-
- return compressedOutput;
- }
-
- /**
- * Decompresses a list of LZ78 tokens back into the original string.
- *
- * @param compressedData The list of {@link Token} objects. Must not be null.
- * @return The original, uncompressed string.
- */
- public static String decompress(List compressedData) {
- if (compressedData == null || compressedData.isEmpty()) {
- return "";
- }
-
- StringBuilder decompressedText = new StringBuilder();
- Map dictionary = new HashMap<>();
- int nextDictionaryIndex = 1;
-
- for (Token token : compressedData) {
- String prefix = (token.index == 0) ? "" : dictionary.get(token.index);
-
- if (token.nextChar == END_OF_STREAM) {
- decompressedText.append(prefix);
- } else {
- String currentPhrase = prefix + token.nextChar;
- decompressedText.append(currentPhrase);
- dictionary.put(nextDictionaryIndex++, currentPhrase);
- }
- }
-
- return decompressedText.toString();
- }
-}
+package com.thealgorithms.compression;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * An implementation of the Lempel-Ziv 78 (LZ78) compression algorithm.
+ *
+ * LZ78 is a dictionary-based lossless data compression algorithm. It processes
+ * input data sequentially, building a dictionary of phrases encountered so far.
+ * It outputs pairs (dictionary_index, next_character), representing
+ * the longest match found in the dictionary plus the character that follows it.
+ *
+ *
+ * This implementation builds the dictionary dynamically during compression.
+ * The dictionary index 0 represents the empty string (no prefix).
+ *
+ *
+ * Time Complexity: O(n) on average for compression and decompression, assuming
+ * efficient dictionary lookups (using a HashMap), where n is the
+ * length of the input string.
+ *
+ *
+ * References:
+ *
+ *
+ */
+public final class LZ78 {
+
+ /**
+ * Special character used to mark end of stream when needed.
+ */
+ private static final char END_OF_STREAM = '\u0000';
+
+ /**
+ * Private constructor to prevent instantiation of this utility class.
+ */
+ private LZ78() {
+ }
+
+ /**
+ * Represents a token in the LZ78 compressed output.
+ * Stores the index of the matching prefix in the dictionary and the next character.
+ * Index 0 represents the empty string (no prefix).
+ */
+ public record Token(int index, char nextChar) {
+ }
+
+ /**
+ * A node in the dictionary trie structure.
+ * Each node represents a phrase and can have child nodes for extended phrases.
+ */
+ private static final class TrieNode {
+ Map children = new HashMap<>();
+ int index = -1; // -1 means not assigned yet
+ }
+
+ /**
+ * Compresses the input text using the LZ78 algorithm.
+ *
+ * @param text The input string to compress. Must not be null.
+ * @return A list of {@link Token} objects representing the compressed data.
+ */
+ public static List compress(String text) {
+ if (text == null || text.isEmpty()) {
+ return new ArrayList<>();
+ }
+
+ List compressedOutput = new ArrayList<>();
+ TrieNode root = new TrieNode();
+ int nextDictionaryIndex = 1;
+
+ TrieNode currentNode = root;
+ int lastMatchedIndex = 0;
+
+ for (int i = 0; i < text.length(); i++) {
+ char currentChar = text.charAt(i);
+
+ if (currentNode.children.containsKey(currentChar)) {
+ currentNode = currentNode.children.get(currentChar);
+ lastMatchedIndex = currentNode.index;
+ } else {
+ // Output: (index of longest matching prefix, current character)
+ compressedOutput.add(new Token(lastMatchedIndex, currentChar));
+
+ TrieNode newNode = new TrieNode();
+ newNode.index = nextDictionaryIndex++;
+ currentNode.children.put(currentChar, newNode);
+
+ currentNode = root;
+ lastMatchedIndex = 0;
+ }
+ }
+
+ // Handle remaining phrase at end of input
+ if (currentNode != root) {
+ compressedOutput.add(new Token(lastMatchedIndex, END_OF_STREAM));
+ }
+
+ return compressedOutput;
+ }
+
+ /**
+ * Decompresses a list of LZ78 tokens back into the original string.
+ *
+ * @param compressedData The list of {@link Token} objects. Must not be null.
+ * @return The original, uncompressed string.
+ */
+ public static String decompress(List compressedData) {
+ if (compressedData == null || compressedData.isEmpty()) {
+ return "";
+ }
+
+ StringBuilder decompressedText = new StringBuilder();
+ Map dictionary = new HashMap<>();
+ int nextDictionaryIndex = 1;
+
+ for (Token token : compressedData) {
+ String prefix = (token.index == 0) ? "" : dictionary.get(token.index);
+
+ if (token.nextChar == END_OF_STREAM) {
+ decompressedText.append(prefix);
+ } else {
+ String currentPhrase = prefix + token.nextChar;
+ decompressedText.append(currentPhrase);
+ dictionary.put(nextDictionaryIndex++, currentPhrase);
+ }
+ }
+
+ return decompressedText.toString();
+ }
+}
diff --git a/src/main/java/com/thealgorithms/compression/LZW.java b/src/main/java/com/thealgorithms/compression/LZW.java
index c8383815ad4f..09dc74ae46a9 100644
--- a/src/main/java/com/thealgorithms/compression/LZW.java
+++ b/src/main/java/com/thealgorithms/compression/LZW.java
@@ -1,136 +1,136 @@
-package com.thealgorithms.compression;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * An implementation of the Lempel-Ziv-Welch (LZW) algorithm.
- *
- *
- * LZW is a universal lossless data compression algorithm created by Abraham
- * Lempel, Jacob Ziv, and Terry Welch. It works by building a dictionary of
- * strings encountered during compression and replacing occurrences of those
- * strings with a shorter code.
- *
- *
- *
- * This implementation handles standard ASCII characters and provides methods for
- * both compression and decompression.
- *
- * - Compressing "TOBEORNOTTOBEORTOBEORNOT" results in a list of integer
- * codes.
- * - Decompressing that list of codes results back in the original
- * string.
- *
- *
- *
- *
- * Time Complexity: O(n) for both compression and decompression, where n is the
- * length of the input string.
- *
- *
- *
- * References:
- *
- *
- */
-public final class LZW {
-
- /**
- * Private constructor to prevent instantiation of this utility class.
- */
- private LZW() {
- }
-
- /**
- * Compresses a string using the LZW algorithm.
- *
- * @param uncompressed The string to be compressed. Can be null.
- * @return A list of integers representing the compressed data. Returns an empty
- * list if the input is null or empty.
- */
- public static List compress(String uncompressed) {
- if (uncompressed == null || uncompressed.isEmpty()) {
- return new ArrayList<>();
- }
-
- // Initialize dictionary with single characters (ASCII 0-255)
- int dictSize = 256;
- Map dictionary = new HashMap<>();
- for (int i = 0; i < dictSize; i++) {
- dictionary.put("" + (char) i, i);
- }
-
- String w = "";
- List result = new ArrayList<>();
- for (char c : uncompressed.toCharArray()) {
- String wc = w + c;
- if (dictionary.containsKey(wc)) {
- // If the new string is in the dictionary, extend the current string
- w = wc;
- } else {
- // Otherwise, output the code for the current string
- result.add(dictionary.get(w));
- // Add the new string to the dictionary
- dictionary.put(wc, dictSize++);
- // Start a new current string
- w = "" + c;
- }
- }
-
- // Output the code for the last remaining string
- result.add(dictionary.get(w));
- return result;
- }
-
- /**
- * Decompresses a list of integers back into a string using the LZW algorithm.
- *
- * @param compressed A list of integers representing the compressed data. Can be
- * null.
- * @return The original, uncompressed string. Returns an empty string if the
- * input is null or empty.
- */
- public static String decompress(List compressed) {
- if (compressed == null || compressed.isEmpty()) {
- return "";
- }
-
- // Initialize dictionary with single characters (ASCII 0-255)
- int dictSize = 256;
- Map dictionary = new HashMap<>();
- for (int i = 0; i < dictSize; i++) {
- dictionary.put(i, "" + (char) i);
- }
-
- // Decompress the first code
- String w = "" + (char) (int) compressed.removeFirst();
- StringBuilder result = new StringBuilder(w);
-
- for (int k : compressed) {
- String entry;
- if (dictionary.containsKey(k)) {
- // The code is in the dictionary
- entry = dictionary.get(k);
- } else if (k == dictSize) {
- // Special case for sequences like "ababab"
- entry = w + w.charAt(0);
- } else {
- throw new IllegalArgumentException("Bad compressed k: " + k);
- }
-
- result.append(entry);
-
- // Add new sequence to the dictionary
- dictionary.put(dictSize++, w + entry.charAt(0));
-
- w = entry;
- }
- return result.toString();
- }
-}
+package com.thealgorithms.compression;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * An implementation of the Lempel-Ziv-Welch (LZW) algorithm.
+ *
+ *
+ * LZW is a universal lossless data compression algorithm created by Abraham
+ * Lempel, Jacob Ziv, and Terry Welch. It works by building a dictionary of
+ * strings encountered during compression and replacing occurrences of those
+ * strings with a shorter code.
+ *
+ *
+ *
+ * This implementation handles standard ASCII characters and provides methods for
+ * both compression and decompression.
+ *
+ * - Compressing "TOBEORNOTTOBEORTOBEORNOT" results in a list of integer
+ * codes.
+ * - Decompressing that list of codes results back in the original
+ * string.
+ *
+ *
+ *
+ *
+ * Time Complexity: O(n) for both compression and decompression, where n is the
+ * length of the input string.
+ *
+ *
+ *
+ * References:
+ *
+ *
+ */
+public final class LZW {
+
+ /**
+ * Private constructor to prevent instantiation of this utility class.
+ */
+ private LZW() {
+ }
+
+ /**
+ * Compresses a string using the LZW algorithm.
+ *
+ * @param uncompressed The string to be compressed. Can be null.
+ * @return A list of integers representing the compressed data. Returns an empty
+ * list if the input is null or empty.
+ */
+ public static List compress(String uncompressed) {
+ if (uncompressed == null || uncompressed.isEmpty()) {
+ return new ArrayList<>();
+ }
+
+ // Initialize dictionary with single characters (ASCII 0-255)
+ int dictSize = 256;
+ Map dictionary = new HashMap<>();
+ for (int i = 0; i < dictSize; i++) {
+ dictionary.put("" + (char) i, i);
+ }
+
+ String w = "";
+ List result = new ArrayList<>();
+ for (char c : uncompressed.toCharArray()) {
+ String wc = w + c;
+ if (dictionary.containsKey(wc)) {
+ // If the new string is in the dictionary, extend the current string
+ w = wc;
+ } else {
+ // Otherwise, output the code for the current string
+ result.add(dictionary.get(w));
+ // Add the new string to the dictionary
+ dictionary.put(wc, dictSize++);
+ // Start a new current string
+ w = "" + c;
+ }
+ }
+
+ // Output the code for the last remaining string
+ result.add(dictionary.get(w));
+ return result;
+ }
+
+ /**
+ * Decompresses a list of integers back into a string using the LZW algorithm.
+ *
+ * @param compressed A list of integers representing the compressed data. Can be
+ * null.
+ * @return The original, uncompressed string. Returns an empty string if the
+ * input is null or empty.
+ */
+ public static String decompress(List compressed) {
+ if (compressed == null || compressed.isEmpty()) {
+ return "";
+ }
+
+ // Initialize dictionary with single characters (ASCII 0-255)
+ int dictSize = 256;
+ Map dictionary = new HashMap<>();
+ for (int i = 0; i < dictSize; i++) {
+ dictionary.put(i, "" + (char) i);
+ }
+
+ // Decompress the first code
+ String w = "" + (char) (int) compressed.removeFirst();
+ StringBuilder result = new StringBuilder(w);
+
+ for (int k : compressed) {
+ String entry;
+ if (dictionary.containsKey(k)) {
+ // The code is in the dictionary
+ entry = dictionary.get(k);
+ } else if (k == dictSize) {
+ // Special case for sequences like "ababab"
+ entry = w + w.charAt(0);
+ } else {
+ throw new IllegalArgumentException("Bad compressed k: " + k);
+ }
+
+ result.append(entry);
+
+ // Add new sequence to the dictionary
+ dictionary.put(dictSize++, w + entry.charAt(0));
+
+ w = entry;
+ }
+ return result.toString();
+ }
+}
diff --git a/src/main/java/com/thealgorithms/compression/MoveToFront.java b/src/main/java/com/thealgorithms/compression/MoveToFront.java
index fa8976df8262..39f151afe354 100644
--- a/src/main/java/com/thealgorithms/compression/MoveToFront.java
+++ b/src/main/java/com/thealgorithms/compression/MoveToFront.java
@@ -1,164 +1,164 @@
-package com.thealgorithms.compression;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.stream.Collectors;
-
-/**
- * Implementation of the Move-to-Front (MTF) transform and its inverse.
- *
- * MTF is a data transformation algorithm that encodes each symbol in the input
- * as its current position in a dynamically-maintained list, then moves that symbol
- * to the front of the list. This transformation is particularly effective when used
- * after the Burrows-Wheeler Transform (BWT), as BWT groups similar characters together.
- *
- *
- * The transform converts runs of repeated characters into sequences of small integers
- * (often zeros), which are highly compressible by subsequent entropy encoding algorithms
- * like Run-Length Encoding (RLE) or Huffman coding. This technique is used in the
- * bzip2 compression algorithm.
- *
- *
- * How it works:
- *
- * - Maintain a list of symbols (the alphabet), initially in a fixed order
- * - For each input symbol:
- *
- * - Output its current index in the list
- * - Move that symbol to the front of the list
- *
- *
- *
- * This means frequently occurring symbols quickly move to the front and are encoded
- * with small indices (often 0), while rare symbols remain near the back.
- *
- *
- * Time Complexity:
- *
- * - Forward transform: O(n × m) where n is input length and m is alphabet size
- * - Inverse transform: O(n × m)
- *
- * Note: Using {@link LinkedList} for O(1) insertions and O(m) search operations.
- *
- *
- * Example:
- *
- * Input: "annb$aa"
- * Alphabet: "$abn" (initial order)
- * Output: [1, 3, 0, 3, 3, 3, 0]
- *
- * Step-by-step:
- * - 'a': index 1 in [$,a,b,n] → output 1, list becomes [a,$,b,n]
- * - 'n': index 3 in [a,$,b,n] → output 3, list becomes [n,a,$,b]
- * - 'n': index 0 in [n,a,$,b] → output 0, list stays [n,a,$,b]
- * - 'b': index 3 in [n,a,$,b] → output 3, list becomes [b,n,a,$]
- * - etc.
- *
- * Notice how repeated 'n' characters produce zeros after the first occurrence!
- *
- *
- * @see Move-to-front transform (Wikipedia)
- */
-public final class MoveToFront {
-
- private MoveToFront() {
- }
-
- /**
- * Performs the forward Move-to-Front transform.
- *
- * Converts the input string into a list of integers, where each integer represents
- * the position of the corresponding character in a dynamically-maintained alphabet list.
- *
- *
- * Note: All characters in the input text must exist in the provided alphabet,
- * otherwise an {@link IllegalArgumentException} is thrown. The alphabet should contain
- * all unique characters that may appear in the input.
- *
- * @param text the input string to transform; if empty, returns an empty list
- * @param initialAlphabet a string containing the initial ordered set of symbols
- * (e.g., "$abn" or the full ASCII set); must not be empty
- * when {@code text} is non-empty
- * @return a list of integers representing the transformed data, where each integer
- * is the index of the corresponding input character in the current alphabet state
- * @throws IllegalArgumentException if {@code text} is non-empty and {@code initialAlphabet}
- * is {@code null} or empty
- * @throws IllegalArgumentException if any character in {@code text} is not found in
- * {@code initialAlphabet}
- */
- public static List transform(String text, String initialAlphabet) {
- if (text == null || text.isEmpty()) {
- return new ArrayList<>();
- }
- if (initialAlphabet == null || initialAlphabet.isEmpty()) {
- throw new IllegalArgumentException("Alphabet cannot be null or empty when text is not empty.");
- }
-
- List output = new ArrayList<>(text.length());
-
- // Use LinkedList for O(1) add-to-front and O(n) remove operations
- // This is more efficient than ArrayList for the move-to-front pattern
- List alphabet = initialAlphabet.chars().mapToObj(c -> (char) c).collect(Collectors.toCollection(LinkedList::new));
-
- for (char c : text.toCharArray()) {
- int index = alphabet.indexOf(c);
- if (index == -1) {
- throw new IllegalArgumentException("Symbol '" + c + "' not found in the initial alphabet.");
- }
-
- output.add(index);
-
- // Move the character to the front
- Character symbol = alphabet.remove(index);
- alphabet.addFirst(symbol);
- }
- return output;
- }
-
- /**
- * Performs the inverse Move-to-Front transform.
- *
- * Reconstructs the original string from the list of indices produced by the
- * forward transform. This requires the exact same initial alphabet that was
- * used in the forward transform.
- *
- *
- * Important: The {@code initialAlphabet} parameter must be identical
- * to the one used in the forward transform, including character order, or the
- * output will be incorrect.
- *
- * @param indices The list of integers from the forward transform.
- * @param initialAlphabet the exact same initial alphabet string used for the forward transform;
- * if {@code null} or empty, returns an empty string
- * @return the original, untransformed string
- * @throws IllegalArgumentException if any index in {@code indices} is negative or
- * exceeds the current alphabet size
- */
- public static String inverseTransform(Collection indices, String initialAlphabet) {
- if (indices == null || indices.isEmpty() || initialAlphabet == null || initialAlphabet.isEmpty()) {
- return "";
- }
-
- StringBuilder output = new StringBuilder(indices.size());
-
- // Use LinkedList for O(1) add-to-front and O(n) remove operations
- List alphabet = initialAlphabet.chars().mapToObj(c -> (char) c).collect(Collectors.toCollection(LinkedList::new));
-
- for (int index : indices) {
- if (index < 0 || index >= alphabet.size()) {
- throw new IllegalArgumentException("Index " + index + " is out of bounds for the current alphabet of size " + alphabet.size() + ".");
- }
-
- // Get the symbol at the index
- char symbol = alphabet.get(index);
- output.append(symbol);
-
- // Move the symbol to the front (mirroring the forward transform)
- alphabet.remove(index);
- alphabet.addFirst(symbol);
- }
- return output.toString();
- }
-}
+package com.thealgorithms.compression;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Implementation of the Move-to-Front (MTF) transform and its inverse.
+ *
+ * MTF is a data transformation algorithm that encodes each symbol in the input
+ * as its current position in a dynamically-maintained list, then moves that symbol
+ * to the front of the list. This transformation is particularly effective when used
+ * after the Burrows-Wheeler Transform (BWT), as BWT groups similar characters together.
+ *
+ *
+ * The transform converts runs of repeated characters into sequences of small integers
+ * (often zeros), which are highly compressible by subsequent entropy encoding algorithms
+ * like Run-Length Encoding (RLE) or Huffman coding. This technique is used in the
+ * bzip2 compression algorithm.
+ *
+ *
+ * How it works:
+ *
+ * - Maintain a list of symbols (the alphabet), initially in a fixed order
+ * - For each input symbol:
+ *
+ * - Output its current index in the list
+ * - Move that symbol to the front of the list
+ *
+ *
+ *
+ * This means frequently occurring symbols quickly move to the front and are encoded
+ * with small indices (often 0), while rare symbols remain near the back.
+ *
+ *
+ * Time Complexity:
+ *
+ * - Forward transform: O(n × m) where n is input length and m is alphabet size
+ * - Inverse transform: O(n × m)
+ *
+ * Note: Using {@link LinkedList} for O(1) insertions and O(m) search operations.
+ *
+ *
+ * Example:
+ *
+ * Input: "annb$aa"
+ * Alphabet: "$abn" (initial order)
+ * Output: [1, 3, 0, 3, 3, 3, 0]
+ *
+ * Step-by-step:
+ * - 'a': index 1 in [$,a,b,n] → output 1, list becomes [a,$,b,n]
+ * - 'n': index 3 in [a,$,b,n] → output 3, list becomes [n,a,$,b]
+ * - 'n': index 0 in [n,a,$,b] → output 0, list stays [n,a,$,b]
+ * - 'b': index 3 in [n,a,$,b] → output 3, list becomes [b,n,a,$]
+ * - etc.
+ *
+ * Notice how repeated 'n' characters produce zeros after the first occurrence!
+ *
+ *
+ * @see Move-to-front transform (Wikipedia)
+ */
+public final class MoveToFront {
+
+ private MoveToFront() {
+ }
+
+ /**
+ * Performs the forward Move-to-Front transform.
+ *
+ * Converts the input string into a list of integers, where each integer represents
+ * the position of the corresponding character in a dynamically-maintained alphabet list.
+ *
+ *
+ * Note: All characters in the input text must exist in the provided alphabet,
+ * otherwise an {@link IllegalArgumentException} is thrown. The alphabet should contain
+ * all unique characters that may appear in the input.
+ *
+ * @param text the input string to transform; if empty, returns an empty list
+ * @param initialAlphabet a string containing the initial ordered set of symbols
+ * (e.g., "$abn" or the full ASCII set); must not be empty
+ * when {@code text} is non-empty
+ * @return a list of integers representing the transformed data, where each integer
+ * is the index of the corresponding input character in the current alphabet state
+ * @throws IllegalArgumentException if {@code text} is non-empty and {@code initialAlphabet}
+ * is {@code null} or empty
+ * @throws IllegalArgumentException if any character in {@code text} is not found in
+ * {@code initialAlphabet}
+ */
+ public static List transform(String text, String initialAlphabet) {
+ if (text == null || text.isEmpty()) {
+ return new ArrayList<>();
+ }
+ if (initialAlphabet == null || initialAlphabet.isEmpty()) {
+ throw new IllegalArgumentException("Alphabet cannot be null or empty when text is not empty.");
+ }
+
+ List output = new ArrayList<>(text.length());
+
+ // Use LinkedList for O(1) add-to-front and O(n) remove operations
+ // This is more efficient than ArrayList for the move-to-front pattern
+ List alphabet = initialAlphabet.chars().mapToObj(c -> (char) c).collect(Collectors.toCollection(LinkedList::new));
+
+ for (char c : text.toCharArray()) {
+ int index = alphabet.indexOf(c);
+ if (index == -1) {
+ throw new IllegalArgumentException("Symbol '" + c + "' not found in the initial alphabet.");
+ }
+
+ output.add(index);
+
+ // Move the character to the front
+ Character symbol = alphabet.remove(index);
+ alphabet.addFirst(symbol);
+ }
+ return output;
+ }
+
+ /**
+ * Performs the inverse Move-to-Front transform.
+ *
+ * Reconstructs the original string from the list of indices produced by the
+ * forward transform. This requires the exact same initial alphabet that was
+ * used in the forward transform.
+ *
+ *
+ * Important: The {@code initialAlphabet} parameter must be identical
+ * to the one used in the forward transform, including character order, or the
+ * output will be incorrect.
+ *
+ * @param indices The list of integers from the forward transform.
+ * @param initialAlphabet the exact same initial alphabet string used for the forward transform;
+ * if {@code null} or empty, returns an empty string
+ * @return the original, untransformed string
+ * @throws IllegalArgumentException if any index in {@code indices} is negative or
+ * exceeds the current alphabet size
+ */
+ public static String inverseTransform(Collection indices, String initialAlphabet) {
+ if (indices == null || indices.isEmpty() || initialAlphabet == null || initialAlphabet.isEmpty()) {
+ return "";
+ }
+
+ StringBuilder output = new StringBuilder(indices.size());
+
+ // Use LinkedList for O(1) add-to-front and O(n) remove operations
+ List alphabet = initialAlphabet.chars().mapToObj(c -> (char) c).collect(Collectors.toCollection(LinkedList::new));
+
+ for (int index : indices) {
+ if (index < 0 || index >= alphabet.size()) {
+ throw new IllegalArgumentException("Index " + index + " is out of bounds for the current alphabet of size " + alphabet.size() + ".");
+ }
+
+ // Get the symbol at the index
+ char symbol = alphabet.get(index);
+ output.append(symbol);
+
+ // Move the symbol to the front (mirroring the forward transform)
+ alphabet.remove(index);
+ alphabet.addFirst(symbol);
+ }
+ return output.toString();
+ }
+}
diff --git a/src/main/java/com/thealgorithms/compression/RunLengthEncoding.java b/src/main/java/com/thealgorithms/compression/RunLengthEncoding.java
index 8d065f4648df..8ac82114b60e 100644
--- a/src/main/java/com/thealgorithms/compression/RunLengthEncoding.java
+++ b/src/main/java/com/thealgorithms/compression/RunLengthEncoding.java
@@ -1,87 +1,87 @@
-package com.thealgorithms.compression;
-
-/**
- * An implementation of the Run-Length Encoding (RLE) algorithm.
- *
- * Run-Length Encoding is a simple form of lossless data compression in which
- * runs of data (sequences in which the same data value occurs in many
- * consecutive data elements) are stored as a single data value and count,
- * rather than as the original run.
- *
- *
This implementation provides methods for both compressing and decompressing
- * a string. For example:
- *
- * - Compressing "AAAABBBCCDAA" results in "4A3B2C1D2A".
- * - Decompressing "4A3B2C1D2A" results in "AAAABBBCCDAA".
- *
- *
- * Time Complexity: O(n) for both compression and decompression, where n is the
- * length of the input string.
- *
- *
References:
- *
- */
-public final class RunLengthEncoding {
-
- /**
- * Private constructor to prevent instantiation of this utility class.
- */
- private RunLengthEncoding() {
- }
-
- /**
- * Compresses a string using the Run-Length Encoding algorithm.
- *
- * @param text The string to be compressed. Must not be null.
- * @return The compressed string. Returns an empty string if the input is empty.
- */
- public static String compress(String text) {
- if (text == null || text.isEmpty()) {
- return "";
- }
-
- StringBuilder compressed = new StringBuilder();
- int count = 1;
-
- for (int i = 0; i < text.length(); i++) {
- // Check if it's the last character or if the next character is different
- if (i == text.length() - 1 || text.charAt(i) != text.charAt(i + 1)) {
- compressed.append(count);
- compressed.append(text.charAt(i));
- count = 1; // Reset count for the new character
- } else {
- count++;
- }
- }
- return compressed.toString();
- }
-
- /**
- * Decompresses a string that was compressed using the Run-Length Encoding algorithm.
- *
- * @param compressedText The compressed string. Must not be null.
- * @return The original, uncompressed string.
- */
- public static String decompress(String compressedText) {
- if (compressedText == null || compressedText.isEmpty()) {
- return "";
- }
-
- StringBuilder decompressed = new StringBuilder();
- int count = 0;
-
- for (char ch : compressedText.toCharArray()) {
- if (Character.isDigit(ch)) {
- // Build the number for runs of 10 or more (e.g., "12A")
- count = count * 10 + ch - '0';
- } else {
- // Append the character 'count' times
- decompressed.append(String.valueOf(ch).repeat(Math.max(0, count)));
- count = 0; // Reset count for the next sequence
- }
- }
- return decompressed.toString();
- }
-}
+package com.thealgorithms.compression;
+
+/**
+ * An implementation of the Run-Length Encoding (RLE) algorithm.
+ *
+ * Run-Length Encoding is a simple form of lossless data compression in which
+ * runs of data (sequences in which the same data value occurs in many
+ * consecutive data elements) are stored as a single data value and count,
+ * rather than as the original run.
+ *
+ *
This implementation provides methods for both compressing and decompressing
+ * a string. For example:
+ *
+ * - Compressing "AAAABBBCCDAA" results in "4A3B2C1D2A".
+ * - Decompressing "4A3B2C1D2A" results in "AAAABBBCCDAA".
+ *
+ *
+ * Time Complexity: O(n) for both compression and decompression, where n is the
+ * length of the input string.
+ *
+ *
References:
+ *
+ */
+public final class RunLengthEncoding {
+
+ /**
+ * Private constructor to prevent instantiation of this utility class.
+ */
+ private RunLengthEncoding() {
+ }
+
+ /**
+ * Compresses a string using the Run-Length Encoding algorithm.
+ *
+ * @param text The string to be compressed. Must not be null.
+ * @return The compressed string. Returns an empty string if the input is empty.
+ */
+ public static String compress(String text) {
+ if (text == null || text.isEmpty()) {
+ return "";
+ }
+
+ StringBuilder compressed = new StringBuilder();
+ int count = 1;
+
+ for (int i = 0; i < text.length(); i++) {
+ // Check if it's the last character or if the next character is different
+ if (i == text.length() - 1 || text.charAt(i) != text.charAt(i + 1)) {
+ compressed.append(count);
+ compressed.append(text.charAt(i));
+ count = 1; // Reset count for the new character
+ } else {
+ count++;
+ }
+ }
+ return compressed.toString();
+ }
+
+ /**
+ * Decompresses a string that was compressed using the Run-Length Encoding algorithm.
+ *
+ * @param compressedText The compressed string. Must not be null.
+ * @return The original, uncompressed string.
+ */
+ public static String decompress(String compressedText) {
+ if (compressedText == null || compressedText.isEmpty()) {
+ return "";
+ }
+
+ StringBuilder decompressed = new StringBuilder();
+ int count = 0;
+
+ for (char ch : compressedText.toCharArray()) {
+ if (Character.isDigit(ch)) {
+ // Build the number for runs of 10 or more (e.g., "12A")
+ count = count * 10 + ch - '0';
+ } else {
+ // Append the character 'count' times
+ decompressed.append(String.valueOf(ch).repeat(Math.max(0, count)));
+ count = 0; // Reset count for the next sequence
+ }
+ }
+ return decompressed.toString();
+ }
+}
diff --git a/src/main/java/com/thealgorithms/compression/ShannonFano.java b/src/main/java/com/thealgorithms/compression/ShannonFano.java
index aa5d7ad91b2f..d6161f9a7a9f 100644
--- a/src/main/java/com/thealgorithms/compression/ShannonFano.java
+++ b/src/main/java/com/thealgorithms/compression/ShannonFano.java
@@ -1,159 +1,159 @@
-package com.thealgorithms.compression;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-/**
- * An implementation of the Shannon-Fano algorithm for generating prefix codes.
- *
- * Shannon-Fano coding is an entropy encoding technique for lossless data
- * compression. It assigns variable-length codes to symbols based on their
- * frequencies of occurrence. It is a precursor to Huffman coding and works by
- * recursively partitioning a sorted list of symbols into two sub-lists with
- * nearly equal total frequencies.
- *
- *
The algorithm works as follows:
- *
- * - Count the frequency of each symbol in the input data.
- * - Sort the symbols in descending order of their frequencies.
- * - Recursively divide the list of symbols into two parts with sums of
- * frequencies as close as possible to each other.
- * - Assign a '0' bit to the codes in the first part and a '1' bit to the codes
- * in the second part.
- * - Repeat the process for each part until a part contains only one symbol.
- *
- *
- * Time Complexity: O(n^2) in this implementation due to the partitioning logic,
- * or O(n log n) if a more optimized partitioning strategy is used.
- * Sorting takes O(n log n), where n is the number of unique symbols.
- *
- *
References:
- *
- */
-public final class ShannonFano {
-
- /**
- * Private constructor to prevent instantiation of this utility class.
- */
- private ShannonFano() {
- }
-
- /**
- * A private inner class to represent a symbol and its frequency.
- * Implements Comparable to allow sorting based on frequency.
- */
- private static class Symbol implements Comparable {
- final char character;
- final int frequency;
- String code = "";
-
- Symbol(char character, int frequency) {
- this.character = character;
- this.frequency = frequency;
- }
-
- @Override
- public int compareTo(Symbol other) {
- return Integer.compare(other.frequency, this.frequency); // Sort descending
- }
- }
-
- /**
- * Generates Shannon-Fano codes for the symbols in a given text.
- *
- * @param text The input string for which to generate codes. Must not be null.
- * @return A map where keys are characters and values are their corresponding Shannon-Fano codes.
- */
- public static Map generateCodes(String text) {
- if (text == null || text.isEmpty()) {
- return Collections.emptyMap();
- }
-
- Map frequencyMap = new HashMap<>();
- for (char c : text.toCharArray()) {
- frequencyMap.put(c, frequencyMap.getOrDefault(c, 0) + 1);
- }
-
- List symbols = new ArrayList<>();
- for (Map.Entry entry : frequencyMap.entrySet()) {
- symbols.add(new Symbol(entry.getKey(), entry.getValue()));
- }
-
- Collections.sort(symbols);
-
- // Special case: only one unique symbol
- if (symbols.size() == 1) {
- symbols.getFirst().code = "0";
- } else {
- buildCodeTree(symbols, 0, symbols.size() - 1, "");
- }
-
- return symbols.stream().collect(Collectors.toMap(s -> s.character, s -> s.code));
- }
-
- /**
- * Recursively builds the Shannon-Fano code tree by partitioning the list of symbols.
- * Uses index-based approach to avoid sublist creation issues.
- *
- * @param symbols The sorted list of symbols to be processed.
- * @param start The start index of the current partition.
- * @param end The end index of the current partition (inclusive).
- * @param prefix The current prefix code being built for the symbols in this partition.
- */
- private static void buildCodeTree(List symbols, int start, int end, String prefix) {
- // The initial check in generateCodes ensures start <= end is always true here.
- // The base case is when a partition has only one symbol.
- if (start == end) {
- symbols.get(start).code = prefix;
- return;
- }
-
- // Find the optimal split point
- int splitIndex = findSplitIndex(symbols, start, end);
-
- // Recursively process left and right partitions with updated prefixes
- buildCodeTree(symbols, start, splitIndex, prefix + "0");
- buildCodeTree(symbols, splitIndex + 1, end, prefix + "1");
- }
-
- /**
- * Finds the index that splits the range into two parts with the most balanced frequency sums.
- * This method tries every possible split point and returns the index that minimizes the
- * absolute difference between the two partition sums.
- *
- * @param symbols The sorted list of symbols.
- * @param start The start index of the range.
- * @param end The end index of the range (inclusive).
- * @return The index of the last element in the first partition.
- */
- private static int findSplitIndex(List symbols, int start, int end) {
- // Calculate total frequency for the entire range
- long totalFrequency = 0;
- for (int i = start; i <= end; i++) {
- totalFrequency += symbols.get(i).frequency;
- }
-
- long leftSum = 0;
- long minDifference = Long.MAX_VALUE;
- int splitIndex = start;
-
- // Try every possible split point and find the one with minimum difference
- for (int i = start; i < end; i++) {
- leftSum += symbols.get(i).frequency;
- long rightSum = totalFrequency - leftSum;
- long difference = Math.abs(leftSum - rightSum);
-
- if (difference < minDifference) {
- minDifference = difference;
- splitIndex = i;
- }
- }
- return splitIndex;
- }
-}
+package com.thealgorithms.compression;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * An implementation of the Shannon-Fano algorithm for generating prefix codes.
+ *
+ * Shannon-Fano coding is an entropy encoding technique for lossless data
+ * compression. It assigns variable-length codes to symbols based on their
+ * frequencies of occurrence. It is a precursor to Huffman coding and works by
+ * recursively partitioning a sorted list of symbols into two sub-lists with
+ * nearly equal total frequencies.
+ *
+ *
The algorithm works as follows:
+ *
+ * - Count the frequency of each symbol in the input data.
+ * - Sort the symbols in descending order of their frequencies.
+ * - Recursively divide the list of symbols into two parts with sums of
+ * frequencies as close as possible to each other.
+ * - Assign a '0' bit to the codes in the first part and a '1' bit to the codes
+ * in the second part.
+ * - Repeat the process for each part until a part contains only one symbol.
+ *
+ *
+ * Time Complexity: O(n^2) in this implementation due to the partitioning logic,
+ * or O(n log n) if a more optimized partitioning strategy is used.
+ * Sorting takes O(n log n), where n is the number of unique symbols.
+ *
+ *
References:
+ *
+ */
+public final class ShannonFano {
+
+ /**
+ * Private constructor to prevent instantiation of this utility class.
+ */
+ private ShannonFano() {
+ }
+
+ /**
+ * A private inner class to represent a symbol and its frequency.
+ * Implements Comparable to allow sorting based on frequency.
+ */
+ private static class Symbol implements Comparable {
+ final char character;
+ final int frequency;
+ String code = "";
+
+ Symbol(char character, int frequency) {
+ this.character = character;
+ this.frequency = frequency;
+ }
+
+ @Override
+ public int compareTo(Symbol other) {
+ return Integer.compare(other.frequency, this.frequency); // Sort descending
+ }
+ }
+
+ /**
+ * Generates Shannon-Fano codes for the symbols in a given text.
+ *
+ * @param text The input string for which to generate codes. Must not be null.
+ * @return A map where keys are characters and values are their corresponding Shannon-Fano codes.
+ */
+ public static Map generateCodes(String text) {
+ if (text == null || text.isEmpty()) {
+ return Collections.emptyMap();
+ }
+
+ Map frequencyMap = new HashMap<>();
+ for (char c : text.toCharArray()) {
+ frequencyMap.put(c, frequencyMap.getOrDefault(c, 0) + 1);
+ }
+
+ List symbols = new ArrayList<>();
+ for (Map.Entry entry : frequencyMap.entrySet()) {
+ symbols.add(new Symbol(entry.getKey(), entry.getValue()));
+ }
+
+ Collections.sort(symbols);
+
+ // Special case: only one unique symbol
+ if (symbols.size() == 1) {
+ symbols.getFirst().code = "0";
+ } else {
+ buildCodeTree(symbols, 0, symbols.size() - 1, "");
+ }
+
+ return symbols.stream().collect(Collectors.toMap(s -> s.character, s -> s.code));
+ }
+
+ /**
+ * Recursively builds the Shannon-Fano code tree by partitioning the list of symbols.
+ * Uses index-based approach to avoid sublist creation issues.
+ *
+ * @param symbols The sorted list of symbols to be processed.
+ * @param start The start index of the current partition.
+ * @param end The end index of the current partition (inclusive).
+ * @param prefix The current prefix code being built for the symbols in this partition.
+ */
+ private static void buildCodeTree(List symbols, int start, int end, String prefix) {
+ // The initial check in generateCodes ensures start <= end is always true here.
+ // The base case is when a partition has only one symbol.
+ if (start == end) {
+ symbols.get(start).code = prefix;
+ return;
+ }
+
+ // Find the optimal split point
+ int splitIndex = findSplitIndex(symbols, start, end);
+
+ // Recursively process left and right partitions with updated prefixes
+ buildCodeTree(symbols, start, splitIndex, prefix + "0");
+ buildCodeTree(symbols, splitIndex + 1, end, prefix + "1");
+ }
+
+ /**
+ * Finds the index that splits the range into two parts with the most balanced frequency sums.
+ * This method tries every possible split point and returns the index that minimizes the
+ * absolute difference between the two partition sums.
+ *
+ * @param symbols The sorted list of symbols.
+ * @param start The start index of the range.
+ * @param end The end index of the range (inclusive).
+ * @return The index of the last element in the first partition.
+ */
+ private static int findSplitIndex(List symbols, int start, int end) {
+ // Calculate total frequency for the entire range
+ long totalFrequency = 0;
+ for (int i = start; i <= end; i++) {
+ totalFrequency += symbols.get(i).frequency;
+ }
+
+ long leftSum = 0;
+ long minDifference = Long.MAX_VALUE;
+ int splitIndex = start;
+
+ // Try every possible split point and find the one with minimum difference
+ for (int i = start; i < end; i++) {
+ leftSum += symbols.get(i).frequency;
+ long rightSum = totalFrequency - leftSum;
+ long difference = Math.abs(leftSum - rightSum);
+
+ if (difference < minDifference) {
+ minDifference = difference;
+ splitIndex = i;
+ }
+ }
+ return splitIndex;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/conversions/AffineConverter.java b/src/main/java/com/thealgorithms/conversions/AffineConverter.java
index 199a6dd517d5..93e85e419999 100644
--- a/src/main/java/com/thealgorithms/conversions/AffineConverter.java
+++ b/src/main/java/com/thealgorithms/conversions/AffineConverter.java
@@ -1,64 +1,64 @@
-package com.thealgorithms.conversions;
-
-/**
- * A utility class to perform affine transformations of the form:
- * y = slope * x + intercept.
- *
- * This class supports inversion and composition of affine transformations.
- * It is immutable, meaning each instance represents a fixed transformation.
- */
-public final class AffineConverter {
- private final double slope;
- private final double intercept;
-
- /**
- * Constructs an AffineConverter with the given slope and intercept.
- *
- * @param inSlope The slope of the affine transformation.
- * @param inIntercept The intercept (constant term) of the affine transformation.
- * @throws IllegalArgumentException if either parameter is NaN.
- */
- public AffineConverter(final double inSlope, final double inIntercept) {
- if (Double.isNaN(inSlope) || Double.isNaN(inIntercept)) {
- throw new IllegalArgumentException("Slope and intercept must be valid numbers.");
- }
- slope = inSlope;
- intercept = inIntercept;
- }
-
- /**
- * Converts the given input value using the affine transformation:
- * result = slope * inValue + intercept.
- *
- * @param inValue The input value to convert.
- * @return The transformed value.
- */
- public double convert(final double inValue) {
- return slope * inValue + intercept;
- }
-
- /**
- * Returns a new AffineConverter representing the inverse of the current transformation.
- * The inverse of y = slope * x + intercept is x = (y - intercept) / slope.
- *
- * @return A new AffineConverter representing the inverse transformation.
- * @throws AssertionError if the slope is zero, as the inverse would be undefined.
- */
- public AffineConverter invert() {
- assert slope != 0.0 : "Slope cannot be zero for inversion.";
- return new AffineConverter(1.0 / slope, -intercept / slope);
- }
-
- /**
- * Composes this affine transformation with another, returning a new AffineConverter.
- * If this transformation is f(x) and the other is g(x), the result is f(g(x)).
- *
- * @param other Another AffineConverter to compose with.
- * @return A new AffineConverter representing the composition of the two transformations.
- */
- public AffineConverter compose(final AffineConverter other) {
- double newSlope = slope * other.slope;
- double newIntercept = slope * other.intercept + intercept;
- return new AffineConverter(newSlope, newIntercept);
- }
-}
+package com.thealgorithms.conversions;
+
+/**
+ * A utility class to perform affine transformations of the form:
+ * y = slope * x + intercept.
+ *
+ * This class supports inversion and composition of affine transformations.
+ * It is immutable, meaning each instance represents a fixed transformation.
+ */
+public final class AffineConverter {
+ private final double slope;
+ private final double intercept;
+
+ /**
+ * Constructs an AffineConverter with the given slope and intercept.
+ *
+ * @param inSlope The slope of the affine transformation.
+ * @param inIntercept The intercept (constant term) of the affine transformation.
+ * @throws IllegalArgumentException if either parameter is NaN.
+ */
+ public AffineConverter(final double inSlope, final double inIntercept) {
+ if (Double.isNaN(inSlope) || Double.isNaN(inIntercept)) {
+ throw new IllegalArgumentException("Slope and intercept must be valid numbers.");
+ }
+ slope = inSlope;
+ intercept = inIntercept;
+ }
+
+ /**
+ * Converts the given input value using the affine transformation:
+ * result = slope * inValue + intercept.
+ *
+ * @param inValue The input value to convert.
+ * @return The transformed value.
+ */
+ public double convert(final double inValue) {
+ return slope * inValue + intercept;
+ }
+
+ /**
+ * Returns a new AffineConverter representing the inverse of the current transformation.
+ * The inverse of y = slope * x + intercept is x = (y - intercept) / slope.
+ *
+ * @return A new AffineConverter representing the inverse transformation.
+ * @throws AssertionError if the slope is zero, as the inverse would be undefined.
+ */
+ public AffineConverter invert() {
+ assert slope != 0.0 : "Slope cannot be zero for inversion.";
+ return new AffineConverter(1.0 / slope, -intercept / slope);
+ }
+
+ /**
+ * Composes this affine transformation with another, returning a new AffineConverter.
+ * If this transformation is f(x) and the other is g(x), the result is f(g(x)).
+ *
+ * @param other Another AffineConverter to compose with.
+ * @return A new AffineConverter representing the composition of the two transformations.
+ */
+ public AffineConverter compose(final AffineConverter other) {
+ double newSlope = slope * other.slope;
+ double newIntercept = slope * other.intercept + intercept;
+ return new AffineConverter(newSlope, newIntercept);
+ }
+}
diff --git a/src/main/java/com/thealgorithms/conversions/AnyBaseToAnyBase.java b/src/main/java/com/thealgorithms/conversions/AnyBaseToAnyBase.java
index 7a9448fd8fe7..120ec8353a6e 100644
--- a/src/main/java/com/thealgorithms/conversions/AnyBaseToAnyBase.java
+++ b/src/main/java/com/thealgorithms/conversions/AnyBaseToAnyBase.java
@@ -1,181 +1,181 @@
-package com.thealgorithms.conversions;
-
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.InputMismatchException;
-import java.util.Scanner;
-
-/**
- * Class for converting from "any" base to "any" other base, when "any" means
- * from 2-36. Works by going from base 1 to decimal to base 2. Includes
- * auxiliary method for determining whether a number is valid for a given base.
- *
- * @author Michael Rolland
- * @version 2017.10.10
- */
-public final class AnyBaseToAnyBase {
- private AnyBaseToAnyBase() {
- }
-
- /**
- * Smallest and largest base you want to accept as valid input
- */
- static final int MINIMUM_BASE = 2;
-
- static final int MAXIMUM_BASE = 36;
-
- public static void main(String[] args) {
- Scanner in = new Scanner(System.in);
- String n;
- int b1;
- int b2;
- while (true) {
- try {
- System.out.print("Enter number: ");
- n = in.next();
- System.out.print("Enter beginning base (between " + MINIMUM_BASE + " and " + MAXIMUM_BASE + "): ");
- b1 = in.nextInt();
- if (b1 > MAXIMUM_BASE || b1 < MINIMUM_BASE) {
- System.out.println("Invalid base!");
- continue;
- }
- if (!validForBase(n, b1)) {
- System.out.println("The number is invalid for this base!");
- continue;
- }
- System.out.print("Enter end base (between " + MINIMUM_BASE + " and " + MAXIMUM_BASE + "): ");
- b2 = in.nextInt();
- if (b2 > MAXIMUM_BASE || b2 < MINIMUM_BASE) {
- System.out.println("Invalid base!");
- continue;
- }
- break;
- } catch (InputMismatchException e) {
- System.out.println("Invalid input.");
- in.next();
- }
- }
- System.out.println(base2base(n, b1, b2));
- in.close();
- }
-
- /**
- * Checks if a number (as a String) is valid for a given base.
- */
- public static boolean validForBase(String n, int base) {
- char[] validDigits = {
- '0',
- '1',
- '2',
- '3',
- '4',
- '5',
- '6',
- '7',
- '8',
- '9',
- 'A',
- 'B',
- 'C',
- 'D',
- 'E',
- 'F',
- 'G',
- 'H',
- 'I',
- 'J',
- 'K',
- 'L',
- 'M',
- 'N',
- 'O',
- 'P',
- 'Q',
- 'R',
- 'S',
- 'T',
- 'U',
- 'V',
- 'W',
- 'X',
- 'Y',
- 'Z',
- };
- // digitsForBase contains all the valid digits for the base given
- char[] digitsForBase = Arrays.copyOfRange(validDigits, 0, base);
-
- // Convert character array into set for convenience of contains() method
- HashSet digitsList = new HashSet<>();
- for (int i = 0; i < digitsForBase.length; i++) {
- digitsList.add(digitsForBase[i]);
- }
-
- // Check that every digit in n is within the list of valid digits for that base.
- for (char c : n.toCharArray()) {
- if (!digitsList.contains(c)) {
- return false;
- }
- }
-
- return true;
- }
-
- /**
- * Method to convert any integer from base b1 to base b2. Works by
- * converting from b1 to decimal, then decimal to b2.
- *
- * @param n The integer to be converted.
- * @param b1 Beginning base.
- * @param b2 End base.
- * @return n in base b2.
- */
- public static String base2base(String n, int b1, int b2) {
- // Declare variables: decimal value of n,
- // character of base b1, character of base b2,
- // and the string that will be returned.
- int decimalValue = 0;
- int charB2;
- char charB1;
- StringBuilder output = new StringBuilder();
- // Go through every character of n
- for (int i = 0; i < n.length(); i++) {
- // store the character in charB1
- charB1 = n.charAt(i);
- // if it is a non-number, convert it to a decimal value >9 and store it in charB2
- if (charB1 >= 'A' && charB1 <= 'Z') {
- charB2 = 10 + (charB1 - 'A');
- } // Else, store the integer value in charB2
- else {
- charB2 = charB1 - '0';
- }
- // Convert the digit to decimal and add it to the
- // decimalValue of n
- decimalValue = decimalValue * b1 + charB2;
- }
-
- // Converting the decimal value to base b2:
- // A number is converted from decimal to another base
- // by continuously dividing by the base and recording
- // the remainder until the quotient is zero. The number in the
- // new base is the remainders, with the last remainder
- // being the left-most digit.
- if (0 == decimalValue) {
- return "0";
- }
- // While the quotient is NOT zero:
- while (decimalValue != 0) {
- // If the remainder is a digit < 10, simply add it to
- // the left side of the new number.
- if (decimalValue % b2 < 10) {
- output.insert(0, decimalValue % b2);
- } // If the remainder is >= 10, add a character with the
- // corresponding value to the new number. (A = 10, B = 11, C = 12, ...)
- else {
- output.insert(0, (char) ((decimalValue % b2) + 55));
- }
- // Divide by the new base again
- decimalValue /= b2;
- }
- return output.toString();
- }
-}
+package com.thealgorithms.conversions;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.InputMismatchException;
+import java.util.Scanner;
+
+/**
+ * Class for converting from "any" base to "any" other base, when "any" means
+ * from 2-36. Works by going from base 1 to decimal to base 2. Includes
+ * auxiliary method for determining whether a number is valid for a given base.
+ *
+ * @author Michael Rolland
+ * @version 2017.10.10
+ */
+public final class AnyBaseToAnyBase {
+ private AnyBaseToAnyBase() {
+ }
+
+ /**
+ * Smallest and largest base you want to accept as valid input
+ */
+ static final int MINIMUM_BASE = 2;
+
+ static final int MAXIMUM_BASE = 36;
+
+ public static void main(String[] args) {
+ Scanner in = new Scanner(System.in);
+ String n;
+ int b1;
+ int b2;
+ while (true) {
+ try {
+ System.out.print("Enter number: ");
+ n = in.next();
+ System.out.print("Enter beginning base (between " + MINIMUM_BASE + " and " + MAXIMUM_BASE + "): ");
+ b1 = in.nextInt();
+ if (b1 > MAXIMUM_BASE || b1 < MINIMUM_BASE) {
+ System.out.println("Invalid base!");
+ continue;
+ }
+ if (!validForBase(n, b1)) {
+ System.out.println("The number is invalid for this base!");
+ continue;
+ }
+ System.out.print("Enter end base (between " + MINIMUM_BASE + " and " + MAXIMUM_BASE + "): ");
+ b2 = in.nextInt();
+ if (b2 > MAXIMUM_BASE || b2 < MINIMUM_BASE) {
+ System.out.println("Invalid base!");
+ continue;
+ }
+ break;
+ } catch (InputMismatchException e) {
+ System.out.println("Invalid input.");
+ in.next();
+ }
+ }
+ System.out.println(base2base(n, b1, b2));
+ in.close();
+ }
+
+ /**
+ * Checks if a number (as a String) is valid for a given base.
+ */
+ public static boolean validForBase(String n, int base) {
+ char[] validDigits = {
+ '0',
+ '1',
+ '2',
+ '3',
+ '4',
+ '5',
+ '6',
+ '7',
+ '8',
+ '9',
+ 'A',
+ 'B',
+ 'C',
+ 'D',
+ 'E',
+ 'F',
+ 'G',
+ 'H',
+ 'I',
+ 'J',
+ 'K',
+ 'L',
+ 'M',
+ 'N',
+ 'O',
+ 'P',
+ 'Q',
+ 'R',
+ 'S',
+ 'T',
+ 'U',
+ 'V',
+ 'W',
+ 'X',
+ 'Y',
+ 'Z',
+ };
+ // digitsForBase contains all the valid digits for the base given
+ char[] digitsForBase = Arrays.copyOfRange(validDigits, 0, base);
+
+ // Convert character array into set for convenience of contains() method
+ HashSet digitsList = new HashSet<>();
+ for (int i = 0; i < digitsForBase.length; i++) {
+ digitsList.add(digitsForBase[i]);
+ }
+
+ // Check that every digit in n is within the list of valid digits for that base.
+ for (char c : n.toCharArray()) {
+ if (!digitsList.contains(c)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Method to convert any integer from base b1 to base b2. Works by
+ * converting from b1 to decimal, then decimal to b2.
+ *
+ * @param n The integer to be converted.
+ * @param b1 Beginning base.
+ * @param b2 End base.
+ * @return n in base b2.
+ */
+ public static String base2base(String n, int b1, int b2) {
+ // Declare variables: decimal value of n,
+ // character of base b1, character of base b2,
+ // and the string that will be returned.
+ int decimalValue = 0;
+ int charB2;
+ char charB1;
+ StringBuilder output = new StringBuilder();
+ // Go through every character of n
+ for (int i = 0; i < n.length(); i++) {
+ // store the character in charB1
+ charB1 = n.charAt(i);
+ // if it is a non-number, convert it to a decimal value >9 and store it in charB2
+ if (charB1 >= 'A' && charB1 <= 'Z') {
+ charB2 = 10 + (charB1 - 'A');
+ } // Else, store the integer value in charB2
+ else {
+ charB2 = charB1 - '0';
+ }
+ // Convert the digit to decimal and add it to the
+ // decimalValue of n
+ decimalValue = decimalValue * b1 + charB2;
+ }
+
+ // Converting the decimal value to base b2:
+ // A number is converted from decimal to another base
+ // by continuously dividing by the base and recording
+ // the remainder until the quotient is zero. The number in the
+ // new base is the remainders, with the last remainder
+ // being the left-most digit.
+ if (0 == decimalValue) {
+ return "0";
+ }
+ // While the quotient is NOT zero:
+ while (decimalValue != 0) {
+ // If the remainder is a digit < 10, simply add it to
+ // the left side of the new number.
+ if (decimalValue % b2 < 10) {
+ output.insert(0, decimalValue % b2);
+ } // If the remainder is >= 10, add a character with the
+ // corresponding value to the new number. (A = 10, B = 11, C = 12, ...)
+ else {
+ output.insert(0, (char) ((decimalValue % b2) + 55));
+ }
+ // Divide by the new base again
+ decimalValue /= b2;
+ }
+ return output.toString();
+ }
+}
diff --git a/src/main/java/com/thealgorithms/conversions/AnyBaseToDecimal.java b/src/main/java/com/thealgorithms/conversions/AnyBaseToDecimal.java
index cdab98c7c28a..935ae6f68a89 100644
--- a/src/main/java/com/thealgorithms/conversions/AnyBaseToDecimal.java
+++ b/src/main/java/com/thealgorithms/conversions/AnyBaseToDecimal.java
@@ -1,52 +1,52 @@
-package com.thealgorithms.conversions;
-
-/**
- * @author Varun Upadhyay (...)
- */
-public final class AnyBaseToDecimal {
- private static final int CHAR_OFFSET_FOR_DIGIT = '0';
- private static final int CHAR_OFFSET_FOR_UPPERCASE = 'A' - 10;
-
- private AnyBaseToDecimal() {
- }
-
- /**
- * Convert any radix to a decimal number.
- *
- * @param input the string to be converted
- * @param radix the radix (base) of the input string
- * @return the decimal equivalent of the input string
- * @throws NumberFormatException if the input string or radix is invalid
- */
- public static int convertToDecimal(String input, int radix) {
- int result = 0;
- int power = 1;
-
- for (int i = input.length() - 1; i >= 0; i--) {
- int digit = valOfChar(input.charAt(i));
- if (digit >= radix) {
- throw new NumberFormatException("For input string: " + input);
- }
- result += digit * power;
- power *= radix;
- }
- return result;
- }
-
- /**
- * Convert a character to its integer value.
- *
- * @param character the character to be converted
- * @return the integer value represented by the character
- * @throws NumberFormatException if the character is not an uppercase letter or a digit
- */
- private static int valOfChar(char character) {
- if (Character.isDigit(character)) {
- return character - CHAR_OFFSET_FOR_DIGIT;
- } else if (Character.isUpperCase(character)) {
- return character - CHAR_OFFSET_FOR_UPPERCASE;
- } else {
- throw new NumberFormatException("invalid character:" + character);
- }
- }
-}
+package com.thealgorithms.conversions;
+
+/**
+ * @author Varun Upadhyay (...)
+ */
+public final class AnyBaseToDecimal {
+ private static final int CHAR_OFFSET_FOR_DIGIT = '0';
+ private static final int CHAR_OFFSET_FOR_UPPERCASE = 'A' - 10;
+
+ private AnyBaseToDecimal() {
+ }
+
+ /**
+ * Convert any radix to a decimal number.
+ *
+ * @param input the string to be converted
+ * @param radix the radix (base) of the input string
+ * @return the decimal equivalent of the input string
+ * @throws NumberFormatException if the input string or radix is invalid
+ */
+ public static int convertToDecimal(String input, int radix) {
+ int result = 0;
+ int power = 1;
+
+ for (int i = input.length() - 1; i >= 0; i--) {
+ int digit = valOfChar(input.charAt(i));
+ if (digit >= radix) {
+ throw new NumberFormatException("For input string: " + input);
+ }
+ result += digit * power;
+ power *= radix;
+ }
+ return result;
+ }
+
+ /**
+ * Convert a character to its integer value.
+ *
+ * @param character the character to be converted
+ * @return the integer value represented by the character
+ * @throws NumberFormatException if the character is not an uppercase letter or a digit
+ */
+ private static int valOfChar(char character) {
+ if (Character.isDigit(character)) {
+ return character - CHAR_OFFSET_FOR_DIGIT;
+ } else if (Character.isUpperCase(character)) {
+ return character - CHAR_OFFSET_FOR_UPPERCASE;
+ } else {
+ throw new NumberFormatException("invalid character:" + character);
+ }
+ }
+}
diff --git a/src/main/java/com/thealgorithms/conversions/AnytoAny.java b/src/main/java/com/thealgorithms/conversions/AnytoAny.java
index e7bdbc2b79c4..e766631f19c9 100644
--- a/src/main/java/com/thealgorithms/conversions/AnytoAny.java
+++ b/src/main/java/com/thealgorithms/conversions/AnytoAny.java
@@ -1,68 +1,68 @@
-package com.thealgorithms.conversions;
-
-/**
- * A utility class for converting numbers from any base to any other base.
- *
- * This class provides a method to convert a source number from a given base
- * to a destination number in another base. Valid bases range from 2 to 10.
- */
-public final class AnytoAny {
- private AnytoAny() {
- }
-
- /**
- * Converts a number from a source base to a destination base.
- *
- * @param sourceNumber The number in the source base (as an integer).
- * @param sourceBase The base of the source number (between 2 and 10).
- * @param destBase The base to which the number should be converted (between 2 and 10).
- * @throws IllegalArgumentException if the bases are not between 2 and 10.
- * @return The converted number in the destination base (as an integer).
- */
- public static int convertBase(int sourceNumber, int sourceBase, int destBase) {
- if (sourceBase < 2 || sourceBase > 10 || destBase < 2 || destBase > 10) {
- throw new IllegalArgumentException("Bases must be between 2 and 10.");
- }
-
- int decimalValue = toDecimal(sourceNumber, sourceBase);
- return fromDecimal(decimalValue, destBase);
- }
-
- /**
- * Converts a number from a given base to its decimal representation (base 10).
- *
- * @param number The number in the original base.
- * @param base The base of the given number.
- * @return The decimal representation of the number.
- */
- private static int toDecimal(int number, int base) {
- int decimalValue = 0;
- int multiplier = 1;
-
- while (number != 0) {
- decimalValue += (number % 10) * multiplier;
- multiplier *= base;
- number /= 10;
- }
- return decimalValue;
- }
-
- /**
- * Converts a decimal (base 10) number to a specified base.
- *
- * @param decimal The decimal number to convert.
- * @param base The destination base for conversion.
- * @return The number in the specified base.
- */
- private static int fromDecimal(int decimal, int base) {
- int result = 0;
- int multiplier = 1;
-
- while (decimal != 0) {
- result += (decimal % base) * multiplier;
- multiplier *= 10;
- decimal /= base;
- }
- return result;
- }
-}
+package com.thealgorithms.conversions;
+
+/**
+ * A utility class for converting numbers from any base to any other base.
+ *
+ * This class provides a method to convert a source number from a given base
+ * to a destination number in another base. Valid bases range from 2 to 10.
+ */
+public final class AnytoAny {
+ private AnytoAny() {
+ }
+
+ /**
+ * Converts a number from a source base to a destination base.
+ *
+ * @param sourceNumber The number in the source base (as an integer).
+ * @param sourceBase The base of the source number (between 2 and 10).
+ * @param destBase The base to which the number should be converted (between 2 and 10).
+ * @throws IllegalArgumentException if the bases are not between 2 and 10.
+ * @return The converted number in the destination base (as an integer).
+ */
+ public static int convertBase(int sourceNumber, int sourceBase, int destBase) {
+ if (sourceBase < 2 || sourceBase > 10 || destBase < 2 || destBase > 10) {
+ throw new IllegalArgumentException("Bases must be between 2 and 10.");
+ }
+
+ int decimalValue = toDecimal(sourceNumber, sourceBase);
+ return fromDecimal(decimalValue, destBase);
+ }
+
+ /**
+ * Converts a number from a given base to its decimal representation (base 10).
+ *
+ * @param number The number in the original base.
+ * @param base The base of the given number.
+ * @return The decimal representation of the number.
+ */
+ private static int toDecimal(int number, int base) {
+ int decimalValue = 0;
+ int multiplier = 1;
+
+ while (number != 0) {
+ decimalValue += (number % 10) * multiplier;
+ multiplier *= base;
+ number /= 10;
+ }
+ return decimalValue;
+ }
+
+ /**
+ * Converts a decimal (base 10) number to a specified base.
+ *
+ * @param decimal The decimal number to convert.
+ * @param base The destination base for conversion.
+ * @return The number in the specified base.
+ */
+ private static int fromDecimal(int decimal, int base) {
+ int result = 0;
+ int multiplier = 1;
+
+ while (decimal != 0) {
+ result += (decimal % base) * multiplier;
+ multiplier *= 10;
+ decimal /= base;
+ }
+ return result;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/conversions/Base64.java b/src/main/java/com/thealgorithms/conversions/Base64.java
index 5219c4ba7f4e..38ab99151bf3 100644
--- a/src/main/java/com/thealgorithms/conversions/Base64.java
+++ b/src/main/java/com/thealgorithms/conversions/Base64.java
@@ -1,196 +1,196 @@
-package com.thealgorithms.conversions;
-
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Base64 is a group of binary-to-text encoding schemes that represent binary data
- * in an ASCII string format by translating it into a radix-64 representation.
- * Each base64 digit represents exactly 6 bits of data.
- *
- * Base64 encoding is commonly used when there is a need to encode binary data
- * that needs to be stored and transferred over media that are designed to deal
- * with textual data.
- *
- * Wikipedia Reference: https://en.wikipedia.org/wiki/Base64
- * Author: Nithin U.
- * Github: https://github.com/NithinU2802
- */
-
-public final class Base64 {
-
- // Base64 character set
- private static final String BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- private static final char PADDING_CHAR = '=';
-
- private Base64() {
- }
-
- /**
- * Encodes the given byte array to a Base64 encoded string.
- *
- * @param input the byte array to encode
- * @return the Base64 encoded string
- * @throws IllegalArgumentException if input is null
- */
- public static String encode(byte[] input) {
- if (input == null) {
- throw new IllegalArgumentException("Input cannot be null");
- }
-
- if (input.length == 0) {
- return "";
- }
-
- StringBuilder result = new StringBuilder();
- int padding = 0;
-
- // Process input in groups of 3 bytes
- for (int i = 0; i < input.length; i += 3) {
- // Get up to 3 bytes
- int byte1 = input[i] & 0xFF;
- int byte2 = (i + 1 < input.length) ? (input[i + 1] & 0xFF) : 0;
- int byte3 = (i + 2 < input.length) ? (input[i + 2] & 0xFF) : 0;
-
- // Calculate padding needed
- if (i + 1 >= input.length) {
- padding = 2;
- } else if (i + 2 >= input.length) {
- padding = 1;
- }
-
- // Combine 3 bytes into a 24-bit number
- int combined = (byte1 << 16) | (byte2 << 8) | byte3;
-
- // Extract four 6-bit groups
- result.append(BASE64_CHARS.charAt((combined >> 18) & 0x3F));
- result.append(BASE64_CHARS.charAt((combined >> 12) & 0x3F));
- result.append(BASE64_CHARS.charAt((combined >> 6) & 0x3F));
- result.append(BASE64_CHARS.charAt(combined & 0x3F));
- }
-
- // Replace padding characters
- if (padding > 0) {
- result.setLength(result.length() - padding);
- for (int i = 0; i < padding; i++) {
- result.append(PADDING_CHAR);
- }
- }
-
- return result.toString();
- }
-
- /**
- * Encodes the given string to a Base64 encoded string using UTF-8 encoding.
- *
- * @param input the string to encode
- * @return the Base64 encoded string
- * @throws IllegalArgumentException if input is null
- */
- public static String encode(String input) {
- if (input == null) {
- throw new IllegalArgumentException("Input cannot be null");
- }
-
- return encode(input.getBytes(StandardCharsets.UTF_8));
- }
-
- /**
- * Decodes the given Base64 encoded string to a byte array.
- *
- * @param input the Base64 encoded string to decode
- * @return the decoded byte array
- * @throws IllegalArgumentException if input is null or contains invalid Base64 characters
- */
- public static byte[] decode(String input) {
- if (input == null) {
- throw new IllegalArgumentException("Input cannot be null");
- }
-
- if (input.isEmpty()) {
- return new byte[0];
- }
-
- // Strict RFC 4648 compliance: length must be a multiple of 4
- if (input.length() % 4 != 0) {
- throw new IllegalArgumentException("Invalid Base64 input length; must be multiple of 4");
- }
-
- // Validate padding: '=' can only appear at the end (last 1 or 2 chars)
- int firstPadding = input.indexOf('=');
- if (firstPadding != -1 && firstPadding < input.length() - 2) {
- throw new IllegalArgumentException("Padding '=' can only appear at the end (last 1 or 2 characters)");
- }
-
- List result = new ArrayList<>();
-
- // Process input in groups of 4 characters
- for (int i = 0; i < input.length(); i += 4) {
- // Get up to 4 characters
- int char1 = getBase64Value(input.charAt(i));
- int char2 = getBase64Value(input.charAt(i + 1));
- int char3 = input.charAt(i + 2) == '=' ? 0 : getBase64Value(input.charAt(i + 2));
- int char4 = input.charAt(i + 3) == '=' ? 0 : getBase64Value(input.charAt(i + 3));
-
- // Combine four 6-bit groups into a 24-bit number
- int combined = (char1 << 18) | (char2 << 12) | (char3 << 6) | char4;
-
- // Extract three 8-bit bytes
- result.add((byte) ((combined >> 16) & 0xFF));
- if (input.charAt(i + 2) != '=') {
- result.add((byte) ((combined >> 8) & 0xFF));
- }
- if (input.charAt(i + 3) != '=') {
- result.add((byte) (combined & 0xFF));
- }
- }
-
- // Convert List to byte[]
- byte[] resultArray = new byte[result.size()];
- for (int i = 0; i < result.size(); i++) {
- resultArray[i] = result.get(i);
- }
-
- return resultArray;
- }
-
- /**
- * Decodes the given Base64 encoded string to a string using UTF-8 encoding.
- *
- * @param input the Base64 encoded string to decode
- * @return the decoded string
- * @throws IllegalArgumentException if input is null or contains invalid Base64 characters
- */
- public static String decodeToString(String input) {
- if (input == null) {
- throw new IllegalArgumentException("Input cannot be null");
- }
-
- byte[] decodedBytes = decode(input);
- return new String(decodedBytes, StandardCharsets.UTF_8);
- }
-
- /**
- * Gets the numeric value of a Base64 character.
- *
- * @param c the Base64 character
- * @return the numeric value (0-63)
- * @throws IllegalArgumentException if character is not a valid Base64 character
- */
- private static int getBase64Value(char c) {
- if (c >= 'A' && c <= 'Z') {
- return c - 'A';
- } else if (c >= 'a' && c <= 'z') {
- return c - 'a' + 26;
- } else if (c >= '0' && c <= '9') {
- return c - '0' + 52;
- } else if (c == '+') {
- return 62;
- } else if (c == '/') {
- return 63;
- } else {
- throw new IllegalArgumentException("Invalid Base64 character: " + c);
- }
- }
-}
+package com.thealgorithms.conversions;
+
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Base64 is a group of binary-to-text encoding schemes that represent binary data
+ * in an ASCII string format by translating it into a radix-64 representation.
+ * Each base64 digit represents exactly 6 bits of data.
+ *
+ * Base64 encoding is commonly used when there is a need to encode binary data
+ * that needs to be stored and transferred over media that are designed to deal
+ * with textual data.
+ *
+ * Wikipedia Reference: https://en.wikipedia.org/wiki/Base64
+ * Author: Nithin U.
+ * Github: https://github.com/NithinU2802
+ */
+
+public final class Base64 {
+
+ // Base64 character set
+ private static final String BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ private static final char PADDING_CHAR = '=';
+
+ private Base64() {
+ }
+
+ /**
+ * Encodes the given byte array to a Base64 encoded string.
+ *
+ * @param input the byte array to encode
+ * @return the Base64 encoded string
+ * @throws IllegalArgumentException if input is null
+ */
+ public static String encode(byte[] input) {
+ if (input == null) {
+ throw new IllegalArgumentException("Input cannot be null");
+ }
+
+ if (input.length == 0) {
+ return "";
+ }
+
+ StringBuilder result = new StringBuilder();
+ int padding = 0;
+
+ // Process input in groups of 3 bytes
+ for (int i = 0; i < input.length; i += 3) {
+ // Get up to 3 bytes
+ int byte1 = input[i] & 0xFF;
+ int byte2 = (i + 1 < input.length) ? (input[i + 1] & 0xFF) : 0;
+ int byte3 = (i + 2 < input.length) ? (input[i + 2] & 0xFF) : 0;
+
+ // Calculate padding needed
+ if (i + 1 >= input.length) {
+ padding = 2;
+ } else if (i + 2 >= input.length) {
+ padding = 1;
+ }
+
+ // Combine 3 bytes into a 24-bit number
+ int combined = (byte1 << 16) | (byte2 << 8) | byte3;
+
+ // Extract four 6-bit groups
+ result.append(BASE64_CHARS.charAt((combined >> 18) & 0x3F));
+ result.append(BASE64_CHARS.charAt((combined >> 12) & 0x3F));
+ result.append(BASE64_CHARS.charAt((combined >> 6) & 0x3F));
+ result.append(BASE64_CHARS.charAt(combined & 0x3F));
+ }
+
+ // Replace padding characters
+ if (padding > 0) {
+ result.setLength(result.length() - padding);
+ for (int i = 0; i < padding; i++) {
+ result.append(PADDING_CHAR);
+ }
+ }
+
+ return result.toString();
+ }
+
+ /**
+ * Encodes the given string to a Base64 encoded string using UTF-8 encoding.
+ *
+ * @param input the string to encode
+ * @return the Base64 encoded string
+ * @throws IllegalArgumentException if input is null
+ */
+ public static String encode(String input) {
+ if (input == null) {
+ throw new IllegalArgumentException("Input cannot be null");
+ }
+
+ return encode(input.getBytes(StandardCharsets.UTF_8));
+ }
+
+ /**
+ * Decodes the given Base64 encoded string to a byte array.
+ *
+ * @param input the Base64 encoded string to decode
+ * @return the decoded byte array
+ * @throws IllegalArgumentException if input is null or contains invalid Base64 characters
+ */
+ public static byte[] decode(String input) {
+ if (input == null) {
+ throw new IllegalArgumentException("Input cannot be null");
+ }
+
+ if (input.isEmpty()) {
+ return new byte[0];
+ }
+
+ // Strict RFC 4648 compliance: length must be a multiple of 4
+ if (input.length() % 4 != 0) {
+ throw new IllegalArgumentException("Invalid Base64 input length; must be multiple of 4");
+ }
+
+ // Validate padding: '=' can only appear at the end (last 1 or 2 chars)
+ int firstPadding = input.indexOf('=');
+ if (firstPadding != -1 && firstPadding < input.length() - 2) {
+ throw new IllegalArgumentException("Padding '=' can only appear at the end (last 1 or 2 characters)");
+ }
+
+ List result = new ArrayList<>();
+
+ // Process input in groups of 4 characters
+ for (int i = 0; i < input.length(); i += 4) {
+ // Get up to 4 characters
+ int char1 = getBase64Value(input.charAt(i));
+ int char2 = getBase64Value(input.charAt(i + 1));
+ int char3 = input.charAt(i + 2) == '=' ? 0 : getBase64Value(input.charAt(i + 2));
+ int char4 = input.charAt(i + 3) == '=' ? 0 : getBase64Value(input.charAt(i + 3));
+
+ // Combine four 6-bit groups into a 24-bit number
+ int combined = (char1 << 18) | (char2 << 12) | (char3 << 6) | char4;
+
+ // Extract three 8-bit bytes
+ result.add((byte) ((combined >> 16) & 0xFF));
+ if (input.charAt(i + 2) != '=') {
+ result.add((byte) ((combined >> 8) & 0xFF));
+ }
+ if (input.charAt(i + 3) != '=') {
+ result.add((byte) (combined & 0xFF));
+ }
+ }
+
+ // Convert List to byte[]
+ byte[] resultArray = new byte[result.size()];
+ for (int i = 0; i < result.size(); i++) {
+ resultArray[i] = result.get(i);
+ }
+
+ return resultArray;
+ }
+
+ /**
+ * Decodes the given Base64 encoded string to a string using UTF-8 encoding.
+ *
+ * @param input the Base64 encoded string to decode
+ * @return the decoded string
+ * @throws IllegalArgumentException if input is null or contains invalid Base64 characters
+ */
+ public static String decodeToString(String input) {
+ if (input == null) {
+ throw new IllegalArgumentException("Input cannot be null");
+ }
+
+ byte[] decodedBytes = decode(input);
+ return new String(decodedBytes, StandardCharsets.UTF_8);
+ }
+
+ /**
+ * Gets the numeric value of a Base64 character.
+ *
+ * @param c the Base64 character
+ * @return the numeric value (0-63)
+ * @throws IllegalArgumentException if character is not a valid Base64 character
+ */
+ private static int getBase64Value(char c) {
+ if (c >= 'A' && c <= 'Z') {
+ return c - 'A';
+ } else if (c >= 'a' && c <= 'z') {
+ return c - 'a' + 26;
+ } else if (c >= '0' && c <= '9') {
+ return c - '0' + 52;
+ } else if (c == '+') {
+ return 62;
+ } else if (c == '/') {
+ return 63;
+ } else {
+ throw new IllegalArgumentException("Invalid Base64 character: " + c);
+ }
+ }
+}
diff --git a/src/main/java/com/thealgorithms/conversions/BinaryToDecimal.java b/src/main/java/com/thealgorithms/conversions/BinaryToDecimal.java
index b3783ab284b2..6011d1bb1fa8 100644
--- a/src/main/java/com/thealgorithms/conversions/BinaryToDecimal.java
+++ b/src/main/java/com/thealgorithms/conversions/BinaryToDecimal.java
@@ -1,59 +1,59 @@
-package com.thealgorithms.conversions;
-
-/**
- * This class converts a Binary number to a Decimal number
- */
-final class BinaryToDecimal {
- private static final int BINARY_BASE = 2;
-
- private BinaryToDecimal() {
- }
-
- /**
- * Converts a binary number to its decimal equivalent.
- *
- * @param binaryNumber The binary number to convert.
- * @return The decimal equivalent of the binary number.
- * @throws IllegalArgumentException If the binary number contains digits other than 0 and 1.
- */
- public static long binaryToDecimal(long binaryNumber) {
- long decimalValue = 0;
- long power = 0;
-
- while (binaryNumber != 0) {
- long digit = binaryNumber % 10;
- if (digit > 1) {
- throw new IllegalArgumentException("Incorrect binary digit: " + digit);
- }
- decimalValue += (long) (digit * Math.pow(BINARY_BASE, power++));
- binaryNumber /= 10;
- }
- return decimalValue;
- }
-
- /**
- * Converts a binary String to its decimal equivalent using bitwise operators.
- *
- * @param binary The binary number to convert.
- * @return The decimal equivalent of the binary number.
- * @throws IllegalArgumentException If the binary number contains digits other than 0 and 1.
- */
- public static long binaryStringToDecimal(String binary) {
- boolean isNegative = binary.charAt(0) == '-';
- if (isNegative) {
- binary = binary.substring(1);
- }
-
- long decimalValue = 0;
-
- for (char bit : binary.toCharArray()) {
- if (bit != '0' && bit != '1') {
- throw new IllegalArgumentException("Incorrect binary digit: " + bit);
- }
- // shift left by 1 (multiply by 2) and add bit value
- decimalValue = (decimalValue << 1) | (bit - '0');
- }
-
- return isNegative ? -decimalValue : decimalValue;
- }
-}
+package com.thealgorithms.conversions;
+
+/**
+ * This class converts a Binary number to a Decimal number
+ */
+final class BinaryToDecimal {
+ private static final int BINARY_BASE = 2;
+
+ private BinaryToDecimal() {
+ }
+
+ /**
+ * Converts a binary number to its decimal equivalent.
+ *
+ * @param binaryNumber The binary number to convert.
+ * @return The decimal equivalent of the binary number.
+ * @throws IllegalArgumentException If the binary number contains digits other than 0 and 1.
+ */
+ public static long binaryToDecimal(long binaryNumber) {
+ long decimalValue = 0;
+ long power = 0;
+
+ while (binaryNumber != 0) {
+ long digit = binaryNumber % 10;
+ if (digit > 1) {
+ throw new IllegalArgumentException("Incorrect binary digit: " + digit);
+ }
+ decimalValue += (long) (digit * Math.pow(BINARY_BASE, power++));
+ binaryNumber /= 10;
+ }
+ return decimalValue;
+ }
+
+ /**
+ * Converts a binary String to its decimal equivalent using bitwise operators.
+ *
+ * @param binary The binary number to convert.
+ * @return The decimal equivalent of the binary number.
+ * @throws IllegalArgumentException If the binary number contains digits other than 0 and 1.
+ */
+ public static long binaryStringToDecimal(String binary) {
+ boolean isNegative = binary.charAt(0) == '-';
+ if (isNegative) {
+ binary = binary.substring(1);
+ }
+
+ long decimalValue = 0;
+
+ for (char bit : binary.toCharArray()) {
+ if (bit != '0' && bit != '1') {
+ throw new IllegalArgumentException("Incorrect binary digit: " + bit);
+ }
+ // shift left by 1 (multiply by 2) and add bit value
+ decimalValue = (decimalValue << 1) | (bit - '0');
+ }
+
+ return isNegative ? -decimalValue : decimalValue;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/conversions/BinaryToHexadecimal.java b/src/main/java/com/thealgorithms/conversions/BinaryToHexadecimal.java
index 9ff2f593fe1f..8454877ef3ec 100644
--- a/src/main/java/com/thealgorithms/conversions/BinaryToHexadecimal.java
+++ b/src/main/java/com/thealgorithms/conversions/BinaryToHexadecimal.java
@@ -1,63 +1,63 @@
-package com.thealgorithms.conversions;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Converts any Binary Number to a Hexadecimal Number
- *
- * @author Nishita Aggarwal
- */
-public final class BinaryToHexadecimal {
- private static final int BITS_IN_HEX_DIGIT = 4;
- private static final int BASE_BINARY = 2;
- private static final int BASE_DECIMAL = 10;
- private static final int HEX_START_DECIMAL = 10;
- private static final int HEX_END_DECIMAL = 15;
-
- private BinaryToHexadecimal() {
- }
-
- /**
- * Converts a binary number to a hexadecimal number.
- *
- * @param binary The binary number to convert.
- * @return The hexadecimal representation of the binary number.
- * @throws IllegalArgumentException If the binary number contains digits other than 0 and 1.
- */
- public static String binToHex(int binary) {
- Map hexMap = initializeHexMap();
- StringBuilder hex = new StringBuilder();
-
- while (binary != 0) {
- int decimalValue = 0;
- for (int i = 0; i < BITS_IN_HEX_DIGIT; i++) {
- int currentBit = binary % BASE_DECIMAL;
- if (currentBit > 1) {
- throw new IllegalArgumentException("Incorrect binary digit: " + currentBit);
- }
- binary /= BASE_DECIMAL;
- decimalValue += (int) (currentBit * Math.pow(BASE_BINARY, i));
- }
- hex.insert(0, hexMap.get(decimalValue));
- }
-
- return !hex.isEmpty() ? hex.toString() : "0";
- }
-
- /**
- * Initializes the hexadecimal map with decimal to hexadecimal mappings.
- *
- * @return The initialized map containing mappings from decimal numbers to hexadecimal digits.
- */
- private static Map initializeHexMap() {
- Map hexMap = new HashMap<>();
- for (int i = 0; i < BASE_DECIMAL; i++) {
- hexMap.put(i, String.valueOf(i));
- }
- for (int i = HEX_START_DECIMAL; i <= HEX_END_DECIMAL; i++) {
- hexMap.put(i, String.valueOf((char) ('A' + i - HEX_START_DECIMAL)));
- }
- return hexMap;
- }
-}
+package com.thealgorithms.conversions;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Converts any Binary Number to a Hexadecimal Number
+ *
+ * @author Nishita Aggarwal
+ */
+public final class BinaryToHexadecimal {
+ private static final int BITS_IN_HEX_DIGIT = 4;
+ private static final int BASE_BINARY = 2;
+ private static final int BASE_DECIMAL = 10;
+ private static final int HEX_START_DECIMAL = 10;
+ private static final int HEX_END_DECIMAL = 15;
+
+ private BinaryToHexadecimal() {
+ }
+
+ /**
+ * Converts a binary number to a hexadecimal number.
+ *
+ * @param binary The binary number to convert.
+ * @return The hexadecimal representation of the binary number.
+ * @throws IllegalArgumentException If the binary number contains digits other than 0 and 1.
+ */
+ public static String binToHex(int binary) {
+ Map hexMap = initializeHexMap();
+ StringBuilder hex = new StringBuilder();
+
+ while (binary != 0) {
+ int decimalValue = 0;
+ for (int i = 0; i < BITS_IN_HEX_DIGIT; i++) {
+ int currentBit = binary % BASE_DECIMAL;
+ if (currentBit > 1) {
+ throw new IllegalArgumentException("Incorrect binary digit: " + currentBit);
+ }
+ binary /= BASE_DECIMAL;
+ decimalValue += (int) (currentBit * Math.pow(BASE_BINARY, i));
+ }
+ hex.insert(0, hexMap.get(decimalValue));
+ }
+
+ return !hex.isEmpty() ? hex.toString() : "0";
+ }
+
+ /**
+ * Initializes the hexadecimal map with decimal to hexadecimal mappings.
+ *
+ * @return The initialized map containing mappings from decimal numbers to hexadecimal digits.
+ */
+ private static Map initializeHexMap() {
+ Map hexMap = new HashMap<>();
+ for (int i = 0; i < BASE_DECIMAL; i++) {
+ hexMap.put(i, String.valueOf(i));
+ }
+ for (int i = HEX_START_DECIMAL; i <= HEX_END_DECIMAL; i++) {
+ hexMap.put(i, String.valueOf((char) ('A' + i - HEX_START_DECIMAL)));
+ }
+ return hexMap;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/conversions/BinaryToOctal.java b/src/main/java/com/thealgorithms/conversions/BinaryToOctal.java
index 5407c8525a23..28ec075def3a 100644
--- a/src/main/java/com/thealgorithms/conversions/BinaryToOctal.java
+++ b/src/main/java/com/thealgorithms/conversions/BinaryToOctal.java
@@ -1,45 +1,45 @@
-package com.thealgorithms.conversions;
-
-public final class BinaryToOctal {
- private static final int BITS_PER_OCTAL_DIGIT = 3;
- private static final int BINARY_BASE = 2;
- private static final int DECIMAL_BASE = 10;
-
- private BinaryToOctal() {
- }
-
- /**
- * This method converts a binary number to an octal number.
- *
- * @param binary The binary number
- * @return The octal number
- * @throws IllegalArgumentException if the input is not a valid binary number
- */
- public static String convertBinaryToOctal(int binary) {
- if (binary == 0) {
- return "0";
- }
-
- if (!String.valueOf(binary).matches("[01]+")) {
- throw new IllegalArgumentException("Input is not a valid binary number.");
- }
-
- StringBuilder octal = new StringBuilder();
- int currentBit;
- int bitValueMultiplier = 1;
-
- while (binary != 0) {
- int octalDigit = 0;
- for (int i = 0; i < BITS_PER_OCTAL_DIGIT && binary != 0; i++) {
- currentBit = binary % DECIMAL_BASE;
- binary /= DECIMAL_BASE;
- octalDigit += currentBit * bitValueMultiplier;
- bitValueMultiplier *= BINARY_BASE;
- }
- octal.insert(0, octalDigit);
- bitValueMultiplier = 1; // Reset multiplier for the next group
- }
-
- return octal.toString();
- }
-}
+package com.thealgorithms.conversions;
+
+public final class BinaryToOctal {
+ private static final int BITS_PER_OCTAL_DIGIT = 3;
+ private static final int BINARY_BASE = 2;
+ private static final int DECIMAL_BASE = 10;
+
+ private BinaryToOctal() {
+ }
+
+ /**
+ * This method converts a binary number to an octal number.
+ *
+ * @param binary The binary number
+ * @return The octal number
+ * @throws IllegalArgumentException if the input is not a valid binary number
+ */
+ public static String convertBinaryToOctal(int binary) {
+ if (binary == 0) {
+ return "0";
+ }
+
+ if (!String.valueOf(binary).matches("[01]+")) {
+ throw new IllegalArgumentException("Input is not a valid binary number.");
+ }
+
+ StringBuilder octal = new StringBuilder();
+ int currentBit;
+ int bitValueMultiplier = 1;
+
+ while (binary != 0) {
+ int octalDigit = 0;
+ for (int i = 0; i < BITS_PER_OCTAL_DIGIT && binary != 0; i++) {
+ currentBit = binary % DECIMAL_BASE;
+ binary /= DECIMAL_BASE;
+ octalDigit += currentBit * bitValueMultiplier;
+ bitValueMultiplier *= BINARY_BASE;
+ }
+ octal.insert(0, octalDigit);
+ bitValueMultiplier = 1; // Reset multiplier for the next group
+ }
+
+ return octal.toString();
+ }
+}
diff --git a/src/main/java/com/thealgorithms/conversions/CoordinateConverter.java b/src/main/java/com/thealgorithms/conversions/CoordinateConverter.java
index 2766a3a1cf89..b2122b70808e 100644
--- a/src/main/java/com/thealgorithms/conversions/CoordinateConverter.java
+++ b/src/main/java/com/thealgorithms/conversions/CoordinateConverter.java
@@ -1,57 +1,57 @@
-package com.thealgorithms.conversions;
-
-/**
- * A utility class to convert between Cartesian and Polar coordinate systems.
- *
- * This class provides methods to perform the following conversions:
- *
- * - Cartesian to Polar coordinates
- * - Polar to Cartesian coordinates
- *
- *
- * The class is final and cannot be instantiated.
- */
-public final class CoordinateConverter {
-
- private CoordinateConverter() {
- // Prevent instantiation
- }
-
- /**
- * Converts Cartesian coordinates to Polar coordinates.
- *
- * @param x the x-coordinate in the Cartesian system; must be a finite number
- * @param y the y-coordinate in the Cartesian system; must be a finite number
- * @return an array where the first element is the radius (r) and the second element is the angle (theta) in degrees
- * @throws IllegalArgumentException if x or y is not a finite number
- */
- public static double[] cartesianToPolar(double x, double y) {
- if (!Double.isFinite(x) || !Double.isFinite(y)) {
- throw new IllegalArgumentException("x and y must be finite numbers.");
- }
- double r = Math.sqrt(x * x + y * y);
- double theta = Math.toDegrees(Math.atan2(y, x));
- return new double[] {r, theta};
- }
-
- /**
- * Converts Polar coordinates to Cartesian coordinates.
- *
- * @param r the radius in the Polar system; must be non-negative
- * @param thetaDegrees the angle (theta) in degrees in the Polar system; must be a finite number
- * @return an array where the first element is the x-coordinate and the second element is the y-coordinate in the Cartesian system
- * @throws IllegalArgumentException if r is negative or thetaDegrees is not a finite number
- */
- public static double[] polarToCartesian(double r, double thetaDegrees) {
- if (r < 0) {
- throw new IllegalArgumentException("Radius (r) must be non-negative.");
- }
- if (!Double.isFinite(thetaDegrees)) {
- throw new IllegalArgumentException("Theta (angle) must be a finite number.");
- }
- double theta = Math.toRadians(thetaDegrees);
- double x = r * Math.cos(theta);
- double y = r * Math.sin(theta);
- return new double[] {x, y};
- }
-}
+package com.thealgorithms.conversions;
+
+/**
+ * A utility class to convert between Cartesian and Polar coordinate systems.
+ *
+ *
This class provides methods to perform the following conversions:
+ *
+ * - Cartesian to Polar coordinates
+ * - Polar to Cartesian coordinates
+ *
+ *
+ * The class is final and cannot be instantiated.
+ */
+public final class CoordinateConverter {
+
+ private CoordinateConverter() {
+ // Prevent instantiation
+ }
+
+ /**
+ * Converts Cartesian coordinates to Polar coordinates.
+ *
+ * @param x the x-coordinate in the Cartesian system; must be a finite number
+ * @param y the y-coordinate in the Cartesian system; must be a finite number
+ * @return an array where the first element is the radius (r) and the second element is the angle (theta) in degrees
+ * @throws IllegalArgumentException if x or y is not a finite number
+ */
+ public static double[] cartesianToPolar(double x, double y) {
+ if (!Double.isFinite(x) || !Double.isFinite(y)) {
+ throw new IllegalArgumentException("x and y must be finite numbers.");
+ }
+ double r = Math.sqrt(x * x + y * y);
+ double theta = Math.toDegrees(Math.atan2(y, x));
+ return new double[] {r, theta};
+ }
+
+ /**
+ * Converts Polar coordinates to Cartesian coordinates.
+ *
+ * @param r the radius in the Polar system; must be non-negative
+ * @param thetaDegrees the angle (theta) in degrees in the Polar system; must be a finite number
+ * @return an array where the first element is the x-coordinate and the second element is the y-coordinate in the Cartesian system
+ * @throws IllegalArgumentException if r is negative or thetaDegrees is not a finite number
+ */
+ public static double[] polarToCartesian(double r, double thetaDegrees) {
+ if (r < 0) {
+ throw new IllegalArgumentException("Radius (r) must be non-negative.");
+ }
+ if (!Double.isFinite(thetaDegrees)) {
+ throw new IllegalArgumentException("Theta (angle) must be a finite number.");
+ }
+ double theta = Math.toRadians(thetaDegrees);
+ double x = r * Math.cos(theta);
+ double y = r * Math.sin(theta);
+ return new double[] {x, y};
+ }
+}
diff --git a/src/main/java/com/thealgorithms/conversions/DecimalToAnyBase.java b/src/main/java/com/thealgorithms/conversions/DecimalToAnyBase.java
index a5615dc002f5..f7f121e938cd 100644
--- a/src/main/java/com/thealgorithms/conversions/DecimalToAnyBase.java
+++ b/src/main/java/com/thealgorithms/conversions/DecimalToAnyBase.java
@@ -1,69 +1,69 @@
-package com.thealgorithms.conversions;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Class that provides methods to convert a decimal number to a string representation
- * in any specified base between 2 and 36.
- *
- * @author Varun Upadhyay (...)
- */
-public final class DecimalToAnyBase {
- private static final int MIN_BASE = 2;
- private static final int MAX_BASE = 36;
- private static final char ZERO_CHAR = '0';
- private static final char A_CHAR = 'A';
- private static final int DIGIT_OFFSET = 10;
-
- private DecimalToAnyBase() {
- }
-
- /**
- * Converts a decimal number to a string representation in the specified base.
- * For example, converting the decimal number 10 to base 2 would return "1010".
- *
- * @param decimal the decimal number to convert
- * @param base the base to convert to (must be between {@value #MIN_BASE} and {@value #MAX_BASE})
- * @return the string representation of the number in the specified base
- * @throws IllegalArgumentException if the base is out of the supported range
- */
- public static String convertToAnyBase(int decimal, int base) {
- if (base < MIN_BASE || base > MAX_BASE) {
- throw new IllegalArgumentException("Base must be between " + MIN_BASE + " and " + MAX_BASE);
- }
-
- if (decimal == 0) {
- return String.valueOf(ZERO_CHAR);
- }
-
- List digits = new ArrayList<>();
- while (decimal > 0) {
- digits.add(convertToChar(decimal % base));
- decimal /= base;
- }
-
- StringBuilder result = new StringBuilder(digits.size());
- for (int i = digits.size() - 1; i >= 0; i--) {
- result.append(digits.get(i));
- }
-
- return result.toString();
- }
-
- /**
- * Converts an integer value to its corresponding character in the specified base.
- * This method is used to convert values from 0 to 35 into their appropriate character representation.
- * For example, 0-9 are represented as '0'-'9', and 10-35 are represented as 'A'-'Z'.
- *
- * @param value the integer value to convert (should be less than the base value)
- * @return the character representing the value in the specified base
- */
- private static char convertToChar(int value) {
- if (value >= 0 && value <= 9) {
- return (char) (ZERO_CHAR + value);
- } else {
- return (char) (A_CHAR + value - DIGIT_OFFSET);
- }
- }
-}
+package com.thealgorithms.conversions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Class that provides methods to convert a decimal number to a string representation
+ * in any specified base between 2 and 36.
+ *
+ * @author Varun Upadhyay (...)
+ */
+public final class DecimalToAnyBase {
+ private static final int MIN_BASE = 2;
+ private static final int MAX_BASE = 36;
+ private static final char ZERO_CHAR = '0';
+ private static final char A_CHAR = 'A';
+ private static final int DIGIT_OFFSET = 10;
+
+ private DecimalToAnyBase() {
+ }
+
+ /**
+ * Converts a decimal number to a string representation in the specified base.
+ * For example, converting the decimal number 10 to base 2 would return "1010".
+ *
+ * @param decimal the decimal number to convert
+ * @param base the base to convert to (must be between {@value #MIN_BASE} and {@value #MAX_BASE})
+ * @return the string representation of the number in the specified base
+ * @throws IllegalArgumentException if the base is out of the supported range
+ */
+ public static String convertToAnyBase(int decimal, int base) {
+ if (base < MIN_BASE || base > MAX_BASE) {
+ throw new IllegalArgumentException("Base must be between " + MIN_BASE + " and " + MAX_BASE);
+ }
+
+ if (decimal == 0) {
+ return String.valueOf(ZERO_CHAR);
+ }
+
+ List digits = new ArrayList<>();
+ while (decimal > 0) {
+ digits.add(convertToChar(decimal % base));
+ decimal /= base;
+ }
+
+ StringBuilder result = new StringBuilder(digits.size());
+ for (int i = digits.size() - 1; i >= 0; i--) {
+ result.append(digits.get(i));
+ }
+
+ return result.toString();
+ }
+
+ /**
+ * Converts an integer value to its corresponding character in the specified base.
+ * This method is used to convert values from 0 to 35 into their appropriate character representation.
+ * For example, 0-9 are represented as '0'-'9', and 10-35 are represented as 'A'-'Z'.
+ *
+ * @param value the integer value to convert (should be less than the base value)
+ * @return the character representing the value in the specified base
+ */
+ private static char convertToChar(int value) {
+ if (value >= 0 && value <= 9) {
+ return (char) (ZERO_CHAR + value);
+ } else {
+ return (char) (A_CHAR + value - DIGIT_OFFSET);
+ }
+ }
+}
diff --git a/src/main/java/com/thealgorithms/conversions/DecimalToBinary.java b/src/main/java/com/thealgorithms/conversions/DecimalToBinary.java
index e8d033e0093c..70c7cb97cd82 100644
--- a/src/main/java/com/thealgorithms/conversions/DecimalToBinary.java
+++ b/src/main/java/com/thealgorithms/conversions/DecimalToBinary.java
@@ -1,49 +1,49 @@
-package com.thealgorithms.conversions;
-
-/**
- * This class provides methods to convert a decimal number to a binary number.
- */
-final class DecimalToBinary {
- private static final int BINARY_BASE = 2;
- private static final int DECIMAL_MULTIPLIER = 10;
-
- private DecimalToBinary() {
- }
-
- /**
- * Converts a decimal number to a binary number using a conventional algorithm.
- * @param decimalNumber the decimal number to convert
- * @return the binary representation of the decimal number
- */
- public static int convertUsingConventionalAlgorithm(int decimalNumber) {
- int binaryNumber = 0;
- int position = 1;
-
- while (decimalNumber > 0) {
- int remainder = decimalNumber % BINARY_BASE;
- binaryNumber += remainder * position;
- position *= DECIMAL_MULTIPLIER;
- decimalNumber /= BINARY_BASE;
- }
-
- return binaryNumber;
- }
-
- /**
- * Converts a decimal number to a binary number using a bitwise algorithm.
- * @param decimalNumber the decimal number to convert
- * @return the binary representation of the decimal number
- */
- public static int convertUsingBitwiseAlgorithm(int decimalNumber) {
- int binaryNumber = 0;
- int position = 1;
-
- while (decimalNumber > 0) {
- int leastSignificantBit = decimalNumber & 1;
- binaryNumber += leastSignificantBit * position;
- position *= DECIMAL_MULTIPLIER;
- decimalNumber >>= 1;
- }
- return binaryNumber;
- }
-}
+package com.thealgorithms.conversions;
+
+/**
+ * This class provides methods to convert a decimal number to a binary number.
+ */
+final class DecimalToBinary {
+ private static final int BINARY_BASE = 2;
+ private static final int DECIMAL_MULTIPLIER = 10;
+
+ private DecimalToBinary() {
+ }
+
+ /**
+ * Converts a decimal number to a binary number using a conventional algorithm.
+ * @param decimalNumber the decimal number to convert
+ * @return the binary representation of the decimal number
+ */
+ public static int convertUsingConventionalAlgorithm(int decimalNumber) {
+ int binaryNumber = 0;
+ int position = 1;
+
+ while (decimalNumber > 0) {
+ int remainder = decimalNumber % BINARY_BASE;
+ binaryNumber += remainder * position;
+ position *= DECIMAL_MULTIPLIER;
+ decimalNumber /= BINARY_BASE;
+ }
+
+ return binaryNumber;
+ }
+
+ /**
+ * Converts a decimal number to a binary number using a bitwise algorithm.
+ * @param decimalNumber the decimal number to convert
+ * @return the binary representation of the decimal number
+ */
+ public static int convertUsingBitwiseAlgorithm(int decimalNumber) {
+ int binaryNumber = 0;
+ int position = 1;
+
+ while (decimalNumber > 0) {
+ int leastSignificantBit = decimalNumber & 1;
+ binaryNumber += leastSignificantBit * position;
+ position *= DECIMAL_MULTIPLIER;
+ decimalNumber >>= 1;
+ }
+ return binaryNumber;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/conversions/DecimalToHexadecimal.java b/src/main/java/com/thealgorithms/conversions/DecimalToHexadecimal.java
index 47a1e36b27e3..cc5ce14dd41c 100644
--- a/src/main/java/com/thealgorithms/conversions/DecimalToHexadecimal.java
+++ b/src/main/java/com/thealgorithms/conversions/DecimalToHexadecimal.java
@@ -1,42 +1,42 @@
-package com.thealgorithms.conversions;
-
-/**
- * This class provides a method to convert a decimal number to a hexadecimal string.
- */
-final class DecimalToHexadecimal {
- private static final int SIZE_OF_INT_IN_HALF_BYTES = 8;
- private static final int NUMBER_OF_BITS_IN_HALF_BYTE = 4;
- private static final int HALF_BYTE_MASK = 0x0F;
- private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
-
- private DecimalToHexadecimal() {
- }
-
- /**
- * Converts a decimal number to a hexadecimal string.
- * @param decimal the decimal number to convert
- * @return the hexadecimal representation of the decimal number
- */
- public static String decToHex(int decimal) {
- StringBuilder hexBuilder = new StringBuilder(SIZE_OF_INT_IN_HALF_BYTES);
- for (int i = SIZE_OF_INT_IN_HALF_BYTES - 1; i >= 0; --i) {
- int currentHalfByte = decimal & HALF_BYTE_MASK;
- hexBuilder.insert(0, HEX_DIGITS[currentHalfByte]);
- decimal >>= NUMBER_OF_BITS_IN_HALF_BYTE;
- }
- return removeLeadingZeros(hexBuilder.toString().toLowerCase());
- }
-
- private static String removeLeadingZeros(String str) {
- if (str == null || str.isEmpty()) {
- return str;
- }
-
- int i = 0;
- while (i < str.length() && str.charAt(i) == '0') {
- i++;
- }
-
- return i == str.length() ? "0" : str.substring(i);
- }
-}
+package com.thealgorithms.conversions;
+
+/**
+ * This class provides a method to convert a decimal number to a hexadecimal string.
+ */
+final class DecimalToHexadecimal {
+ private static final int SIZE_OF_INT_IN_HALF_BYTES = 8;
+ private static final int NUMBER_OF_BITS_IN_HALF_BYTE = 4;
+ private static final int HALF_BYTE_MASK = 0x0F;
+ private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
+
+ private DecimalToHexadecimal() {
+ }
+
+ /**
+ * Converts a decimal number to a hexadecimal string.
+ * @param decimal the decimal number to convert
+ * @return the hexadecimal representation of the decimal number
+ */
+ public static String decToHex(int decimal) {
+ StringBuilder hexBuilder = new StringBuilder(SIZE_OF_INT_IN_HALF_BYTES);
+ for (int i = SIZE_OF_INT_IN_HALF_BYTES - 1; i >= 0; --i) {
+ int currentHalfByte = decimal & HALF_BYTE_MASK;
+ hexBuilder.insert(0, HEX_DIGITS[currentHalfByte]);
+ decimal >>= NUMBER_OF_BITS_IN_HALF_BYTE;
+ }
+ return removeLeadingZeros(hexBuilder.toString().toLowerCase());
+ }
+
+ private static String removeLeadingZeros(String str) {
+ if (str == null || str.isEmpty()) {
+ return str;
+ }
+
+ int i = 0;
+ while (i < str.length() && str.charAt(i) == '0') {
+ i++;
+ }
+
+ return i == str.length() ? "0" : str.substring(i);
+ }
+}
diff --git a/src/main/java/com/thealgorithms/conversions/DecimalToOctal.java b/src/main/java/com/thealgorithms/conversions/DecimalToOctal.java
index 75687fc589ae..2e30c90c4a26 100644
--- a/src/main/java/com/thealgorithms/conversions/DecimalToOctal.java
+++ b/src/main/java/com/thealgorithms/conversions/DecimalToOctal.java
@@ -1,38 +1,38 @@
-package com.thealgorithms.conversions;
-
-/**
- * This class converts Decimal numbers to Octal Numbers
- */
-public final class DecimalToOctal {
- private static final int OCTAL_BASE = 8;
- private static final int INITIAL_OCTAL_VALUE = 0;
- private static final int INITIAL_PLACE_VALUE = 1;
-
- private DecimalToOctal() {
- }
-
- /**
- * Converts a decimal number to its octal equivalent.
- *
- * @param decimal The decimal number to convert.
- * @return The octal equivalent as an integer.
- * @throws IllegalArgumentException if the decimal number is negative.
- */
- public static int convertToOctal(int decimal) {
- if (decimal < 0) {
- throw new IllegalArgumentException("Decimal number cannot be negative.");
- }
-
- int octal = INITIAL_OCTAL_VALUE;
- int placeValue = INITIAL_PLACE_VALUE;
-
- while (decimal != 0) {
- int remainder = decimal % OCTAL_BASE;
- octal += remainder * placeValue;
- decimal /= OCTAL_BASE;
- placeValue *= 10;
- }
-
- return octal;
- }
-}
+package com.thealgorithms.conversions;
+
+/**
+ * This class converts Decimal numbers to Octal Numbers
+ */
+public final class DecimalToOctal {
+ private static final int OCTAL_BASE = 8;
+ private static final int INITIAL_OCTAL_VALUE = 0;
+ private static final int INITIAL_PLACE_VALUE = 1;
+
+ private DecimalToOctal() {
+ }
+
+ /**
+ * Converts a decimal number to its octal equivalent.
+ *
+ * @param decimal The decimal number to convert.
+ * @return The octal equivalent as an integer.
+ * @throws IllegalArgumentException if the decimal number is negative.
+ */
+ public static int convertToOctal(int decimal) {
+ if (decimal < 0) {
+ throw new IllegalArgumentException("Decimal number cannot be negative.");
+ }
+
+ int octal = INITIAL_OCTAL_VALUE;
+ int placeValue = INITIAL_PLACE_VALUE;
+
+ while (decimal != 0) {
+ int remainder = decimal % OCTAL_BASE;
+ octal += remainder * placeValue;
+ decimal /= OCTAL_BASE;
+ placeValue *= 10;
+ }
+
+ return octal;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/conversions/EndianConverter.java b/src/main/java/com/thealgorithms/conversions/EndianConverter.java
index 0d69098e8255..9837b9424467 100644
--- a/src/main/java/com/thealgorithms/conversions/EndianConverter.java
+++ b/src/main/java/com/thealgorithms/conversions/EndianConverter.java
@@ -1,47 +1,47 @@
-package com.thealgorithms.conversions;
-
-/**
- * Utility class for converting integers between big-endian and little-endian formats.
- *
- * Endianness defines how byte sequences represent multi-byte data types:
- *
- * - Big-endian: The most significant byte (MSB) comes first.
- * - Little-endian: The least significant byte (LSB) comes first.
- *
- *
- * Example conversion:
- *
- * - Big-endian to little-endian: {@code 0x12345678} → {@code 0x78563412}
- * - Little-endian to big-endian: {@code 0x78563412} → {@code 0x12345678}
- *
- *
- * Note: Both conversions in this utility are equivalent since reversing the bytes is symmetric.
- *
- * This class only supports 32-bit integers.
- *
- * @author Hardvan
- */
-public final class EndianConverter {
- private EndianConverter() {
- }
-
- /**
- * Converts a 32-bit integer from big-endian to little-endian.
- *
- * @param value the integer in big-endian format
- * @return the integer in little-endian format
- */
- public static int bigToLittleEndian(int value) {
- return Integer.reverseBytes(value);
- }
-
- /**
- * Converts a 32-bit integer from little-endian to big-endian.
- *
- * @param value the integer in little-endian format
- * @return the integer in big-endian format
- */
- public static int littleToBigEndian(int value) {
- return Integer.reverseBytes(value);
- }
-}
+package com.thealgorithms.conversions;
+
+/**
+ * Utility class for converting integers between big-endian and little-endian formats.
+ *
+ * Endianness defines how byte sequences represent multi-byte data types:
+ *
+ * - Big-endian: The most significant byte (MSB) comes first.
+ * - Little-endian: The least significant byte (LSB) comes first.
+ *
+ *
+ * Example conversion:
+ *
+ * - Big-endian to little-endian: {@code 0x12345678} → {@code 0x78563412}
+ * - Little-endian to big-endian: {@code 0x78563412} → {@code 0x12345678}
+ *
+ *
+ * Note: Both conversions in this utility are equivalent since reversing the bytes is symmetric.
+ *
+ * This class only supports 32-bit integers.
+ *
+ * @author Hardvan
+ */
+public final class EndianConverter {
+ private EndianConverter() {
+ }
+
+ /**
+ * Converts a 32-bit integer from big-endian to little-endian.
+ *
+ * @param value the integer in big-endian format
+ * @return the integer in little-endian format
+ */
+ public static int bigToLittleEndian(int value) {
+ return Integer.reverseBytes(value);
+ }
+
+ /**
+ * Converts a 32-bit integer from little-endian to big-endian.
+ *
+ * @param value the integer in little-endian format
+ * @return the integer in big-endian format
+ */
+ public static int littleToBigEndian(int value) {
+ return Integer.reverseBytes(value);
+ }
+}
diff --git a/src/main/java/com/thealgorithms/conversions/HexToOct.java b/src/main/java/com/thealgorithms/conversions/HexToOct.java
index d3a672d37424..0ca5ef7d784b 100644
--- a/src/main/java/com/thealgorithms/conversions/HexToOct.java
+++ b/src/main/java/com/thealgorithms/conversions/HexToOct.java
@@ -1,62 +1,62 @@
-package com.thealgorithms.conversions;
-
-/**
- * Converts any Hexadecimal Number to Octal
- *
- * @author Tanmay Joshi
- */
-public final class HexToOct {
- private HexToOct() {
- }
-
- /**
- * Converts a Hexadecimal number to a Decimal number.
- *
- * @param hex The Hexadecimal number as a String.
- * @return The Decimal equivalent as an integer.
- */
- public static int hexToDecimal(String hex) {
- String hexDigits = "0123456789ABCDEF";
- hex = hex.toUpperCase();
- int decimalValue = 0;
-
- for (int i = 0; i < hex.length(); i++) {
- char hexChar = hex.charAt(i);
- int digitValue = hexDigits.indexOf(hexChar);
- decimalValue = 16 * decimalValue + digitValue;
- }
-
- return decimalValue;
- }
-
- /**
- * Converts a Decimal number to an Octal number.
- *
- * @param decimal The Decimal number as an integer.
- * @return The Octal equivalent as an integer.
- */
- public static int decimalToOctal(int decimal) {
- int octalValue = 0;
- int placeValue = 1;
-
- while (decimal > 0) {
- int remainder = decimal % 8;
- octalValue += remainder * placeValue;
- decimal /= 8;
- placeValue *= 10;
- }
-
- return octalValue;
- }
-
- /**
- * Converts a Hexadecimal number to an Octal number.
- *
- * @param hex The Hexadecimal number as a String.
- * @return The Octal equivalent as an integer.
- */
- public static int hexToOctal(String hex) {
- int decimalValue = hexToDecimal(hex);
- return decimalToOctal(decimalValue);
- }
-}
+package com.thealgorithms.conversions;
+
+/**
+ * Converts any Hexadecimal Number to Octal
+ *
+ * @author Tanmay Joshi
+ */
+public final class HexToOct {
+ private HexToOct() {
+ }
+
+ /**
+ * Converts a Hexadecimal number to a Decimal number.
+ *
+ * @param hex The Hexadecimal number as a String.
+ * @return The Decimal equivalent as an integer.
+ */
+ public static int hexToDecimal(String hex) {
+ String hexDigits = "0123456789ABCDEF";
+ hex = hex.toUpperCase();
+ int decimalValue = 0;
+
+ for (int i = 0; i < hex.length(); i++) {
+ char hexChar = hex.charAt(i);
+ int digitValue = hexDigits.indexOf(hexChar);
+ decimalValue = 16 * decimalValue + digitValue;
+ }
+
+ return decimalValue;
+ }
+
+ /**
+ * Converts a Decimal number to an Octal number.
+ *
+ * @param decimal The Decimal number as an integer.
+ * @return The Octal equivalent as an integer.
+ */
+ public static int decimalToOctal(int decimal) {
+ int octalValue = 0;
+ int placeValue = 1;
+
+ while (decimal > 0) {
+ int remainder = decimal % 8;
+ octalValue += remainder * placeValue;
+ decimal /= 8;
+ placeValue *= 10;
+ }
+
+ return octalValue;
+ }
+
+ /**
+ * Converts a Hexadecimal number to an Octal number.
+ *
+ * @param hex The Hexadecimal number as a String.
+ * @return The Octal equivalent as an integer.
+ */
+ public static int hexToOctal(String hex) {
+ int decimalValue = hexToDecimal(hex);
+ return decimalToOctal(decimalValue);
+ }
+}
diff --git a/src/main/java/com/thealgorithms/conversions/HexaDecimalToBinary.java b/src/main/java/com/thealgorithms/conversions/HexaDecimalToBinary.java
index c0eb9a01ba17..11e6dc630de1 100644
--- a/src/main/java/com/thealgorithms/conversions/HexaDecimalToBinary.java
+++ b/src/main/java/com/thealgorithms/conversions/HexaDecimalToBinary.java
@@ -1,62 +1,62 @@
-package com.thealgorithms.conversions;
-
-/**
- * Utility class for converting hexadecimal numbers to binary representation.
- *
- * A hexadecimal number consists of digits from {@code [0-9]} and {@code [A-F]} (case-insensitive),
- * while binary representation uses only {@code [0, 1]}.
- *
- * This class provides methods to:
- *
- * - Convert a hexadecimal string to its binary string equivalent.
- * - Ensure the binary output is padded to 8 bits (1 byte).
- *
- *
- * Example:
- *
- * - {@code "A1"} → {@code "10100001"}
- * - {@code "1"} → {@code "00000001"}
- *
- *
- * This class assumes that the input hexadecimal string is valid.
- */
-public class HexaDecimalToBinary {
-
- /**
- * Converts a hexadecimal string to its binary string equivalent.
- * The binary output is padded to a minimum of 8 bits (1 byte).
- * Steps:
- *
- * - Convert the hexadecimal string to an integer.
- * - Convert the integer to a binary string.
- * - Pad the binary string to ensure it is at least 8 bits long.
- * - Return the padded binary string.
- *
- *
- * @param numHex the hexadecimal string (e.g., "A1", "7F")
- * @throws NumberFormatException if the input string is not a valid hexadecimal number
- * @return the binary string representation, padded to 8 bits (e.g., "10100001")
- */
- public String convert(String numHex) {
- int conHex = Integer.parseInt(numHex, 16);
- String binary = Integer.toBinaryString(conHex);
- return completeDigits(binary);
- }
-
- /**
- * Pads the binary string to ensure it is at least 8 bits long.
- * If the binary string is shorter than 8 bits, it adds leading zeros.
- *
- * @param binNum the binary string to pad
- * @return the padded binary string with a minimum length of 8
- */
- public String completeDigits(String binNum) {
- final int byteSize = 8;
- StringBuilder binNumBuilder = new StringBuilder(binNum);
- while (binNumBuilder.length() < byteSize) {
- binNumBuilder.insert(0, "0");
- }
- binNum = binNumBuilder.toString();
- return binNum;
- }
-}
+package com.thealgorithms.conversions;
+
+/**
+ * Utility class for converting hexadecimal numbers to binary representation.
+ *
+ * A hexadecimal number consists of digits from {@code [0-9]} and {@code [A-F]} (case-insensitive),
+ * while binary representation uses only {@code [0, 1]}.
+ *
+ * This class provides methods to:
+ *
+ * - Convert a hexadecimal string to its binary string equivalent.
+ * - Ensure the binary output is padded to 8 bits (1 byte).
+ *
+ *
+ * Example:
+ *
+ * - {@code "A1"} → {@code "10100001"}
+ * - {@code "1"} → {@code "00000001"}
+ *
+ *
+ * This class assumes that the input hexadecimal string is valid.
+ */
+public class HexaDecimalToBinary {
+
+ /**
+ * Converts a hexadecimal string to its binary string equivalent.
+ * The binary output is padded to a minimum of 8 bits (1 byte).
+ * Steps:
+ *
+ * - Convert the hexadecimal string to an integer.
+ * - Convert the integer to a binary string.
+ * - Pad the binary string to ensure it is at least 8 bits long.
+ * - Return the padded binary string.
+ *
+ *
+ * @param numHex the hexadecimal string (e.g., "A1", "7F")
+ * @throws NumberFormatException if the input string is not a valid hexadecimal number
+ * @return the binary string representation, padded to 8 bits (e.g., "10100001")
+ */
+ public String convert(String numHex) {
+ int conHex = Integer.parseInt(numHex, 16);
+ String binary = Integer.toBinaryString(conHex);
+ return completeDigits(binary);
+ }
+
+ /**
+ * Pads the binary string to ensure it is at least 8 bits long.
+ * If the binary string is shorter than 8 bits, it adds leading zeros.
+ *
+ * @param binNum the binary string to pad
+ * @return the padded binary string with a minimum length of 8
+ */
+ public String completeDigits(String binNum) {
+ final int byteSize = 8;
+ StringBuilder binNumBuilder = new StringBuilder(binNum);
+ while (binNumBuilder.length() < byteSize) {
+ binNumBuilder.insert(0, "0");
+ }
+ binNum = binNumBuilder.toString();
+ return binNum;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/conversions/HexaDecimalToDecimal.java b/src/main/java/com/thealgorithms/conversions/HexaDecimalToDecimal.java
index 2cf6024d90a3..fdfb7359fbf6 100644
--- a/src/main/java/com/thealgorithms/conversions/HexaDecimalToDecimal.java
+++ b/src/main/java/com/thealgorithms/conversions/HexaDecimalToDecimal.java
@@ -1,45 +1,45 @@
-package com.thealgorithms.conversions;
-
-/**
- * Utility class for converting a hexadecimal string to its decimal representation.
- *
- * A hexadecimal number uses the base-16 numeral system, with the following characters:
- *
- * - Digits: 0-9
- * - Letters: A-F (case-insensitive)
- *
- * Each character represents a power of 16. For example:
- *
- * Hexadecimal "A1" = 10*16^1 + 1*16^0 = 161 (decimal)
- *
- *
- * This class provides a method to perform the conversion without using built-in Java utilities.
- */
-public final class HexaDecimalToDecimal {
- private HexaDecimalToDecimal() {
- }
-
- /**
- * Converts a hexadecimal string to its decimal integer equivalent.
- * The input string is case-insensitive, and must contain valid hexadecimal characters [0-9, A-F].
- *
- * @param hex the hexadecimal string to convert
- * @return the decimal integer representation of the input hexadecimal string
- * @throws IllegalArgumentException if the input string contains invalid characters
- */
- public static int getHexaToDec(String hex) {
- String digits = "0123456789ABCDEF";
- hex = hex.toUpperCase();
- int val = 0;
-
- for (int i = 0; i < hex.length(); i++) {
- int d = digits.indexOf(hex.charAt(i));
- if (d == -1) {
- throw new IllegalArgumentException("Invalid hexadecimal character: " + hex.charAt(i));
- }
- val = 16 * val + d;
- }
-
- return val;
- }
-}
+package com.thealgorithms.conversions;
+
+/**
+ * Utility class for converting a hexadecimal string to its decimal representation.
+ *
+ * A hexadecimal number uses the base-16 numeral system, with the following characters:
+ *
+ * - Digits: 0-9
+ * - Letters: A-F (case-insensitive)
+ *
+ * Each character represents a power of 16. For example:
+ *
+ * Hexadecimal "A1" = 10*16^1 + 1*16^0 = 161 (decimal)
+ *
+ *
+ * This class provides a method to perform the conversion without using built-in Java utilities.
+ */
+public final class HexaDecimalToDecimal {
+ private HexaDecimalToDecimal() {
+ }
+
+ /**
+ * Converts a hexadecimal string to its decimal integer equivalent.
+ * The input string is case-insensitive, and must contain valid hexadecimal characters [0-9, A-F].
+ *
+ * @param hex the hexadecimal string to convert
+ * @return the decimal integer representation of the input hexadecimal string
+ * @throws IllegalArgumentException if the input string contains invalid characters
+ */
+ public static int getHexaToDec(String hex) {
+ String digits = "0123456789ABCDEF";
+ hex = hex.toUpperCase();
+ int val = 0;
+
+ for (int i = 0; i < hex.length(); i++) {
+ int d = digits.indexOf(hex.charAt(i));
+ if (d == -1) {
+ throw new IllegalArgumentException("Invalid hexadecimal character: " + hex.charAt(i));
+ }
+ val = 16 * val + d;
+ }
+
+ return val;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/conversions/IPConverter.java b/src/main/java/com/thealgorithms/conversions/IPConverter.java
index 765cb0201dd5..171b378baa10 100644
--- a/src/main/java/com/thealgorithms/conversions/IPConverter.java
+++ b/src/main/java/com/thealgorithms/conversions/IPConverter.java
@@ -1,58 +1,58 @@
-package com.thealgorithms.conversions;
-
-/**
- * Converts an IPv4 address to its binary equivalent and vice-versa.
- * IP to Binary: Converts an IPv4 address to its binary equivalent.
- * Example: 127.3.4.5 -> 01111111.00000011.00000100.00000101
- *
- * Binary to IP: Converts a binary equivalent to an IPv4 address.
- * Example: 01111111.00000011.00000100.00000101 -> 127.3.4.5
- *
- * @author Hardvan
- */
-public final class IPConverter {
- private IPConverter() {
- }
-
- /**
- * Converts an IPv4 address to its binary equivalent.
- * @param ip The IPv4 address to convert.
- * @return The binary equivalent of the IPv4 address.
- */
- public static String ipToBinary(String ip) {
- StringBuilder binary = new StringBuilder();
- for (String octet : ip.split("\\.")) {
- binary.append(octetToBinary(Integer.parseInt(octet))).append(".");
- }
- return binary.substring(0, binary.length() - 1);
- }
-
- /**
- * Converts a single octet to its 8-bit binary representation.
- * @param octet The octet to convert (0-255).
- * @return The 8-bit binary representation as a String.
- */
- private static String octetToBinary(int octet) {
- char[] binary = {'0', '0', '0', '0', '0', '0', '0', '0'};
- for (int i = 7; i >= 0; i--) {
- if ((octet & 1) == 1) {
- binary[i] = '1';
- }
- octet >>>= 1;
- }
- return new String(binary);
- }
-
- /**
- * Converts a binary equivalent to an IPv4 address.
- * @param binary The binary equivalent to convert.
- * @return The IPv4 address of the binary equivalent.
- */
- public static String binaryToIP(String binary) {
- StringBuilder ip = new StringBuilder();
- for (String octet : binary.split("\\.")) {
- ip.append(Integer.parseInt(octet, 2)).append(".");
- }
- return ip.substring(0, ip.length() - 1);
- }
-}
+package com.thealgorithms.conversions;
+
+/**
+ * Converts an IPv4 address to its binary equivalent and vice-versa.
+ * IP to Binary: Converts an IPv4 address to its binary equivalent.
+ * Example: 127.3.4.5 -> 01111111.00000011.00000100.00000101
+ *
+ * Binary to IP: Converts a binary equivalent to an IPv4 address.
+ * Example: 01111111.00000011.00000100.00000101 -> 127.3.4.5
+ *
+ * @author Hardvan
+ */
+public final class IPConverter {
+ private IPConverter() {
+ }
+
+ /**
+ * Converts an IPv4 address to its binary equivalent.
+ * @param ip The IPv4 address to convert.
+ * @return The binary equivalent of the IPv4 address.
+ */
+ public static String ipToBinary(String ip) {
+ StringBuilder binary = new StringBuilder();
+ for (String octet : ip.split("\\.")) {
+ binary.append(octetToBinary(Integer.parseInt(octet))).append(".");
+ }
+ return binary.substring(0, binary.length() - 1);
+ }
+
+ /**
+ * Converts a single octet to its 8-bit binary representation.
+ * @param octet The octet to convert (0-255).
+ * @return The 8-bit binary representation as a String.
+ */
+ private static String octetToBinary(int octet) {
+ char[] binary = {'0', '0', '0', '0', '0', '0', '0', '0'};
+ for (int i = 7; i >= 0; i--) {
+ if ((octet & 1) == 1) {
+ binary[i] = '1';
+ }
+ octet >>>= 1;
+ }
+ return new String(binary);
+ }
+
+ /**
+ * Converts a binary equivalent to an IPv4 address.
+ * @param binary The binary equivalent to convert.
+ * @return The IPv4 address of the binary equivalent.
+ */
+ public static String binaryToIP(String binary) {
+ StringBuilder ip = new StringBuilder();
+ for (String octet : binary.split("\\.")) {
+ ip.append(Integer.parseInt(octet, 2)).append(".");
+ }
+ return ip.substring(0, ip.length() - 1);
+ }
+}
diff --git a/src/main/java/com/thealgorithms/conversions/IPv6Converter.java b/src/main/java/com/thealgorithms/conversions/IPv6Converter.java
index d42ffd027514..37fda29818a2 100644
--- a/src/main/java/com/thealgorithms/conversions/IPv6Converter.java
+++ b/src/main/java/com/thealgorithms/conversions/IPv6Converter.java
@@ -1,98 +1,98 @@
-package com.thealgorithms.conversions;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.Arrays;
-
-/**
- * A utility class for converting between IPv6 and IPv4 addresses.
- *
- * - Converts IPv4 to IPv6-mapped IPv6 address.
- * - Extracts IPv4 address from IPv6-mapped IPv6.
- * - Handles exceptions for invalid inputs.
- *
- * @author Hardvan
- */
-public final class IPv6Converter {
- private IPv6Converter() {
- }
-
- /**
- * Converts an IPv4 address (e.g., "192.0.2.128") to an IPv6-mapped IPv6 address.
- * Example: IPv4 "192.0.2.128" -> IPv6 "::ffff:192.0.2.128"
- *
- * @param ipv4Address The IPv4 address in string format.
- * @return The corresponding IPv6-mapped IPv6 address.
- * @throws UnknownHostException If the IPv4 address is invalid.
- * @throws IllegalArgumentException If the IPv6 address is not a mapped IPv4 address.
- */
- public static String ipv4ToIpv6(String ipv4Address) throws UnknownHostException {
- if (ipv4Address == null || ipv4Address.isEmpty()) {
- throw new UnknownHostException("IPv4 address is empty.");
- }
-
- InetAddress ipv4 = InetAddress.getByName(ipv4Address);
- byte[] ipv4Bytes = ipv4.getAddress();
-
- // Create IPv6-mapped IPv6 address (starts with ::ffff:)
- byte[] ipv6Bytes = new byte[16];
- ipv6Bytes[10] = (byte) 0xff;
- ipv6Bytes[11] = (byte) 0xff;
- System.arraycopy(ipv4Bytes, 0, ipv6Bytes, 12, 4);
-
- // Manually format to "::ffff:x.x.x.x" format
- StringBuilder ipv6String = new StringBuilder("::ffff:");
- for (int i = 12; i < 16; i++) {
- ipv6String.append(ipv6Bytes[i] & 0xFF);
- if (i < 15) {
- ipv6String.append('.');
- }
- }
- return ipv6String.toString();
- }
-
- /**
- * Extracts the IPv4 address from an IPv6-mapped IPv6 address.
- * Example: IPv6 "::ffff:192.0.2.128" -> IPv4 "192.0.2.128"
- *
- * @param ipv6Address The IPv6 address in string format.
- * @return The extracted IPv4 address.
- * @throws UnknownHostException If the IPv6 address is invalid or not a mapped IPv4 address.
- */
- public static String ipv6ToIpv4(String ipv6Address) throws UnknownHostException {
- InetAddress ipv6 = InetAddress.getByName(ipv6Address);
- byte[] ipv6Bytes = ipv6.getAddress();
-
- // Check if the address is an IPv6-mapped IPv4 address
- if (isValidIpv6MappedIpv4(ipv6Bytes)) {
- byte[] ipv4Bytes = Arrays.copyOfRange(ipv6Bytes, 12, 16);
- InetAddress ipv4 = InetAddress.getByAddress(ipv4Bytes);
- return ipv4.getHostAddress();
- } else {
- throw new IllegalArgumentException("Not a valid IPv6-mapped IPv4 address.");
- }
- }
-
- /**
- * Helper function to check if the given byte array represents
- * an IPv6-mapped IPv4 address (prefix 0:0:0:0:0:ffff).
- *
- * @param ipv6Bytes Byte array representation of the IPv6 address.
- * @return True if the address is IPv6-mapped IPv4, otherwise false.
- */
- private static boolean isValidIpv6MappedIpv4(byte[] ipv6Bytes) {
- // IPv6-mapped IPv4 addresses are 16 bytes long, with the first 10 bytes set to 0,
- // followed by 0xff, 0xff, and the last 4 bytes representing the IPv4 address.
- if (ipv6Bytes.length != 16) {
- return false;
- }
-
- for (int i = 0; i < 10; i++) {
- if (ipv6Bytes[i] != 0) {
- return false;
- }
- }
-
- return ipv6Bytes[10] == (byte) 0xff && ipv6Bytes[11] == (byte) 0xff;
- }
-}
+package com.thealgorithms.conversions;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+
+/**
+ * A utility class for converting between IPv6 and IPv4 addresses.
+ *
+ * - Converts IPv4 to IPv6-mapped IPv6 address.
+ * - Extracts IPv4 address from IPv6-mapped IPv6.
+ * - Handles exceptions for invalid inputs.
+ *
+ * @author Hardvan
+ */
+public final class IPv6Converter {
+ private IPv6Converter() {
+ }
+
+ /**
+ * Converts an IPv4 address (e.g., "192.0.2.128") to an IPv6-mapped IPv6 address.
+ * Example: IPv4 "192.0.2.128" -> IPv6 "::ffff:192.0.2.128"
+ *
+ * @param ipv4Address The IPv4 address in string format.
+ * @return The corresponding IPv6-mapped IPv6 address.
+ * @throws UnknownHostException If the IPv4 address is invalid.
+ * @throws IllegalArgumentException If the IPv6 address is not a mapped IPv4 address.
+ */
+ public static String ipv4ToIpv6(String ipv4Address) throws UnknownHostException {
+ if (ipv4Address == null || ipv4Address.isEmpty()) {
+ throw new UnknownHostException("IPv4 address is empty.");
+ }
+
+ InetAddress ipv4 = InetAddress.getByName(ipv4Address);
+ byte[] ipv4Bytes = ipv4.getAddress();
+
+ // Create IPv6-mapped IPv6 address (starts with ::ffff:)
+ byte[] ipv6Bytes = new byte[16];
+ ipv6Bytes[10] = (byte) 0xff;
+ ipv6Bytes[11] = (byte) 0xff;
+ System.arraycopy(ipv4Bytes, 0, ipv6Bytes, 12, 4);
+
+ // Manually format to "::ffff:x.x.x.x" format
+ StringBuilder ipv6String = new StringBuilder("::ffff:");
+ for (int i = 12; i < 16; i++) {
+ ipv6String.append(ipv6Bytes[i] & 0xFF);
+ if (i < 15) {
+ ipv6String.append('.');
+ }
+ }
+ return ipv6String.toString();
+ }
+
+ /**
+ * Extracts the IPv4 address from an IPv6-mapped IPv6 address.
+ * Example: IPv6 "::ffff:192.0.2.128" -> IPv4 "192.0.2.128"
+ *
+ * @param ipv6Address The IPv6 address in string format.
+ * @return The extracted IPv4 address.
+ * @throws UnknownHostException If the IPv6 address is invalid or not a mapped IPv4 address.
+ */
+ public static String ipv6ToIpv4(String ipv6Address) throws UnknownHostException {
+ InetAddress ipv6 = InetAddress.getByName(ipv6Address);
+ byte[] ipv6Bytes = ipv6.getAddress();
+
+ // Check if the address is an IPv6-mapped IPv4 address
+ if (isValidIpv6MappedIpv4(ipv6Bytes)) {
+ byte[] ipv4Bytes = Arrays.copyOfRange(ipv6Bytes, 12, 16);
+ InetAddress ipv4 = InetAddress.getByAddress(ipv4Bytes);
+ return ipv4.getHostAddress();
+ } else {
+ throw new IllegalArgumentException("Not a valid IPv6-mapped IPv4 address.");
+ }
+ }
+
+ /**
+ * Helper function to check if the given byte array represents
+ * an IPv6-mapped IPv4 address (prefix 0:0:0:0:0:ffff).
+ *
+ * @param ipv6Bytes Byte array representation of the IPv6 address.
+ * @return True if the address is IPv6-mapped IPv4, otherwise false.
+ */
+ private static boolean isValidIpv6MappedIpv4(byte[] ipv6Bytes) {
+ // IPv6-mapped IPv4 addresses are 16 bytes long, with the first 10 bytes set to 0,
+ // followed by 0xff, 0xff, and the last 4 bytes representing the IPv4 address.
+ if (ipv6Bytes.length != 16) {
+ return false;
+ }
+
+ for (int i = 0; i < 10; i++) {
+ if (ipv6Bytes[i] != 0) {
+ return false;
+ }
+ }
+
+ return ipv6Bytes[10] == (byte) 0xff && ipv6Bytes[11] == (byte) 0xff;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/conversions/IntegerToEnglish.java b/src/main/java/com/thealgorithms/conversions/IntegerToEnglish.java
index e85c608af5d0..d69ab834d6ee 100644
--- a/src/main/java/com/thealgorithms/conversions/IntegerToEnglish.java
+++ b/src/main/java/com/thealgorithms/conversions/IntegerToEnglish.java
@@ -1,108 +1,108 @@
-package com.thealgorithms.conversions;
-
-import java.util.Map;
-
-/**
- * A utility class to convert integers to their English word representation.
- *
- * The class supports conversion of numbers from 0 to 2,147,483,647
- * (the maximum value of a 32-bit signed integer). It divides the number
- * into groups of three digits (thousands, millions, billions, etc.) and
- * translates each group into words.
- *
- * Example Usage
- *
- * IntegerToEnglish.integerToEnglishWords(12345);
- * // Output: "Twelve Thousand Three Hundred Forty Five"
- *
- *
- * This class uses two maps:
- *
- * - BASE_NUMBERS_MAP: Holds English words for numbers 0-20, multiples of 10 up to 90, and 100.
- * - THOUSAND_POWER_MAP: Maps powers of 1000 (e.g., Thousand, Million, Billion).
- *
- */
-public final class IntegerToEnglish {
-
- private static final Map BASE_NUMBERS_MAP = Map.ofEntries(Map.entry(0, ""), Map.entry(1, "One"), Map.entry(2, "Two"), Map.entry(3, "Three"), Map.entry(4, "Four"), Map.entry(5, "Five"), Map.entry(6, "Six"), Map.entry(7, "Seven"), Map.entry(8, "Eight"), Map.entry(9, "Nine"),
- Map.entry(10, "Ten"), Map.entry(11, "Eleven"), Map.entry(12, "Twelve"), Map.entry(13, "Thirteen"), Map.entry(14, "Fourteen"), Map.entry(15, "Fifteen"), Map.entry(16, "Sixteen"), Map.entry(17, "Seventeen"), Map.entry(18, "Eighteen"), Map.entry(19, "Nineteen"), Map.entry(20, "Twenty"),
- Map.entry(30, "Thirty"), Map.entry(40, "Forty"), Map.entry(50, "Fifty"), Map.entry(60, "Sixty"), Map.entry(70, "Seventy"), Map.entry(80, "Eighty"), Map.entry(90, "Ninety"), Map.entry(100, "Hundred"));
-
- private static final Map THOUSAND_POWER_MAP = Map.ofEntries(Map.entry(1, "Thousand"), Map.entry(2, "Million"), Map.entry(3, "Billion"));
-
- private IntegerToEnglish() {
- }
-
- /**
- * Converts numbers less than 1000 into English words.
- *
- * @param number the integer value (0-999) to convert
- * @return the English word representation of the input number
- */
- private static String convertToWords(int number) {
- int remainder = number % 100;
- StringBuilder result = new StringBuilder();
-
- if (remainder <= 20) {
- result.append(BASE_NUMBERS_MAP.get(remainder));
- } else if (BASE_NUMBERS_MAP.containsKey(remainder)) {
- result.append(BASE_NUMBERS_MAP.get(remainder));
- } else {
- int tensDigit = remainder / 10;
- int onesDigit = remainder % 10;
- String tens = BASE_NUMBERS_MAP.getOrDefault(tensDigit * 10, "");
- String ones = BASE_NUMBERS_MAP.getOrDefault(onesDigit, "");
- result.append(tens);
- if (ones != null && !ones.isEmpty()) {
- result.append(" ").append(ones);
- }
- }
-
- int hundredsDigit = number / 100;
- if (hundredsDigit > 0) {
- if (result.length() > 0) {
- result.insert(0, " ");
- }
- result.insert(0, String.format("%s Hundred", BASE_NUMBERS_MAP.get(hundredsDigit)));
- }
-
- return result.toString().trim();
- }
-
- /**
- * Converts a non-negative integer to its English word representation.
- *
- * @param number the integer to convert (0-2,147,483,647)
- * @return the English word representation of the input number
- */
- public static String integerToEnglishWords(int number) {
- if (number == 0) {
- return "Zero";
- }
-
- StringBuilder result = new StringBuilder();
- int index = 0;
-
- while (number > 0) {
- int remainder = number % 1000;
- number /= 1000;
-
- if (remainder > 0) {
- String subResult = convertToWords(remainder);
- if (!subResult.isEmpty()) {
- if (index > 0) {
- subResult += " " + THOUSAND_POWER_MAP.get(index);
- }
- if (result.length() > 0) {
- result.insert(0, " ");
- }
- result.insert(0, subResult);
- }
- }
-
- index++;
- }
-
- return result.toString().trim();
- }
-}
+package com.thealgorithms.conversions;
+
+import java.util.Map;
+
+/**
+ * A utility class to convert integers to their English word representation.
+ *
+ * The class supports conversion of numbers from 0 to 2,147,483,647
+ * (the maximum value of a 32-bit signed integer). It divides the number
+ * into groups of three digits (thousands, millions, billions, etc.) and
+ * translates each group into words.
+ *
+ * Example Usage
+ *
+ * IntegerToEnglish.integerToEnglishWords(12345);
+ * // Output: "Twelve Thousand Three Hundred Forty Five"
+ *
+ *
+ * This class uses two maps:
+ *
+ * - BASE_NUMBERS_MAP: Holds English words for numbers 0-20, multiples of 10 up to 90, and 100.
+ * - THOUSAND_POWER_MAP: Maps powers of 1000 (e.g., Thousand, Million, Billion).
+ *
+ */
+public final class IntegerToEnglish {
+
+ private static final Map BASE_NUMBERS_MAP = Map.ofEntries(Map.entry(0, ""), Map.entry(1, "One"), Map.entry(2, "Two"), Map.entry(3, "Three"), Map.entry(4, "Four"), Map.entry(5, "Five"), Map.entry(6, "Six"), Map.entry(7, "Seven"), Map.entry(8, "Eight"), Map.entry(9, "Nine"),
+ Map.entry(10, "Ten"), Map.entry(11, "Eleven"), Map.entry(12, "Twelve"), Map.entry(13, "Thirteen"), Map.entry(14, "Fourteen"), Map.entry(15, "Fifteen"), Map.entry(16, "Sixteen"), Map.entry(17, "Seventeen"), Map.entry(18, "Eighteen"), Map.entry(19, "Nineteen"), Map.entry(20, "Twenty"),
+ Map.entry(30, "Thirty"), Map.entry(40, "Forty"), Map.entry(50, "Fifty"), Map.entry(60, "Sixty"), Map.entry(70, "Seventy"), Map.entry(80, "Eighty"), Map.entry(90, "Ninety"), Map.entry(100, "Hundred"));
+
+ private static final Map THOUSAND_POWER_MAP = Map.ofEntries(Map.entry(1, "Thousand"), Map.entry(2, "Million"), Map.entry(3, "Billion"));
+
+ private IntegerToEnglish() {
+ }
+
+ /**
+ * Converts numbers less than 1000 into English words.
+ *
+ * @param number the integer value (0-999) to convert
+ * @return the English word representation of the input number
+ */
+ private static String convertToWords(int number) {
+ int remainder = number % 100;
+ StringBuilder result = new StringBuilder();
+
+ if (remainder <= 20) {
+ result.append(BASE_NUMBERS_MAP.get(remainder));
+ } else if (BASE_NUMBERS_MAP.containsKey(remainder)) {
+ result.append(BASE_NUMBERS_MAP.get(remainder));
+ } else {
+ int tensDigit = remainder / 10;
+ int onesDigit = remainder % 10;
+ String tens = BASE_NUMBERS_MAP.getOrDefault(tensDigit * 10, "");
+ String ones = BASE_NUMBERS_MAP.getOrDefault(onesDigit, "");
+ result.append(tens);
+ if (ones != null && !ones.isEmpty()) {
+ result.append(" ").append(ones);
+ }
+ }
+
+ int hundredsDigit = number / 100;
+ if (hundredsDigit > 0) {
+ if (result.length() > 0) {
+ result.insert(0, " ");
+ }
+ result.insert(0, String.format("%s Hundred", BASE_NUMBERS_MAP.get(hundredsDigit)));
+ }
+
+ return result.toString().trim();
+ }
+
+ /**
+ * Converts a non-negative integer to its English word representation.
+ *
+ * @param number the integer to convert (0-2,147,483,647)
+ * @return the English word representation of the input number
+ */
+ public static String integerToEnglishWords(int number) {
+ if (number == 0) {
+ return "Zero";
+ }
+
+ StringBuilder result = new StringBuilder();
+ int index = 0;
+
+ while (number > 0) {
+ int remainder = number % 1000;
+ number /= 1000;
+
+ if (remainder > 0) {
+ String subResult = convertToWords(remainder);
+ if (!subResult.isEmpty()) {
+ if (index > 0) {
+ subResult += " " + THOUSAND_POWER_MAP.get(index);
+ }
+ if (result.length() > 0) {
+ result.insert(0, " ");
+ }
+ result.insert(0, subResult);
+ }
+ }
+
+ index++;
+ }
+
+ return result.toString().trim();
+ }
+}
diff --git a/src/main/java/com/thealgorithms/conversions/IntegerToRoman.java b/src/main/java/com/thealgorithms/conversions/IntegerToRoman.java
index fec437668fe6..4a368a47df72 100644
--- a/src/main/java/com/thealgorithms/conversions/IntegerToRoman.java
+++ b/src/main/java/com/thealgorithms/conversions/IntegerToRoman.java
@@ -1,68 +1,68 @@
-package com.thealgorithms.conversions;
-
-/**
- * A utility class to convert integers into Roman numerals.
- *
- * Roman numerals follow these rules:
- *
- * - I = 1
- * - IV = 4
- * - V = 5
- * - IX = 9
- * - X = 10
- * - XL = 40
- * - L = 50
- * - XC = 90
- * - C = 100
- * - D = 500
- * - M = 1000
- *
- *
- * Conversion is based on repeatedly subtracting the largest possible Roman numeral value
- * from the input number until it reaches zero. For example, 1994 is converted as:
- *
- * 1994 -> MCMXCIV (1000 + 900 + 90 + 4)
- *
- */
-public final class IntegerToRoman {
-
- // Array of Roman numeral values in descending order
- private static final int[] ALL_ROMAN_NUMBERS_IN_ARABIC = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
-
- // Corresponding Roman numeral symbols
- private static final String[] ALL_ROMAN_NUMBERS = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
-
- private IntegerToRoman() {
- }
-
- /**
- * Converts an integer to its Roman numeral representation.
- * Steps:
- *
- * - Iterate over the Roman numeral values in descending order
- * - Calculate how many times a numeral fits
- * - Append the corresponding symbol
- * - Subtract the value from the number
- * - Repeat until the number is zero
- * - Return the Roman numeral representation
- *
- *
- * @param num the integer value to convert (must be greater than 0)
- * @return the Roman numeral representation of the input integer
- * or an empty string if the input is non-positive
- */
- public static String integerToRoman(int num) {
- if (num <= 0) {
- return "";
- }
-
- StringBuilder builder = new StringBuilder();
- for (int i = 0; i < ALL_ROMAN_NUMBERS_IN_ARABIC.length; i++) {
- int times = num / ALL_ROMAN_NUMBERS_IN_ARABIC[i];
- builder.append(ALL_ROMAN_NUMBERS[i].repeat(Math.max(0, times)));
- num -= times * ALL_ROMAN_NUMBERS_IN_ARABIC[i];
- }
-
- return builder.toString();
- }
-}
+package com.thealgorithms.conversions;
+
+/**
+ * A utility class to convert integers into Roman numerals.
+ *
+ * Roman numerals follow these rules:
+ *
+ * - I = 1
+ * - IV = 4
+ * - V = 5
+ * - IX = 9
+ * - X = 10
+ * - XL = 40
+ * - L = 50
+ * - XC = 90
+ * - C = 100
+ * - D = 500
+ * - M = 1000
+ *
+ *
+ * Conversion is based on repeatedly subtracting the largest possible Roman numeral value
+ * from the input number until it reaches zero. For example, 1994 is converted as:
+ *
+ * 1994 -> MCMXCIV (1000 + 900 + 90 + 4)
+ *
+ */
+public final class IntegerToRoman {
+
+ // Array of Roman numeral values in descending order
+ private static final int[] ALL_ROMAN_NUMBERS_IN_ARABIC = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
+
+ // Corresponding Roman numeral symbols
+ private static final String[] ALL_ROMAN_NUMBERS = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
+
+ private IntegerToRoman() {
+ }
+
+ /**
+ * Converts an integer to its Roman numeral representation.
+ * Steps:
+ *
+ * - Iterate over the Roman numeral values in descending order
+ * - Calculate how many times a numeral fits
+ * - Append the corresponding symbol
+ * - Subtract the value from the number
+ * - Repeat until the number is zero
+ * - Return the Roman numeral representation
+ *
+ *
+ * @param num the integer value to convert (must be greater than 0)
+ * @return the Roman numeral representation of the input integer
+ * or an empty string if the input is non-positive
+ */
+ public static String integerToRoman(int num) {
+ if (num <= 0) {
+ return "";
+ }
+
+ StringBuilder builder = new StringBuilder();
+ for (int i = 0; i < ALL_ROMAN_NUMBERS_IN_ARABIC.length; i++) {
+ int times = num / ALL_ROMAN_NUMBERS_IN_ARABIC[i];
+ builder.append(ALL_ROMAN_NUMBERS[i].repeat(Math.max(0, times)));
+ num -= times * ALL_ROMAN_NUMBERS_IN_ARABIC[i];
+ }
+
+ return builder.toString();
+ }
+}
diff --git a/src/main/java/com/thealgorithms/conversions/MorseCodeConverter.java b/src/main/java/com/thealgorithms/conversions/MorseCodeConverter.java
index a3973da0c586..4ea15ba8474c 100644
--- a/src/main/java/com/thealgorithms/conversions/MorseCodeConverter.java
+++ b/src/main/java/com/thealgorithms/conversions/MorseCodeConverter.java
@@ -1,98 +1,98 @@
-package com.thealgorithms.conversions;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Converts text to Morse code and vice-versa.
- * Text to Morse code: Each letter is separated by a space and each word is separated by a pipe (|).
- * Example: "HELLO WORLD" -> ".... . .-.. .-.. --- | .-- --- .-. .-.. -.."
- *
- * Morse code to text: Each letter is separated by a space and each word is separated by a pipe (|).
- * Example: ".... . .-.. .-.. --- | .-- --- .-. .-.. -.." -> "HELLO WORLD"
- *
- * Applications: Used in radio communications and algorithmic challenges.
- *
- * @author Hardvan
- */
-public final class MorseCodeConverter {
- private MorseCodeConverter() {
- }
-
- private static final Map MORSE_MAP = new HashMap<>();
- private static final Map REVERSE_MAP = new HashMap<>();
-
- static {
- MORSE_MAP.put('A', ".-");
- MORSE_MAP.put('B', "-...");
- MORSE_MAP.put('C', "-.-.");
- MORSE_MAP.put('D', "-..");
- MORSE_MAP.put('E', ".");
- MORSE_MAP.put('F', "..-.");
- MORSE_MAP.put('G', "--.");
- MORSE_MAP.put('H', "....");
- MORSE_MAP.put('I', "..");
- MORSE_MAP.put('J', ".---");
- MORSE_MAP.put('K', "-.-");
- MORSE_MAP.put('L', ".-..");
- MORSE_MAP.put('M', "--");
- MORSE_MAP.put('N', "-.");
- MORSE_MAP.put('O', "---");
- MORSE_MAP.put('P', ".--.");
- MORSE_MAP.put('Q', "--.-");
- MORSE_MAP.put('R', ".-.");
- MORSE_MAP.put('S', "...");
- MORSE_MAP.put('T', "-");
- MORSE_MAP.put('U', "..-");
- MORSE_MAP.put('V', "...-");
- MORSE_MAP.put('W', ".--");
- MORSE_MAP.put('X', "-..-");
- MORSE_MAP.put('Y', "-.--");
- MORSE_MAP.put('Z', "--..");
-
- // Build reverse map for decoding
- MORSE_MAP.forEach((k, v) -> REVERSE_MAP.put(v, k));
- }
-
- /**
- * Converts text to Morse code.
- * Each letter is separated by a space and each word is separated by a pipe (|).
- *
- * @param text The text to convert to Morse code.
- * @return The Morse code representation of the text.
- */
- public static String textToMorse(String text) {
- StringBuilder morse = new StringBuilder();
- String[] words = text.toUpperCase().split(" ");
- for (int i = 0; i < words.length; i++) {
- for (char c : words[i].toCharArray()) {
- morse.append(MORSE_MAP.getOrDefault(c, "")).append(" ");
- }
- if (i < words.length - 1) {
- morse.append("| ");
- }
- }
- return morse.toString().trim();
- }
-
- /**
- * Converts Morse code to text.
- * Each letter is separated by a space and each word is separated by a pipe (|).
- *
- * @param morse The Morse code to convert to text.
- * @return The text representation of the Morse code.
- */
- public static String morseToText(String morse) {
- StringBuilder text = new StringBuilder();
- String[] words = morse.split(" \\| ");
- for (int i = 0; i < words.length; i++) {
- for (String code : words[i].split(" ")) {
- text.append(REVERSE_MAP.getOrDefault(code, '?'));
- }
- if (i < words.length - 1) {
- text.append(" ");
- }
- }
- return text.toString();
- }
-}
+package com.thealgorithms.conversions;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Converts text to Morse code and vice-versa.
+ * Text to Morse code: Each letter is separated by a space and each word is separated by a pipe (|).
+ * Example: "HELLO WORLD" -> ".... . .-.. .-.. --- | .-- --- .-. .-.. -.."
+ *
+ * Morse code to text: Each letter is separated by a space and each word is separated by a pipe (|).
+ * Example: ".... . .-.. .-.. --- | .-- --- .-. .-.. -.." -> "HELLO WORLD"
+ *
+ * Applications: Used in radio communications and algorithmic challenges.
+ *
+ * @author Hardvan
+ */
+public final class MorseCodeConverter {
+ private MorseCodeConverter() {
+ }
+
+ private static final Map MORSE_MAP = new HashMap<>();
+ private static final Map REVERSE_MAP = new HashMap<>();
+
+ static {
+ MORSE_MAP.put('A', ".-");
+ MORSE_MAP.put('B', "-...");
+ MORSE_MAP.put('C', "-.-.");
+ MORSE_MAP.put('D', "-..");
+ MORSE_MAP.put('E', ".");
+ MORSE_MAP.put('F', "..-.");
+ MORSE_MAP.put('G', "--.");
+ MORSE_MAP.put('H', "....");
+ MORSE_MAP.put('I', "..");
+ MORSE_MAP.put('J', ".---");
+ MORSE_MAP.put('K', "-.-");
+ MORSE_MAP.put('L', ".-..");
+ MORSE_MAP.put('M', "--");
+ MORSE_MAP.put('N', "-.");
+ MORSE_MAP.put('O', "---");
+ MORSE_MAP.put('P', ".--.");
+ MORSE_MAP.put('Q', "--.-");
+ MORSE_MAP.put('R', ".-.");
+ MORSE_MAP.put('S', "...");
+ MORSE_MAP.put('T', "-");
+ MORSE_MAP.put('U', "..-");
+ MORSE_MAP.put('V', "...-");
+ MORSE_MAP.put('W', ".--");
+ MORSE_MAP.put('X', "-..-");
+ MORSE_MAP.put('Y', "-.--");
+ MORSE_MAP.put('Z', "--..");
+
+ // Build reverse map for decoding
+ MORSE_MAP.forEach((k, v) -> REVERSE_MAP.put(v, k));
+ }
+
+ /**
+ * Converts text to Morse code.
+ * Each letter is separated by a space and each word is separated by a pipe (|).
+ *
+ * @param text The text to convert to Morse code.
+ * @return The Morse code representation of the text.
+ */
+ public static String textToMorse(String text) {
+ StringBuilder morse = new StringBuilder();
+ String[] words = text.toUpperCase().split(" ");
+ for (int i = 0; i < words.length; i++) {
+ for (char c : words[i].toCharArray()) {
+ morse.append(MORSE_MAP.getOrDefault(c, "")).append(" ");
+ }
+ if (i < words.length - 1) {
+ morse.append("| ");
+ }
+ }
+ return morse.toString().trim();
+ }
+
+ /**
+ * Converts Morse code to text.
+ * Each letter is separated by a space and each word is separated by a pipe (|).
+ *
+ * @param morse The Morse code to convert to text.
+ * @return The text representation of the Morse code.
+ */
+ public static String morseToText(String morse) {
+ StringBuilder text = new StringBuilder();
+ String[] words = morse.split(" \\| ");
+ for (int i = 0; i < words.length; i++) {
+ for (String code : words[i].split(" ")) {
+ text.append(REVERSE_MAP.getOrDefault(code, '?'));
+ }
+ if (i < words.length - 1) {
+ text.append(" ");
+ }
+ }
+ return text.toString();
+ }
+}
diff --git a/src/main/java/com/thealgorithms/conversions/NumberToWords.java b/src/main/java/com/thealgorithms/conversions/NumberToWords.java
index e39c5b2dea86..4133dfc247c1 100644
--- a/src/main/java/com/thealgorithms/conversions/NumberToWords.java
+++ b/src/main/java/com/thealgorithms/conversions/NumberToWords.java
@@ -1,100 +1,100 @@
-package com.thealgorithms.conversions;
-
-import java.math.BigDecimal;
-
-/**
- A Java-based utility for converting numeric values into their English word
- representations. Whether you need to convert a small number, a large number
- with millions and billions, or even a number with decimal places, this utility
- has you covered.
- *
- */
-public final class NumberToWords {
-
- private NumberToWords() {
- }
-
- private static final String[] UNITS = {"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"};
-
- private static final String[] TENS = {"", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"};
-
- private static final String[] POWERS = {"", "Thousand", "Million", "Billion", "Trillion"};
-
- private static final String ZERO = "Zero";
- private static final String POINT = " Point";
- private static final String NEGATIVE = "Negative ";
-
- public static String convert(BigDecimal number) {
- if (number == null) {
- return "Invalid Input";
- }
-
- // Check for negative sign
- boolean isNegative = number.signum() < 0;
-
- // Split the number into whole and fractional parts
- BigDecimal[] parts = number.abs().divideAndRemainder(BigDecimal.ONE);
- BigDecimal wholePart = parts[0]; // Keep whole part as BigDecimal
- String fractionalPartStr = parts[1].compareTo(BigDecimal.ZERO) > 0 ? parts[1].toPlainString().substring(2) : ""; // Get fractional part only if it exists
-
- // Convert whole part to words
- StringBuilder result = new StringBuilder();
- if (isNegative) {
- result.append(NEGATIVE);
- }
- result.append(convertWholeNumberToWords(wholePart));
-
- // Convert fractional part to words
- if (!fractionalPartStr.isEmpty()) {
- result.append(POINT);
- for (char digit : fractionalPartStr.toCharArray()) {
- int digitValue = Character.getNumericValue(digit);
- result.append(" ").append(digitValue == 0 ? ZERO : UNITS[digitValue]);
- }
- }
-
- return result.toString().trim();
- }
-
- private static String convertWholeNumberToWords(BigDecimal number) {
- if (number.compareTo(BigDecimal.ZERO) == 0) {
- return ZERO;
- }
-
- StringBuilder words = new StringBuilder();
- int power = 0;
-
- while (number.compareTo(BigDecimal.ZERO) > 0) {
- // Get the last three digits
- BigDecimal[] divisionResult = number.divideAndRemainder(BigDecimal.valueOf(1000));
- int chunk = divisionResult[1].intValue();
-
- if (chunk > 0) {
- String chunkWords = convertChunk(chunk);
- if (power > 0) {
- words.insert(0, POWERS[power] + " ");
- }
- words.insert(0, chunkWords + " ");
- }
-
- number = divisionResult[0]; // Continue with the remaining part
- power++;
- }
-
- return words.toString().trim();
- }
-
- private static String convertChunk(int number) {
- String chunkWords;
-
- if (number < 20) {
- chunkWords = UNITS[number];
- } else if (number < 100) {
- chunkWords = TENS[number / 10] + (number % 10 > 0 ? " " + UNITS[number % 10] : "");
- } else {
- chunkWords = UNITS[number / 100] + " Hundred" + (number % 100 > 0 ? " " + convertChunk(number % 100) : "");
- }
-
- return chunkWords;
- }
-}
+package com.thealgorithms.conversions;
+
+import java.math.BigDecimal;
+
+/**
+ A Java-based utility for converting numeric values into their English word
+ representations. Whether you need to convert a small number, a large number
+ with millions and billions, or even a number with decimal places, this utility
+ has you covered.
+ *
+ */
+public final class NumberToWords {
+
+ private NumberToWords() {
+ }
+
+ private static final String[] UNITS = {"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"};
+
+ private static final String[] TENS = {"", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"};
+
+ private static final String[] POWERS = {"", "Thousand", "Million", "Billion", "Trillion"};
+
+ private static final String ZERO = "Zero";
+ private static final String POINT = " Point";
+ private static final String NEGATIVE = "Negative ";
+
+ public static String convert(BigDecimal number) {
+ if (number == null) {
+ return "Invalid Input";
+ }
+
+ // Check for negative sign
+ boolean isNegative = number.signum() < 0;
+
+ // Split the number into whole and fractional parts
+ BigDecimal[] parts = number.abs().divideAndRemainder(BigDecimal.ONE);
+ BigDecimal wholePart = parts[0]; // Keep whole part as BigDecimal
+ String fractionalPartStr = parts[1].compareTo(BigDecimal.ZERO) > 0 ? parts[1].toPlainString().substring(2) : ""; // Get fractional part only if it exists
+
+ // Convert whole part to words
+ StringBuilder result = new StringBuilder();
+ if (isNegative) {
+ result.append(NEGATIVE);
+ }
+ result.append(convertWholeNumberToWords(wholePart));
+
+ // Convert fractional part to words
+ if (!fractionalPartStr.isEmpty()) {
+ result.append(POINT);
+ for (char digit : fractionalPartStr.toCharArray()) {
+ int digitValue = Character.getNumericValue(digit);
+ result.append(" ").append(digitValue == 0 ? ZERO : UNITS[digitValue]);
+ }
+ }
+
+ return result.toString().trim();
+ }
+
+ private static String convertWholeNumberToWords(BigDecimal number) {
+ if (number.compareTo(BigDecimal.ZERO) == 0) {
+ return ZERO;
+ }
+
+ StringBuilder words = new StringBuilder();
+ int power = 0;
+
+ while (number.compareTo(BigDecimal.ZERO) > 0) {
+ // Get the last three digits
+ BigDecimal[] divisionResult = number.divideAndRemainder(BigDecimal.valueOf(1000));
+ int chunk = divisionResult[1].intValue();
+
+ if (chunk > 0) {
+ String chunkWords = convertChunk(chunk);
+ if (power > 0) {
+ words.insert(0, POWERS[power] + " ");
+ }
+ words.insert(0, chunkWords + " ");
+ }
+
+ number = divisionResult[0]; // Continue with the remaining part
+ power++;
+ }
+
+ return words.toString().trim();
+ }
+
+ private static String convertChunk(int number) {
+ String chunkWords;
+
+ if (number < 20) {
+ chunkWords = UNITS[number];
+ } else if (number < 100) {
+ chunkWords = TENS[number / 10] + (number % 10 > 0 ? " " + UNITS[number % 10] : "");
+ } else {
+ chunkWords = UNITS[number / 100] + " Hundred" + (number % 100 > 0 ? " " + convertChunk(number % 100) : "");
+ }
+
+ return chunkWords;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/conversions/OctalToBinary.java b/src/main/java/com/thealgorithms/conversions/OctalToBinary.java
index a66db97633b4..b6581b96ddd7 100644
--- a/src/main/java/com/thealgorithms/conversions/OctalToBinary.java
+++ b/src/main/java/com/thealgorithms/conversions/OctalToBinary.java
@@ -1,82 +1,82 @@
-package com.thealgorithms.conversions;
-
-/**
- * A utility class to convert an octal (base-8) number into its binary (base-2) representation.
- *
- * This class provides methods to:
- *
- * - Convert an octal number to its binary equivalent
- * - Convert individual octal digits to binary
- *
- *
- * Octal to Binary Conversion:
- * An octal number is converted to binary by converting each octal digit to its 3-bit binary equivalent.
- * The result is a long representing the full binary equivalent of the octal number.
- *
- * Example Usage
- *
- * long binary = OctalToBinary.convertOctalToBinary(52); // Output: 101010 (52 in octal is 101010 in binary)
- *
- *
- * @author Bama Charan Chhandogi
- * @see Octal Number System
- * @see Binary Number System
- */
-public final class OctalToBinary {
- private OctalToBinary() {
- }
-
- /**
- * Converts an octal number to its binary representation.
- *
- * Each octal digit is individually converted to its 3-bit binary equivalent, and the binary
- * digits are concatenated to form the final binary number.
- *
- * @param octalNumber the octal number to convert (non-negative integer)
- * @return the binary equivalent as a long
- */
- public static long convertOctalToBinary(int octalNumber) {
- long binaryNumber = 0;
- int digitPosition = 1;
-
- while (octalNumber != 0) {
- int octalDigit = octalNumber % 10;
- long binaryDigit = convertOctalDigitToBinary(octalDigit);
-
- binaryNumber += binaryDigit * digitPosition;
-
- octalNumber /= 10;
- digitPosition *= 1000;
- }
-
- return binaryNumber;
- }
-
- /**
- * Converts a single octal digit (0-7) to its binary equivalent.
- *
- * For example:
- *
- * - Octal digit 7 is converted to binary 111
- * - Octal digit 3 is converted to binary 011
- *
- *
- *
- * @param octalDigit a single octal digit (0-7)
- * @return the binary equivalent as a long
- */
- public static long convertOctalDigitToBinary(int octalDigit) {
- long binaryDigit = 0;
- int binaryMultiplier = 1;
-
- while (octalDigit != 0) {
- int octalDigitRemainder = octalDigit % 2;
- binaryDigit += octalDigitRemainder * binaryMultiplier;
-
- octalDigit /= 2;
- binaryMultiplier *= 10;
- }
-
- return binaryDigit;
- }
-}
+package com.thealgorithms.conversions;
+
+/**
+ * A utility class to convert an octal (base-8) number into its binary (base-2) representation.
+ *
+ * This class provides methods to:
+ *
+ * - Convert an octal number to its binary equivalent
+ * - Convert individual octal digits to binary
+ *
+ *
+ * Octal to Binary Conversion:
+ * An octal number is converted to binary by converting each octal digit to its 3-bit binary equivalent.
+ * The result is a long representing the full binary equivalent of the octal number.
+ *
+ * Example Usage
+ *
+ * long binary = OctalToBinary.convertOctalToBinary(52); // Output: 101010 (52 in octal is 101010 in binary)
+ *
+ *
+ * @author Bama Charan Chhandogi
+ * @see Octal Number System
+ * @see Binary Number System
+ */
+public final class OctalToBinary {
+ private OctalToBinary() {
+ }
+
+ /**
+ * Converts an octal number to its binary representation.
+ *
+ * Each octal digit is individually converted to its 3-bit binary equivalent, and the binary
+ * digits are concatenated to form the final binary number.
+ *
+ * @param octalNumber the octal number to convert (non-negative integer)
+ * @return the binary equivalent as a long
+ */
+ public static long convertOctalToBinary(int octalNumber) {
+ long binaryNumber = 0;
+ int digitPosition = 1;
+
+ while (octalNumber != 0) {
+ int octalDigit = octalNumber % 10;
+ long binaryDigit = convertOctalDigitToBinary(octalDigit);
+
+ binaryNumber += binaryDigit * digitPosition;
+
+ octalNumber /= 10;
+ digitPosition *= 1000;
+ }
+
+ return binaryNumber;
+ }
+
+ /**
+ * Converts a single octal digit (0-7) to its binary equivalent.
+ *
+ * For example:
+ *
+ * - Octal digit 7 is converted to binary 111
+ * - Octal digit 3 is converted to binary 011
+ *
+ *
+ *
+ * @param octalDigit a single octal digit (0-7)
+ * @return the binary equivalent as a long
+ */
+ public static long convertOctalDigitToBinary(int octalDigit) {
+ long binaryDigit = 0;
+ int binaryMultiplier = 1;
+
+ while (octalDigit != 0) {
+ int octalDigitRemainder = octalDigit % 2;
+ binaryDigit += octalDigitRemainder * binaryMultiplier;
+
+ octalDigit /= 2;
+ binaryMultiplier *= 10;
+ }
+
+ return binaryDigit;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/conversions/OctalToDecimal.java b/src/main/java/com/thealgorithms/conversions/OctalToDecimal.java
index d91ce6eb3634..cb62f4ec0967 100644
--- a/src/main/java/com/thealgorithms/conversions/OctalToDecimal.java
+++ b/src/main/java/com/thealgorithms/conversions/OctalToDecimal.java
@@ -1,42 +1,42 @@
-package com.thealgorithms.conversions;
-
-/**
- * Class for converting an octal number to a decimal number. Octal numbers are based on 8, using digits from 0 to 7.
- *
- */
-public final class OctalToDecimal {
- private static final int OCTAL_BASE = 8;
-
- private OctalToDecimal() {
- }
-
- /**
- * Converts a given octal number (as a string) to its decimal representation.
- * If the input is not a valid octal number (i.e., contains characters other than 0-7),
- * the method throws an IllegalArgumentException.
- *
- * @param inputOctal The octal number as a string
- * @return The decimal equivalent of the octal number
- * @throws IllegalArgumentException if the input is not a valid octal number
- */
- public static int convertOctalToDecimal(String inputOctal) {
- if (inputOctal == null || inputOctal.isEmpty()) {
- throw new IllegalArgumentException("Input cannot be null or empty");
- }
-
- int decimalValue = 0;
-
- for (int i = 0; i < inputOctal.length(); i++) {
- char currentChar = inputOctal.charAt(i);
-
- if (currentChar < '0' || currentChar > '7') {
- throw new IllegalArgumentException("Incorrect input: Expecting an octal number (digits 0-7)");
- }
-
- int currentDigit = currentChar - '0';
- decimalValue = decimalValue * OCTAL_BASE + currentDigit;
- }
-
- return decimalValue;
- }
-}
+package com.thealgorithms.conversions;
+
+/**
+ * Class for converting an octal number to a decimal number. Octal numbers are based on 8, using digits from 0 to 7.
+ *
+ */
+public final class OctalToDecimal {
+ private static final int OCTAL_BASE = 8;
+
+ private OctalToDecimal() {
+ }
+
+ /**
+ * Converts a given octal number (as a string) to its decimal representation.
+ * If the input is not a valid octal number (i.e., contains characters other than 0-7),
+ * the method throws an IllegalArgumentException.
+ *
+ * @param inputOctal The octal number as a string
+ * @return The decimal equivalent of the octal number
+ * @throws IllegalArgumentException if the input is not a valid octal number
+ */
+ public static int convertOctalToDecimal(String inputOctal) {
+ if (inputOctal == null || inputOctal.isEmpty()) {
+ throw new IllegalArgumentException("Input cannot be null or empty");
+ }
+
+ int decimalValue = 0;
+
+ for (int i = 0; i < inputOctal.length(); i++) {
+ char currentChar = inputOctal.charAt(i);
+
+ if (currentChar < '0' || currentChar > '7') {
+ throw new IllegalArgumentException("Incorrect input: Expecting an octal number (digits 0-7)");
+ }
+
+ int currentDigit = currentChar - '0';
+ decimalValue = decimalValue * OCTAL_BASE + currentDigit;
+ }
+
+ return decimalValue;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/conversions/OctalToHexadecimal.java b/src/main/java/com/thealgorithms/conversions/OctalToHexadecimal.java
index bac56dc2e221..5779a12b852f 100644
--- a/src/main/java/com/thealgorithms/conversions/OctalToHexadecimal.java
+++ b/src/main/java/com/thealgorithms/conversions/OctalToHexadecimal.java
@@ -1,61 +1,61 @@
-package com.thealgorithms.conversions;
-
-/**
- * Class for converting an Octal number to its Hexadecimal equivalent.
- *
- * @author Tanmay Joshi
- */
-public final class OctalToHexadecimal {
- private static final int OCTAL_BASE = 8;
- private static final int HEX_BASE = 16;
- private static final String HEX_DIGITS = "0123456789ABCDEF";
-
- private OctalToHexadecimal() {
- }
-
- /**
- * Converts an Octal number (as a string) to its Decimal equivalent.
- *
- * @param octalNumber The Octal number as a string
- * @return The Decimal equivalent of the Octal number
- * @throws IllegalArgumentException if the input contains invalid octal digits
- */
- public static int octalToDecimal(String octalNumber) {
- if (octalNumber == null || octalNumber.isEmpty()) {
- throw new IllegalArgumentException("Input cannot be null or empty");
- }
-
- int decimalValue = 0;
- for (int i = 0; i < octalNumber.length(); i++) {
- char currentChar = octalNumber.charAt(i);
- if (currentChar < '0' || currentChar > '7') {
- throw new IllegalArgumentException("Incorrect octal digit: " + currentChar);
- }
- int currentDigit = currentChar - '0';
- decimalValue = decimalValue * OCTAL_BASE + currentDigit;
- }
-
- return decimalValue;
- }
-
- /**
- * Converts a Decimal number to its Hexadecimal equivalent.
- *
- * @param decimalNumber The Decimal number
- * @return The Hexadecimal equivalent of the Decimal number
- */
- public static String decimalToHexadecimal(int decimalNumber) {
- if (decimalNumber == 0) {
- return "0";
- }
-
- StringBuilder hexValue = new StringBuilder();
- while (decimalNumber > 0) {
- int digit = decimalNumber % HEX_BASE;
- hexValue.insert(0, HEX_DIGITS.charAt(digit));
- decimalNumber /= HEX_BASE;
- }
-
- return hexValue.toString();
- }
-}
+package com.thealgorithms.conversions;
+
+/**
+ * Class for converting an Octal number to its Hexadecimal equivalent.
+ *
+ * @author Tanmay Joshi
+ */
+public final class OctalToHexadecimal {
+ private static final int OCTAL_BASE = 8;
+ private static final int HEX_BASE = 16;
+ private static final String HEX_DIGITS = "0123456789ABCDEF";
+
+ private OctalToHexadecimal() {
+ }
+
+ /**
+ * Converts an Octal number (as a string) to its Decimal equivalent.
+ *
+ * @param octalNumber The Octal number as a string
+ * @return The Decimal equivalent of the Octal number
+ * @throws IllegalArgumentException if the input contains invalid octal digits
+ */
+ public static int octalToDecimal(String octalNumber) {
+ if (octalNumber == null || octalNumber.isEmpty()) {
+ throw new IllegalArgumentException("Input cannot be null or empty");
+ }
+
+ int decimalValue = 0;
+ for (int i = 0; i < octalNumber.length(); i++) {
+ char currentChar = octalNumber.charAt(i);
+ if (currentChar < '0' || currentChar > '7') {
+ throw new IllegalArgumentException("Incorrect octal digit: " + currentChar);
+ }
+ int currentDigit = currentChar - '0';
+ decimalValue = decimalValue * OCTAL_BASE + currentDigit;
+ }
+
+ return decimalValue;
+ }
+
+ /**
+ * Converts a Decimal number to its Hexadecimal equivalent.
+ *
+ * @param decimalNumber The Decimal number
+ * @return The Hexadecimal equivalent of the Decimal number
+ */
+ public static String decimalToHexadecimal(int decimalNumber) {
+ if (decimalNumber == 0) {
+ return "0";
+ }
+
+ StringBuilder hexValue = new StringBuilder();
+ while (decimalNumber > 0) {
+ int digit = decimalNumber % HEX_BASE;
+ hexValue.insert(0, HEX_DIGITS.charAt(digit));
+ decimalNumber /= HEX_BASE;
+ }
+
+ return hexValue.toString();
+ }
+}
diff --git a/src/main/java/com/thealgorithms/conversions/PhoneticAlphabetConverter.java b/src/main/java/com/thealgorithms/conversions/PhoneticAlphabetConverter.java
index 730ce2214e2d..674cbda0c171 100644
--- a/src/main/java/com/thealgorithms/conversions/PhoneticAlphabetConverter.java
+++ b/src/main/java/com/thealgorithms/conversions/PhoneticAlphabetConverter.java
@@ -1,84 +1,84 @@
-package com.thealgorithms.conversions;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Converts text to the NATO phonetic alphabet.
- * Examples:
- * "ABC" -> "Alpha Bravo Charlie"
- * "Hello" -> "Hotel Echo Lima Lima Oscar"
- * "123" -> "One Two Three"
- * "A1B2C3" -> "Alpha One Bravo Two Charlie Three"
- *
- * @author Hardvan
- */
-public final class PhoneticAlphabetConverter {
- private PhoneticAlphabetConverter() {
- }
-
- private static final Map PHONETIC_MAP = new HashMap<>();
-
- static {
- PHONETIC_MAP.put('A', "Alpha");
- PHONETIC_MAP.put('B', "Bravo");
- PHONETIC_MAP.put('C', "Charlie");
- PHONETIC_MAP.put('D', "Delta");
- PHONETIC_MAP.put('E', "Echo");
- PHONETIC_MAP.put('F', "Foxtrot");
- PHONETIC_MAP.put('G', "Golf");
- PHONETIC_MAP.put('H', "Hotel");
- PHONETIC_MAP.put('I', "India");
- PHONETIC_MAP.put('J', "Juliett");
- PHONETIC_MAP.put('K', "Kilo");
- PHONETIC_MAP.put('L', "Lima");
- PHONETIC_MAP.put('M', "Mike");
- PHONETIC_MAP.put('N', "November");
- PHONETIC_MAP.put('O', "Oscar");
- PHONETIC_MAP.put('P', "Papa");
- PHONETIC_MAP.put('Q', "Quebec");
- PHONETIC_MAP.put('R', "Romeo");
- PHONETIC_MAP.put('S', "Sierra");
- PHONETIC_MAP.put('T', "Tango");
- PHONETIC_MAP.put('U', "Uniform");
- PHONETIC_MAP.put('V', "Victor");
- PHONETIC_MAP.put('W', "Whiskey");
- PHONETIC_MAP.put('X', "X-ray");
- PHONETIC_MAP.put('Y', "Yankee");
- PHONETIC_MAP.put('Z', "Zulu");
- PHONETIC_MAP.put('0', "Zero");
- PHONETIC_MAP.put('1', "One");
- PHONETIC_MAP.put('2', "Two");
- PHONETIC_MAP.put('3', "Three");
- PHONETIC_MAP.put('4', "Four");
- PHONETIC_MAP.put('5', "Five");
- PHONETIC_MAP.put('6', "Six");
- PHONETIC_MAP.put('7', "Seven");
- PHONETIC_MAP.put('8', "Eight");
- PHONETIC_MAP.put('9', "Nine");
- }
-
- /**
- * Converts text to the NATO phonetic alphabet.
- * Steps:
- * 1. Convert the text to uppercase.
- * 2. Iterate over each character in the text.
- * 3. Get the phonetic equivalent of the character from the map.
- * 4. Append the phonetic equivalent to the result.
- * 5. Append a space to separate the phonetic equivalents.
- * 6. Return the result.
- *
- * @param text the text to convert
- * @return the NATO phonetic alphabet
- */
- public static String textToPhonetic(String text) {
- StringBuilder phonetic = new StringBuilder();
- for (char c : text.toUpperCase().toCharArray()) {
- if (Character.isWhitespace(c)) {
- continue;
- }
- phonetic.append(PHONETIC_MAP.getOrDefault(c, String.valueOf(c))).append(" ");
- }
- return phonetic.toString().trim();
- }
-}
+package com.thealgorithms.conversions;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Converts text to the NATO phonetic alphabet.
+ * Examples:
+ * "ABC" -> "Alpha Bravo Charlie"
+ * "Hello" -> "Hotel Echo Lima Lima Oscar"
+ * "123" -> "One Two Three"
+ * "A1B2C3" -> "Alpha One Bravo Two Charlie Three"
+ *
+ * @author Hardvan
+ */
+public final class PhoneticAlphabetConverter {
+ private PhoneticAlphabetConverter() {
+ }
+
+ private static final Map PHONETIC_MAP = new HashMap<>();
+
+ static {
+ PHONETIC_MAP.put('A', "Alpha");
+ PHONETIC_MAP.put('B', "Bravo");
+ PHONETIC_MAP.put('C', "Charlie");
+ PHONETIC_MAP.put('D', "Delta");
+ PHONETIC_MAP.put('E', "Echo");
+ PHONETIC_MAP.put('F', "Foxtrot");
+ PHONETIC_MAP.put('G', "Golf");
+ PHONETIC_MAP.put('H', "Hotel");
+ PHONETIC_MAP.put('I', "India");
+ PHONETIC_MAP.put('J', "Juliett");
+ PHONETIC_MAP.put('K', "Kilo");
+ PHONETIC_MAP.put('L', "Lima");
+ PHONETIC_MAP.put('M', "Mike");
+ PHONETIC_MAP.put('N', "November");
+ PHONETIC_MAP.put('O', "Oscar");
+ PHONETIC_MAP.put('P', "Papa");
+ PHONETIC_MAP.put('Q', "Quebec");
+ PHONETIC_MAP.put('R', "Romeo");
+ PHONETIC_MAP.put('S', "Sierra");
+ PHONETIC_MAP.put('T', "Tango");
+ PHONETIC_MAP.put('U', "Uniform");
+ PHONETIC_MAP.put('V', "Victor");
+ PHONETIC_MAP.put('W', "Whiskey");
+ PHONETIC_MAP.put('X', "X-ray");
+ PHONETIC_MAP.put('Y', "Yankee");
+ PHONETIC_MAP.put('Z', "Zulu");
+ PHONETIC_MAP.put('0', "Zero");
+ PHONETIC_MAP.put('1', "One");
+ PHONETIC_MAP.put('2', "Two");
+ PHONETIC_MAP.put('3', "Three");
+ PHONETIC_MAP.put('4', "Four");
+ PHONETIC_MAP.put('5', "Five");
+ PHONETIC_MAP.put('6', "Six");
+ PHONETIC_MAP.put('7', "Seven");
+ PHONETIC_MAP.put('8', "Eight");
+ PHONETIC_MAP.put('9', "Nine");
+ }
+
+ /**
+ * Converts text to the NATO phonetic alphabet.
+ * Steps:
+ * 1. Convert the text to uppercase.
+ * 2. Iterate over each character in the text.
+ * 3. Get the phonetic equivalent of the character from the map.
+ * 4. Append the phonetic equivalent to the result.
+ * 5. Append a space to separate the phonetic equivalents.
+ * 6. Return the result.
+ *
+ * @param text the text to convert
+ * @return the NATO phonetic alphabet
+ */
+ public static String textToPhonetic(String text) {
+ StringBuilder phonetic = new StringBuilder();
+ for (char c : text.toUpperCase().toCharArray()) {
+ if (Character.isWhitespace(c)) {
+ continue;
+ }
+ phonetic.append(PHONETIC_MAP.getOrDefault(c, String.valueOf(c))).append(" ");
+ }
+ return phonetic.toString().trim();
+ }
+}
diff --git a/src/main/java/com/thealgorithms/conversions/RgbHsvConversion.java b/src/main/java/com/thealgorithms/conversions/RgbHsvConversion.java
index 84cbff09db6b..f11f5d32f5dd 100644
--- a/src/main/java/com/thealgorithms/conversions/RgbHsvConversion.java
+++ b/src/main/java/com/thealgorithms/conversions/RgbHsvConversion.java
@@ -1,168 +1,168 @@
-package com.thealgorithms.conversions;
-
-import java.util.Arrays;
-
-/**
- * The RGB color model is an additive color model in which red, green, and blue
- * light are added together in various ways to reproduce a broad array of
- * colors. The name of the model comes from the initials of the three additive
- * primary colors, red, green, and blue. Meanwhile, the HSV representation
- * models how colors appear under light. In it, colors are represented using
- * three components: hue, saturation and (brightness-)value. This class provides
- * methods for converting colors from one representation to the other.
- * (description adapted from [1] and
- * [2]).
- */
-public final class RgbHsvConversion {
- private RgbHsvConversion() {
- }
-
- public static void main(String[] args) {
- // Expected RGB-values taken from https://www.rapidtables.com/convert/color/hsv-to-rgb.html
-
- // Test hsvToRgb-method
- assert Arrays.equals(hsvToRgb(0, 0, 0), new int[] {0, 0, 0});
- assert Arrays.equals(hsvToRgb(0, 0, 1), new int[] {255, 255, 255});
- assert Arrays.equals(hsvToRgb(0, 1, 1), new int[] {255, 0, 0});
- assert Arrays.equals(hsvToRgb(60, 1, 1), new int[] {255, 255, 0});
- assert Arrays.equals(hsvToRgb(120, 1, 1), new int[] {0, 255, 0});
- assert Arrays.equals(hsvToRgb(240, 1, 1), new int[] {0, 0, 255});
- assert Arrays.equals(hsvToRgb(300, 1, 1), new int[] {255, 0, 255});
- assert Arrays.equals(hsvToRgb(180, 0.5, 0.5), new int[] {64, 128, 128});
- assert Arrays.equals(hsvToRgb(234, 0.14, 0.88), new int[] {193, 196, 224});
- assert Arrays.equals(hsvToRgb(330, 0.75, 0.5), new int[] {128, 32, 80});
-
- // Test rgbToHsv-method
- // approximate-assertions needed because of small deviations due to converting between
- // int-values and double-values.
- assert approximatelyEqualHsv(rgbToHsv(0, 0, 0), new double[] {0, 0, 0});
- assert approximatelyEqualHsv(rgbToHsv(255, 255, 255), new double[] {0, 0, 1});
- assert approximatelyEqualHsv(rgbToHsv(255, 0, 0), new double[] {0, 1, 1});
- assert approximatelyEqualHsv(rgbToHsv(255, 255, 0), new double[] {60, 1, 1});
- assert approximatelyEqualHsv(rgbToHsv(0, 255, 0), new double[] {120, 1, 1});
- assert approximatelyEqualHsv(rgbToHsv(0, 0, 255), new double[] {240, 1, 1});
- assert approximatelyEqualHsv(rgbToHsv(255, 0, 255), new double[] {300, 1, 1});
- assert approximatelyEqualHsv(rgbToHsv(64, 128, 128), new double[] {180, 0.5, 0.5});
- assert approximatelyEqualHsv(rgbToHsv(193, 196, 224), new double[] {234, 0.14, 0.88});
- assert approximatelyEqualHsv(rgbToHsv(128, 32, 80), new double[] {330, 0.75, 0.5});
- }
-
- /**
- * Conversion from the HSV-representation to the RGB-representation.
- *
- * @param hue Hue of the color.
- * @param saturation Saturation of the color.
- * @param value Brightness-value of the color.
- * @return The tuple of RGB-components.
- */
- public static int[] hsvToRgb(double hue, double saturation, double value) {
- if (hue < 0 || hue > 360) {
- throw new IllegalArgumentException("hue should be between 0 and 360");
- }
-
- if (saturation < 0 || saturation > 1) {
- throw new IllegalArgumentException("saturation should be between 0 and 1");
- }
-
- if (value < 0 || value > 1) {
- throw new IllegalArgumentException("value should be between 0 and 1");
- }
-
- double chroma = value * saturation;
- double hueSection = hue / 60;
- double secondLargestComponent = chroma * (1 - Math.abs(hueSection % 2 - 1));
- double matchValue = value - chroma;
-
- return getRgbBySection(hueSection, chroma, matchValue, secondLargestComponent);
- }
-
- /**
- * Conversion from the RGB-representation to the HSV-representation.
- *
- * @param red Red-component of the color.
- * @param green Green-component of the color.
- * @param blue Blue-component of the color.
- * @return The tuple of HSV-components.
- */
- public static double[] rgbToHsv(int red, int green, int blue) {
- if (red < 0 || red > 255) {
- throw new IllegalArgumentException("red should be between 0 and 255");
- }
-
- if (green < 0 || green > 255) {
- throw new IllegalArgumentException("green should be between 0 and 255");
- }
-
- if (blue < 0 || blue > 255) {
- throw new IllegalArgumentException("blue should be between 0 and 255");
- }
-
- double dRed = (double) red / 255;
- double dGreen = (double) green / 255;
- double dBlue = (double) blue / 255;
- double value = Math.max(Math.max(dRed, dGreen), dBlue);
- double chroma = value - Math.min(Math.min(dRed, dGreen), dBlue);
- double saturation = value == 0 ? 0 : chroma / value;
- double hue;
-
- if (chroma == 0) {
- hue = 0;
- } else if (value == dRed) {
- hue = 60 * (0 + (dGreen - dBlue) / chroma);
- } else if (value == dGreen) {
- hue = 60 * (2 + (dBlue - dRed) / chroma);
- } else {
- hue = 60 * (4 + (dRed - dGreen) / chroma);
- }
-
- hue = (hue + 360) % 360;
-
- return new double[] {hue, saturation, value};
- }
-
- private static boolean approximatelyEqualHsv(double[] hsv1, double[] hsv2) {
- boolean bHue = Math.abs(hsv1[0] - hsv2[0]) < 0.2;
- boolean bSaturation = Math.abs(hsv1[1] - hsv2[1]) < 0.002;
- boolean bValue = Math.abs(hsv1[2] - hsv2[2]) < 0.002;
-
- return bHue && bSaturation && bValue;
- }
-
- private static int[] getRgbBySection(double hueSection, double chroma, double matchValue, double secondLargestComponent) {
- int red;
- int green;
- int blue;
-
- if (hueSection >= 0 && hueSection <= 1) {
- red = convertToInt(chroma + matchValue);
- green = convertToInt(secondLargestComponent + matchValue);
- blue = convertToInt(matchValue);
- } else if (hueSection > 1 && hueSection <= 2) {
- red = convertToInt(secondLargestComponent + matchValue);
- green = convertToInt(chroma + matchValue);
- blue = convertToInt(matchValue);
- } else if (hueSection > 2 && hueSection <= 3) {
- red = convertToInt(matchValue);
- green = convertToInt(chroma + matchValue);
- blue = convertToInt(secondLargestComponent + matchValue);
- } else if (hueSection > 3 && hueSection <= 4) {
- red = convertToInt(matchValue);
- green = convertToInt(secondLargestComponent + matchValue);
- blue = convertToInt(chroma + matchValue);
- } else if (hueSection > 4 && hueSection <= 5) {
- red = convertToInt(secondLargestComponent + matchValue);
- green = convertToInt(matchValue);
- blue = convertToInt(chroma + matchValue);
- } else {
- red = convertToInt(chroma + matchValue);
- green = convertToInt(matchValue);
- blue = convertToInt(secondLargestComponent + matchValue);
- }
-
- return new int[] {red, green, blue};
- }
-
- private static int convertToInt(double input) {
- return (int) Math.round(255 * input);
- }
-}
+package com.thealgorithms.conversions;
+
+import java.util.Arrays;
+
+/**
+ * The RGB color model is an additive color model in which red, green, and blue
+ * light are added together in various ways to reproduce a broad array of
+ * colors. The name of the model comes from the initials of the three additive
+ * primary colors, red, green, and blue. Meanwhile, the HSV representation
+ * models how colors appear under light. In it, colors are represented using
+ * three components: hue, saturation and (brightness-)value. This class provides
+ * methods for converting colors from one representation to the other.
+ * (description adapted from [1] and
+ * [2]).
+ */
+public final class RgbHsvConversion {
+ private RgbHsvConversion() {
+ }
+
+ public static void main(String[] args) {
+ // Expected RGB-values taken from https://www.rapidtables.com/convert/color/hsv-to-rgb.html
+
+ // Test hsvToRgb-method
+ assert Arrays.equals(hsvToRgb(0, 0, 0), new int[] {0, 0, 0});
+ assert Arrays.equals(hsvToRgb(0, 0, 1), new int[] {255, 255, 255});
+ assert Arrays.equals(hsvToRgb(0, 1, 1), new int[] {255, 0, 0});
+ assert Arrays.equals(hsvToRgb(60, 1, 1), new int[] {255, 255, 0});
+ assert Arrays.equals(hsvToRgb(120, 1, 1), new int[] {0, 255, 0});
+ assert Arrays.equals(hsvToRgb(240, 1, 1), new int[] {0, 0, 255});
+ assert Arrays.equals(hsvToRgb(300, 1, 1), new int[] {255, 0, 255});
+ assert Arrays.equals(hsvToRgb(180, 0.5, 0.5), new int[] {64, 128, 128});
+ assert Arrays.equals(hsvToRgb(234, 0.14, 0.88), new int[] {193, 196, 224});
+ assert Arrays.equals(hsvToRgb(330, 0.75, 0.5), new int[] {128, 32, 80});
+
+ // Test rgbToHsv-method
+ // approximate-assertions needed because of small deviations due to converting between
+ // int-values and double-values.
+ assert approximatelyEqualHsv(rgbToHsv(0, 0, 0), new double[] {0, 0, 0});
+ assert approximatelyEqualHsv(rgbToHsv(255, 255, 255), new double[] {0, 0, 1});
+ assert approximatelyEqualHsv(rgbToHsv(255, 0, 0), new double[] {0, 1, 1});
+ assert approximatelyEqualHsv(rgbToHsv(255, 255, 0), new double[] {60, 1, 1});
+ assert approximatelyEqualHsv(rgbToHsv(0, 255, 0), new double[] {120, 1, 1});
+ assert approximatelyEqualHsv(rgbToHsv(0, 0, 255), new double[] {240, 1, 1});
+ assert approximatelyEqualHsv(rgbToHsv(255, 0, 255), new double[] {300, 1, 1});
+ assert approximatelyEqualHsv(rgbToHsv(64, 128, 128), new double[] {180, 0.5, 0.5});
+ assert approximatelyEqualHsv(rgbToHsv(193, 196, 224), new double[] {234, 0.14, 0.88});
+ assert approximatelyEqualHsv(rgbToHsv(128, 32, 80), new double[] {330, 0.75, 0.5});
+ }
+
+ /**
+ * Conversion from the HSV-representation to the RGB-representation.
+ *
+ * @param hue Hue of the color.
+ * @param saturation Saturation of the color.
+ * @param value Brightness-value of the color.
+ * @return The tuple of RGB-components.
+ */
+ public static int[] hsvToRgb(double hue, double saturation, double value) {
+ if (hue < 0 || hue > 360) {
+ throw new IllegalArgumentException("hue should be between 0 and 360");
+ }
+
+ if (saturation < 0 || saturation > 1) {
+ throw new IllegalArgumentException("saturation should be between 0 and 1");
+ }
+
+ if (value < 0 || value > 1) {
+ throw new IllegalArgumentException("value should be between 0 and 1");
+ }
+
+ double chroma = value * saturation;
+ double hueSection = hue / 60;
+ double secondLargestComponent = chroma * (1 - Math.abs(hueSection % 2 - 1));
+ double matchValue = value - chroma;
+
+ return getRgbBySection(hueSection, chroma, matchValue, secondLargestComponent);
+ }
+
+ /**
+ * Conversion from the RGB-representation to the HSV-representation.
+ *
+ * @param red Red-component of the color.
+ * @param green Green-component of the color.
+ * @param blue Blue-component of the color.
+ * @return The tuple of HSV-components.
+ */
+ public static double[] rgbToHsv(int red, int green, int blue) {
+ if (red < 0 || red > 255) {
+ throw new IllegalArgumentException("red should be between 0 and 255");
+ }
+
+ if (green < 0 || green > 255) {
+ throw new IllegalArgumentException("green should be between 0 and 255");
+ }
+
+ if (blue < 0 || blue > 255) {
+ throw new IllegalArgumentException("blue should be between 0 and 255");
+ }
+
+ double dRed = (double) red / 255;
+ double dGreen = (double) green / 255;
+ double dBlue = (double) blue / 255;
+ double value = Math.max(Math.max(dRed, dGreen), dBlue);
+ double chroma = value - Math.min(Math.min(dRed, dGreen), dBlue);
+ double saturation = value == 0 ? 0 : chroma / value;
+ double hue;
+
+ if (chroma == 0) {
+ hue = 0;
+ } else if (value == dRed) {
+ hue = 60 * (0 + (dGreen - dBlue) / chroma);
+ } else if (value == dGreen) {
+ hue = 60 * (2 + (dBlue - dRed) / chroma);
+ } else {
+ hue = 60 * (4 + (dRed - dGreen) / chroma);
+ }
+
+ hue = (hue + 360) % 360;
+
+ return new double[] {hue, saturation, value};
+ }
+
+ private static boolean approximatelyEqualHsv(double[] hsv1, double[] hsv2) {
+ boolean bHue = Math.abs(hsv1[0] - hsv2[0]) < 0.2;
+ boolean bSaturation = Math.abs(hsv1[1] - hsv2[1]) < 0.002;
+ boolean bValue = Math.abs(hsv1[2] - hsv2[2]) < 0.002;
+
+ return bHue && bSaturation && bValue;
+ }
+
+ private static int[] getRgbBySection(double hueSection, double chroma, double matchValue, double secondLargestComponent) {
+ int red;
+ int green;
+ int blue;
+
+ if (hueSection >= 0 && hueSection <= 1) {
+ red = convertToInt(chroma + matchValue);
+ green = convertToInt(secondLargestComponent + matchValue);
+ blue = convertToInt(matchValue);
+ } else if (hueSection > 1 && hueSection <= 2) {
+ red = convertToInt(secondLargestComponent + matchValue);
+ green = convertToInt(chroma + matchValue);
+ blue = convertToInt(matchValue);
+ } else if (hueSection > 2 && hueSection <= 3) {
+ red = convertToInt(matchValue);
+ green = convertToInt(chroma + matchValue);
+ blue = convertToInt(secondLargestComponent + matchValue);
+ } else if (hueSection > 3 && hueSection <= 4) {
+ red = convertToInt(matchValue);
+ green = convertToInt(secondLargestComponent + matchValue);
+ blue = convertToInt(chroma + matchValue);
+ } else if (hueSection > 4 && hueSection <= 5) {
+ red = convertToInt(secondLargestComponent + matchValue);
+ green = convertToInt(matchValue);
+ blue = convertToInt(chroma + matchValue);
+ } else {
+ red = convertToInt(chroma + matchValue);
+ green = convertToInt(matchValue);
+ blue = convertToInt(secondLargestComponent + matchValue);
+ }
+
+ return new int[] {red, green, blue};
+ }
+
+ private static int convertToInt(double input) {
+ return (int) Math.round(255 * input);
+ }
+}
diff --git a/src/main/java/com/thealgorithms/conversions/RomanToInteger.java b/src/main/java/com/thealgorithms/conversions/RomanToInteger.java
index a634c720326f..a37b12947915 100644
--- a/src/main/java/com/thealgorithms/conversions/RomanToInteger.java
+++ b/src/main/java/com/thealgorithms/conversions/RomanToInteger.java
@@ -1,91 +1,91 @@
-package com.thealgorithms.conversions;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * A utility class to convert Roman numerals into integers.
- *
- * Roman numerals are based on seven symbols given below:
- *
- * - I = 1
- * - V = 5
- * - X = 10
- * - L = 50
- * - C = 100
- * - D = 500
- * - M = 1000
- *
- *
- * If a smaller numeral appears before a larger numeral, it is subtracted.
- * Otherwise, it is added. For example:
- *
- * MCMXCIV = 1000 + (1000 - 100) + (100 - 10) + (5 - 1) = 1994
- *
- */
-public final class RomanToInteger {
-
- private static final Map ROMAN_TO_INT = new HashMap<>() {
- {
- put('I', 1);
- put('V', 5);
- put('X', 10);
- put('L', 50);
- put('C', 100);
- put('D', 500);
- put('M', 1000);
- }
- };
-
- private RomanToInteger() {
- }
-
- /**
- * Converts a single Roman numeral character to its integer value.
- *
- * @param symbol the Roman numeral character
- * @return the corresponding integer value
- * @throws IllegalArgumentException if the symbol is not a valid Roman numeral
- */
- private static int romanSymbolToInt(final char symbol) {
- return ROMAN_TO_INT.computeIfAbsent(symbol, c -> { throw new IllegalArgumentException("Unknown Roman symbol: " + c); });
- }
-
- /**
- * Converts a Roman numeral string to its integer equivalent.
- * Steps:
- *
- * - Iterate over the string from right to left.
- * - For each character, convert it to an integer value.
- * - If the current value is greater than or equal to the max previous value, add it.
- * - Otherwise, subtract it from the sum.
- * - Update the max previous value.
- * - Return the sum.
- *
- *
- * @param roman the Roman numeral string
- * @return the integer value of the Roman numeral
- * @throws IllegalArgumentException if the input contains invalid Roman characters
- * @throws NullPointerException if the input is {@code null}
- */
- public static int romanToInt(String roman) {
- if (roman == null) {
- throw new NullPointerException("Input cannot be null");
- }
-
- roman = roman.toUpperCase();
- int sum = 0;
- int maxPrevValue = 0;
- for (int i = roman.length() - 1; i >= 0; i--) {
- int currentValue = romanSymbolToInt(roman.charAt(i));
- if (currentValue >= maxPrevValue) {
- sum += currentValue;
- maxPrevValue = currentValue;
- } else {
- sum -= currentValue;
- }
- }
-
- return sum;
- }
-}
+package com.thealgorithms.conversions;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A utility class to convert Roman numerals into integers.
+ *
+ * Roman numerals are based on seven symbols given below:
+ *
+ * - I = 1
+ * - V = 5
+ * - X = 10
+ * - L = 50
+ * - C = 100
+ * - D = 500
+ * - M = 1000
+ *
+ *
+ * If a smaller numeral appears before a larger numeral, it is subtracted.
+ * Otherwise, it is added. For example:
+ *
+ * MCMXCIV = 1000 + (1000 - 100) + (100 - 10) + (5 - 1) = 1994
+ *
+ */
+public final class RomanToInteger {
+
+ private static final Map ROMAN_TO_INT = new HashMap<>() {
+ {
+ put('I', 1);
+ put('V', 5);
+ put('X', 10);
+ put('L', 50);
+ put('C', 100);
+ put('D', 500);
+ put('M', 1000);
+ }
+ };
+
+ private RomanToInteger() {
+ }
+
+ /**
+ * Converts a single Roman numeral character to its integer value.
+ *
+ * @param symbol the Roman numeral character
+ * @return the corresponding integer value
+ * @throws IllegalArgumentException if the symbol is not a valid Roman numeral
+ */
+ private static int romanSymbolToInt(final char symbol) {
+ return ROMAN_TO_INT.computeIfAbsent(symbol, c -> { throw new IllegalArgumentException("Unknown Roman symbol: " + c); });
+ }
+
+ /**
+ * Converts a Roman numeral string to its integer equivalent.
+ * Steps:
+ *
+ * - Iterate over the string from right to left.
+ * - For each character, convert it to an integer value.
+ * - If the current value is greater than or equal to the max previous value, add it.
+ * - Otherwise, subtract it from the sum.
+ * - Update the max previous value.
+ * - Return the sum.
+ *
+ *
+ * @param roman the Roman numeral string
+ * @return the integer value of the Roman numeral
+ * @throws IllegalArgumentException if the input contains invalid Roman characters
+ * @throws NullPointerException if the input is {@code null}
+ */
+ public static int romanToInt(String roman) {
+ if (roman == null) {
+ throw new NullPointerException("Input cannot be null");
+ }
+
+ roman = roman.toUpperCase();
+ int sum = 0;
+ int maxPrevValue = 0;
+ for (int i = roman.length() - 1; i >= 0; i--) {
+ int currentValue = romanSymbolToInt(roman.charAt(i));
+ if (currentValue >= maxPrevValue) {
+ sum += currentValue;
+ maxPrevValue = currentValue;
+ } else {
+ sum -= currentValue;
+ }
+ }
+
+ return sum;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/conversions/TemperatureConverter.java b/src/main/java/com/thealgorithms/conversions/TemperatureConverter.java
index 901db17c665d..9a71735e6188 100644
--- a/src/main/java/com/thealgorithms/conversions/TemperatureConverter.java
+++ b/src/main/java/com/thealgorithms/conversions/TemperatureConverter.java
@@ -1,46 +1,46 @@
-package com.thealgorithms.conversions;
-
-/**
- * A utility class to convert between different temperature units.
- *
- * This class supports conversions between the following units:
- *
- * - Celsius
- * - Fahrenheit
- * - Kelvin
- *
- *
- * This class is final and cannot be instantiated.
- *
- * @author krishna-medapati (https://github.com/krishna-medapati)
- * @see Wikipedia: Temperature Conversion
- */
-public final class TemperatureConverter {
-
- private TemperatureConverter() {
- }
-
- public static double celsiusToFahrenheit(double celsius) {
- return celsius * 9.0 / 5.0 + 32.0;
- }
-
- public static double celsiusToKelvin(double celsius) {
- return celsius + 273.15;
- }
-
- public static double fahrenheitToCelsius(double fahrenheit) {
- return (fahrenheit - 32.0) * 5.0 / 9.0;
- }
-
- public static double fahrenheitToKelvin(double fahrenheit) {
- return (fahrenheit - 32.0) * 5.0 / 9.0 + 273.15;
- }
-
- public static double kelvinToCelsius(double kelvin) {
- return kelvin - 273.15;
- }
-
- public static double kelvinToFahrenheit(double kelvin) {
- return (kelvin - 273.15) * 9.0 / 5.0 + 32.0;
- }
-}
+package com.thealgorithms.conversions;
+
+/**
+ * A utility class to convert between different temperature units.
+ *
+ *
This class supports conversions between the following units:
+ *
+ * - Celsius
+ * - Fahrenheit
+ * - Kelvin
+ *
+ *
+ * This class is final and cannot be instantiated.
+ *
+ * @author krishna-medapati (https://github.com/krishna-medapati)
+ * @see Wikipedia: Temperature Conversion
+ */
+public final class TemperatureConverter {
+
+ private TemperatureConverter() {
+ }
+
+ public static double celsiusToFahrenheit(double celsius) {
+ return celsius * 9.0 / 5.0 + 32.0;
+ }
+
+ public static double celsiusToKelvin(double celsius) {
+ return celsius + 273.15;
+ }
+
+ public static double fahrenheitToCelsius(double fahrenheit) {
+ return (fahrenheit - 32.0) * 5.0 / 9.0;
+ }
+
+ public static double fahrenheitToKelvin(double fahrenheit) {
+ return (fahrenheit - 32.0) * 5.0 / 9.0 + 273.15;
+ }
+
+ public static double kelvinToCelsius(double kelvin) {
+ return kelvin - 273.15;
+ }
+
+ public static double kelvinToFahrenheit(double kelvin) {
+ return (kelvin - 273.15) * 9.0 / 5.0 + 32.0;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/conversions/TimeConverter.java b/src/main/java/com/thealgorithms/conversions/TimeConverter.java
index 41cae37d7ad1..b62d2f94c12f 100644
--- a/src/main/java/com/thealgorithms/conversions/TimeConverter.java
+++ b/src/main/java/com/thealgorithms/conversions/TimeConverter.java
@@ -1,97 +1,97 @@
-package com.thealgorithms.conversions;
-
-import java.util.Locale;
-import java.util.Map;
-
-/**
- * A utility class to convert between different units of time.
- *
- *
This class supports conversions between the following units:
- *
- * - seconds
- * - minutes
- * - hours
- * - days
- * - weeks
- * - months (approximated as 30.44 days)
- * - years (approximated as 365.25 days)
- *
- *
- * The conversion is based on predefined constants in seconds.
- * Results are rounded to three decimal places for consistency.
- *
- *
This class is final and cannot be instantiated.
- *
- * @see Wikipedia: Unit of time
- */
-public final class TimeConverter {
-
- private TimeConverter() {
- // Prevent instantiation
- }
-
- /**
- * Supported time units with their equivalent in seconds.
- */
- private enum TimeUnit {
- SECONDS(1.0),
- MINUTES(60.0),
- HOURS(3600.0),
- DAYS(86400.0),
- WEEKS(604800.0),
- MONTHS(2629800.0), // 30.44 days
- YEARS(31557600.0); // 365.25 days
-
- private final double seconds;
-
- TimeUnit(double seconds) {
- this.seconds = seconds;
- }
-
- public double toSeconds(double value) {
- return value * seconds;
- }
-
- public double fromSeconds(double secondsValue) {
- return secondsValue / seconds;
- }
- }
-
- private static final Map UNIT_LOOKUP
- = Map.ofEntries(Map.entry("seconds", TimeUnit.SECONDS), Map.entry("minutes", TimeUnit.MINUTES), Map.entry("hours", TimeUnit.HOURS), Map.entry("days", TimeUnit.DAYS), Map.entry("weeks", TimeUnit.WEEKS), Map.entry("months", TimeUnit.MONTHS), Map.entry("years", TimeUnit.YEARS));
-
- /**
- * Converts a time value from one unit to another.
- *
- * @param timeValue the numeric value of time to convert; must be non-negative
- * @param unitFrom the unit of the input value (e.g., "minutes", "hours")
- * @param unitTo the unit to convert into (e.g., "seconds", "days")
- * @return the converted value in the target unit, rounded to three decimals
- * @throws IllegalArgumentException if {@code timeValue} is negative
- * @throws IllegalArgumentException if either {@code unitFrom} or {@code unitTo} is not supported
- */
- public static double convertTime(double timeValue, String unitFrom, String unitTo) {
- if (timeValue < 0) {
- throw new IllegalArgumentException("timeValue must be a non-negative number.");
- }
-
- TimeUnit from = resolveUnit(unitFrom);
- TimeUnit to = resolveUnit(unitTo);
-
- double secondsValue = from.toSeconds(timeValue);
- double converted = to.fromSeconds(secondsValue);
-
- return Math.round(converted * 1000.0) / 1000.0;
- }
-
- private static TimeUnit resolveUnit(String unit) {
- if (unit == null) {
- throw new IllegalArgumentException("Unit cannot be null.");
- }
- TimeUnit resolved = UNIT_LOOKUP.get(unit.toLowerCase(Locale.ROOT));
- if (resolved == null) {
- throw new IllegalArgumentException("Invalid unit '" + unit + "'. Supported units are: " + UNIT_LOOKUP.keySet());
- }
- return resolved;
- }
-}
+package com.thealgorithms.conversions;
+
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * A utility class to convert between different units of time.
+ *
+ * This class supports conversions between the following units:
+ *
+ * - seconds
+ * - minutes
+ * - hours
+ * - days
+ * - weeks
+ * - months (approximated as 30.44 days)
+ * - years (approximated as 365.25 days)
+ *
+ *
+ * The conversion is based on predefined constants in seconds.
+ * Results are rounded to three decimal places for consistency.
+ *
+ *
This class is final and cannot be instantiated.
+ *
+ * @see Wikipedia: Unit of time
+ */
+public final class TimeConverter {
+
+ private TimeConverter() {
+ // Prevent instantiation
+ }
+
+ /**
+ * Supported time units with their equivalent in seconds.
+ */
+ private enum TimeUnit {
+ SECONDS(1.0),
+ MINUTES(60.0),
+ HOURS(3600.0),
+ DAYS(86400.0),
+ WEEKS(604800.0),
+ MONTHS(2629800.0), // 30.44 days
+ YEARS(31557600.0); // 365.25 days
+
+ private final double seconds;
+
+ TimeUnit(double seconds) {
+ this.seconds = seconds;
+ }
+
+ public double toSeconds(double value) {
+ return value * seconds;
+ }
+
+ public double fromSeconds(double secondsValue) {
+ return secondsValue / seconds;
+ }
+ }
+
+ private static final Map UNIT_LOOKUP
+ = Map.ofEntries(Map.entry("seconds", TimeUnit.SECONDS), Map.entry("minutes", TimeUnit.MINUTES), Map.entry("hours", TimeUnit.HOURS), Map.entry("days", TimeUnit.DAYS), Map.entry("weeks", TimeUnit.WEEKS), Map.entry("months", TimeUnit.MONTHS), Map.entry("years", TimeUnit.YEARS));
+
+ /**
+ * Converts a time value from one unit to another.
+ *
+ * @param timeValue the numeric value of time to convert; must be non-negative
+ * @param unitFrom the unit of the input value (e.g., "minutes", "hours")
+ * @param unitTo the unit to convert into (e.g., "seconds", "days")
+ * @return the converted value in the target unit, rounded to three decimals
+ * @throws IllegalArgumentException if {@code timeValue} is negative
+ * @throws IllegalArgumentException if either {@code unitFrom} or {@code unitTo} is not supported
+ */
+ public static double convertTime(double timeValue, String unitFrom, String unitTo) {
+ if (timeValue < 0) {
+ throw new IllegalArgumentException("timeValue must be a non-negative number.");
+ }
+
+ TimeUnit from = resolveUnit(unitFrom);
+ TimeUnit to = resolveUnit(unitTo);
+
+ double secondsValue = from.toSeconds(timeValue);
+ double converted = to.fromSeconds(secondsValue);
+
+ return Math.round(converted * 1000.0) / 1000.0;
+ }
+
+ private static TimeUnit resolveUnit(String unit) {
+ if (unit == null) {
+ throw new IllegalArgumentException("Unit cannot be null.");
+ }
+ TimeUnit resolved = UNIT_LOOKUP.get(unit.toLowerCase(Locale.ROOT));
+ if (resolved == null) {
+ throw new IllegalArgumentException("Invalid unit '" + unit + "'. Supported units are: " + UNIT_LOOKUP.keySet());
+ }
+ return resolved;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/conversions/TurkishToLatinConversion.java b/src/main/java/com/thealgorithms/conversions/TurkishToLatinConversion.java
index 50726380621a..637245134963 100644
--- a/src/main/java/com/thealgorithms/conversions/TurkishToLatinConversion.java
+++ b/src/main/java/com/thealgorithms/conversions/TurkishToLatinConversion.java
@@ -1,56 +1,56 @@
-package com.thealgorithms.conversions;
-
-/**
- * Converts turkish character to latin character
- *
- * @author Özgün Gökşenli
- */
-public final class TurkishToLatinConversion {
- private TurkishToLatinConversion() {
- }
-
- /**
- * This method converts a turkish character to latin character.
- * Steps:
- * 1. Define turkish characters and their corresponding latin characters
- * 2. Replace all turkish characters with their corresponding latin characters
- * 3. Return the converted string
- *
- * @param param String parameter
- * @return String
- */
- public static String convertTurkishToLatin(String param) {
- char[] turkishChars = new char[] {
- 0x131,
- 0x130,
- 0xFC,
- 0xDC,
- 0xF6,
- 0xD6,
- 0x15F,
- 0x15E,
- 0xE7,
- 0xC7,
- 0x11F,
- 0x11E,
- };
- char[] latinChars = new char[] {
- 'i',
- 'I',
- 'u',
- 'U',
- 'o',
- 'O',
- 's',
- 'S',
- 'c',
- 'C',
- 'g',
- 'G',
- };
- for (int i = 0; i < turkishChars.length; i++) {
- param = param.replaceAll(String.valueOf(turkishChars[i]), String.valueOf(latinChars[i]));
- }
- return param;
- }
-}
+package com.thealgorithms.conversions;
+
+/**
+ * Converts turkish character to latin character
+ *
+ * @author Özgün Gökşenli
+ */
+public final class TurkishToLatinConversion {
+ private TurkishToLatinConversion() {
+ }
+
+ /**
+ * This method converts a turkish character to latin character.
+ * Steps:
+ * 1. Define turkish characters and their corresponding latin characters
+ * 2. Replace all turkish characters with their corresponding latin characters
+ * 3. Return the converted string
+ *
+ * @param param String parameter
+ * @return String
+ */
+ public static String convertTurkishToLatin(String param) {
+ char[] turkishChars = new char[] {
+ 0x131,
+ 0x130,
+ 0xFC,
+ 0xDC,
+ 0xF6,
+ 0xD6,
+ 0x15F,
+ 0x15E,
+ 0xE7,
+ 0xC7,
+ 0x11F,
+ 0x11E,
+ };
+ char[] latinChars = new char[] {
+ 'i',
+ 'I',
+ 'u',
+ 'U',
+ 'o',
+ 'O',
+ 's',
+ 'S',
+ 'c',
+ 'C',
+ 'g',
+ 'G',
+ };
+ for (int i = 0; i < turkishChars.length; i++) {
+ param = param.replaceAll(String.valueOf(turkishChars[i]), String.valueOf(latinChars[i]));
+ }
+ return param;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/conversions/UnitConversions.java b/src/main/java/com/thealgorithms/conversions/UnitConversions.java
index 15f74a21a17e..ac2a3611d9d1 100644
--- a/src/main/java/com/thealgorithms/conversions/UnitConversions.java
+++ b/src/main/java/com/thealgorithms/conversions/UnitConversions.java
@@ -1,51 +1,51 @@
-package com.thealgorithms.conversions;
-
-import static java.util.Map.entry;
-
-import java.util.Map;
-import org.apache.commons.lang3.tuple.Pair;
-
-/**
- * A utility class to perform unit conversions between different measurement systems.
- *
- * Currently, the class supports temperature conversions between several scales:
- * Celsius, Fahrenheit, Kelvin, Réaumur, Delisle, and Rankine.
- *
- *
Example Usage
- *
- * double result = UnitConversions.TEMPERATURE.convert("Celsius", "Fahrenheit", 100.0);
- * // Output: 212.0 (Celsius to Fahrenheit conversion of 100°C)
- *
- *
- * This class makes use of an {@link UnitsConverter} that handles the conversion logic
- * based on predefined affine transformations. These transformations include scaling factors
- * and offsets for temperature conversions.
- *
- *
Temperature Scales Supported
- *
- * - Celsius
- * - Fahrenheit
- * - Kelvin
- * - Réaumur
- * - Delisle
- * - Rankine
- *
- */
-public final class UnitConversions {
- private UnitConversions() {
- }
-
- /**
- * A preconfigured instance of {@link UnitsConverter} for temperature conversions.
- * The converter handles conversions between the following temperature units:
- *
- * - Kelvin to Celsius
- * - Celsius to Fahrenheit
- * - Réaumur to Celsius
- * - Delisle to Celsius
- * - Rankine to Kelvin
- *
- */
- public static final UnitsConverter TEMPERATURE = new UnitsConverter(Map.ofEntries(entry(Pair.of("Kelvin", "Celsius"), new AffineConverter(1.0, -273.15)), entry(Pair.of("Celsius", "Fahrenheit"), new AffineConverter(9.0 / 5.0, 32.0)),
- entry(Pair.of("Réaumur", "Celsius"), new AffineConverter(5.0 / 4.0, 0.0)), entry(Pair.of("Delisle", "Celsius"), new AffineConverter(-2.0 / 3.0, 100.0)), entry(Pair.of("Rankine", "Kelvin"), new AffineConverter(5.0 / 9.0, 0.0))));
-}
+package com.thealgorithms.conversions;
+
+import static java.util.Map.entry;
+
+import java.util.Map;
+import org.apache.commons.lang3.tuple.Pair;
+
+/**
+ * A utility class to perform unit conversions between different measurement systems.
+ *
+ * Currently, the class supports temperature conversions between several scales:
+ * Celsius, Fahrenheit, Kelvin, Réaumur, Delisle, and Rankine.
+ *
+ *
Example Usage
+ *
+ * double result = UnitConversions.TEMPERATURE.convert("Celsius", "Fahrenheit", 100.0);
+ * // Output: 212.0 (Celsius to Fahrenheit conversion of 100°C)
+ *
+ *
+ * This class makes use of an {@link UnitsConverter} that handles the conversion logic
+ * based on predefined affine transformations. These transformations include scaling factors
+ * and offsets for temperature conversions.
+ *
+ *
Temperature Scales Supported
+ *
+ * - Celsius
+ * - Fahrenheit
+ * - Kelvin
+ * - Réaumur
+ * - Delisle
+ * - Rankine
+ *
+ */
+public final class UnitConversions {
+ private UnitConversions() {
+ }
+
+ /**
+ * A preconfigured instance of {@link UnitsConverter} for temperature conversions.
+ * The converter handles conversions between the following temperature units:
+ *
+ * - Kelvin to Celsius
+ * - Celsius to Fahrenheit
+ * - Réaumur to Celsius
+ * - Delisle to Celsius
+ * - Rankine to Kelvin
+ *
+ */
+ public static final UnitsConverter TEMPERATURE = new UnitsConverter(Map.ofEntries(entry(Pair.of("Kelvin", "Celsius"), new AffineConverter(1.0, -273.15)), entry(Pair.of("Celsius", "Fahrenheit"), new AffineConverter(9.0 / 5.0, 32.0)),
+ entry(Pair.of("Réaumur", "Celsius"), new AffineConverter(5.0 / 4.0, 0.0)), entry(Pair.of("Delisle", "Celsius"), new AffineConverter(-2.0 / 3.0, 100.0)), entry(Pair.of("Rankine", "Kelvin"), new AffineConverter(5.0 / 9.0, 0.0))));
+}
diff --git a/src/main/java/com/thealgorithms/conversions/UnitsConverter.java b/src/main/java/com/thealgorithms/conversions/UnitsConverter.java
index 00690b2c0f9b..11ee20861590 100644
--- a/src/main/java/com/thealgorithms/conversions/UnitsConverter.java
+++ b/src/main/java/com/thealgorithms/conversions/UnitsConverter.java
@@ -1,147 +1,147 @@
-package com.thealgorithms.conversions;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.Set;
-import org.apache.commons.lang3.tuple.Pair;
-
-/**
- * A class that handles unit conversions using affine transformations.
- *
- * The {@code UnitsConverter} allows converting values between different units using
- * pre-defined affine conversion formulas. Each conversion is represented by an
- * {@link AffineConverter} that defines the scaling and offset for the conversion.
- *
- *
For each unit, both direct conversions (e.g., Celsius to Fahrenheit) and inverse
- * conversions (e.g., Fahrenheit to Celsius) are generated automatically. It also computes
- * transitive conversions (e.g., Celsius to Kelvin via Fahrenheit if both conversions exist).
- *
- *
Key features include:
- *
- * - Automatic handling of inverse conversions (e.g., Fahrenheit to Celsius).
- * - Compositional conversions, meaning if conversions between A -> B and B -> C exist,
- * it can automatically generate A -> C conversion.
- * - Supports multiple unit systems as long as conversions are provided in pairs.
- *
- *
- * Example Usage
- *
- * Map<Pair<String, String>, AffineConverter> basicConversions = Map.ofEntries(
- * entry(Pair.of("Celsius", "Fahrenheit"), new AffineConverter(9.0 / 5.0, 32.0)),
- * entry(Pair.of("Kelvin", "Celsius"), new AffineConverter(1.0, -273.15))
- * );
- *
- * UnitsConverter converter = new UnitsConverter(basicConversions);
- * double result = converter.convert("Celsius", "Fahrenheit", 100.0);
- * // Output: 212.0 (Celsius to Fahrenheit conversion of 100°C)
- *
- *
- * Exception Handling
- *
- * - If the input unit and output unit are the same, an {@link IllegalArgumentException} is thrown.
- * - If a conversion between the requested units does not exist, a {@link NoSuchElementException} is thrown.
- *
- */
-public final class UnitsConverter {
- private final Map, AffineConverter> conversions;
- private final Set units;
-
- private static void putIfNeeded(Map, AffineConverter> conversions, final String inputUnit, final String outputUnit, final AffineConverter converter) {
- if (!inputUnit.equals(outputUnit)) {
- final var key = Pair.of(inputUnit, outputUnit);
- conversions.putIfAbsent(key, converter);
- }
- }
-
- private static Map, AffineConverter> addInversions(final Map, AffineConverter> knownConversions) {
- Map, AffineConverter> res = new HashMap, AffineConverter>();
- for (final var curConversion : knownConversions.entrySet()) {
- final var inputUnit = curConversion.getKey().getKey();
- final var outputUnit = curConversion.getKey().getValue();
- putIfNeeded(res, inputUnit, outputUnit, curConversion.getValue());
- putIfNeeded(res, outputUnit, inputUnit, curConversion.getValue().invert());
- }
- return res;
- }
-
- private static Map, AffineConverter> addCompositions(final Map, AffineConverter> knownConversions) {
- Map, AffineConverter> res = new HashMap, AffineConverter>();
- for (final var first : knownConversions.entrySet()) {
- final var firstKey = first.getKey();
- putIfNeeded(res, firstKey.getKey(), firstKey.getValue(), first.getValue());
- for (final var second : knownConversions.entrySet()) {
- final var secondKey = second.getKey();
- if (firstKey.getValue().equals(secondKey.getKey())) {
- final var newConversion = second.getValue().compose(first.getValue());
- putIfNeeded(res, firstKey.getKey(), secondKey.getValue(), newConversion);
- }
- }
- }
- return res;
- }
-
- private static Map, AffineConverter> addAll(final Map, AffineConverter> knownConversions) {
- final var res = addInversions(knownConversions);
- return addCompositions(res);
- }
-
- private static Map, AffineConverter> computeAllConversions(final Map, AffineConverter> basicConversions) {
- var tmp = basicConversions;
- var res = addAll(tmp);
- while (res.size() != tmp.size()) {
- tmp = res;
- res = addAll(tmp);
- }
- return res;
- }
-
- private static Set extractUnits(final Map, AffineConverter> conversions) {
- Set res = new HashSet<>();
- for (final var conversion : conversions.entrySet()) {
- res.add(conversion.getKey().getKey());
- }
- return res;
- }
-
- /**
- * Constructor for {@code UnitsConverter}.
- *
- * Accepts a map of basic conversions and automatically generates inverse and
- * transitive conversions.
- *
- * @param basicConversions the initial set of unit conversions to add.
- */
- public UnitsConverter(final Map, AffineConverter> basicConversions) {
- conversions = computeAllConversions(basicConversions);
- units = extractUnits(conversions);
- }
-
- /**
- * Converts a value from one unit to another.
- *
- * @param inputUnit the unit of the input value.
- * @param outputUnit the unit to convert the value into.
- * @param value the value to convert.
- * @return the converted value in the target unit.
- * @throws IllegalArgumentException if inputUnit equals outputUnit.
- * @throws NoSuchElementException if no conversion exists between the units.
- */
- public double convert(final String inputUnit, final String outputUnit, final double value) {
- if (inputUnit.equals(outputUnit)) {
- throw new IllegalArgumentException("inputUnit must be different from outputUnit.");
- }
- final var conversionKey = Pair.of(inputUnit, outputUnit);
- return conversions.computeIfAbsent(conversionKey, k -> { throw new NoSuchElementException("No converter for: " + k); }).convert(value);
- }
-
- /**
- * Retrieves the set of all units supported by this converter.
- *
- * @return a set of available units.
- */
- public Set availableUnits() {
- return units;
- }
-}
+package com.thealgorithms.conversions;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import org.apache.commons.lang3.tuple.Pair;
+
+/**
+ * A class that handles unit conversions using affine transformations.
+ *
+ * The {@code UnitsConverter} allows converting values between different units using
+ * pre-defined affine conversion formulas. Each conversion is represented by an
+ * {@link AffineConverter} that defines the scaling and offset for the conversion.
+ *
+ *
For each unit, both direct conversions (e.g., Celsius to Fahrenheit) and inverse
+ * conversions (e.g., Fahrenheit to Celsius) are generated automatically. It also computes
+ * transitive conversions (e.g., Celsius to Kelvin via Fahrenheit if both conversions exist).
+ *
+ *
Key features include:
+ *
+ * - Automatic handling of inverse conversions (e.g., Fahrenheit to Celsius).
+ * - Compositional conversions, meaning if conversions between A -> B and B -> C exist,
+ * it can automatically generate A -> C conversion.
+ * - Supports multiple unit systems as long as conversions are provided in pairs.
+ *
+ *
+ * Example Usage
+ *
+ * Map<Pair<String, String>, AffineConverter> basicConversions = Map.ofEntries(
+ * entry(Pair.of("Celsius", "Fahrenheit"), new AffineConverter(9.0 / 5.0, 32.0)),
+ * entry(Pair.of("Kelvin", "Celsius"), new AffineConverter(1.0, -273.15))
+ * );
+ *
+ * UnitsConverter converter = new UnitsConverter(basicConversions);
+ * double result = converter.convert("Celsius", "Fahrenheit", 100.0);
+ * // Output: 212.0 (Celsius to Fahrenheit conversion of 100°C)
+ *
+ *
+ * Exception Handling
+ *
+ * - If the input unit and output unit are the same, an {@link IllegalArgumentException} is thrown.
+ * - If a conversion between the requested units does not exist, a {@link NoSuchElementException} is thrown.
+ *
+ */
+public final class UnitsConverter {
+ private final Map, AffineConverter> conversions;
+ private final Set units;
+
+ private static void putIfNeeded(Map, AffineConverter> conversions, final String inputUnit, final String outputUnit, final AffineConverter converter) {
+ if (!inputUnit.equals(outputUnit)) {
+ final var key = Pair.of(inputUnit, outputUnit);
+ conversions.putIfAbsent(key, converter);
+ }
+ }
+
+ private static Map, AffineConverter> addInversions(final Map, AffineConverter> knownConversions) {
+ Map, AffineConverter> res = new HashMap, AffineConverter>();
+ for (final var curConversion : knownConversions.entrySet()) {
+ final var inputUnit = curConversion.getKey().getKey();
+ final var outputUnit = curConversion.getKey().getValue();
+ putIfNeeded(res, inputUnit, outputUnit, curConversion.getValue());
+ putIfNeeded(res, outputUnit, inputUnit, curConversion.getValue().invert());
+ }
+ return res;
+ }
+
+ private static Map, AffineConverter> addCompositions(final Map, AffineConverter> knownConversions) {
+ Map, AffineConverter> res = new HashMap, AffineConverter>();
+ for (final var first : knownConversions.entrySet()) {
+ final var firstKey = first.getKey();
+ putIfNeeded(res, firstKey.getKey(), firstKey.getValue(), first.getValue());
+ for (final var second : knownConversions.entrySet()) {
+ final var secondKey = second.getKey();
+ if (firstKey.getValue().equals(secondKey.getKey())) {
+ final var newConversion = second.getValue().compose(first.getValue());
+ putIfNeeded(res, firstKey.getKey(), secondKey.getValue(), newConversion);
+ }
+ }
+ }
+ return res;
+ }
+
+ private static Map, AffineConverter> addAll(final Map, AffineConverter> knownConversions) {
+ final var res = addInversions(knownConversions);
+ return addCompositions(res);
+ }
+
+ private static Map, AffineConverter> computeAllConversions(final Map, AffineConverter> basicConversions) {
+ var tmp = basicConversions;
+ var res = addAll(tmp);
+ while (res.size() != tmp.size()) {
+ tmp = res;
+ res = addAll(tmp);
+ }
+ return res;
+ }
+
+ private static Set extractUnits(final Map, AffineConverter> conversions) {
+ Set res = new HashSet<>();
+ for (final var conversion : conversions.entrySet()) {
+ res.add(conversion.getKey().getKey());
+ }
+ return res;
+ }
+
+ /**
+ * Constructor for {@code UnitsConverter}.
+ *
+ * Accepts a map of basic conversions and automatically generates inverse and
+ * transitive conversions.
+ *
+ * @param basicConversions the initial set of unit conversions to add.
+ */
+ public UnitsConverter(final Map, AffineConverter> basicConversions) {
+ conversions = computeAllConversions(basicConversions);
+ units = extractUnits(conversions);
+ }
+
+ /**
+ * Converts a value from one unit to another.
+ *
+ * @param inputUnit the unit of the input value.
+ * @param outputUnit the unit to convert the value into.
+ * @param value the value to convert.
+ * @return the converted value in the target unit.
+ * @throws IllegalArgumentException if inputUnit equals outputUnit.
+ * @throws NoSuchElementException if no conversion exists between the units.
+ */
+ public double convert(final String inputUnit, final String outputUnit, final double value) {
+ if (inputUnit.equals(outputUnit)) {
+ throw new IllegalArgumentException("inputUnit must be different from outputUnit.");
+ }
+ final var conversionKey = Pair.of(inputUnit, outputUnit);
+ return conversions.computeIfAbsent(conversionKey, k -> { throw new NoSuchElementException("No converter for: " + k); }).convert(value);
+ }
+
+ /**
+ * Retrieves the set of all units supported by this converter.
+ *
+ * @return a set of available units.
+ */
+ public Set availableUnits() {
+ return units;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/conversions/WordsToNumber.java b/src/main/java/com/thealgorithms/conversions/WordsToNumber.java
index e2b81a0f4b47..63fa1cd9f889 100644
--- a/src/main/java/com/thealgorithms/conversions/WordsToNumber.java
+++ b/src/main/java/com/thealgorithms/conversions/WordsToNumber.java
@@ -1,343 +1,343 @@
-package com.thealgorithms.conversions;
-
-import java.io.Serial;
-import java.math.BigDecimal;
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-/**
- A Java-based utility for converting English word representations of numbers
- into their numeric form. This utility supports whole numbers, decimals,
- large values up to trillions, and even scientific notation where applicable.
- It ensures accurate parsing while handling edge cases like negative numbers,
- improper word placements, and ambiguous inputs.
- *
- */
-
-public final class WordsToNumber {
-
- private WordsToNumber() {
- }
-
- private enum NumberWord {
- ZERO("zero", 0),
- ONE("one", 1),
- TWO("two", 2),
- THREE("three", 3),
- FOUR("four", 4),
- FIVE("five", 5),
- SIX("six", 6),
- SEVEN("seven", 7),
- EIGHT("eight", 8),
- NINE("nine", 9),
- TEN("ten", 10),
- ELEVEN("eleven", 11),
- TWELVE("twelve", 12),
- THIRTEEN("thirteen", 13),
- FOURTEEN("fourteen", 14),
- FIFTEEN("fifteen", 15),
- SIXTEEN("sixteen", 16),
- SEVENTEEN("seventeen", 17),
- EIGHTEEN("eighteen", 18),
- NINETEEN("nineteen", 19),
- TWENTY("twenty", 20),
- THIRTY("thirty", 30),
- FORTY("forty", 40),
- FIFTY("fifty", 50),
- SIXTY("sixty", 60),
- SEVENTY("seventy", 70),
- EIGHTY("eighty", 80),
- NINETY("ninety", 90);
-
- private final String word;
- private final int value;
-
- NumberWord(String word, int value) {
- this.word = word;
- this.value = value;
- }
-
- public static Integer getValue(String word) {
- for (NumberWord num : values()) {
- if (word.equals(num.word)) {
- return num.value;
- }
- }
- return null;
- }
- }
-
- private enum PowerOfTen {
- THOUSAND("thousand", new BigDecimal("1000")),
- MILLION("million", new BigDecimal("1000000")),
- BILLION("billion", new BigDecimal("1000000000")),
- TRILLION("trillion", new BigDecimal("1000000000000"));
-
- private final String word;
- private final BigDecimal value;
-
- PowerOfTen(String word, BigDecimal value) {
- this.word = word;
- this.value = value;
- }
-
- public static BigDecimal getValue(String word) {
- for (PowerOfTen power : values()) {
- if (word.equals(power.word)) {
- return power.value;
- }
- }
- return null;
- }
- }
-
- public static String convert(String numberInWords) {
- if (numberInWords == null) {
- throw new WordsToNumberException(WordsToNumberException.ErrorType.NULL_INPUT, "");
- }
-
- ArrayDeque wordDeque = preprocessWords(numberInWords);
- BigDecimal completeNumber = convertWordQueueToBigDecimal(wordDeque);
-
- return completeNumber.toString();
- }
-
- public static BigDecimal convertToBigDecimal(String numberInWords) {
- String conversionResult = convert(numberInWords);
- return new BigDecimal(conversionResult);
- }
-
- private static ArrayDeque preprocessWords(String numberInWords) {
- String[] wordSplitArray = numberInWords.trim().split("[ ,-]");
- ArrayDeque wordDeque = new ArrayDeque<>();
- for (String word : wordSplitArray) {
- if (word.isEmpty()) {
- continue;
- }
- wordDeque.add(word.toLowerCase());
- }
- if (wordDeque.isEmpty()) {
- throw new WordsToNumberException(WordsToNumberException.ErrorType.NULL_INPUT, "");
- }
- return wordDeque;
- }
-
- private static void handleConjunction(boolean prevNumWasHundred, boolean prevNumWasPowerOfTen, ArrayDeque wordDeque) {
- if (wordDeque.isEmpty()) {
- throw new WordsToNumberException(WordsToNumberException.ErrorType.INVALID_CONJUNCTION, "");
- }
-
- String nextWord = wordDeque.pollFirst();
- String afterNextWord = wordDeque.peekFirst();
-
- wordDeque.addFirst(nextWord);
-
- Integer number = NumberWord.getValue(nextWord);
-
- boolean isPrevWordValid = prevNumWasHundred || prevNumWasPowerOfTen;
- boolean isNextWordValid = number != null && (number >= 10 || afterNextWord == null || "point".equals(afterNextWord));
-
- if (!isPrevWordValid || !isNextWordValid) {
- throw new WordsToNumberException(WordsToNumberException.ErrorType.INVALID_CONJUNCTION, "");
- }
- }
-
- private static BigDecimal handleHundred(BigDecimal currentChunk, String word, boolean prevNumWasPowerOfTen) {
- boolean currentChunkIsZero = currentChunk.compareTo(BigDecimal.ZERO) == 0;
- if (currentChunk.compareTo(BigDecimal.TEN) >= 0 || prevNumWasPowerOfTen) {
- throw new WordsToNumberException(WordsToNumberException.ErrorType.UNEXPECTED_WORD, word);
- }
- if (currentChunkIsZero) {
- currentChunk = currentChunk.add(BigDecimal.ONE);
- }
- return currentChunk.multiply(BigDecimal.valueOf(100));
- }
-
- private static void handlePowerOfTen(List chunks, BigDecimal currentChunk, BigDecimal powerOfTen, String word, boolean prevNumWasPowerOfTen) {
- boolean currentChunkIsZero = currentChunk.compareTo(BigDecimal.ZERO) == 0;
- if (currentChunkIsZero || prevNumWasPowerOfTen) {
- throw new WordsToNumberException(WordsToNumberException.ErrorType.UNEXPECTED_WORD, word);
- }
- BigDecimal nextChunk = currentChunk.multiply(powerOfTen);
-
- if (!(chunks.isEmpty() || isAdditionSafe(chunks.getLast(), nextChunk))) {
- throw new WordsToNumberException(WordsToNumberException.ErrorType.UNEXPECTED_WORD, word);
- }
- chunks.add(nextChunk);
- }
-
- private static BigDecimal handleNumber(Collection chunks, BigDecimal currentChunk, String word, Integer number) {
- boolean currentChunkIsZero = currentChunk.compareTo(BigDecimal.ZERO) == 0;
- if (number == 0 && !(currentChunkIsZero && chunks.isEmpty())) {
- throw new WordsToNumberException(WordsToNumberException.ErrorType.UNEXPECTED_WORD, word);
- }
- BigDecimal bigDecimalNumber = BigDecimal.valueOf(number);
-
- if (!currentChunkIsZero && !isAdditionSafe(currentChunk, bigDecimalNumber)) {
- throw new WordsToNumberException(WordsToNumberException.ErrorType.UNEXPECTED_WORD, word);
- }
- return currentChunk.add(bigDecimalNumber);
- }
-
- private static void handlePoint(Collection chunks, BigDecimal currentChunk, ArrayDeque wordDeque) {
- boolean currentChunkIsZero = currentChunk.compareTo(BigDecimal.ZERO) == 0;
- if (!currentChunkIsZero) {
- chunks.add(currentChunk);
- }
-
- String decimalPart = convertDecimalPart(wordDeque);
- chunks.add(new BigDecimal(decimalPart));
- }
-
- private static void handleNegative(boolean isNegative) {
- if (isNegative) {
- throw new WordsToNumberException(WordsToNumberException.ErrorType.MULTIPLE_NEGATIVES, "");
- }
- throw new WordsToNumberException(WordsToNumberException.ErrorType.INVALID_NEGATIVE, "");
- }
-
- private static BigDecimal convertWordQueueToBigDecimal(ArrayDeque wordDeque) {
- BigDecimal currentChunk = BigDecimal.ZERO;
- List chunks = new ArrayList<>();
-
- boolean isNegative = "negative".equals(wordDeque.peek());
- if (isNegative) {
- wordDeque.poll();
- }
-
- boolean prevNumWasHundred = false;
- boolean prevNumWasPowerOfTen = false;
-
- while (!wordDeque.isEmpty()) {
- String word = wordDeque.poll();
-
- switch (word) {
- case "and" -> {
- handleConjunction(prevNumWasHundred, prevNumWasPowerOfTen, wordDeque);
- continue;
- }
- case "hundred" -> {
- currentChunk = handleHundred(currentChunk, word, prevNumWasPowerOfTen);
- prevNumWasHundred = true;
- continue;
- }
- default -> {
-
- }
- }
- prevNumWasHundred = false;
-
- BigDecimal powerOfTen = PowerOfTen.getValue(word);
- if (powerOfTen != null) {
- handlePowerOfTen(chunks, currentChunk, powerOfTen, word, prevNumWasPowerOfTen);
- currentChunk = BigDecimal.ZERO;
- prevNumWasPowerOfTen = true;
- continue;
- }
- prevNumWasPowerOfTen = false;
-
- Integer number = NumberWord.getValue(word);
- if (number != null) {
- currentChunk = handleNumber(chunks, currentChunk, word, number);
- continue;
- }
-
- switch (word) {
- case "point" -> {
- handlePoint(chunks, currentChunk, wordDeque);
- currentChunk = BigDecimal.ZERO;
- continue;
- }
- case "negative" -> {
- handleNegative(isNegative);
- }
- default -> {
-
- }
- }
-
- throw new WordsToNumberException(WordsToNumberException.ErrorType.UNKNOWN_WORD, word);
- }
-
- if (currentChunk.compareTo(BigDecimal.ZERO) != 0) {
- chunks.add(currentChunk);
- }
-
- BigDecimal completeNumber = combineChunks(chunks);
- return isNegative ? completeNumber.multiply(BigDecimal.valueOf(-1))
- :
- completeNumber;
- }
-
- private static boolean isAdditionSafe(BigDecimal currentChunk, BigDecimal number) {
- int chunkDigitCount = currentChunk.toString().length();
- int numberDigitCount = number.toString().length();
- return chunkDigitCount > numberDigitCount;
- }
-
- private static String convertDecimalPart(ArrayDeque wordDeque) {
- StringBuilder decimalPart = new StringBuilder(".");
-
- while (!wordDeque.isEmpty()) {
- String word = wordDeque.poll();
- Integer number = NumberWord.getValue(word);
- if (number == null) {
- throw new WordsToNumberException(WordsToNumberException.ErrorType.UNEXPECTED_WORD_AFTER_POINT, word);
- }
- decimalPart.append(number);
- }
-
- boolean missingNumbers = decimalPart.length() == 1;
- if (missingNumbers) {
- throw new WordsToNumberException(WordsToNumberException.ErrorType.MISSING_DECIMAL_NUMBERS, "");
- }
- return decimalPart.toString();
- }
-
- private static BigDecimal combineChunks(List chunks) {
- BigDecimal completeNumber = BigDecimal.ZERO;
- for (BigDecimal chunk : chunks) {
- completeNumber = completeNumber.add(chunk);
- }
- return completeNumber;
- }
- }
-
- class WordsToNumberException extends RuntimeException {
-
- @Serial private static final long serialVersionUID = 1L;
-
- enum ErrorType {
- NULL_INPUT("'null' or empty input provided"),
- UNKNOWN_WORD("Unknown Word: "),
- UNEXPECTED_WORD("Unexpected Word: "),
- UNEXPECTED_WORD_AFTER_POINT("Unexpected Word (after Point): "),
- MISSING_DECIMAL_NUMBERS("Decimal part is missing numbers."),
- MULTIPLE_NEGATIVES("Multiple 'Negative's detected."),
- INVALID_NEGATIVE("Incorrect 'negative' placement"),
- INVALID_CONJUNCTION("Incorrect 'and' placement");
-
- private final String message;
-
- ErrorType(String message) {
- this.message = message;
- }
-
- public String formatMessage(String details) {
- return "Invalid Input. " + message + (details.isEmpty() ? "" : details);
- }
- }
-
- public final ErrorType errorType;
-
- WordsToNumberException(ErrorType errorType, String details) {
- super(errorType.formatMessage(details));
- this.errorType = errorType;
- }
-
- public ErrorType getErrorType() {
- return errorType;
- }
- }
+package com.thealgorithms.conversions;
+
+import java.io.Serial;
+import java.math.BigDecimal;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ A Java-based utility for converting English word representations of numbers
+ into their numeric form. This utility supports whole numbers, decimals,
+ large values up to trillions, and even scientific notation where applicable.
+ It ensures accurate parsing while handling edge cases like negative numbers,
+ improper word placements, and ambiguous inputs.
+ *
+ */
+
+public final class WordsToNumber {
+
+ private WordsToNumber() {
+ }
+
+ private enum NumberWord {
+ ZERO("zero", 0),
+ ONE("one", 1),
+ TWO("two", 2),
+ THREE("three", 3),
+ FOUR("four", 4),
+ FIVE("five", 5),
+ SIX("six", 6),
+ SEVEN("seven", 7),
+ EIGHT("eight", 8),
+ NINE("nine", 9),
+ TEN("ten", 10),
+ ELEVEN("eleven", 11),
+ TWELVE("twelve", 12),
+ THIRTEEN("thirteen", 13),
+ FOURTEEN("fourteen", 14),
+ FIFTEEN("fifteen", 15),
+ SIXTEEN("sixteen", 16),
+ SEVENTEEN("seventeen", 17),
+ EIGHTEEN("eighteen", 18),
+ NINETEEN("nineteen", 19),
+ TWENTY("twenty", 20),
+ THIRTY("thirty", 30),
+ FORTY("forty", 40),
+ FIFTY("fifty", 50),
+ SIXTY("sixty", 60),
+ SEVENTY("seventy", 70),
+ EIGHTY("eighty", 80),
+ NINETY("ninety", 90);
+
+ private final String word;
+ private final int value;
+
+ NumberWord(String word, int value) {
+ this.word = word;
+ this.value = value;
+ }
+
+ public static Integer getValue(String word) {
+ for (NumberWord num : values()) {
+ if (word.equals(num.word)) {
+ return num.value;
+ }
+ }
+ return null;
+ }
+ }
+
+ private enum PowerOfTen {
+ THOUSAND("thousand", new BigDecimal("1000")),
+ MILLION("million", new BigDecimal("1000000")),
+ BILLION("billion", new BigDecimal("1000000000")),
+ TRILLION("trillion", new BigDecimal("1000000000000"));
+
+ private final String word;
+ private final BigDecimal value;
+
+ PowerOfTen(String word, BigDecimal value) {
+ this.word = word;
+ this.value = value;
+ }
+
+ public static BigDecimal getValue(String word) {
+ for (PowerOfTen power : values()) {
+ if (word.equals(power.word)) {
+ return power.value;
+ }
+ }
+ return null;
+ }
+ }
+
+ public static String convert(String numberInWords) {
+ if (numberInWords == null) {
+ throw new WordsToNumberException(WordsToNumberException.ErrorType.NULL_INPUT, "");
+ }
+
+ ArrayDeque wordDeque = preprocessWords(numberInWords);
+ BigDecimal completeNumber = convertWordQueueToBigDecimal(wordDeque);
+
+ return completeNumber.toString();
+ }
+
+ public static BigDecimal convertToBigDecimal(String numberInWords) {
+ String conversionResult = convert(numberInWords);
+ return new BigDecimal(conversionResult);
+ }
+
+ private static ArrayDeque preprocessWords(String numberInWords) {
+ String[] wordSplitArray = numberInWords.trim().split("[ ,-]");
+ ArrayDeque wordDeque = new ArrayDeque<>();
+ for (String word : wordSplitArray) {
+ if (word.isEmpty()) {
+ continue;
+ }
+ wordDeque.add(word.toLowerCase());
+ }
+ if (wordDeque.isEmpty()) {
+ throw new WordsToNumberException(WordsToNumberException.ErrorType.NULL_INPUT, "");
+ }
+ return wordDeque;
+ }
+
+ private static void handleConjunction(boolean prevNumWasHundred, boolean prevNumWasPowerOfTen, ArrayDeque wordDeque) {
+ if (wordDeque.isEmpty()) {
+ throw new WordsToNumberException(WordsToNumberException.ErrorType.INVALID_CONJUNCTION, "");
+ }
+
+ String nextWord = wordDeque.pollFirst();
+ String afterNextWord = wordDeque.peekFirst();
+
+ wordDeque.addFirst(nextWord);
+
+ Integer number = NumberWord.getValue(nextWord);
+
+ boolean isPrevWordValid = prevNumWasHundred || prevNumWasPowerOfTen;
+ boolean isNextWordValid = number != null && (number >= 10 || afterNextWord == null || "point".equals(afterNextWord));
+
+ if (!isPrevWordValid || !isNextWordValid) {
+ throw new WordsToNumberException(WordsToNumberException.ErrorType.INVALID_CONJUNCTION, "");
+ }
+ }
+
+ private static BigDecimal handleHundred(BigDecimal currentChunk, String word, boolean prevNumWasPowerOfTen) {
+ boolean currentChunkIsZero = currentChunk.compareTo(BigDecimal.ZERO) == 0;
+ if (currentChunk.compareTo(BigDecimal.TEN) >= 0 || prevNumWasPowerOfTen) {
+ throw new WordsToNumberException(WordsToNumberException.ErrorType.UNEXPECTED_WORD, word);
+ }
+ if (currentChunkIsZero) {
+ currentChunk = currentChunk.add(BigDecimal.ONE);
+ }
+ return currentChunk.multiply(BigDecimal.valueOf(100));
+ }
+
+ private static void handlePowerOfTen(List chunks, BigDecimal currentChunk, BigDecimal powerOfTen, String word, boolean prevNumWasPowerOfTen) {
+ boolean currentChunkIsZero = currentChunk.compareTo(BigDecimal.ZERO) == 0;
+ if (currentChunkIsZero || prevNumWasPowerOfTen) {
+ throw new WordsToNumberException(WordsToNumberException.ErrorType.UNEXPECTED_WORD, word);
+ }
+ BigDecimal nextChunk = currentChunk.multiply(powerOfTen);
+
+ if (!(chunks.isEmpty() || isAdditionSafe(chunks.getLast(), nextChunk))) {
+ throw new WordsToNumberException(WordsToNumberException.ErrorType.UNEXPECTED_WORD, word);
+ }
+ chunks.add(nextChunk);
+ }
+
+ private static BigDecimal handleNumber(Collection chunks, BigDecimal currentChunk, String word, Integer number) {
+ boolean currentChunkIsZero = currentChunk.compareTo(BigDecimal.ZERO) == 0;
+ if (number == 0 && !(currentChunkIsZero && chunks.isEmpty())) {
+ throw new WordsToNumberException(WordsToNumberException.ErrorType.UNEXPECTED_WORD, word);
+ }
+ BigDecimal bigDecimalNumber = BigDecimal.valueOf(number);
+
+ if (!currentChunkIsZero && !isAdditionSafe(currentChunk, bigDecimalNumber)) {
+ throw new WordsToNumberException(WordsToNumberException.ErrorType.UNEXPECTED_WORD, word);
+ }
+ return currentChunk.add(bigDecimalNumber);
+ }
+
+ private static void handlePoint(Collection chunks, BigDecimal currentChunk, ArrayDeque wordDeque) {
+ boolean currentChunkIsZero = currentChunk.compareTo(BigDecimal.ZERO) == 0;
+ if (!currentChunkIsZero) {
+ chunks.add(currentChunk);
+ }
+
+ String decimalPart = convertDecimalPart(wordDeque);
+ chunks.add(new BigDecimal(decimalPart));
+ }
+
+ private static void handleNegative(boolean isNegative) {
+ if (isNegative) {
+ throw new WordsToNumberException(WordsToNumberException.ErrorType.MULTIPLE_NEGATIVES, "");
+ }
+ throw new WordsToNumberException(WordsToNumberException.ErrorType.INVALID_NEGATIVE, "");
+ }
+
+ private static BigDecimal convertWordQueueToBigDecimal(ArrayDeque wordDeque) {
+ BigDecimal currentChunk = BigDecimal.ZERO;
+ List chunks = new ArrayList<>();
+
+ boolean isNegative = "negative".equals(wordDeque.peek());
+ if (isNegative) {
+ wordDeque.poll();
+ }
+
+ boolean prevNumWasHundred = false;
+ boolean prevNumWasPowerOfTen = false;
+
+ while (!wordDeque.isEmpty()) {
+ String word = wordDeque.poll();
+
+ switch (word) {
+ case "and" -> {
+ handleConjunction(prevNumWasHundred, prevNumWasPowerOfTen, wordDeque);
+ continue;
+ }
+ case "hundred" -> {
+ currentChunk = handleHundred(currentChunk, word, prevNumWasPowerOfTen);
+ prevNumWasHundred = true;
+ continue;
+ }
+ default -> {
+
+ }
+ }
+ prevNumWasHundred = false;
+
+ BigDecimal powerOfTen = PowerOfTen.getValue(word);
+ if (powerOfTen != null) {
+ handlePowerOfTen(chunks, currentChunk, powerOfTen, word, prevNumWasPowerOfTen);
+ currentChunk = BigDecimal.ZERO;
+ prevNumWasPowerOfTen = true;
+ continue;
+ }
+ prevNumWasPowerOfTen = false;
+
+ Integer number = NumberWord.getValue(word);
+ if (number != null) {
+ currentChunk = handleNumber(chunks, currentChunk, word, number);
+ continue;
+ }
+
+ switch (word) {
+ case "point" -> {
+ handlePoint(chunks, currentChunk, wordDeque);
+ currentChunk = BigDecimal.ZERO;
+ continue;
+ }
+ case "negative" -> {
+ handleNegative(isNegative);
+ }
+ default -> {
+
+ }
+ }
+
+ throw new WordsToNumberException(WordsToNumberException.ErrorType.UNKNOWN_WORD, word);
+ }
+
+ if (currentChunk.compareTo(BigDecimal.ZERO) != 0) {
+ chunks.add(currentChunk);
+ }
+
+ BigDecimal completeNumber = combineChunks(chunks);
+ return isNegative ? completeNumber.multiply(BigDecimal.valueOf(-1))
+ :
+ completeNumber;
+ }
+
+ private static boolean isAdditionSafe(BigDecimal currentChunk, BigDecimal number) {
+ int chunkDigitCount = currentChunk.toString().length();
+ int numberDigitCount = number.toString().length();
+ return chunkDigitCount > numberDigitCount;
+ }
+
+ private static String convertDecimalPart(ArrayDeque wordDeque) {
+ StringBuilder decimalPart = new StringBuilder(".");
+
+ while (!wordDeque.isEmpty()) {
+ String word = wordDeque.poll();
+ Integer number = NumberWord.getValue(word);
+ if (number == null) {
+ throw new WordsToNumberException(WordsToNumberException.ErrorType.UNEXPECTED_WORD_AFTER_POINT, word);
+ }
+ decimalPart.append(number);
+ }
+
+ boolean missingNumbers = decimalPart.length() == 1;
+ if (missingNumbers) {
+ throw new WordsToNumberException(WordsToNumberException.ErrorType.MISSING_DECIMAL_NUMBERS, "");
+ }
+ return decimalPart.toString();
+ }
+
+ private static BigDecimal combineChunks(List chunks) {
+ BigDecimal completeNumber = BigDecimal.ZERO;
+ for (BigDecimal chunk : chunks) {
+ completeNumber = completeNumber.add(chunk);
+ }
+ return completeNumber;
+ }
+ }
+
+ class WordsToNumberException extends RuntimeException {
+
+ @Serial private static final long serialVersionUID = 1L;
+
+ enum ErrorType {
+ NULL_INPUT("'null' or empty input provided"),
+ UNKNOWN_WORD("Unknown Word: "),
+ UNEXPECTED_WORD("Unexpected Word: "),
+ UNEXPECTED_WORD_AFTER_POINT("Unexpected Word (after Point): "),
+ MISSING_DECIMAL_NUMBERS("Decimal part is missing numbers."),
+ MULTIPLE_NEGATIVES("Multiple 'Negative's detected."),
+ INVALID_NEGATIVE("Incorrect 'negative' placement"),
+ INVALID_CONJUNCTION("Incorrect 'and' placement");
+
+ private final String message;
+
+ ErrorType(String message) {
+ this.message = message;
+ }
+
+ public String formatMessage(String details) {
+ return "Invalid Input. " + message + (details.isEmpty() ? "" : details);
+ }
+ }
+
+ public final ErrorType errorType;
+
+ WordsToNumberException(ErrorType errorType, String details) {
+ super(errorType.formatMessage(details));
+ this.errorType = errorType;
+ }
+
+ public ErrorType getErrorType() {
+ return errorType;
+ }
+ }
diff --git a/src/main/java/com/thealgorithms/datastructures/Node.java b/src/main/java/com/thealgorithms/datastructures/Node.java
index c8d0e6cb4f7d..ebe5659dbebd 100644
--- a/src/main/java/com/thealgorithms/datastructures/Node.java
+++ b/src/main/java/com/thealgorithms/datastructures/Node.java
@@ -1,32 +1,32 @@
-package com.thealgorithms.datastructures;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class Node {
-
- private final T value;
- private final List> children;
-
- public Node(final T value) {
- this.value = value;
- this.children = new ArrayList<>();
- }
-
- public Node(final T value, final List> children) {
- this.value = value;
- this.children = children;
- }
-
- public T getValue() {
- return value;
- }
-
- public void addChild(Node child) {
- children.add(child);
- }
-
- public List> getChildren() {
- return children;
- }
-}
+package com.thealgorithms.datastructures;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Node {
+
+ private final T value;
+ private final List> children;
+
+ public Node(final T value) {
+ this.value = value;
+ this.children = new ArrayList<>();
+ }
+
+ public Node(final T value, final List> children) {
+ this.value = value;
+ this.children = children;
+ }
+
+ public T getValue() {
+ return value;
+ }
+
+ public void addChild(Node child) {
+ children.add(child);
+ }
+
+ public List> getChildren() {
+ return children;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/datastructures/bags/Bag.java b/src/main/java/com/thealgorithms/datastructures/bags/Bag.java
index afc3bbe40cce..3d33b188a821 100644
--- a/src/main/java/com/thealgorithms/datastructures/bags/Bag.java
+++ b/src/main/java/com/thealgorithms/datastructures/bags/Bag.java
@@ -1,138 +1,138 @@
-package com.thealgorithms.datastructures.bags;
-
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-/**
- * A generic collection that allows adding and iterating over elements but does not support
- * element removal. This class implements a simple bag data structure, which can hold duplicate
- * elements and provides operations to check for membership and the size of the collection.
- *
- * Bag is not thread-safe and should not be accessed by multiple threads concurrently.
- *
- * @param the type of elements in this bag
- */
-public class Bag implements Iterable {
-
- private Node firstElement; // Reference to the first element in the bag
- private int size; // Count of elements in the bag
-
- // Node class representing each element in the bag
- private static final class Node {
- private E content;
- private Node nextElement;
- }
-
- /**
- * Constructs an empty bag.
- * This initializes the bag with zero elements.
- */
- public Bag() {
- firstElement = null;
- size = 0;
- }
-
- /**
- * Checks if the bag is empty.
- *
- * @return {@code true} if the bag contains no elements; {@code false} otherwise
- */
- public boolean isEmpty() {
- return size == 0;
- }
-
- /**
- * Returns the number of elements in the bag.
- *
- * @return the number of elements currently in the bag
- */
- public int size() {
- return size;
- }
-
- /**
- * Adds an element to the bag.
- *
- *
This method adds the specified element to the bag. Duplicates are allowed, and the
- * bag will maintain the order in which elements are added.
- *
- * @param element the element to add; must not be {@code null}
- */
- public void add(E element) {
- Node newNode = new Node<>();
- newNode.content = element;
- newNode.nextElement = firstElement;
- firstElement = newNode;
- size++;
- }
-
- /**
- * Checks if the bag contains a specific element.
- *
- * This method uses the {@code equals} method of the element to determine membership.
- *
- * @param element the element to check for; must not be {@code null}
- * @return {@code true} if the bag contains the specified element; {@code false} otherwise
- */
- public boolean contains(E element) {
- for (E value : this) {
- if (value.equals(element)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Returns an iterator over the elements in this bag.
- *
- *
The iterator provides a way to traverse the elements in the order they were added.
- *
- * @return an iterator that iterates over the elements in the bag
- */
- @Override
- public Iterator iterator() {
- return new ListIterator<>(firstElement);
- }
-
- // Private class for iterating over elements
- private static class ListIterator implements Iterator {
-
- private Node currentElement;
-
- /**
- * Constructs a ListIterator starting from the given first element.
- *
- * @param firstElement the first element of the bag to iterate over
- */
- ListIterator(Node firstElement) {
- this.currentElement = firstElement;
- }
-
- /**
- * Checks if there are more elements to iterate over.
- *
- * @return {@code true} if there are more elements; {@code false} otherwise
- */
- @Override
- public boolean hasNext() {
- return currentElement != null;
- }
-
- /**
- * Returns the next element in the iteration.
- *
- * @return the next element in the bag
- * @throws NoSuchElementException if there are no more elements to return
- */
- @Override
- public E next() {
- if (!hasNext()) {
- throw new NoSuchElementException("No more elements in the bag.");
- }
- E element = currentElement.content;
- currentElement = currentElement.nextElement;
- return element;
- }
- }
-}
+package com.thealgorithms.datastructures.bags;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * A generic collection that allows adding and iterating over elements but does not support
+ * element removal. This class implements a simple bag data structure, which can hold duplicate
+ * elements and provides operations to check for membership and the size of the collection.
+ *
+ * Bag is not thread-safe and should not be accessed by multiple threads concurrently.
+ *
+ * @param the type of elements in this bag
+ */
+public class Bag implements Iterable {
+
+ private Node firstElement; // Reference to the first element in the bag
+ private int size; // Count of elements in the bag
+
+ // Node class representing each element in the bag
+ private static final class Node {
+ private E content;
+ private Node nextElement;
+ }
+
+ /**
+ * Constructs an empty bag.
+ * This initializes the bag with zero elements.
+ */
+ public Bag() {
+ firstElement = null;
+ size = 0;
+ }
+
+ /**
+ * Checks if the bag is empty.
+ *
+ * @return {@code true} if the bag contains no elements; {@code false} otherwise
+ */
+ public boolean isEmpty() {
+ return size == 0;
+ }
+
+ /**
+ * Returns the number of elements in the bag.
+ *
+ * @return the number of elements currently in the bag
+ */
+ public int size() {
+ return size;
+ }
+
+ /**
+ * Adds an element to the bag.
+ *
+ *
This method adds the specified element to the bag. Duplicates are allowed, and the
+ * bag will maintain the order in which elements are added.
+ *
+ * @param element the element to add; must not be {@code null}
+ */
+ public void add(E element) {
+ Node newNode = new Node<>();
+ newNode.content = element;
+ newNode.nextElement = firstElement;
+ firstElement = newNode;
+ size++;
+ }
+
+ /**
+ * Checks if the bag contains a specific element.
+ *
+ * This method uses the {@code equals} method of the element to determine membership.
+ *
+ * @param element the element to check for; must not be {@code null}
+ * @return {@code true} if the bag contains the specified element; {@code false} otherwise
+ */
+ public boolean contains(E element) {
+ for (E value : this) {
+ if (value.equals(element)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns an iterator over the elements in this bag.
+ *
+ *
The iterator provides a way to traverse the elements in the order they were added.
+ *
+ * @return an iterator that iterates over the elements in the bag
+ */
+ @Override
+ public Iterator iterator() {
+ return new ListIterator<>(firstElement);
+ }
+
+ // Private class for iterating over elements
+ private static class ListIterator implements Iterator {
+
+ private Node currentElement;
+
+ /**
+ * Constructs a ListIterator starting from the given first element.
+ *
+ * @param firstElement the first element of the bag to iterate over
+ */
+ ListIterator(Node firstElement) {
+ this.currentElement = firstElement;
+ }
+
+ /**
+ * Checks if there are more elements to iterate over.
+ *
+ * @return {@code true} if there are more elements; {@code false} otherwise
+ */
+ @Override
+ public boolean hasNext() {
+ return currentElement != null;
+ }
+
+ /**
+ * Returns the next element in the iteration.
+ *
+ * @return the next element in the bag
+ * @throws NoSuchElementException if there are no more elements to return
+ */
+ @Override
+ public E next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException("No more elements in the bag.");
+ }
+ E element = currentElement.content;
+ currentElement = currentElement.nextElement;
+ return element;
+ }
+ }
+}
diff --git a/src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java b/src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java
index 90625ad1c902..3ac48d90f963 100644
--- a/src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java
+++ b/src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java
@@ -1,177 +1,177 @@
-package com.thealgorithms.datastructures.bloomfilter;
-
-import java.util.Arrays;
-import java.util.BitSet;
-
-/**
- * A generic BloomFilter implementation for probabilistic membership checking.
- *
- * Bloom filters are space-efficient data structures that provide a fast way to
- * test whether an
- * element is a member of a set. They may produce false positives, indicating an
- * element is
- * in the set when it is not, but they will never produce false negatives.
- *
- *
- * @param The type of elements to be stored in the Bloom filter.
- */
-@SuppressWarnings("rawtypes")
-public class BloomFilter {
-
- private final int numberOfHashFunctions;
- private final BitSet bitArray;
- private final Hash[] hashFunctions;
-
- /**
- * Constructs a BloomFilter with a specified number of hash functions and bit
- * array size.
- *
- * @param numberOfHashFunctions the number of hash functions to use
- * @param bitArraySize the size of the bit array, which determines the
- * capacity of the filter
- * @throws IllegalArgumentException if numberOfHashFunctions or bitArraySize is
- * less than 1
- */
- @SuppressWarnings("unchecked")
- public BloomFilter(int numberOfHashFunctions, int bitArraySize) {
- if (numberOfHashFunctions < 1 || bitArraySize < 1) {
- throw new IllegalArgumentException("Number of hash functions and bit array size must be greater than 0");
- }
- this.numberOfHashFunctions = numberOfHashFunctions;
- this.bitArray = new BitSet(bitArraySize);
- this.hashFunctions = new Hash[numberOfHashFunctions];
- initializeHashFunctions();
- }
-
- /**
- * Initializes the hash functions with unique indices to ensure different
- * hashing.
- */
- private void initializeHashFunctions() {
- for (int i = 0; i < numberOfHashFunctions; i++) {
- hashFunctions[i] = new Hash<>(i);
- }
- }
-
- /**
- * Inserts an element into the Bloom filter.
- *
- * This method hashes the element using all defined hash functions and sets the
- * corresponding
- * bits in the bit array.
- *
- *
- * @param key the element to insert into the Bloom filter
- */
- public void insert(T key) {
- for (Hash hash : hashFunctions) {
- int position = Math.abs(hash.compute(key) % bitArray.size());
- bitArray.set(position);
- }
- }
-
- /**
- * Checks if an element might be in the Bloom filter.
- *
- * This method checks the bits at the positions computed by each hash function.
- * If any of these
- * bits are not set, the element is definitely not in the filter. If all bits
- * are set, the element
- * might be in the filter.
- *
- *
- * @param key the element to check for membership in the Bloom filter
- * @return {@code true} if the element might be in the Bloom filter,
- * {@code false} if it is definitely not
- */
- public boolean contains(T key) {
- for (Hash hash : hashFunctions) {
- int position = Math.abs(hash.compute(key) % bitArray.size());
- if (!bitArray.get(position)) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Inner class representing a hash function used by the Bloom filter.
- *
- * Each instance of this class represents a different hash function based on its
- * index.
- *
- *
- * @param The type of elements to be hashed.
- */
- private static class Hash {
-
- private final int index;
-
- /**
- * Constructs a Hash function with a specified index.
- *
- * @param index the index of this hash function, used to create a unique hash
- */
- Hash(int index) {
- this.index = index;
- }
-
- /**
- * Computes the hash of the given key.
- *
- * The hash value is calculated by multiplying the index of the hash function
- * with the ASCII sum of the string representation of the key.
- *
- *
- * @param key the element to hash
- * @return the computed hash value
- */
- public int compute(T key) {
- return index * contentHash(key);
- }
-
- /**
- * Computes the ASCII value sum of the characters in a string.
- *
- * This method iterates through each character of the string and accumulates
- * their ASCII values to produce a single integer value.
- *
- *
- * @param word the string to compute
- * @return the sum of ASCII values of the characters in the string
- */
- private int asciiString(String word) {
- int sum = 0;
- for (char c : word.toCharArray()) {
- sum += c;
- }
- return sum;
- }
-
- /**
- * Computes a content-based hash for arrays; falls back to ASCII-sum of String value otherwise.
- */
- private int contentHash(Object key) {
- if (key instanceof int[]) {
- return Arrays.hashCode((int[]) key);
- } else if (key instanceof long[]) {
- return Arrays.hashCode((long[]) key);
- } else if (key instanceof byte[]) {
- return Arrays.hashCode((byte[]) key);
- } else if (key instanceof short[]) {
- return Arrays.hashCode((short[]) key);
- } else if (key instanceof char[]) {
- return Arrays.hashCode((char[]) key);
- } else if (key instanceof boolean[]) {
- return Arrays.hashCode((boolean[]) key);
- } else if (key instanceof float[]) {
- return Arrays.hashCode((float[]) key);
- } else if (key instanceof double[]) {
- return Arrays.hashCode((double[]) key);
- } else if (key instanceof Object[]) {
- return Arrays.deepHashCode((Object[]) key);
- }
- return asciiString(String.valueOf(key));
- }
- }
-}
+package com.thealgorithms.datastructures.bloomfilter;
+
+import java.util.Arrays;
+import java.util.BitSet;
+
+/**
+ * A generic BloomFilter implementation for probabilistic membership checking.
+ *
+ * Bloom filters are space-efficient data structures that provide a fast way to
+ * test whether an
+ * element is a member of a set. They may produce false positives, indicating an
+ * element is
+ * in the set when it is not, but they will never produce false negatives.
+ *
+ *
+ * @param The type of elements to be stored in the Bloom filter.
+ */
+@SuppressWarnings("rawtypes")
+public class BloomFilter {
+
+ private final int numberOfHashFunctions;
+ private final BitSet bitArray;
+ private final Hash[] hashFunctions;
+
+ /**
+ * Constructs a BloomFilter with a specified number of hash functions and bit
+ * array size.
+ *
+ * @param numberOfHashFunctions the number of hash functions to use
+ * @param bitArraySize the size of the bit array, which determines the
+ * capacity of the filter
+ * @throws IllegalArgumentException if numberOfHashFunctions or bitArraySize is
+ * less than 1
+ */
+ @SuppressWarnings("unchecked")
+ public BloomFilter(int numberOfHashFunctions, int bitArraySize) {
+ if (numberOfHashFunctions < 1 || bitArraySize < 1) {
+ throw new IllegalArgumentException("Number of hash functions and bit array size must be greater than 0");
+ }
+ this.numberOfHashFunctions = numberOfHashFunctions;
+ this.bitArray = new BitSet(bitArraySize);
+ this.hashFunctions = new Hash[numberOfHashFunctions];
+ initializeHashFunctions();
+ }
+
+ /**
+ * Initializes the hash functions with unique indices to ensure different
+ * hashing.
+ */
+ private void initializeHashFunctions() {
+ for (int i = 0; i < numberOfHashFunctions; i++) {
+ hashFunctions[i] = new Hash<>(i);
+ }
+ }
+
+ /**
+ * Inserts an element into the Bloom filter.
+ *
+ * This method hashes the element using all defined hash functions and sets the
+ * corresponding
+ * bits in the bit array.
+ *
+ *
+ * @param key the element to insert into the Bloom filter
+ */
+ public void insert(T key) {
+ for (Hash hash : hashFunctions) {
+ int position = Math.abs(hash.compute(key) % bitArray.size());
+ bitArray.set(position);
+ }
+ }
+
+ /**
+ * Checks if an element might be in the Bloom filter.
+ *
+ * This method checks the bits at the positions computed by each hash function.
+ * If any of these
+ * bits are not set, the element is definitely not in the filter. If all bits
+ * are set, the element
+ * might be in the filter.
+ *
+ *
+ * @param key the element to check for membership in the Bloom filter
+ * @return {@code true} if the element might be in the Bloom filter,
+ * {@code false} if it is definitely not
+ */
+ public boolean contains(T key) {
+ for (Hash hash : hashFunctions) {
+ int position = Math.abs(hash.compute(key) % bitArray.size());
+ if (!bitArray.get(position)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Inner class representing a hash function used by the Bloom filter.
+ *
+ * Each instance of this class represents a different hash function based on its
+ * index.
+ *
+ *
+ * @param The type of elements to be hashed.
+ */
+ private static class Hash {
+
+ private final int index;
+
+ /**
+ * Constructs a Hash function with a specified index.
+ *
+ * @param index the index of this hash function, used to create a unique hash
+ */
+ Hash(int index) {
+ this.index = index;
+ }
+
+ /**
+ * Computes the hash of the given key.
+ *
+ * The hash value is calculated by multiplying the index of the hash function
+ * with the ASCII sum of the string representation of the key.
+ *
+ *
+ * @param key the element to hash
+ * @return the computed hash value
+ */
+ public int compute(T key) {
+ return index * contentHash(key);
+ }
+
+ /**
+ * Computes the ASCII value sum of the characters in a string.
+ *
+ * This method iterates through each character of the string and accumulates
+ * their ASCII values to produce a single integer value.
+ *
+ *
+ * @param word the string to compute
+ * @return the sum of ASCII values of the characters in the string
+ */
+ private int asciiString(String word) {
+ int sum = 0;
+ for (char c : word.toCharArray()) {
+ sum += c;
+ }
+ return sum;
+ }
+
+ /**
+ * Computes a content-based hash for arrays; falls back to ASCII-sum of String value otherwise.
+ */
+ private int contentHash(Object key) {
+ if (key instanceof int[]) {
+ return Arrays.hashCode((int[]) key);
+ } else if (key instanceof long[]) {
+ return Arrays.hashCode((long[]) key);
+ } else if (key instanceof byte[]) {
+ return Arrays.hashCode((byte[]) key);
+ } else if (key instanceof short[]) {
+ return Arrays.hashCode((short[]) key);
+ } else if (key instanceof char[]) {
+ return Arrays.hashCode((char[]) key);
+ } else if (key instanceof boolean[]) {
+ return Arrays.hashCode((boolean[]) key);
+ } else if (key instanceof float[]) {
+ return Arrays.hashCode((float[]) key);
+ } else if (key instanceof double[]) {
+ return Arrays.hashCode((double[]) key);
+ } else if (key instanceof Object[]) {
+ return Arrays.deepHashCode((Object[]) key);
+ }
+ return asciiString(String.valueOf(key));
+ }
+ }
+}
diff --git a/src/main/java/com/thealgorithms/datastructures/buffers/CircularBuffer.java b/src/main/java/com/thealgorithms/datastructures/buffers/CircularBuffer.java
index 3b89c2119ae0..f0d328c0c0e4 100644
--- a/src/main/java/com/thealgorithms/datastructures/buffers/CircularBuffer.java
+++ b/src/main/java/com/thealgorithms/datastructures/buffers/CircularBuffer.java
@@ -1,133 +1,133 @@
-package com.thealgorithms.datastructures.buffers;
-
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * The {@code CircularBuffer} class implements a generic circular (or ring) buffer.
- * A circular buffer is a fixed-size data structure that operates in a FIFO (First In, First Out) manner.
- * The buffer allows you to overwrite old data when the buffer is full and efficiently use limited memory.
- * When the buffer is full, adding a new item will overwrite the oldest data.
- *
- * @param - The type of elements stored in the circular buffer.
- */
-@SuppressWarnings("unchecked")
-public class CircularBuffer
- {
- private final Item[] buffer;
- private final CircularPointer putPointer;
- private final CircularPointer getPointer;
- private final AtomicInteger size = new AtomicInteger(0);
-
- /**
- * Constructor to initialize the circular buffer with a specified size.
- *
- * @param size The size of the circular buffer.
- * @throws IllegalArgumentException if the size is zero or negative.
- */
- public CircularBuffer(int size) {
- if (size <= 0) {
- throw new IllegalArgumentException("Buffer size must be positive");
- }
- // noinspection unchecked
- this.buffer = (Item[]) new Object[size];
- this.putPointer = new CircularPointer(0, size);
- this.getPointer = new CircularPointer(0, size);
- }
-
- /**
- * Checks if the circular buffer is empty.
- * This method is based on the current size of the buffer.
- *
- * @return {@code true} if the buffer is empty, {@code false} otherwise.
- */
- public boolean isEmpty() {
- return size.get() == 0;
- }
-
- /**
- * Checks if the circular buffer is full.
- * The buffer is considered full when its size equals its capacity.
- *
- * @return {@code true} if the buffer is full, {@code false} otherwise.
- */
- public boolean isFull() {
- return size.get() == buffer.length;
- }
-
- /**
- * Retrieves and removes the item at the front of the buffer (FIFO).
- * This operation will move the {@code getPointer} forward.
- *
- * @return The item at the front of the buffer, or {@code null} if the buffer is empty.
- */
- public Item get() {
- if (isEmpty()) {
- return null;
- }
-
- Item item = buffer[getPointer.getAndIncrement()];
- size.decrementAndGet();
- return item;
- }
-
- /**
- * Adds an item to the end of the buffer (FIFO).
- * If the buffer is full, this operation will overwrite the oldest data.
- *
- * @param item The item to be added.
- * @throws IllegalArgumentException if the item is null.
- * @return {@code true} if the item was successfully added, {@code false} if the buffer was full and the item overwrote existing data.
- */
- public boolean put(Item item) {
- if (item == null) {
- throw new IllegalArgumentException("Null items are not allowed");
- }
-
- boolean wasEmpty = isEmpty();
- if (isFull()) {
- getPointer.getAndIncrement(); // Move get pointer to discard oldest item
- } else {
- size.incrementAndGet();
- }
-
- buffer[putPointer.getAndIncrement()] = item;
- return wasEmpty;
- }
-
- /**
- * The {@code CircularPointer} class is a helper class used to track the current index (pointer)
- * in the circular buffer.
- * The max value represents the capacity of the buffer.
- * The `CircularPointer` class ensures that the pointer automatically wraps around to 0
- * when it reaches the maximum index.
- * This is achieved in the `getAndIncrement` method, where the pointer
- * is incremented and then taken modulo the maximum value (`max`).
- * This operation ensures that the pointer always stays within the bounds of the buffer.
- */
- private static class CircularPointer {
- private int pointer;
- private final int max;
-
- /**
- * Constructor to initialize the circular pointer.
- *
- * @param pointer The initial position of the pointer.
- * @param max The maximum size (capacity) of the circular buffer.
- */
- CircularPointer(int pointer, int max) {
- this.pointer = pointer;
- this.max = max;
- }
-
- /**
- * Increments the pointer by 1 and wraps it around to 0 if it reaches the maximum value.
- * This ensures the pointer always stays within the buffer's bounds.
- *
- * @return The current pointer value before incrementing.
- */
- public int getAndIncrement() {
- int tmp = pointer;
- pointer = (pointer + 1) % max;
- return tmp;
- }
- }
-}
+package com.thealgorithms.datastructures.buffers;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * The {@code CircularBuffer} class implements a generic circular (or ring) buffer.
+ * A circular buffer is a fixed-size data structure that operates in a FIFO (First In, First Out) manner.
+ * The buffer allows you to overwrite old data when the buffer is full and efficiently use limited memory.
+ * When the buffer is full, adding a new item will overwrite the oldest data.
+ *
+ * @param
- The type of elements stored in the circular buffer.
+ */
+@SuppressWarnings("unchecked")
+public class CircularBuffer
- {
+ private final Item[] buffer;
+ private final CircularPointer putPointer;
+ private final CircularPointer getPointer;
+ private final AtomicInteger size = new AtomicInteger(0);
+
+ /**
+ * Constructor to initialize the circular buffer with a specified size.
+ *
+ * @param size The size of the circular buffer.
+ * @throws IllegalArgumentException if the size is zero or negative.
+ */
+ public CircularBuffer(int size) {
+ if (size <= 0) {
+ throw new IllegalArgumentException("Buffer size must be positive");
+ }
+ // noinspection unchecked
+ this.buffer = (Item[]) new Object[size];
+ this.putPointer = new CircularPointer(0, size);
+ this.getPointer = new CircularPointer(0, size);
+ }
+
+ /**
+ * Checks if the circular buffer is empty.
+ * This method is based on the current size of the buffer.
+ *
+ * @return {@code true} if the buffer is empty, {@code false} otherwise.
+ */
+ public boolean isEmpty() {
+ return size.get() == 0;
+ }
+
+ /**
+ * Checks if the circular buffer is full.
+ * The buffer is considered full when its size equals its capacity.
+ *
+ * @return {@code true} if the buffer is full, {@code false} otherwise.
+ */
+ public boolean isFull() {
+ return size.get() == buffer.length;
+ }
+
+ /**
+ * Retrieves and removes the item at the front of the buffer (FIFO).
+ * This operation will move the {@code getPointer} forward.
+ *
+ * @return The item at the front of the buffer, or {@code null} if the buffer is empty.
+ */
+ public Item get() {
+ if (isEmpty()) {
+ return null;
+ }
+
+ Item item = buffer[getPointer.getAndIncrement()];
+ size.decrementAndGet();
+ return item;
+ }
+
+ /**
+ * Adds an item to the end of the buffer (FIFO).
+ * If the buffer is full, this operation will overwrite the oldest data.
+ *
+ * @param item The item to be added.
+ * @throws IllegalArgumentException if the item is null.
+ * @return {@code true} if the item was successfully added, {@code false} if the buffer was full and the item overwrote existing data.
+ */
+ public boolean put(Item item) {
+ if (item == null) {
+ throw new IllegalArgumentException("Null items are not allowed");
+ }
+
+ boolean wasEmpty = isEmpty();
+ if (isFull()) {
+ getPointer.getAndIncrement(); // Move get pointer to discard oldest item
+ } else {
+ size.incrementAndGet();
+ }
+
+ buffer[putPointer.getAndIncrement()] = item;
+ return wasEmpty;
+ }
+
+ /**
+ * The {@code CircularPointer} class is a helper class used to track the current index (pointer)
+ * in the circular buffer.
+ * The max value represents the capacity of the buffer.
+ * The `CircularPointer` class ensures that the pointer automatically wraps around to 0
+ * when it reaches the maximum index.
+ * This is achieved in the `getAndIncrement` method, where the pointer
+ * is incremented and then taken modulo the maximum value (`max`).
+ * This operation ensures that the pointer always stays within the bounds of the buffer.
+ */
+ private static class CircularPointer {
+ private int pointer;
+ private final int max;
+
+ /**
+ * Constructor to initialize the circular pointer.
+ *
+ * @param pointer The initial position of the pointer.
+ * @param max The maximum size (capacity) of the circular buffer.
+ */
+ CircularPointer(int pointer, int max) {
+ this.pointer = pointer;
+ this.max = max;
+ }
+
+ /**
+ * Increments the pointer by 1 and wraps it around to 0 if it reaches the maximum value.
+ * This ensures the pointer always stays within the buffer's bounds.
+ *
+ * @return The current pointer value before incrementing.
+ */
+ public int getAndIncrement() {
+ int tmp = pointer;
+ pointer = (pointer + 1) % max;
+ return tmp;
+ }
+ }
+}
diff --git a/src/main/java/com/thealgorithms/datastructures/caches/FIFOCache.java b/src/main/java/com/thealgorithms/datastructures/caches/FIFOCache.java
index fa048434a187..7a2c4df05831 100644
--- a/src/main/java/com/thealgorithms/datastructures/caches/FIFOCache.java
+++ b/src/main/java/com/thealgorithms/datastructures/caches/FIFOCache.java
@@ -1,549 +1,549 @@
-package com.thealgorithms.datastructures.caches;
-
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-import java.util.function.BiConsumer;
-
-/**
- * A thread-safe generic cache implementation using the First-In-First-Out eviction policy.
- *
- * The cache holds a fixed number of entries, defined by its capacity. When the cache is full and a
- * new entry is added, the oldest entry in the cache is selected and evicted to make space.
- *
- * Optionally, entries can have a time-to-live (TTL) in milliseconds. If a TTL is set, entries will
- * automatically expire and be removed upon access or insertion attempts.
- *
- * Features:
- *
- * - Removes oldest entry when capacity is exceeded
- * - Optional TTL (time-to-live in milliseconds) per entry or default TTL for all entries
- * - Thread-safe access using locking
- * - Hit and miss counters for cache statistics
- * - Eviction listener callback support
- *
- *
- * @param the type of keys maintained by this cache
- * @param the type of mapped values
- * See FIFO
- * @author Kevin Babu (GitHub)
- */
-public final class FIFOCache {
-
- private final int capacity;
- private final long defaultTTL;
- private final Map> cache;
- private final Lock lock;
-
- private long hits = 0;
- private long misses = 0;
- private final BiConsumer evictionListener;
- private final EvictionStrategy evictionStrategy;
-
- /**
- * Internal structure to store value + expiry timestamp.
- *
- * @param the type of the value being cached
- */
- private static class CacheEntry {
- V value;
- long expiryTime;
-
- /**
- * Constructs a new {@code CacheEntry} with the specified value and time-to-live (TTL).
- * If TTL is 0, the entry is kept indefinitely, that is, unless it is the first value,
- * then it will be removed according to the FIFO principle
- *
- * @param value the value to cache
- * @param ttlMillis the time-to-live in milliseconds
- */
- CacheEntry(V value, long ttlMillis) {
- this.value = value;
- if (ttlMillis == 0) {
- this.expiryTime = Long.MAX_VALUE;
- } else {
- this.expiryTime = System.currentTimeMillis() + ttlMillis;
- }
- }
-
- /**
- * Checks if the cache entry has expired.
- *
- * @return {@code true} if the current time is past the expiration time; {@code false} otherwise
- */
- boolean isExpired() {
- return System.currentTimeMillis() > expiryTime;
- }
- }
-
- /**
- * Constructs a new {@code FIFOCache} instance using the provided {@link Builder}.
- *
- * This constructor initializes the cache with the specified capacity and default TTL,
- * sets up internal data structures (a {@code LinkedHashMap} for cache entries and configures eviction.
- *
- * @param builder the {@code Builder} object containing configuration parameters
- */
- private FIFOCache(Builder builder) {
- this.capacity = builder.capacity;
- this.defaultTTL = builder.defaultTTL;
- this.cache = new LinkedHashMap<>();
- this.lock = new ReentrantLock();
- this.evictionListener = builder.evictionListener;
- this.evictionStrategy = builder.evictionStrategy;
- }
-
- /**
- * Retrieves the value associated with the specified key from the cache.
- *
- * If the key is not present or the corresponding entry has expired, this method
- * returns {@code null}. If an expired entry is found, it will be removed and the
- * eviction listener (if any) will be notified. Cache hit-and-miss statistics are
- * also updated accordingly.
- *
- * @param key the key whose associated value is to be returned; must not be {@code null}
- * @return the cached value associated with the key, or {@code null} if not present or expired
- * @throws IllegalArgumentException if {@code key} is {@code null}
- */
- public V get(K key) {
- if (key == null) {
- throw new IllegalArgumentException("Key must not be null");
- }
-
- lock.lock();
- try {
- evictionStrategy.onAccess(this);
-
- CacheEntry entry = cache.get(key);
- if (entry == null || entry.isExpired()) {
- if (entry != null) {
- cache.remove(key);
- notifyEviction(key, entry.value);
- }
- misses++;
- return null;
- }
- hits++;
- return entry.value;
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Adds a key-value pair to the cache using the default time-to-live (TTL).
- *
- * The key may overwrite an existing entry. The actual insertion is delegated
- * to the overloaded {@link #put(K, V, long)} method.
- *
- * @param key the key to cache the value under
- * @param value the value to be cached
- */
- public void put(K key, V value) {
- put(key, value, defaultTTL);
- }
-
- /**
- * Adds a key-value pair to the cache with a specified time-to-live (TTL).
- *
- *
If the key already exists, its value is removed, re-inserted at tail and its TTL is reset.
- * If the key does not exist and the cache is full, the oldest entry is evicted to make space.
- * Expired entries are also cleaned up prior to any eviction. The eviction listener
- * is notified when an entry gets evicted.
- *
- * @param key the key to associate with the cached value; must not be {@code null}
- * @param value the value to be cached; must not be {@code null}
- * @param ttlMillis the time-to-live for this entry in milliseconds; must be >= 0
- * @throws IllegalArgumentException if {@code key} or {@code value} is {@code null}, or if {@code ttlMillis} is negative
- */
- public void put(K key, V value, long ttlMillis) {
- if (key == null || value == null) {
- throw new IllegalArgumentException("Key and value must not be null");
- }
- if (ttlMillis < 0) {
- throw new IllegalArgumentException("TTL must be >= 0");
- }
-
- lock.lock();
- try {
- // If key already exists, remove it
- CacheEntry oldEntry = cache.remove(key);
- if (oldEntry != null && !oldEntry.isExpired()) {
- notifyEviction(key, oldEntry.value);
- }
-
- // Evict expired entries to make space for new entry
- evictExpired();
-
- // If no expired entry was removed, remove the oldest
- if (cache.size() >= capacity) {
- Iterator>> it = cache.entrySet().iterator();
- if (it.hasNext()) {
- Map.Entry> eldest = it.next();
- it.remove();
- notifyEviction(eldest.getKey(), eldest.getValue().value);
- }
- }
-
- // Insert new entry at tail
- cache.put(key, new CacheEntry<>(value, ttlMillis));
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Removes all expired entries from the cache.
- *
- * This method iterates through the list of cached keys and checks each associated
- * entry for expiration. Expired entries are removed the cache map. For each eviction,
- * the eviction listener is notified.
- */
- private int evictExpired() {
- int count = 0;
- Iterator>> it = cache.entrySet().iterator();
-
- while (it.hasNext()) {
- Map.Entry> entry = it.next();
- if (entry != null && entry.getValue().isExpired()) {
- it.remove();
- notifyEviction(entry.getKey(), entry.getValue().value);
- count++;
- }
- }
-
- return count;
- }
-
- /**
- * Removes the specified key and its associated entry from the cache.
- *
- * @param key the key to remove from the cache;
- * @return the value associated with the key; or {@code null} if no such key exists
- */
- public V removeKey(K key) {
- if (key == null) {
- throw new IllegalArgumentException("Key cannot be null");
- }
- CacheEntry entry = cache.remove(key);
-
- // No such key in cache
- if (entry == null) {
- return null;
- }
-
- notifyEviction(key, entry.value);
- return entry.value;
- }
-
- /**
- * Notifies the eviction listener, if one is registered, that a key-value pair has been evicted.
- *
- * If the {@code evictionListener} is not {@code null}, it is invoked with the provided key
- * and value. Any exceptions thrown by the listener are caught and logged to standard error,
- * preventing them from disrupting cache operations.
- *
- * @param key the key that was evicted
- * @param value the value that was associated with the evicted key
- */
- private void notifyEviction(K key, V value) {
- if (evictionListener != null) {
- try {
- evictionListener.accept(key, value);
- } catch (Exception e) {
- System.err.println("Eviction listener failed: " + e.getMessage());
- }
- }
- }
-
- /**
- * Returns the number of successful cache lookups (hits).
- *
- * @return the number of cache hits
- */
- public long getHits() {
- lock.lock();
- try {
- return hits;
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Returns the number of failed cache lookups (misses), including expired entries.
- *
- * @return the number of cache misses
- */
- public long getMisses() {
- lock.lock();
- try {
- return misses;
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Returns the current number of entries in the cache, excluding expired ones.
- *
- * @return the current cache size
- */
- public int size() {
- lock.lock();
- try {
- evictionStrategy.onAccess(this);
-
- int count = 0;
- for (CacheEntry entry : cache.values()) {
- if (!entry.isExpired()) {
- ++count;
- }
- }
- return count;
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Removes all entries from the cache, regardless of their expiration status.
- *
- * This method clears the internal cache map entirely, resets the hit-and-miss counters,
- * and notifies the eviction listener (if any) for each removed entry.
- * Note that expired entries are treated the same as active ones for the purpose of clearing.
- *
- *
This operation acquires the internal lock to ensure thread safety.
- */
- public void clear() {
- lock.lock();
- try {
- for (Map.Entry> entry : cache.entrySet()) {
- notifyEviction(entry.getKey(), entry.getValue().value);
- }
- cache.clear();
- hits = 0;
- misses = 0;
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Returns a set of all keys currently stored in the cache that have not expired.
- *
- * This method iterates through the cache and collects the keys of all non-expired entries.
- * Expired entries are ignored but not removed. If you want to ensure expired entries are cleaned up,
- * consider invoking {@link EvictionStrategy#onAccess(FIFOCache)} or calling {@link #evictExpired()} manually.
- *
- *
This operation acquires the internal lock to ensure thread safety.
- *
- * @return a set containing all non-expired keys currently in the cache
- */
- public Set getAllKeys() {
- lock.lock();
- try {
- Set keys = new LinkedHashSet<>();
-
- for (Map.Entry> entry : cache.entrySet()) {
- if (!entry.getValue().isExpired()) {
- keys.add(entry.getKey());
- }
- }
-
- return keys;
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Returns the current {@link EvictionStrategy} used by this cache instance.
-
- * @return the eviction strategy currently assigned to this cache
- */
- public EvictionStrategy getEvictionStrategy() {
- return evictionStrategy;
- }
-
- /**
- * Returns a string representation of the cache, including metadata and current non-expired entries.
- *
- * The returned string includes the cache's capacity, current size (excluding expired entries),
- * hit-and-miss counts, and a map of all non-expired key-value pairs. This method acquires a lock
- * to ensure thread-safe access.
- *
- * @return a string summarizing the state of the cache
- */
- @Override
- public String toString() {
- lock.lock();
- try {
- Map visible = new LinkedHashMap<>();
- for (Map.Entry> entry : cache.entrySet()) {
- if (!entry.getValue().isExpired()) {
- visible.put(entry.getKey(), entry.getValue().value);
- }
- }
- return String.format("Cache(capacity=%d, size=%d, hits=%d, misses=%d, entries=%s)", capacity, visible.size(), hits, misses, visible);
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * A strategy interface for controlling when expired entries are evicted from the cache.
- *
- * Implementations decide whether and when to trigger {@link FIFOCache#evictExpired()} based
- * on cache usage patterns. This allows for flexible eviction behaviour such as periodic cleanup,
- * or no automatic cleanup.
- *
- * @param the type of keys maintained by the cache
- * @param the type of cached values
- */
- public interface EvictionStrategy {
- /**
- * Called on each cache access (e.g., {@link FIFOCache#get(Object)}) to optionally trigger eviction.
- *
- * @param cache the cache instance on which this strategy is applied
- * @return the number of expired entries evicted during this access
- */
- int onAccess(FIFOCache cache);
- }
-
- /**
- * An eviction strategy that performs eviction of expired entries on each call.
- *
- * @param