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    }