CS100M Spring 2001 Solutions to Review Questions R4 for the Final (test T4) =============================================================================== R4.1 =============================================================================== a) What are some test cases that should be tried to see that the code works? Intersection and containment should be tested on: + empty intervals, e.g. $[1,0]$ + two disjoint intervals, e.g. $[0,1]$ and $[2,3]$ + two overlapping intervals, e.g. $[0,2] and $[1,3]$ + first properly contains the second, e.g. $[0,3]$ and $[1,2]$ + second properly contains the first, e.g. $[1,2]$ and $[0,3]$ b) Matlab functions (use structs to be more like Java). Other operations cannot be disallowed: essentially, everything is $public$ in Matlab, so anybody/everybody is allowed to look inside and modify any piece of data. function s = interval(left,right) % s = interval(left,right): struct $s$ represents interval $[left,right]$ s.a = left; s.b = right; function s = intersect(x,y) % s = intersect(x,y): intersection of intervals $x$, $y$ s = interval(max(x.a,y.a), min(x.b,y.b)); function yesno = contains(x,y) % yesno = contains(x,y): "interval $x$ contains interval $y$?" yesno = y.a > y.b | ( x.a <= y.a & y.b <= x.b ); function s = tostring(x) % s = tostring(x): string representation of interval $x$ s = ['[' num2str(x.a) ',' num2str(x.b) ']']; test script: x = interval(0,2); y = interval(1,3); z = intersect(x,y); fprintf('%s intersect %s: %s', tostring(x), tostring(y), tostring(z)); fprintf('%s contains %s: %d', tostring(y), tostring(z), contains(y,z)); c) Java code // closed intervals (endpoints are included) public class Interval { private double a; // left endpoint private double b; // right endpoint // constructor public Interval(double left, double right) { a = left; b = right; } // return intersection of self with $y$ public Interval intersect(Interval y) { return new Interval(Math.max(a,y.a), Math.min(b,y.b)); } // return "self contains $y$?" public boolean contains(Interval y) { return y.a > y.b || ( a <= y.a && y.b <= b ); } // description of self public String toString() { return "[" + a + "," + b + "]"; } public static void main(String[] args) { Interval x = new Interval(0,2); Interval y = new Interval(1,3); Interval z = x.intersect(y); System.out.println(x + " intersect " + y + ": " + z); System.out.println(y + " intersect " + z + ": " + y.contains(z)); } } =============================================================================== R4.2 =============================================================================== a) Java code public class R4_2 { // minimum and its position (first occurrence) of each column of matrix $x$: // java $m=min(x);$ approximates matlab $[val,pos]=min(x); m=[val;pos];$ public static int[][] min( int[][] x ) { // inv: $m[0..1][0..col-1]$ holds minimums and positions // for $x[:][0..col-1]$ int col = 0 ; int[][] m = new int[2][x[0].length] ; while ( col != x[0].length ) { // update $m$ for current (unprocessed) column in $x$. // inv: $pos$ is the row of the minimum in rows $0..row-1$ of // current column int pos = 0 ; int row = 1 ; while ( row != x.length ) { if ( x[row][col] < x[pos][col] ) // new minimum? pos = row ; row += 1 ; // advance to next row } m[0][col] = x[pos][col] ; // record minimum m[1][col] = pos ; // record position col += 1 ; // advance to next column } return m ; } // here is the java equivalent (but output is not formatted) of the matlab // code $[val,pos] = min([27 -18 24 ; 26 4 17 ]); disp([val' pos'])$ public static void main(String[] args) { int[][] m=min(new int[][] { new int[] {27,-18,24}, new int[] {26,4,17} }); // print one column of $m$ per line of text // inv: already did columns $0:i-1$ int i = 0; while ( i < m[0].length ) { System.out.println( m[0][i] + " " m[1][i] ); i += 1; } } } b) Matlab code function [values,positions] = min(x) % [values,positions] = min(x): first minimum value and its position % for each column in matrix $x$ if size(x,2) = 1 x = x'; % convert a row vector into a column vector end for col = 1:size(x,2) pos = 1; for row = 2:size(x,1) if x(row,col) < x(pos,col) pos = row; end end values(col) = x(row,pos); positions(col) = pos; end =============================================================================== R4.3 =============================================================================== // Given: public class Creature { protected String name; // Creature's name // constructor: initialize name to n public Creature(String n) { name = n; } // speak, i.e. vocalize public void speak() { System.out.println(name + " speaks"); } // perform an action public void act() { speak(); } } // create 4 Creatures and repeatedly (5 times) have each act one at a time public class Target { public static void main(String args[]) { Creature[] c = { // 4 Creatures new Creature("Butch"), new Creature("Fluffy"), new Creature("Sleepy"), new Creature("Clarus") }; // repeat 5 times: each Creature acts for (int times=5; times>0; times--) for (int i = 0; i0; times--) for (int i = 0; i 0 ; i--) System.out.print(" "); and for (int i = n-row+1; i > 0 ; i--) System.out.print(" "); Remark 2: the body of the outer loop could be something like this: int col = 1; // next column to print // print leftmost star for ( ; col < row; col++) System.out.print(" "); System.out.print("*"); col++; // print rightmost star (if different from leftmost) for ( ; col < n ; col++) System.out.print(" "); if (row != n) System.out.print("*"); System.out.println(); b) Observe that the number of "hollow" spaces goes down by 2 on each row, whereas the number of "padding" spaces goes up by 1 on each row. n=1 n=3 n=5 n=7 * *** ***** ******* row 1 * * * * * row 2 * * * row 3 * row 4 Since the row number $row$ goes up by 1 on each row, this means hollow = something - 2*row and padding = something + row. Plugging in a few numbers from the examples yields hollow = n - 2*row and padding = -1 + row. int n = in.readInt(); // size (=base) of hollow isosceles triangle int last = (n+1)/2; // index of last row of triangle // print row 1 -- no padding spaces, n stars, advance to next line for (int i = 0; i < n; i++) System.out.print("*"); System.out.println(); // print rows 2 through last -- note, last row has only 1 star for (int row = 2; row <= last; row++) { // print row $row$ // print row-1 padding spaces and a star for (int i = 0; i < row-1; i++) System.out.print(" "); System.out.print("*"); // print n-2*row hollow spaces and (if needed) another star for (int i = 0; i < n-2*row ; i++) System.out.print(" "); if (row < last) System.out.print("*"); // advance to next line System.out.println(); } Remark 1: again the inner loops could count down instead of up. Remark 2: Here is another solutions for rows after the first row. The leftmost and rightmost stars are initially at columns 2 and $n-1$, and "move in" by 1 on each row. We stop when the leftmost and rightmost stars swap positions. This solution is: int n = in.readInt(); // size (=base) of hollow isosceles triangle // print row 1 -- no padding spaces, n stars, advance to next line for (int i = 0; i < n; i++) System.out.print("*"); System.out.println(); // print remaining rows int leftmost = 2; // leftmost star on next row to print int rightmost = n-1; // rightmost star on next row to print while (leftmost <= rightmost) { int col = 1; // column to print next // print leftmost star for ( ; col < leftmost; col++) System.out.print(" "); System.out.print("*"); col++; // print rightmost star (if different from leftmost) for ( ; col < rightmost; col++) System.out.print(" "); if (leftmost != rightmost) System.out.print("*"); // advance to next print line and move leftmost, rightmost in by 1 System.out.println(); leftmost++; rightmost--; } For both parts (a) and (b), the code can be written super-concisely by following this pseudocode: loop from row 1 until the last row loop from column 1 until the last column needed if a star is needed, then print a star, otherwise print a space println to go to the next row It turns out "is a star needed?" is not too hard to answer: A star is needed = we are on row 1 OR we are at the leftmost star OR we are at the rightmost star. a) int n = in.readInt(); for (int row = 1; row <= n; row++) { for (int col = 1; col <= n; col++) if (row == 1 || col == row || col == n) System.out.print("*"); else System.out.print(" "); System.out.println(); } b) int right = in.readInt(); for (int row = 1; row <= right; row++) { for (int col = 1; col<=right; col++) if (row == 1 || col == row || col == right) System.out.print("*"); else System.out.print(" "); right--; System.out.println(); } =============================================================================== R4.6 =============================================================================== A number $m>0$ is *perfect* if it is equal to the sum of all its proper divisors $d$ (proper means $0