commit 524510999f0703c35c5129bbea9d9b1435255b72 Author: Michael Zhang Date: Mon Jan 29 17:37:09 2018 -0600 f diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6b468b6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.class diff --git a/lab1.py b/lab1.py new file mode 100644 index 0000000..5c48cbd --- /dev/null +++ b/lab1.py @@ -0,0 +1,99 @@ +def isInside(v, e): + if type(e) is str: + return v == e + elif type(e) is tuple: + if isInside(v, e[0]) or isInside(v, e[2]): return True + return False + +def solve(v, q): + if isInside(v, q[0]): return solving(v, q) + elif isInside(v, q[2]): return solving(v, q[::-1]) + else: return None + +def solvingAdd(v, q): + if isInside(v, q[0][0]): + return solving(v, (q[0][0], '=', (q[2], '-', q[0][2]))) + elif isInside(v, q[0][2]): + return solving(v, (q[0][2], '=', (q[2], '-', q[0][0]))) + +def solvingSubtract(v, q): + if isInside(v, q[0][0]): + return solving(v, (q[0][0], '=', (q[2], '+', q[0][2]))) + elif isInside(v, q[0][2]): + return solving(v, (q[0][2], '=', (q[0][0], '-', q[2]))) + +def solvingMultiply(v, q): + if isInside(v, q[0][0]): + return solving(v, (q[0][0], '=', (q[2], '/', q[0][2]))) + elif isInside(v, q[0][2]): + return solving(v, (q[0][2], '=', (q[2], '/', q[0][0]))) + +def solvingDivide(v, q): + if isInside(v, q[0][0]): + return solving(v, (q[0][0], '=', (q[2], '*', q[0][2]))) + elif isInside(v, q[0][2]): + return solving(v, (q[0][2], '=', (q[0][0], '/', q[2]))) + +def solving(v, q): + assert isInside(v, q[0]) + if v == q[0]: + return q + else: + return { + '+': solvingAdd, + '-': solvingSubtract, + '*': solvingMultiply, + '/': solvingDivide + }[q[0][1]](v, q) + +# +# TESTS. Test the equation solver for CSci 1913 Lab 1. +# +# James B. Moen +# 12 Sep 16 +# + +# Each PRINT is followed by a comment that shows what must be printed if your +# program works correctly. + +print(isInside('x', 'x')) # True +print(isInside('x', 'y')) # False +print(isInside('x', ('x', '+', 'y'))) # True +print(isInside('x', ('a', '+', 'b'))) # False +print(isInside('x', (('m', '*', 'x'), '+', 'b'))) # True + +print(solve('x', (('a', '+', 'x'), '=', 'c'))) # ('x', '=', ('c', '-', 'a')) +print(solve('x', (('x', '+', 'b'), '=', 'c'))) # ('x', '=', ('c', '-', 'b')) + +print(solve('x', (('a', '-', 'x'), '=', 'c'))) # ('x', '=', ('a', '-', 'c')) +print(solve('x', (('x', '-', 'b'), '=', 'c'))) # ('x', '=', ('c', '+', 'b')) + +print(solve('x', (('a', '*', 'x'), '=', 'c'))) # ('x', '=', ('c', '/', 'a')) +print(solve('x', (('x', '*', 'b'), '=', 'c'))) # ('x', '=', ('c', '/', 'b')) + +print(solve('x', (('a', '/', 'x'), '=', 'c'))) # ('x', '=', ('a', '/', 'c')) +print(solve('x', (('x', '/', 'b'), '=', 'c'))) # ('x', '=', ('c', '*', 'b')) + +print(solve('x', ('y', '=', (('m', '*', 'x'), '+', 'b')))) # ('x', '=', (('y', '-', 'b'), '/', 'm') + +# custom case +print(solve('x', (('a', '+', 'b'), '=', ('w', '-', ('x', '*', ('y', '/', 'z')))))) + +''' +Results: +True +False +True +False +True +('x', '=', ('c', '-', 'a')) +('x', '=', ('c', '-', 'b')) +('x', '=', ('a', '-', 'c')) +('x', '=', ('c', '+', 'b')) +('x', '=', ('c', '/', 'a')) +('x', '=', ('c', '/', 'b')) +('x', '=', ('a', '/', 'c')) +('x', '=', ('c', '*', 'b')) +('x', '=', (('y', '-', 'b'), '/', 'm')) +('x', '=', (('w', '-', ('a', '+', 'b')), '/', ('y', '/', 'z'))) +''' \ No newline at end of file diff --git a/lab10.java b/lab10.java new file mode 100644 index 0000000..a932e18 --- /dev/null +++ b/lab10.java @@ -0,0 +1,128 @@ +// ARRAY QUEUE. A fixed length queue implemented as a circular array. + +class ArrayQueue { + private int front; // Index of front object in OBJECTS. + private int rear; // Index obf rear object in OBJECTS. + private Base[] objects; // The objects in the queue. + + public class Iterator { + private ArrayQueue parent; + private int position; + public Iterator(ArrayQueue parent) { + this.parent = parent; + this.position = 0; + } + public boolean hasNext() { + int _rear = parent.rear - parent.front; + if (_rear < 0) _rear += parent.objects.length; + return this.position < _rear; + } + public Base next() { + return parent.objects[(parent.front + ++this.position) % parent.objects.length]; + } + } + + public Iterator iterator() { + return new Iterator(this); + } + + // Constructor. Make a new empty queue that can hold SIZE - 1 elements. + + public ArrayQueue(int size) { + if (size >= 1) { + front = 0; + rear = 0; + objects = (Base[]) new Object[size]; + } else { + throw new IllegalArgumentException("Size must be at least one."); + } + } + + // IS EMPTY. Test if the queue is empty. + + public boolean isEmpty() { + return front == rear; + } + + // IS FULL. Test if the queue can hold no more elements. + + public boolean isFull() { + return front == (rear + 1) % objects.length; + } + + // ENQUEUE. Add OBJECT to the rear of the queue. + + public void enqueue(Base object) { + int nextRear = (rear + 1) % objects.length; + if (front == nextRear) { + throw new IllegalStateException("Queue is full."); + } else { + rear = nextRear; + objects[rear] = object; + } + } + + // DEQUEUE. Remove an object from the front of the queue and return it. + + public Base dequeue() { + if (isEmpty()) { + throw new IllegalStateException("Queue is empty."); + } else { + front = (front + 1) % objects.length; + Base temp = objects[front]; + objects[front] = null; + return temp; + } + } +} + +class lab10 { + + // MAIN. Start execution here. + + public static void main(String[] args) { + + // Make an ARRAY QUEUE and enqueue some things. + + ArrayQueue queue = new ArrayQueue(5); + queue.enqueue("A"); + queue.enqueue("B"); + queue.enqueue("C"); + + // Make an ITERATOR for QUEUE. + + ArrayQueue.Iterator first = queue.iterator(); + while (first.hasNext()) { + System.out.println(first.next()); // Print A B C, one per line. + } + + // The iterator hasn’t changed QUEUE!. + + System.out.println(queue.isEmpty()); // Print false + System.out.println(queue.dequeue()); // Print A + System.out.println(queue.dequeue()); // Print B + System.out.println(queue.dequeue()); // Print C + System.out.println(queue.isEmpty()); // Print true + + // Let’s enqueue more things to QUEUE. + + queue.enqueue("X"); + queue.enqueue("Y"); + queue.enqueue("Z"); + + // Now make a SECOND ITERATOR for QUEUE. The FIRST one won’t work any more. + + ArrayQueue.Iterator second = queue.iterator(); + while (second.hasNext()) { + System.out.println(second.next()); // Print X Y Z, one per line. + } + + // The SECOND iterator hasn’t changed QUEUE either! + + System.out.println(queue.isEmpty()); // Print false + System.out.println(queue.dequeue()); // Print X + System.out.println(queue.dequeue()); // Print Y + System.out.println(queue.dequeue()); // Print Z + System.out.println(queue.isEmpty()); // Print true + } +} \ No newline at end of file diff --git a/lab11.java b/lab11.java new file mode 100644 index 0000000..e908c0f --- /dev/null +++ b/lab11.java @@ -0,0 +1,95 @@ +class AssociationList { + class Node { + private Key key; + private Value value; + private Node next; + public Node(Key key, Value value, Node next) { + this.key = key; + this.value = value; + this.next = next; + } + } + private Node head; + public AssociationList() { + head = new Node(null, null, null); + } + public Value get(Key key) { + Node search = head.next; + while (search != null) { + if (search.key.equals(key)) { + return search.value; + } + search = search.next; + } + throw new IllegalArgumentException("Key not found."); + } + public boolean isEmpty() { + return head.next == null; + } + public void put(Key key, Value value) { + if (key == null) + throw new IllegalArgumentException("Key is null."); + Node search = head.next; + while (search != null) { + if (search.key.equals(key)) { + search.value = value; + return; + } + search = search.next; + } + Node newNode = new Node(key, value, head.next); + head.next = newNode; + } + public void remove(Key key) { + Node search = head; + while (search.next != null) { + if (search.next.key.equals(key)) { + search.next = search.next.next; + return; + } + search = search.next; + } + } +} + +class SmallMediumLarge +{ + public static void main(String [] args) + { + AssociationList a = new AssociationList(); + + a.put("small", 0); + a.put("medium", 1); + a.put("large", 2); + + System.out.println(a.get("small")); // 0 + System.out.println(a.get("medium")); // 1 + System.out.println(a.get("large")); // 2 + + a.put("large", 1000); + + System.out.println(a.get("small")); // 0 + System.out.println(a.get("medium")); // 1 + System.out.println(a.get("large")); // 1000 + + a.remove("large"); + + System.out.println(a.get("small")); // 0 + System.out.println(a.get("medium")); // 1 + System.out.println(a.get("large")); // Throw an exception. + } +} + +/* +0 +1 +2 +0 +1 +1000 +0 +1 +Exception in thread "main" java.lang.IllegalArgumentException: Key not found. + at AssociationList.get(SmallMediumLarge.java:24) + at SmallMediumLarge.main(SmallMediumLarge.java:79) +*/ \ No newline at end of file diff --git a/lab2.py b/lab2.py new file mode 100644 index 0000000..6128ef4 --- /dev/null +++ b/lab2.py @@ -0,0 +1,34 @@ +class Zillion(object): + def __init__(self, digits): + if any([c not in "012456789, " for c in digits]): raise RuntimeError("Contains invalid characters.") + self.digits = [int(c) for c in digits if c.isdigit()] + if not self.digits: raise RuntimeError("Contains no digits.") + def increment(self): + pos = len(self.digits) + while True: + pos -= 1 + self.digits[pos] += 1 + if self.digits[pos] == 10: + if pos == 0: + self.digits = [1, 0] + self.digits[1:] + break + self.digits[pos] = 0 + else: break + def isZero(self): + return all([d == 0 for d in self.digits]) + def __str__(self): + """ + In Python, it's customary to use the __str__ operator overloader to overload the str() + function, rather than using a toString() function, which is common in languages that + don't support operator overloading, such as Java. + + See https://docs.python.org/2/reference/datamodel.html#object.__str__ for more details. + """ + return "".join(map(str, self.digits)) + def toString(self): + return str(self) + +z = Zillion('9') +print z.isZero() +z.increment() +print z, z.digits \ No newline at end of file diff --git a/lab3.py b/lab3.py new file mode 100644 index 0000000..d8b82d2 --- /dev/null +++ b/lab3.py @@ -0,0 +1,32 @@ +class Sieve(object): + def __init__(self, max): + if max < 0: + raise ValueError("max must be positive.") + self.numbers = [False, False] + [True] * (max - 2) + def findPrimes(self): + for i, v in enumerate(self.numbers): + if not v: + continue + for j in range(2 * i, len(self.numbers), i): + self.numbers[j] = False + def howMany(self): + return reduce(lambda i, v: i + (1 if v else 0), self.numbers) + def toList(self): + return [i for i, v in enumerate(self.numbers) if v] + +try: + S = Sieve(-10) +except: + print "Failed!" + +S = Sieve(100) +print S.howMany() # 98 +print S.findPrimes() +print S.howMany() # 25 +print S.toList() # [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97] + +S = Sieve(1000) +print S.howMany() # 98 +print S.findPrimes() +print S.howMany() # 25 +print S.toList() # [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97] \ No newline at end of file diff --git a/lab4.java b/lab4.java new file mode 100644 index 0000000..a775ce8 --- /dev/null +++ b/lab4.java @@ -0,0 +1,46 @@ +class Zillion { + int[] digits; + public Zillion(int size) { + this.digits = new int[size]; + } + public void increment() { + int position = this.digits.length; + while (true) { + position -= 1; + this.digits[position] += 1; + if (this.digits[position] == 10) { + this.digits[position] = 0; + if (position == 0) { + break; + } + } else { + break; + } + } + } + @Override + public String toString() { + String result = ""; + for (int digit : this.digits) { + result += digit; + } + return result; + } +} + +public class Main { + public static void main(String[] args) { + Zillion z = new Zillion(3); + for (int i = 0; i < 999; i += 1) { + z.increment(); + } + System.out.println(z); + z.increment(); + System.out.println(z); + /* + Output: + 999 + 000 + */ + } +} \ No newline at end of file diff --git a/lab5.java b/lab5.java new file mode 100644 index 0000000..45c3416 --- /dev/null +++ b/lab5.java @@ -0,0 +1,62 @@ +class Pathname { + private int depth; + private String[] directories; + private String name; + private String type; + public Pathname(String name) { + this(name, ""); + } + public Pathname(String name, String type) { + this.depth = 0; + this.directories = new String[10]; + this.type = type; + this.name = name; + } + public void addDirectory(String directory) { + if (this.depth >= 10) return; + this.directories[this.depth++] = directory; + } + public boolean equals(Pathname other) { + if (this.depth != other.depth) return false; + for (int i = 0; i < this.depth; i += 1) { + if (this.directories[i] != other.directories[i]) return false; + } + return true; + } + public String toString() { + String result = ""; + for (int i = 0; i < this.depth; i += 1) { + result += "/" + this.directories[i]; + } + result += "/" + this.name; + if (this.type != "") { + result += "." + this.type; + } + return result; + } +} + +class Pathfinder +{ + public static void main(String [] args) + { + Pathname p0 = new Pathname("coffee", "java"); + p0.addDirectory("home"); + p0.addDirectory("Desktop"); + p0.addDirectory("labs"); + System.out.println(p0); // Prints /home/Desktop/labs/coffee.java + + Pathname p1 = new Pathname("cola"); + p1.addDirectory("home"); + p1.addDirectory("hax"); + System.out.println(p1); // Prints /home/hax/cola + + Pathname p2 = new Pathname("tea"); + System.out.println(p2); // Prints /tea + + System.out.println(p0.equals(p0)); // Prints true + System.out.println(p0.equals(p1)); // Prints false + System.out.println(p1.equals(p2)); // Prints false + System.out.println(p0.equals("Not a pathname")); // Prints false + } +} \ No newline at end of file diff --git a/lab6.java b/lab6.java new file mode 100644 index 0000000..dc64f04 --- /dev/null +++ b/lab6.java @@ -0,0 +1,59 @@ +class Polygon { + private int[] sideLengths; + + public Polygon(int sides, int...lengths) { + int index = 0; + sideLengths = new int[sides]; + for (int length: lengths) { + sideLengths[index] = length; + index += 1; + } + } + + public int side(int number) { + return sideLengths[number]; + } + + public int perimeter() { + int total = 0; + for (int index = 0; index < sideLengths.length; index += 1) { + total += side(index); + } + return total; + } +} + +class Rectangle extends Polygon { + private int width, height; + public Rectangle(int width, int height) { + super(4, new int[] { width, height, width, height }); + this.width = width; + this.height = height; + } + public int area() { + return this.width * this.height; + } +} + +class Square extends Polygon { + private int sideLength; + public Square(int sideLength) { + super(4, new int[] { sideLength, sideLength, sideLength, sideLength }); + this.sideLength = sideLength; + } + public int area() { + return this.sideLength * this.sideLength; + } +} + +class Shapes { + public static void main(String[] args) { + Rectangle wrecked = new Rectangle(3, 5); // Make a 3 × 5 rectangle. + System.out.println(wrecked.area()); // Print its area, 15. + System.out.println(wrecked.perimeter()); // Print its perimeter, 16. + + Square nerd = new Square(7); // Make a 7 × 7 square. + System.out.println(nerd.area()); // Print its area, 49. + System.out.println(nerd.perimeter()); // Print its perimeter, 28. + } +} \ No newline at end of file diff --git a/lab7.docx b/lab7.docx new file mode 100644 index 0000000..4767de5 Binary files /dev/null and b/lab7.docx differ diff --git a/lab7.java b/lab7.java new file mode 100644 index 0000000..ee3f94c --- /dev/null +++ b/lab7.java @@ -0,0 +1,89 @@ +class BinaryVsLinear +{ + + private static int linearSearch(int key, int[] array) + { + int comparisons = 0; + for (int i = 0; i < array.length; i += 1) { + comparisons += 1; + if (array[i] == key) + return comparisons; + } + return comparisons; + } + + private static int binarySearch(int key, int[] array) + { + int comparisons = 0; + int low = 0, high = array.length - 1; + while (low < high) { + int mid = (low + high) / 2; + comparisons += 1; + if (array[mid] == key) + return comparisons; + comparisons += 1; + if (array[mid] < key) + low = mid + 1; + else + high = mid - 1; + } + return comparisons; + } + + public static void main(String[] args) + { + for (int length = 1; length <= 30; length += 1) + { + int[] array = new int[length]; + for (int index = 0; index < length; index += 1) + { + array[index] = index; + } + + double linearTotal = 0.0; + double binaryTotal = 0.0; + for (int element = 0; element < length; element += 1) + { + linearTotal += linearSearch(element, array); + binaryTotal += binarySearch(element, array); + } + + double linearAverage = linearTotal / length; + double binaryAverage = binaryTotal / length; + System.out.println(length + " " + linearAverage + " " + binaryAverage); + } + } +} + +/* OUTPUT +1 1.0 0.0 +2 1.5 1.5 +3 2.0 1.6666666666666667 +4 2.5 2.5 +5 3.0 3.0 +6 3.5 3.1666666666666665 +7 4.0 3.2857142857142856 +8 4.5 3.75 +9 5.0 4.111111111111111 +10 5.5 4.4 +11 6.0 4.636363636363637 +12 6.5 4.75 +13 7.0 4.846153846153846 +14 7.5 4.928571428571429 +15 8.0 5.0 +16 8.5 5.25 +17 9.0 5.470588235294118 +18 9.5 5.666666666666667 +19 10.0 5.842105263157895 +20 10.5 6.0 +21 11.0 6.142857142857143 +22 11.5 6.2727272727272725 +23 12.0 6.391304347826087 +24 12.5 6.458333333333333 +25 13.0 6.52 +26 13.5 6.576923076923077 +27 14.0 6.62962962962963 +28 14.5 6.678571428571429 +29 15.0 6.724137931034483 +30 15.5 6.766666666666667 +*/ \ No newline at end of file diff --git a/lab9.java b/lab9.java new file mode 100644 index 0000000..8e86ac7 --- /dev/null +++ b/lab9.java @@ -0,0 +1,95 @@ +class RunnyStack { + class Run { + public Base object; + public int length; + public Run next; + public Run(Base object, Run next) { + this.object = object; + this.length = 1; + this.next = next; + } + public Run(Base object) { + this(object, null); + } + public boolean is(Base other) { + if (other == null || this.object == null) { + return this.object == other; + } else { + return this.object.equals(other); + } + } + } + private int runs, depth; + private Run top; + public RunnyStack() { + this.runs = 0; + this.depth = 0; + this.top = null; + } + public boolean isEmpty() { + return this.top == null; + } + public int depth() { + return this.depth; + } + public int runs() { + return this.runs; + } + public void push(Base object) { + Run run = new Run(object, top); + if (this.top == null) { + this.runs = 1; + this.depth = 1; + this.top = run; + } else { + if (this.top.is(object)) { + this.depth += 1; + this.top.length += 1; + } else { + this.runs += 1; + this.depth += 1; + Run top = this.top; + run.next = top; + this.top = run; + } + } + } + public void pop() { + if (this.isEmpty()) { + throw new IllegalStateException("The stack is empty."); + } + this.depth -= 1; + this.top.length -= 1; + if (this.top.length == 0) { + this.runs -= 1; + this.top = this.top.next; + } + } + public Base peek() { + if (this.isEmpty()) { + throw new IllegalStateException("The stack is empty."); + } + return this.top.object; + } +} + +class RunnyDriver { + public static void main(String[] args) { + RunnyStack s = new RunnyStack(); + + s.push("A"); + System.out.println(s.peek() + " " + s.depth() + " " + s.runs()); // A 1 1 + + s.push("B"); + System.out.println(s.peek() + " " + s.depth() + " " + s.runs()); // B 2 2 + + s.push("B"); + System.out.println(s.peek() + " " + s.depth() + " " + s.runs()); // B 3 2 + + s.pop(); + System.out.println(s.peek() + " " + s.depth() + " " + s.runs()); // B 2 2 + + s.pop(); + System.out.println(s.peek() + " " + s.depth() + " " + s.runs()); // A 1 1 + } +} \ No newline at end of file diff --git a/project1.py b/project1.py new file mode 100644 index 0000000..655eea1 --- /dev/null +++ b/project1.py @@ -0,0 +1,79 @@ +class Random: + def __init__(self, seed): + self.seed = seed + + def next(self, range=2147483648): + number = (7 ** 5 * self.seed) % (2 ** 31 - 1) + self.seed = number + return number % range + + def choose(self, objects): + return objects[self.next(len(objects))] + +class Nonce: + def __init__(self, seed): + self._first = [] + self._follow = {} + self._random = Random(seed) + + def add(self, word): + if word[0] not in self._first: + self._first.append(word[0]) + for i in range(len(word) - 1): + if word[i] not in self._follow: + self._follow[word[i]] = [] + if word[i + 1] not in self._follow[word[i]]: + self._follow[word[i]].append(word[i + 1]) + + def make(self, size): + word = self._random.choose(self._first) + while len(word) < size: + next = self._follow.get(word[-1]) + if not next: + word += self._random.choose(self._first) + else: + word += self._random.choose(next) + return word + +nw = Nonce(101) +nw.add("ada") +nw.add("algol") +nw.add("bliss") +nw.add("ceylon") +nw.add("clojure") +nw.add("curl") +nw.add("dart") +nw.add("eiffel") +nw.add("elephant") +nw.add("elisp") +nw.add("falcon") +nw.add("fortran") +nw.add("go") +nw.add("groovy") +nw.add("haskell") +nw.add("heron") +nw.add("intercal") +nw.add("java") +nw.add("javascript") +nw.add("latex") +nw.add("lisp") +nw.add("mathematica") +nw.add("nice") +nw.add("oak") +nw.add("occam") +nw.add("orson") +nw.add("pascal") +nw.add("postscript") +nw.add("prolog") +nw.add("python") +nw.add("ruby") +nw.add("scala") +nw.add("scheme") +nw.add("self") +nw.add("snobol") +nw.add("swift") +nw.add("tex") +nw.add("wolfram") + +for i in range(100): + print nw.make(6) \ No newline at end of file diff --git a/project2.java b/project2.java new file mode 100644 index 0000000..1c26c50 --- /dev/null +++ b/project2.java @@ -0,0 +1,278 @@ +import java.util.Random; + +// CARD. A playing card. It's immutable. + +final class Card { + + // RANK NAME. Printable names of card ranks. + + private static final String[] rankName = { + "ace", // 0 + "two", // 1 + "three", // 2 + "four", // 3 + "five", // 4 + "six", // 5 + "seven", // 6 + "eight", // 7 + "nine", // 8 + "ten", // 9 + "jack", // 10 + "queen", // 11 + "king" // 12 + }; + + // SUIT NAME. Printable names of card suits. + + private static final String[] suitName = { + "spade", // 0 + "heart", // 1 + "diamond", // 2 + "club" // 3 + }; + + private int rank; // Card rank, between 0 and 12 inclusive. + private int suit; // Card suit, between 0 and 3 inclusive. + + // CARD. Constructor. Make a new CARD with the given RANK and SUIT. + + public Card(int rank, int suit) { + if (0 <= suit && suit <= 3 && 0 <= rank && rank <= 12) { + this.rank = rank; + this.suit = suit; + } else { + throw new IllegalArgumentException("No such card."); + } + } + + // GET RANK. Return the RANK of this card. + + public int getRank() { + return rank; + } + + // GET SUIT. Return the SUIT of this card. + + public int getSuit() { + return suit; + } + + // TO STRING. Return a string that describes this card, for printing only. For + // example, we might return "the queen of diamonds" or "the ace of hearts". + + public String toString() { + return "the " + rankName[rank] + " of " + suitName[suit] + "s"; + } +} + +class Deck { + private Card[] cards; + private Random random; + private int index; + public Deck() { + this.index = 0; + this.random = new Random(); + this.cards = new Card[52]; + for (int suit = 0; suit < 4; suit += 1) { + for (int rank = 0; rank < 13; rank += 1) { + this.cards[4 * rank + suit] = new Card(rank, suit); + } + } + } + public void shuffle() { + for (int i = this.cards.length - 1; i >= 1; i -= 1) { + int j = Math.abs(random.nextInt()) % (i + 1); + Card temp = this.cards[i]; + this.cards[i] = this.cards[j]; + this.cards[j] = temp; + } + } + public boolean canDeal() { + return this.index < this.cards.length; + } + public Card deal() { + if (!this.canDeal()) { + throw new IllegalArgumentException("There are no more cards to deal!"); + } + return this.cards[this.index++]; + } +} + +class Tableau { + private class Pile { + private Card card; + private Pile next; + public Pile(Card card) { + this.card = card; + } + } + private Deck deck; + private Pile pile; + public Tableau() { + this.deck = new Deck(); + this.deck.shuffle(); + this.addPile(this.deck.deal()); + } + public void addPile(Card card) { + Pile pile = new Pile(card); + pile.next = this.pile; + this.pile = pile; + System.out.println("Added " + card.toString() + "."); + } + private boolean canMerge() { + if (!this.hasManyPiles()) + return false; + return this.canPutOn(this.pile.card, this.pile.next.card); + } + private boolean canPutOn(Card left, Card right) { + return left.getSuit() == right.getSuit() || left.getRank() > right.getRank(); + } + private boolean hasManyPiles() { + return this.pile.next != null; + } + private void mergeTwoPiles() { + if (!this.canMerge()) + throw new IllegalStateException("Can't merge!"); + Card c1 = this.pile.card; + Card c2 = this.pile.next.card; + this.pile.next.card = c1; + this.pile = this.pile.next; + System.out.println("Merged " + c1.toString() + " and " + c2.toString() + "."); + } + private void results() { + if (this.hasManyPiles()) { + System.out.println("Lost the game."); + // System.exit(1); + } else { + System.out.println("Won the game."); + // System.exit(0); + } + } + public void play() { + while (this.deck.canDeal()) { + this.addPile(this.deck.deal()); + while (this.canMerge()) { + this.mergeTwoPiles(); + } + } + results(); + } +} + +public class Main { + public static void main(String[] args) { + new Tableau().play(); + } +} + +/* + +NOTES: +A winning seed is 7389. Put this number in Random() constructor. Another one is 46720. Here is the output for 46720: + +Added the two of spades. +Added the queen of clubs. +Merged the queen of clubs and the two of spades. +Added the four of clubs. +Merged the four of clubs and the queen of clubs. +Added the three of diamonds. +Added the queen of hearts. +Merged the queen of hearts and the three of diamonds. +Merged the queen of hearts and the four of clubs. +Added the ace of hearts. +Merged the ace of hearts and the queen of hearts. +Added the eight of spades. +Merged the eight of spades and the ace of hearts. +Added the queen of spades. +Merged the queen of spades and the eight of spades. +Added the six of hearts. +Added the jack of diamonds. +Merged the jack of diamonds and the six of hearts. +Added the ten of diamonds. +Merged the ten of diamonds and the jack of diamonds. +Added the nine of hearts. +Added the seven of hearts. +Merged the seven of hearts and the nine of hearts. +Added the seven of spades. +Added the eight of clubs. +Merged the eight of clubs and the seven of spades. +Merged the eight of clubs and the seven of hearts. +Added the four of diamonds. +Added the ace of spades. +Added the jack of hearts. +Merged the jack of hearts and the ace of spades. +Merged the jack of hearts and the four of diamonds. +Merged the jack of hearts and the eight of clubs. +Merged the jack of hearts and the ten of diamonds. +Added the six of spades. +Added the king of diamonds. +Merged the king of diamonds and the six of spades. +Merged the king of diamonds and the jack of hearts. +Merged the king of diamonds and the queen of spades. +Added the four of spades. +Added the ten of spades. +Merged the ten of spades and the four of spades. +Added the ten of clubs. +Added the eight of hearts. +Added the six of diamonds. +Added the five of hearts. +Added the five of clubs. +Added the queen of diamonds. +Merged the queen of diamonds and the five of clubs. +Merged the queen of diamonds and the five of hearts. +Merged the queen of diamonds and the six of diamonds. +Merged the queen of diamonds and the eight of hearts. +Merged the queen of diamonds and the ten of clubs. +Merged the queen of diamonds and the ten of spades. +Merged the queen of diamonds and the king of diamonds. +Added the four of hearts. +Added the nine of clubs. +Merged the nine of clubs and the four of hearts. +Added the six of clubs. +Merged the six of clubs and the nine of clubs. +Added the seven of clubs. +Merged the seven of clubs and the six of clubs. +Added the jack of spades. +Merged the jack of spades and the seven of clubs. +Added the three of hearts. +Added the three of spades. +Added the two of hearts. +Added the king of hearts. +Merged the king of hearts and the two of hearts. +Merged the king of hearts and the three of spades. +Merged the king of hearts and the three of hearts. +Merged the king of hearts and the jack of spades. +Merged the king of hearts and the queen of diamonds. +Added the seven of diamonds. +Added the five of diamonds. +Merged the five of diamonds and the seven of diamonds. +Added the ace of clubs. +Added the ten of hearts. +Merged the ten of hearts and the ace of clubs. +Merged the ten of hearts and the five of diamonds. +Merged the ten of hearts and the king of hearts. +Added the two of diamonds. +Added the two of clubs. +Added the king of spades. +Merged the king of spades and the two of clubs. +Merged the king of spades and the two of diamonds. +Merged the king of spades and the ten of hearts. +Added the ace of diamonds. +Added the nine of spades. +Merged the nine of spades and the ace of diamonds. +Merged the nine of spades and the king of spades. +Added the three of clubs. +Added the nine of diamonds. +Merged the nine of diamonds and the three of clubs. +Added the five of spades. +Added the jack of clubs. +Merged the jack of clubs and the five of spades. +Merged the jack of clubs and the nine of diamonds. +Merged the jack of clubs and the nine of spades. +Added the eight of diamonds. +Added the king of clubs. +Merged the king of clubs and the eight of diamonds. +Merged the king of clubs and the jack of clubs. +Won the game. + +*/ \ No newline at end of file