Making ChatGPT do Clean Code

lluismf

Lluís Josep Martínez

Posted on October 26, 2023

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.

💖 💪 🙅 🚩
lluismf
Lluís Josep Martínez

Posted on October 26, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Making ChatGPT do Clean Code
chagpt Making ChatGPT do Clean Code

October 26, 2023