HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaModerate

TDD for Euler Problem #4

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
problemtddforeuler

Problem

I am in the process of learning Java and going through the Euler problems. For Problem 4 I decided to also implement a TDD approach with JUnit.

My questions are:

  • Is there a better TDD approach to this problem?



  • I wrote out all these test cases initially. Some obviously pass and some fail initially because I'm checking a boolean. This makes it impossible to write a failing test in this fashion, should I have written only a failing scenario (say test100), then added in more as my method worked?



  • Being new to Java, are there obvious code organization things I am missing?



  • Any naming tips would be appreciated as well as I am terrible at this generally!



I have three source files:

main.java

public class main {

    public static void main(String[] args) {

        PalindromeChecker p = new PalindromeChecker();
        int largest=0;
        int product;

        for (int i = 999; i>100; i--){

            for (int j = 999; j>100; j--){
                product = i*j;
                if (p.isPalindrome(product) && product > largest) {
                    largest = product;
                }
            }
        }
        System.out.println(largest);
    }
}


PalindromeChecker.java

public class PalindromeChecker {

    public boolean isPalindrome(int input){

        String str = new Integer(input).toString();
        int len = str.length();

        for(int i = 0; i < Math.ceil(len/2.0); i++){

            if (str.charAt(i) != str.charAt(len-i-1)) {
                return false;
            }
        }

        return true;

    }
}


PalindromeCheckerTest.java

```
import static org.junit.Assert.*;
import org.junit.Test;

public class PalindromeCheckerTest {

@Test
public void test10() {
PalindromeChecker checker = new PalindromeChecker();
assertFalse("10 failed",checker.isPalindrome(10));
}
@Test
public void test112() {
PalindromeChecker checker = new PalindromeChecker();
assertFalse("112 f

Solution

First of all, your PalindromeChecker does not contain any state, it is a simple input --> output operation not depending on outer factors. This makes it an ideal candidate for being a static method.

Your naming is okay overall, but I would use the name Palindromes for your class.

String str = new Integer(input).toString();


It is better to use String.valueOf here. There's no need to create an Integer object.

for (int j = 999; j>100; j--){


Technically, you're off by one here. You're missing the case when j == 100, which is also a three-digit number (the same goes for i btw).

Correct would be (also with improved spacing)

for (int j = 999; j >= 100; j--) {


So, here's how I would make your class:

public class Palindromes {

    public static boolean isPalindrome(int input) {
        String str = String.valueOf(input);
        int len = str.length();

        for(int i = 0; i < Math.ceil(len/2.0); i++) {
            if (str.charAt(i) != str.charAt(len - i - 1)) {
                return false;
            }
        }
        return true;
    }

}


All your test cases contains pretty much the same code, but with different parameters.

With the change to a static method, the test cases will look more like:

assertFalse("10 failed", Palindromes.isPalindrome(10));


This is ideal for a Parameterized test, which will make it significantly easier to add more tests.

@RunWith(Parameterized.class)
public class PalindromeTest {
    @Parameters
    public static Collection data() {
        return Arrays.asList(new Object[][] {     
                 { 10, false },
                 { 100, false },
                 { 909, true },
                 ...
           });
    }

    private final int input;

    private final boolean expectedPalindrome;

    public PalindromeTest(int input, boolean expectedPalindrome) {
        this.input = input;
        this.expectedPalindrome = expectedPalindrome;
    }

    @Test
    public void test() {
        assertEquals("Failed for " + input,
            expectedPalindrome, Palindromes.isPalindrome(input));
    }
}

Code Snippets

String str = new Integer(input).toString();
for (int j = 999; j>100; j--){
for (int j = 999; j >= 100; j--) {
public class Palindromes {

    public static boolean isPalindrome(int input) {
        String str = String.valueOf(input);
        int len = str.length();

        for(int i = 0; i < Math.ceil(len/2.0); i++) {
            if (str.charAt(i) != str.charAt(len - i - 1)) {
                return false;
            }
        }
        return true;
    }

}
assertFalse("10 failed", Palindromes.isPalindrome(10));

Context

StackExchange Code Review Q#82840, answer score: 10

Revisions (0)

No revisions yet.