001 /**
002 * We designed this class in lecture. A Russian doll is an object
003 * that contains another Russian doll. There is a special Russian
004 * doll called ZERO that contains itself. Our public methods do
005 * not allow the user to construct any other dolls that are nested
006 * inside themselves.<p>
007 *
008 * Russian dolls can be used to represent integers without actually
009 * using Java's integer class. ZERO represents 0, a doll that
010 * contains ZERO represents 1, a doll that contains 1 represents 2,
011 * etc.<p>
012 *
013 * Notice that there may be many different dolls that represent a
014 * number such as 5. In other words, even if rd1 and rd2 are both
015 * dolls that represent 5, there is no guarantee that rd1 == rd2.
016 * They might be different objects in memory.<p>
017 *
018 * @author Jason Eisner
019 * @author YOUR NAME HERE
020 * @version 0.5 (you should update this to 1.0 when you're done)
021 */
022
023 public class RussianDoll {
024
025 // We'll organize the code for the class in the order suggested
026 // in section 1.9.2 of the textbook, page 47.
027
028 // ************** CONSTANTS ***************
029
030 /** The special doll representing ZERO. */
031
032 public static final RussianDoll ZERO = new RussianDoll();
033
034 // ************** INSTANCE VARIABLES ***************
035
036 /** Contains the next doll in, or in the special case of ZERO,
037 * contains this doll itself.
038 */
039
040 private RussianDoll inner;
041
042 // ************** CONSTRUCTORS ***************
043
044 /** The usual constructor. Wraps a new doll around an existing one. */
045
046 private RussianDoll(RussianDoll rd) {
047 inner = rd;
048 }
049
050 /** A special constructor returning a cyclic doll. Used only by ZERO. */
051 private RussianDoll() {
052 inner = this;
053 }
054
055 // ************** BASIC METHODS ***************
056
057 /** Subtracts one. Special case: When applied to ZERO, returns ZERO.
058 * @return The inner Russian doll, or ZERO.
059 */
060
061 public RussianDoll smaller() {
062 return inner;
063 }
064
065 /** Adds one.
066 * @return A newly created, bigger Russian doll that contains the old one.
067 */
068
069 public RussianDoll bigger() {
070 return new RussianDoll(this);
071 }
072
073 /** Converts to a string representing a Peano integer: "0", "S0", "SS0", etc.
074 * The letter "S" stands for "successor," but in the case of Russian dolls,
075 * it could stand for "surrounds": S0 is a doll that surrounds 0.
076 * SS0 is a doll that surrounds S0, etc.
077 */
078
079 public String toString() {
080 if (this == ZERO)
081 return "0";
082 else
083 return "S" + inner.toString();
084 }
085
086 // ************** TYPE CONVERSIONS ***************
087 // this would be a good place to put longValue and valueOf
088
089 // ************** INSTRUMENTATION METHODS ***************
090 // this would be a good place to put newWork and newSpace
091
092 // ************** COMPARISON METHODS ***************
093 // this would be a good place to put equals and compareTo
094
095 // ************** ARITHMETIC METHODS ***************
096
097 /** Implements {@link Numeric#add(Numeric)}. */
098 public RussianDoll add(RussianDoll val) {
099 if (this==ZERO)
100 return val; // 0+val == val
101 else
102 return smaller().add(val.bigger());
103
104 /* If you have trouble understanding the above line,
105 * it is equivalent to the following:
106 *
107 * RussianDoll rdThisMinusOne = smaller();
108 * RussianDoll rdValPlusOne = val.bigger();
109 * return rdThisMinusOne.add(rdValPlusOne);
110 *
111 * So we are taking advantage of the fact
112 * that a+b == (a-1)+(b+1) for any a > 0.
113 * We keep recursing using this formula,
114 * counting downward with a
115 * while we count upward with b.
116 */
117 }
118
119 // ************** TEST METHODS ***************
120
121 /** A test method of your choice; do whatever you want
122 * here. See also {@link NumericTest}.
123 */
124
125 public static void main(String args[]) {
126 System.out.println("Zero : " + ZERO);
127 System.out.println("Zero ++ ++ ++ -- ++ : "
128 + ZERO.bigger().bigger().bigger().smaller().bigger());
129 System.out.println("Zero ++ -- -- ++ : "
130 + ZERO.bigger().smaller().smaller().bigger());
131
132 RussianDoll rdThree = ZERO.bigger().bigger().bigger();
133
134 RussianDoll rdFour = ZERO.bigger().bigger().bigger().bigger();
135 System.out.println("Three : " + rdThree);
136 System.out.println("Four : " + rdFour);
137
138 System.out.println("Three + Four (instance method) : "
139 + rdThree.add(rdFour));
140 }
141 }