CSE 143 19au - Midterm Key

1. Recursive Tracing

Method Call                      Output Produced
------------------------------------------------
mystery(5);                      +*
mystery(15);                     ++**
mystery(304);                    +++*--
mystery(9247);                   ++++*--*
mystery(43269);                  +++++-*--*

2. Recursive Programming

Two possible solutions are shown below

public int doubleDigit(int n, int d) {
	if (d < 0 || d > 9) {
		throw new IllegalArgumentException();
	}
	
	if (n < 0) {
		return -doubleDigit(-n, d);
	} else if (n == 0) {
		return 0;
	} else if (n % 10 == d) {
		return doubleDigit(n / 10, d) * 100 + d * 11;
	} else {
		return doubleDigit(n / 10, d) * 10 + n % 10;
	}
}

public int doubleDigit(int n, int d) {
	if (d < 0 || d > 9) {
		throw new IllegalArgumentException();
	}
	if (n < 0) {
		return -doubleDigit(-n, d);
	} else if (n == d) {
		return d * 11;
	} else if (n < 10) {
		return n;
	} else if (n % 10 == d) {
		return doubleDigit(n / 10, d) * 100 + doubleDigit(n % 10, d);
	} else {
		return doubleDigit(n / 10, d) * 10 + n % 10;
	}
}

3. ListNode Programming

One possible solution is shown for each problem below

before                   after                      code
-----------------------+-----------------------+-------------------------------
 p->[1]                | p                     | q.next.next = p;
                       |                       | p = null;
 q->[2]->[3]           | q->[2]->[3]->[1]      |
-----------------------+-----------------------+-------------------------------
 p->[1]->[2]->[3]      | p->[2]->[3]           | q = p;
                       |                       | p = p.next;
 q                     | q->[1]                | q.next = null;
-----------------------+-----------------------+-------------------------------
 p->[1]->[2]           | p->[2]                | q.next.next = q;
                       |                       | q = q.next;
 q->[3]->[4]           | q->[4]->[3]->[1]      | q.next.next = p;
                       |                       | p = p.next;
                       |                       | q.next.next.next = null;
-----------------------+-----------------------+-------------------------------
 p->[1]->[2]           | p->[4]->[2]->[3]      | q.next.next.next = p;
                       |                       | ListNode temp = q;
 q->[3]->[4]->[5]      | q->[5]->[1]           | q = q.next.next;
                       |                       | temp.next.next = q.next.next;
                       |                       | p.next.next = temp;
                       |                       | p = temp.next;
                       |                       | p.next.next.next = null;
                       |                       | q.next.next = null;
-----------------------+-----------------------+-------------------------------

4. ArrayIntList Programming

Two possible solutions are shown below

public void removeRange(int start, int stop) {
	if (start < 0 || stop > size || start > stop) {
		throw new IllegalArgumentException();
	}
	int delta = stop - start;
	for (int i = stop; i < size; i++) {
		elementData[i - delta] = elementData[i];
	}
	size -= delta;
}

public void removeRange(int start, int stop) {
	if (stop - start < 0 || stop > size || start < 0) {
		throw new IllegalArgumentException();
	}
	int newSize = start;
	for (int i = stop; i < size; i++) {
		elementData[newSize] = elementData[i];
		newSize++;
	}
	size = newSize;
}

5. Collections Programming

One possible solution is shown below.

public static Set<String> whatToCook(Map<String, Set<String>> recipes, Set<String> pantry) {
	if (recipes.size() == 0) {
		throw new IllegalArgumentException();
	}
	Set<String> result = new HashSet<>();

	// Lower case all items in pantry for lookup later
	Set<String> lowercasePantry = new HashSet<>();
	for (String ingredient : pantry) {
		lowercasePantry.add(ingredient.toLowerCase());
	}
	
	// Go through each recipe
	for (String recipe : recipes.keySet()) {
		Set<String> ingredients = recipes.get(recipe);
		boolean canMake = true;
	
		for (String ingredient : ingredients) {
			if (!lowercasePantry.contains(ingredient.toLowerCase())) {
				canMake = false;
			}
		}
		if (canMake) {
			result.add(recipe);
		}
	}
	return result;
}

6. Stacks and Queues

One possible solution is shown below

public static void expand(Stack<Integer> s1, Stack<Integer> s2) {
	if (s1.size() != s2.size()) {
		throw new IllegalArgumentException();
	}
	Queue<Integer> q = new LinkedList<Integer>();

	// merge the values into the q
	while (!s1.isEmpty()) {
		q.add(s2.pop());
		q.add(s1.pop());
	}

	// split the values up and make duplicates as you go
	while (!q.isEmpty()) {
		int n2 = q.remove();
		int n1 = q.remove();
		for (int i = 0; i < n2; i++) {
			s1.push(n1);
		}
		s2.push(n2);
	}

	// fix order
	s2q(s2, q);
	q2s(q, s2);
	s2q(s1, q);
	q2s(q, s1);
}