Collatz conjecture code

[Download Collatz.java]

// A simple example of a "state-ful" class. Instances of `class Collatz`
// represent the current state of the "3n+1 game" --- on each turn, divide your
// number by 2 if it's even, or multiply it by 3 then add one if it's odd, and
// see how many turns it takes to reach 1.
//
// (Of course, this isn't really much of a *game*. I'm talking about it as if it
// were a game because we wrote this code in discussion as practice for the
// MatchCardGame code. The common idea is that both the card game and the 3n+1
// "game" have relatively simple, turn-based rules, and part of the "fun" is
// seeing how many turns it takes to finish.)
//
// (On that note, this problem --- called the Collatz conjecture or the 3n+1
// problem --- is an open problem in mathematics. We don't currently know
// whether you'll always end up at 1; it's possible that for some huge starting
// number n, you'll find a different cycle (for example, if you start at -5,
// you'll never get to 1; the conjecture is about whether or not you're
// guaranteed to reach 1 for any positive starting integer.)

// How this problem might be stated:
//
// > Design a class that represents the state of the Collatz conjecture "game".
// > Write a "nice" printing function to print the current state of the "game",
// > a function to advance one "turn", and the whatever other methods make
// > sense. Then, write a main() function to run the Collatz code.

public class Collatz {
    // Create a Collatz object that will start counting from n.
    // If n is any positive 32-bit integer, this will eventually reach 1 (or
    // overflow).
    public Collatz(int n) {
        currNum = n;
        currStep = 0;
    }

    // Return a human-friendly representation of the "game board". For this
    // class, that means the current number and current step counter.
    public String print() {
        return "Step " + currStep + ": " + currNum;
    }

    // Play one "turn" of the "game", i.e. apply the Collatz rule to advance
    // the sequence.
    public void advance() {
        // '%' is the modulus (or remainder) operator.
        // So, for example, 10 % 3 == 1, because 10 divided by 3
        // is 3 with remainder 1.
        if (currNum % 2 == 0) {
            // If the current number is even...
            currNum /= 2;
        } else {
            // If the current number is odd...
            currNum = (currNum * 3) + 1;
        }
        currStep++;
    }

    // Test whether this cycle has ended, i.e. whether we've reached 1 yet.
    // Note: this is broken for negative integers, but those are outside of
    // our scope.
    public boolean isEnded() {
        return currNum == 1;
    }

    // Return the current number from the sequence.
    public int currStep() {
        return currStep;
    }

    // Return the current value of the step counter.
    public int currNum() {
        return currNum;
    }

    public static void main(String[] args) {
        System.out.println("Enter starting number:");
        java.util.Scanner reader = new java.util.Scanner (System.in);
        int n = reader.nextInt();

        if (n >= 1) {
            Collatz collatz = new Collatz(n);
            while (!collatz.isEnded()) {
                System.out.println(collatz.print());
                collatz.advance();
            }
            System.out.println("Finished in " + collatz.currStep()
                    + " steps.");
        }
    }

    private int currStep;
    private int currNum;
}