DEV Community

Lluís Josep Martínez
Lluís Josep Martínez

Posted on

Making ChatGPT do Clean Code

Just for fun, I asked chatGPT to give me a Java implementation of the sieve of Eratosthenes to find the first 100 prime numbers.
It gave me this:

public class SieveOfEratosthenes {
    public static void main(String[] args) {
        int n = 100; // Change this to the desired limit to find prime numbers up to n.
        boolean[] isPrime = new boolean[n + 1];

        Arrays.fill(isPrime, true);
        isPrime[0] = isPrime[1] = false;

        for (int p = 2; p * p <= n; p++) {
            if (isPrime[p]) {
                for (int i = p * p; i <= n; i += p) {
                    isPrime[i] = false;
                }
            }
        }

        System.out.println("Prime numbers up to " + n + ":");
        for (int i = 2; i <= n; i++) {
            if (isPrime[i]) {
                System.out.print(i + " ");
            }
        }
    }
} 
Enter fullscreen mode Exit fullscreen mode

So far so good. Now I asked for an implementation with lambdas. That pesky for loops are just too old.

public class SieveOfEratosthenesWithLambdas {
    public static void main(String[] args) {
        int n = 100; // Change this to the desired limit to find prime numbers up to n.

        List<Integer> primes = IntStream.rangeClosed(2, n)
            .boxed()
            .filter(SieveOfEratosthenesWithLambdas::isPrime)
            .collect(Collectors.toList());

        System.out.println("Prime numbers up to " + n + ":");
        primes.forEach(System.out::print);
    }

    static boolean isPrime(int number) {
        return IntStream.rangeClosed(2, (int) Math.sqrt(number))
            .allMatch(i -> number % i != 0);
    }
}
Enter fullscreen mode Exit fullscreen mode

Looks good. Compact and efficient.
Now it's when the fun starts. I ask for a "clean code" implementation, whatever that means. Here's the result:

public class SieveOfEratosthenesCleanCode {
    public static void main(String[] args) {
        int limit = 100; // Change this to the desired limit to find prime numbers up to 'limit'.
        List<Integer> primes = findPrimesUpTo(limit);

        System.out.println("Prime numbers up to " + limit + ":");
        for (int prime : primes) {
            System.out.print(prime + " ");
        }
    }

    public static List<Integer> findPrimesUpTo(int limit) {
        boolean[] isPrime = new boolean[limit + 1];
        List<Integer> primes = new ArrayList<>();

        // Initialize the array
        for (int i = 2; i <= limit; i++) {
            isPrime[i] = true;
        }

        // Sieve of Eratosthenes
        for (int p = 2; p * p <= limit; p++) {
            if (isPrime[p]) {
                for (int i = p * p; i <= limit; i += p) {
                    isPrime[i] = false;
                }
            }
        }

        // Collect the prime numbers
        for (int i = 2; i <= limit; i++) {
            if (isPrime[i]) {
                primes.add(i);
            }
        }

        return primes;
    }
}
Enter fullscreen mode Exit fullscreen mode

I don't think it's "clean" enough. Methods are too large. I ask for a "cleaner" version:

public class PrimeNumberFinder {
    public static void main(String[] args) {
        int upperLimit = 100; // Change this to the desired limit to find prime numbers up to 'upperLimit'.
        List<Integer> primeNumbers = findPrimeNumbers(upperLimit);

        displayPrimeNumbers(primeNumbers);
    }

    public static List<Integer> findPrimeNumbers(int upperLimit) {
        List<Integer> primeNumbers = new ArrayList<>();
        boolean[] isComposite = new boolean[upperLimit + 1];

        for (int number = 2; number * number <= upperLimit; number++) {
            if (!isComposite[number]) {
                for (int multiple = number * number; multiple <= upperLimit; multiple += number) {
                    isComposite[multiple] = true;
                }
            }
        }

        for (int number = 2; number <= upperLimit; number++) {
            if (!isComposite[number]) {
                primeNumbers.add(number);
            }
        }

        return primeNumbers;
    }

    public static void displayPrimeNumbers(List<Integer> primeNumbers) {
        System.out.println("Prime numbers found:");
        for (int prime : primeNumbers) {
            System.out.print(prime + " ");
        }
        System.out.println();
    }
}
Enter fullscreen mode Exit fullscreen mode

Methods are still too large. Refactor till you die.

public class PrimeNumberFinder {
    public static void main(String[] args) {
        int upperLimit = 100; // Change this to the desired limit to find prime numbers up to 'upperLimit'.
        List<Integer> primeNumbers = findPrimeNumbers(upperLimit);

        displayPrimeNumbers(primeNumbers);
    }

    public static List<Integer> findPrimeNumbers(int upperLimit) {
        boolean[] isComposite = new boolean[upperLimit + 1];
        sieveOfEratosthenes(isComposite, upperLimit);
        return collectPrimes(isComposite);
    }

    private static void sieveOfEratosthenes(boolean[] isComposite, int upperLimit) {
        for (int number = 2; number * number <= upperLimit; number++) {
            if (!isComposite[number]) {
                markMultiplesAsComposite(isComposite, number, upperLimit);
            }
        }
    }

    private static void markMultiplesAsComposite(boolean[] isComposite, int number, int upperLimit) {
        for (int multiple = number * number; multiple <= upperLimit; multiple += number) {
            isComposite[multiple] = true;
        }
    }

    private static List<Integer> collectPrimes(boolean[] isComposite) {
        List<Integer> primeNumbers = new ArrayList<>();
        for (int number = 2; number < isComposite.length; number++) {
            if (!isComposite[number]) {
                primeNumbers.add(number);
            }
        }
        return primeNumbers;
    }

    public static void displayPrimeNumbers(List<Integer> primeNumbers) {
        System.out.println("Prime numbers found:");
        for (int prime : primeNumbers) {
            System.out.print(prime + " ");
        }
        System.out.println();
    }
}
Enter fullscreen mode Exit fullscreen mode

Well, that's it! A perfectly good algorithm has been "cleaned" until it is an incomprehensible garbage that needs much more cognitive load to understand than the original version.
Thanks Clean Code!

PS: the version in the book is even worse.

Top comments (0)