/** * Suggested solutions to DIT012 exam 2017-04-12 */ // --------- 1 -------------- See lecture slides (4p) // --------- 2 -------------- a) Will give compilation error. Static method can't call instance method. (4p) But instance method can call static. // ----- 3 ---------- (2p) void program() { Scanner sc = new Scanner(in); out.print("Input b1 > "); double b1 = sc.nextDouble(); out.print("Input b2 > "); double b2 = sc.nextDouble(); out.print("Input h > "); double h = sc.nextDouble(); double area = h * (b1 + b2) / 2; out.println("Area = " + area); } // --------- 4 ------------------- (4p) double log1p(double x, int nTerms) { double val = 0; double exp = x; for (int i = 1; i < nTerms; i++) { if (i % 2 == 0) { val = val - exp / i; } else { val = val + exp / i; } exp = x * exp; } return val; } // --------- 5 ------------------- (6p) public String[] generations(int n) { if (n == 0) { return new String[]{"ME"}; } int size = (int) pow(2, n) - 1; String[] pre = new String[size]; pre[0] = "ME"; for (int i = 0; i < size / 2; i++) { pre[2 * i + 1] = pre[i] + ".dad"; pre[2 * i + 2] = pre[i] + ".mum"; } return pre; } // -------- 6 --------- (8p) Basic idea: Start from end of ordering (= actual). Find first index of actual in target (from left). Check from index to end of target if any char preceding actual in ordering is present public boolean isOrdered(String ordering, String source) { String pre = ordering; // Going backwards for (int n = ordering.length() - 1; n > 0; n--) { char actual = ordering.charAt(n); pre = pre.substring(0, pre.length() - 1); int i = source.indexOf(actual); for (int j = i + 1; j < source.length(); j++) { char ch = source.charAt(j); if (pre.indexOf(ch) >= 0) { return false; } } } return true; } // -------- 7 --------- (6p) See drawing. // ------ 8 ------------- (8p) // Create world Obstacle[] obs = {new Obstacle(1, 2), new Obstacle(3, 4), new Obstacle(5, 6)}; World w = new World(obs); out.println(w.contains(obs[0])); public class World { private final Obstacle[] obstacles; public World(Obstacle[] obstacles) { this.obstacles = obstacles; } // Other solutions possible, using identity public boolean contains(Obstacle obstacle) { for (Obstacle o : obstacles) { if (o.x == obstacle.x && o.y == obstacle.y) { return true; } } return false; } } public class Obstacle { private final int x; private final int y; public Obstacle(int x, int y) { this.x = x; this.y = y; } } // ---------- 9 ------------------- (10p) General idea for splitInt(7,4): [ 2, 2, 0, 3 ] is represented as * * | * * || * * * Put random bars between the start and calculate values. See wikipedia on: Combinations, Starts and bars int[] splitInt(int n, int nTerms) { if (nTerms == 1) { return new int[]{n}; } // To cut in n terms need n-1 cuts int bars[] = new int[nTerms - 1]; Random rand = new Random(); for (int i = 0; i < nTerms - 1; i++) { int r = rand.nextInt(n + 1); bars[i] = r; } Arrays.sort(bars); int[] split = new int[nTerms]; split[0] = bars[0]; for (int i = 1; i < nTerms - 1; i++) { split[i] = bars[i] - bars[i - 1]; } split[nTerms - 1] = n - bars[nTerms - 2]; return split; } // -------- 10 -------------- (8p) Will print 11. - When calling b.get() we execute method get() on object of type Derived. - get() is inherited from Base. - get() method calls inc(). - Inc is overridden, so inc() in Derived is called (i.e. call inc() is same as call this.inc(), and this is reference to actual object i.e. an Derived object). - Instance methods always called on runtime type not on type of reference. - Summary: this in code may reference any subtype to actual type. }