import java.util.Iterator; /* Taxman.java ** An instance of this class represents the state of a game of Taxman, a ** solitaire game in which the player tries to "earn" more income than ** what must be "paid" in taxes. ** ** For some positive integer N chosen at the beginning of the game, each ** integer in the range [1..N] eventually is earned as income or is paid ** in taxes. ** ** A number is referred to as being "active" if it has not yet been earned ** as income or paid in taxes. The game begins with all the numbers in the ** range [1..N] being active. On each turn, the player chooses an active ** number k that has at least one proper divisor that is also active. As a ** result of that choice, k is credited to the player as income and all its ** active proper divisors are paid as taxes. All these proper divisors, as ** well as k itself, become inactive. ** ** At such time that there remain no active numbers that have an active ** proper divisor, all remaining active numbers are paid as residual taxes ** and the game comes to an end. */ public class Taxman { // instance variables // ------------------ private final int N; // Initial range of active #'s is [1..N] private SetOfInt activeNumSet; // set of numbers that are still active private SetOfInt incomeSet; // set of numbers earned as income private SetOfInt taxSet; // set of numbers paid as taxes // class invariant: // --the union of activeNumSet, incomeSet, and taxSet is [1..N] // --activeNumSet, incomeSet, and taxSet are paireise disjoint // (i.e., no two of them have any common members) // constructor // ----------- /* Establishes this Taxman game so that all integers in the range ** [1..N] are active, no income has been earned, and no taxes paid. */ public Taxman(int n) { N = n; activeNumSet = new SetOfInt(); for (int i = 1; i <= N; i++) { activeNumSet.insert(i); } incomeSet = new SetOfInt(); taxSet = new SetOfInt(); } // observers // --------- /* Returns how much income has been earned. */ public int incomeEarned() { return -1; } // STUB /* Returns how much has been paid in taxes. */ public int taxesPaid() { return -1; } // STUB /* Returns a string showing which numbers are still active. */ public String activeNumbersImage() { return activeNumSet.toString(); } /* Returns a string showing which numbers were earned as income. */ public String incomesImage() { return incomeSet.toString(); } /* Returns a string showing which numbers were paid in taxes. */ public String taxesImage() { return taxSet.toString(); } /* Reports whether the given number can be chosen to be added to ** the player's income, which requires that it be active and that ** at least one of its proper divisors is active. */ public boolean isLegalChoice(int k) { return false; // STUB } /* Reports whether there are any numbers that can be chosen by a ** player to add as income. Such a number must be both active and ** have at least one proper divisor that is active. */ public boolean hasLegalChoices() { return false; // STUB } // mutators // -------- /* Updates the state of this game to reflect that the given number k ** has been chosen as income and, as a consequence, all its active proper ** divisors have been paid in taxes. Also, k and all those divisors ** have become inactive. ** pre: isLegalChoice(k) */ public void chooseAsIncome(int k) { // STUB } /* Updates the state of the game to reflect that all remaining active ** numbers have been paid as taxes and have become inactive. */ public void payResidualTaxes() { // STUB } // private // ------- /* Returns the sum of the members of the given set. */ private int sumOf(SetOfInt s) { int sumSoFar = 0; Iterator iter = s.iterator(); while (iter.hasNext()) { sumSoFar = sumSoFar + iter.next(); } return sumSoFar; } /* Returns the set consisting of the proper divisors of the given ** postive integer k, meaning the set of integers in the range [1..k) ** that are divisors of k. ** pre: k > 1 */ private SetOfInt properDivisorsOf(int k) { SetOfInt result = new SetOfInt(); result.insert(1); final int sqrtOfK = (int)(Math.sqrt(k)); for (int i = 2; i <= sqrtOfK; i++) { if (k % i == 0) { result.insert(i); result.insert(k/i); } } return result; } }