Repository: TheAlgorithms/Java
Pull request #5385 (2024-08-24 20:45:48)

refactor: `LowestBasePalindrome`
Class cleanup.
Readability improvements.
Tests cleanup.

<!--
Thank you for your contribution!
In order to reduce the number of notifications sent to the maintainers, please:
- create your PR as draft, cf. https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests#draft-pull-requests,
- make sure that all of the CI checks pass,
- mark your PR as ready for review, cf. https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/changing-the-stage-of-a-pull-request#marking-a-pull-request-as-ready-for-review
-->

<!-- For completed items, change [ ] to [x] -->

- [x] I have read [CONTRIBUTING.md](https://github.com/TheAlgorithms/Java/blob/master/CONTRIBUTING.md).
- [x] This pull request is all my own work -- I have not plagiarized it.
- [x] All filenames are in PascalCase.
- [x] All functions and variable names follow Java naming conventions.
- [x] All new algorithms have a URL in their comments that points to Wikipedia or other similar explanations.
- [x] All new code is formatted with `clang-format -i --style=file path/to/your/file.java`

codecov-commenter: ## [Codecov](https://app.codecov.io/gh/TheAlgorithms/Java/pull/5385?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TheAlgorithms) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 46.93%. Comparing base [(`b231a72`)](https://app.codecov.io/gh/TheAlgorithms/Java/commit/b231a72d449420c6dc7004bc5969285aea7ec956?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TheAlgorithms) to head [(`319e5a8`)](https://app.codecov.io/gh/TheAlgorithms/Java/commit/319e5a8783c522c708d0bddb5fc9326b89e578a6?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TheAlgorithms).

<details><summary>Additional details and impacted files</summary>


```diff
@@             Coverage Diff              @@
##             master    #5385      +/-   ##
============================================
+ Coverage     46.90%   46.93%   +0.02%     
- Complexity     2903     2904       +1     
============================================
  Files           525      525              
  Lines         15363    15365       +2     
  Branches       2908     2909       +1     
============================================
+ Hits           7206     7211       +5     
+ Misses         7855     7854       -1     
+ Partials        302      300       -2     
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/TheAlgorithms/Java/pull/5385?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TheAlgorithms).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TheAlgorithms).


Patch:
diff --git a/src/main/java/com/thealgorithms/others/LowestBasePalindrome.java b/src/main/java/com/thealgorithms/others/LowestBasePalindrome.java
index c8328a4e..76d1ed4a 100644
--- a/src/main/java/com/thealgorithms/others/LowestBasePalindrome.java
+++ b/src/main/java/com/thealgorithms/others/LowestBasePalindrome.java
@@ -1,6 +1,7 @@
 package com.thealgorithms.others;
 
 import java.util.ArrayList;
+import java.util.List;
 
 /**
  * @brief Class for finding the lowest base in which a given integer is a palindrome.
@@ -10,45 +11,61 @@ public final class LowestBasePalindrome {
     private LowestBasePalindrome() {
     }
 
+    /**
+     * Validates the base, ensuring it is greater than 1.
+     *
+     * @param base the base to be checked
+     * @throws IllegalArgumentException if the base is less than or equal to 1
+     */
     private static void checkBase(int base) {
         if (base <= 1) {
-            throw new IllegalArgumentException("base must be greater than 1.");
+            throw new IllegalArgumentException("Base must be greater than 1.");
         }
     }
 
+    /**
+     * Validates the number, ensuring it is non-negative.
+     *
+     * @param number the number to be checked
+     * @throws IllegalArgumentException if the number is negative
+     */
     private static void checkNumber(int number) {
         if (number < 0) {
-            throw new IllegalArgumentException("number must be nonnegative.");
+            throw new IllegalArgumentException("Number must be non-negative.");
         }
     }
 
     /**
-     * @brief computes the representation of the input number in given base
-     * @param number the input number
-     * @param base the given base
-     * @exception IllegalArgumentException number is negative or base is less than 2
-     * @return the list containing the digits of the input number in the given base, the most
-     *     significant digit is at the end of the array
+     * Computes the digits of a given number in a specified base.
+     *
+     * @param number the number to be converted
+     * @param base the base to be used for the conversion
+     * @return a list of digits representing the number in the given base, with the most
+     *         significant digit at the end of the list
+     * @throws IllegalArgumentException if the number is negative or the base is less than 2
      */
-    public static ArrayList<Integer> computeDigitsInBase(int number, int base) {
+    public static List<Integer> computeDigitsInBase(int number, int base) {
         checkNumber(number);
         checkBase(base);
-        var result = new ArrayList<Integer>();
+
+        List<Integer> digits = new ArrayList<>();
         while (number > 0) {
-            result.add(number % base);
+            digits.add(number % base);
             number /= base;
         }
-        return result;
+        return digits;
     }
 
     /**
-     * @brief checks if the input array is a palindrome
-     * @brief list the input array
-     * @return true, if the input array is a palindrome, false otherwise
+     * Checks if a list of integers is palindromic.
+     *
+     * @param list the list of integers to be checked
+     * @return {@code true} if the list is a palindrome, {@code false} otherwise
      */
-    public static boolean isPalindromic(ArrayList<Integer> list) {
-        for (int pos = 0; pos < list.size() / 2; ++pos) {
-            if (list.get(pos) != list.get(list.size() - 1 - pos)) {
+    public static boolean isPalindromic(List<Integer> list) {
+        int size = list.size();
+        for (int i = 0; i < size / 2; i++) {
+            if (!list.get(i).equals(list.get(size - 1 - i))) {
                 return false;
             }
         }
@@ -56,12 +73,12 @@ public final class LowestBasePalindrome {
     }
 
     /**
-     * @brief checks if representation of the input number in given base is a palindrome
-     * @param number the input number
-     * @param base the given base
-     * @exception IllegalArgumentException number is negative or base is less than 2
-     * @return true, if the input number represented in the given base is a palindrome, false
-     *     otherwise
+     * Checks if the representation of a given number in a specified base is palindromic.
+     *
+     * @param number the number to be checked
+     * @param base the base in which the number will be represented
+     * @return {@code true} if the number is palindromic in the specified base, {@code false} otherwise
+     * @throws IllegalArgumentException if the number is negative or the base is less than 2
      */
     public static boolean isPalindromicInBase(int number, int base) {
         checkNumber(number);
@@ -72,7 +89,7 @@ public final class LowestBasePalindrome {
         }
 
         if (number % base == 0) {
-            // the last digit of number written in base is 0
+            // If the last digit of the number in the given base is 0, it can't be palindromic
             return false;
         }
 
@@ -80,16 +97,18 @@ public final class LowestBasePalindrome {
     }
 
     /**
-     * @brief finds the smallest base for which the representation of the input number is a
-     * palindrome
-     * @param number the input number
-     * @exception IllegalArgumentException number is negative
-     * @return the smallest base for which the representation of the input number is a palindrome
+     * Finds the smallest base in which the representation of a given number is palindromic.
+     *
+     * @param number the number to be checked
+     * @return the smallest base in which the number is a palindrome
+     * @throws IllegalArgumentException if the number is negative
      */
     public static int lowestBasePalindrome(int number) {
+        checkNumber(number);
+
         int base = 2;
         while (!isPalindromicInBase(number, base)) {
-            ++base;
+            base++;
         }
         return base;
     }


Test patch:
diff --git a/src/test/java/com/thealgorithms/others/LowestBasePalindromeTest.java b/src/test/java/com/thealgorithms/others/LowestBasePalindromeTest.java
index c8e173ab..1014f39a 100644
--- a/src/test/java/com/thealgorithms/others/LowestBasePalindromeTest.java
+++ b/src/test/java/com/thealgorithms/others/LowestBasePalindromeTest.java
@@ -2,79 +2,76 @@ package com.thealgorithms.others;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.HashMap;
-import org.junit.jupiter.api.Test;
+import java.util.List;
+import java.util.stream.Stream;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
 
 public class LowestBasePalindromeTest {
-    @Test
-    public void testIsPalindromicPositive() {
-        assertTrue(LowestBasePalindrome.isPalindromic(new ArrayList<Integer>()));
-        assertTrue(LowestBasePalindrome.isPalindromic(new ArrayList<Integer>(Arrays.asList(1))));
-        assertTrue(LowestBasePalindrome.isPalindromic(new ArrayList<Integer>(Arrays.asList(1, 1))));
-        assertTrue(LowestBasePalindrome.isPalindromic(new ArrayList<Integer>(Arrays.asList(1, 2, 1))));
-        assertTrue(LowestBasePalindrome.isPalindromic(new ArrayList<Integer>(Arrays.asList(1, 2, 2, 1))));
+
+    @ParameterizedTest
+    @MethodSource("provideListsForIsPalindromicPositive")
+    public void testIsPalindromicPositive(List<Integer> list) {
+        assertTrue(LowestBasePalindrome.isPalindromic(list));
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideListsForIsPalindromicNegative")
+    public void testIsPalindromicNegative(List<Integer> list) {
+        assertFalse(LowestBasePalindrome.isPalindromic(list));
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideNumbersAndBasesForIsPalindromicInBasePositive")
+    public void testIsPalindromicInBasePositive(int number, int base) {
+        assertTrue(LowestBasePalindrome.isPalindromicInBase(number, base));
     }
 
-    @Test
-    public void testIsPalindromicNegative() {
-        assertFalse(LowestBasePalindrome.isPalindromic(new ArrayList<Integer>(Arrays.asList(1, 2))));
-        assertFalse(LowestBasePalindrome.isPalindromic(new ArrayList<Integer>(Arrays.asList(1, 2, 1, 1))));
+    @ParameterizedTest
+    @MethodSource("provideNumbersAndBasesForIsPalindromicInBaseNegative")
+    public void testIsPalindromicInBaseNegative(int number, int base) {
+        assertFalse(LowestBasePalindrome.isPalindromicInBase(number, base));
     }
 
-    @Test
-    public void testIsPalindromicInBasePositive() {
-        assertTrue(LowestBasePalindrome.isPalindromicInBase(101, 10));
-        assertTrue(LowestBasePalindrome.isPalindromicInBase(1, 190));
-        assertTrue(LowestBasePalindrome.isPalindromicInBase(0, 11));
-        assertTrue(LowestBasePalindrome.isPalindromicInBase(10101, 10));
-        assertTrue(LowestBasePalindrome.isPalindromicInBase(23, 22));
+    @ParameterizedTest
+    @MethodSource("provideNumbersAndBasesForExceptions")
+    public void testIsPalindromicInBaseThrowsException(int number, int base) {
+        org.junit.jupiter.api.Assertions.assertThrows(IllegalArgumentException.class, () -> LowestBasePalindrome.isPalindromicInBase(number, base));
     }
 
-    @Test
-    public void testIsPalindromicInBaseNegative() {
-        assertFalse(LowestBasePalindrome.isPalindromicInBase(1010, 10));
-        assertFalse(LowestBasePalindrome.isPalindromicInBase(123, 10));
+    @ParameterizedTest
+    @MethodSource("provideNumbersForLowestBasePalindrome")
+    public void testLowestBasePalindrome(int number, int expectedBase) {
+        assertEquals(expectedBase, LowestBasePalindrome.lowestBasePalindrome(number));
     }
 
-    @Test
-    public void testIsPalindromicInBaseThrowsExceptionForNegativeNumbers() {
-        assertThrows(IllegalArgumentException.class, () -> LowestBasePalindrome.isPalindromicInBase(-1, 5));
+    private static Stream<Arguments> provideListsForIsPalindromicPositive() {
+        return Stream.of(Arguments.of(new ArrayList<>()), Arguments.of(new ArrayList<>(List.of(1))), Arguments.of(new ArrayList<>(Arrays.asList(1, 1))), Arguments.of(new ArrayList<>(Arrays.asList(1, 2, 1))), Arguments.of(new ArrayList<>(Arrays.asList(1, 2, 2, 1))));
     }
 
-    @Test
-    public void testIsPalindromicInBaseThrowsExceptionForWrongBases() {
-        assertThrows(IllegalArgumentException.class, () -> LowestBasePalindrome.isPalindromicInBase(10, 1));
+    private static Stream<Arguments> provideListsForIsPalindromicNegative() {
+        return Stream.of(Arguments.of(new ArrayList<>(Arrays.asList(1, 2))), Arguments.of(new ArrayList<>(Arrays.asList(1, 2, 1, 1))));
     }
 
-    @Test
-    public void testLowestBasePalindrome() {
-        HashMap<Integer, Integer> testCases = new HashMap<>();
-        testCases.put(0, 2);
-        testCases.put(1, 2);
-        testCases.put(2, 3);
-        testCases.put(3, 2);
-        testCases.put(10, 3);
-        testCases.put(11, 10);
-        testCases.put(15, 2);
-        testCases.put(39, 12);
-        testCases.put(44, 10);
-        testCases.put(58, 28);
-        testCases.put(69, 22);
-        testCases.put(79, 78);
-        testCases.put(87, 28);
-        testCases.put(90, 14);
-        testCases.put(5591, 37);
-        testCases.put(5895, 130);
-        testCases.put(9950, 198);
-        testCases.put(9974, 4986);
+    private static Stream<Arguments> provideNumbersAndBasesForIsPalindromicInBasePositive() {
+        return Stream.of(Arguments.of(101, 10), Arguments.of(1, 190), Arguments.of(0, 11), Arguments.of(10101, 10), Arguments.of(23, 22));
+    }
+
+    private static Stream<Arguments> provideNumbersAndBasesForIsPalindromicInBaseNegative() {
+        return Stream.of(Arguments.of(1010, 10), Arguments.of(123, 10));
+    }
+
+    private static Stream<Arguments> provideNumbersAndBasesForExceptions() {
+        return Stream.of(Arguments.of(-1, 5), Arguments.of(10, 1));
+    }
 
-        for (final var tc : testCases.entrySet()) {
-            assertEquals(LowestBasePalindrome.lowestBasePalindrome(tc.getKey()), tc.getValue());
-        }
+    private static Stream<Arguments> provideNumbersForLowestBasePalindrome() {
+        return Stream.of(Arguments.of(0, 2), Arguments.of(1, 2), Arguments.of(2, 3), Arguments.of(3, 2), Arguments.of(10, 3), Arguments.of(11, 10), Arguments.of(15, 2), Arguments.of(39, 12), Arguments.of(44, 10), Arguments.of(58, 28), Arguments.of(69, 22), Arguments.of(79, 78), Arguments.of(87, 28),
+            Arguments.of(90, 14), Arguments.of(5591, 37), Arguments.of(5895, 130), Arguments.of(9950, 198), Arguments.of(9974, 4986));
     }
 }