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

Fibonacci forever

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

Problem

I recently wrote a Fibonacci program in Python, and one of the answers mentioned an Infinite Sequence. I decided to implement an infinite sequence in Java, as I am not that experienced in Python.

import java.math.BigInteger;
import java.util.LinkedList;
import java.util.List;

public class InfiniteFibonacci {

    /**
     * The default starting amount of numbers in the sequence to be generated.
     */
    public static final int DEFAULT_STARTING_CAP = 64;

    private List parts;

    private int currentSize = 2;

    private BigInteger current = BigInteger.ONE;
    private BigInteger previous = BigInteger.ONE;

    /**
     * Creates a new InfiniteFibonacci object, with the default amount of numbers.
     */
    public InfiniteFibonacci() {
        this(DEFAULT_STARTING_CAP);
    }

    /**
     * Creates a new InfiniteFibonacci object, with the specified amount of numbers.
     * 
     * @param startCap The amount of numbers to generate. It will be rounded up to the nearest 16.
     */
    public InfiniteFibonacci(int startCap) {
        parts = new LinkedList<>();
        initFirst();
        initTo(startCap);
    }

    private void initFirst() {
        SequencePart part = new SequencePart();
        part.values[0] = previous;
        part.values[1] = current;
        for (int i = 2; i nth number in the sequence, zero-based.
     * 
     * @param index the n as described
     * 
     * @return the specified in the sequence, zero-based.
     */
    public BigInteger getNumberAt(int index) {
        if (index > currentSize) {
            initTo(index);
        }
        return parts.get(index / SequencePart.SIZE).values[index % SequencePart.SIZE];
    }

    private class SequencePart {

        private static final int SIZE = 16;

        private BigInteger[] values = new BigInteger[SIZE];

        private SequencePart() {

        }

    }

}


Concerns:

  • I don't like the initFirst() method, as it is very WET. Is there a way to avoid it?



  • Is my

Solution

I'm not sure if SequencePart is necessary.

It would be much simpler to just keep a List of numbers in InfiniteFibonacci, unless you've already done the testing to see if your chunked LinkedList is faster than a plain ArrayList.

You would end up with something like this:

public BigInteger getNth(int index) {
    if (index >= nums.size()) {
        initTo(index);
    }
    return nums[index];
}


with no initFirst and with a much simpler initTo(index) method that just appends to this.nums until index.

Edit: OK, sorry, I realize why you're doing this chunking strategy (cheap insertion at the end of a LinkedList). I think it depends on your intended use case, and how often users will request arbitrary Fibs. I would still suggest testing tweaking the size of your SequenceParts to see if 16 is the optimum size for your intended usage.

Iterator

Since this is an infinite sequence, I would also suggest exposing an iterator interface that doesn't maintain a cache. If a caller only needs the numbers once, then you can let them iterate through Fibonacci numbers infinitely using constant space, as opposed to building up your internal list of calculated numbers.

Code Snippets

public BigInteger getNth(int index) {
    if (index >= nums.size()) {
        initTo(index);
    }
    return nums[index];
}

Context

StackExchange Code Review Q#114501, answer score: 7

Revisions (0)

No revisions yet.