2
\$\begingroup\$

Purpose

This question comes from a HackerRank problem called Fibonacci Modified. I think I have coded a valid solution, but would like feedback about my approach, implementation, and of course, any errors / edge cases that I may have missed.

Task

enter image description here

Implementation

public class FibonacciModifiedImpl implements FibonacciModified {

    @Override
    public BigInteger calculateNextTerm(final BigInteger currentTerm, final BigInteger lastTerm) {
        if (-1 == lastTerm.compareTo(BigInteger.ZERO) ) {
            throw new IllegalArgumentException("last term must be non-negative");
        }

        if (-1 == currentTerm.compareTo(lastTerm)) {
            throw new IllegalArgumentException("current term must be greater than or equal to last term");
        }

        final BigInteger squaredTerm = new BigDecimal(Math.pow(currentTerm.doubleValue(), 2)).toBigInteger();
        return squaredTerm.add(lastTerm);
    }

    @Override
    public BigInteger calculateNthTerm(final BigInteger firstTerm, final BigInteger secondTerm, final int n) {
        if (-1 == firstTerm.compareTo(BigInteger.ZERO) ) {
            throw new IllegalArgumentException("first term must be non-negative");
        }

        if (-1 == secondTerm.compareTo(firstTerm)) {
            throw new IllegalArgumentException("second term must be greater than or equal to last term");
        }

        if (n < 1) {
            throw new IllegalArgumentException("number of terms must be greater than 0");
        }

        switch (n) {
            case 1: {
                return firstTerm;
            }

            case 2: {
                return secondTerm;
            }

            default: {
                int counter = 2;
                BigInteger currentTerm = secondTerm;
                BigInteger lastTerm = firstTerm;
                while (counter < n) {
                    BigInteger nextTerm = calculateNextTerm(currentTerm, lastTerm);
                    lastTerm = currentTerm;
                    currentTerm = nextTerm;
                    counter++;
                }

                return currentTerm;
            }
        }
    }
}
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

Generally looks good. Except

    final BigInteger squaredTerm = new BigDecimal(Math.pow(currentTerm.doubleValue(), 2)).toBigInteger();

There is absolutely no reason to cast Math in. The computations are supposed to be exact, which Math is notoriously lacking. I recommend

    final BigInteger squaredTerm = currentTerm.multiply(currentTerm);
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.