# 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;
}