1.  Lines that will cause compilation errors:

    5     accessing private variable [4 pts]

    In a different package: the above plus

    7     package-private variable   [6 pts]

2.  

    correct bound          [2pts]
    correct length         [2pts]
    correct comparison     [2pts]
    right action in if     [2pts]
    correct return         [2pts]

    public static int firstIndex(int a[], int n) {
        for (int i = 0; i < a.length; i++)
            if (a[i] == n)
                return i;
        return -1;
    }

3.  There are three unintended syntax errors:

    p1.printDescription(), // , instead of ;

    Square square // missing ;

    rectangle.printDescription; // missing ()

    Everybody gets 3pts to compensate for teacher stupidity.
    

    Comment out: [4pts]

    square = new Rectangle();  // Rectangle is not a Square  [3pts]
    square.printDescription(); // since square is not initialized [1pt]
    
    Printout: [3pts]

    Four sides
    Four sides, all equal
    Four sides, all equal

    You can still get these 3pts if you made a mistake in the first
    part, as long as the printout is consistent with what was
    commented out.

4.  B: [4pts]

        this.x1 = x1;
        this.y1 = y1;
        this.x2 = x2;
        this.y2 = y2;
        this.x3 = x3;
        this.y3 = y3;

    C: [5pts]

        Line edge1 = new Line(x1, y1, x2, y2);
        edge1.draw();
        Line edge2 = new Line(x2, y2, x3, y3);
        edge2.draw();
        Line edge3 = new Line(x3, y3, x1, y1);
        edge3.draw();

    D: [2pts]

        private int x1, y1, width, height;

    E: [4pts]

        this.x1 = x1;
        this.y1 = y1;
        this.width = width;
        this.height = height;

    F: [5pts]

        Line edge1 = new Line(x1, y1, x1 + width, y1);
        edge1.draw();
        Line edge2 = new Line(x1 + width, y1, x1 + width, y1 + height);
        edge2.draw();
        Line edge3 = new Line(x1 + width, y1 + height, x1, y1 + height);
        edge3.draw();
        Line edge4 = new Line(x1, y1 + height, x1, y1);
        edge4.draw();

    G: [5pts]

        super(x1, y1, length, length);

    H: [5pts]

        super.draw();

5. 
        face: [5pts]
        Rectangle face = new Rectangle(x, y, 18, 20);
        face.draw();

        left eye: [5pts]
        Square leftEye = new Square(x+3, y+5, 5);
        leftEye.draw();

        right eye: [5pts]
        Square rightEye = new Square(x+10, y+5, 5);
        rightEye.draw();

        mouth: [5pts]
        Triangle mouth = new Triangle(x+8, y+15, x+10, y+15, x+9, y+20);
        mouth.draw();

6.

    The easiest solution is to start from the end of the array,
    keeping track of the largest element found so far and using it to
    replace the zeros along the way:

    public int[] replaceZero(int[] nums) {
        int n = nums.length;

        int[] res = new int[n];

        if (n == 0) return res;
        
        int largestSoFar = nums[n-1];

        for (int i = n-1; i >= 0; i--)
            if (nums[i] == 0)
                res[i] = largestSoFar;
            else {
                res[i] = nums[i];
                if (nums[i] > largestSoFar)
                    largestSoFar = nums[i];
            }

        return res;
    }

    An alternative solution is to start from the front, going into a
    nested loop everytime a zero is found in order to determine the
    largest element to the right of it.  This is more complicated, and
    also much slower (but still gives the same number of points!).

    public int[] slowReplaceZero(int[] nums) {
        int n = nums.length;
        int[] res = new int[n];

        if (n == 0) return res;

        for(int i = 0; i < n-1; i++) {
            if (nums[i] != 0)
                res[i] = nums[i];
            else {
                int maxRight = nums[i+1];
                for (int j = i+2; j < n; j++)
                    if (nums[j] > maxRight)
                        maxRight = nums[j];
                res[i] = maxRight;
            }
        }

        res[n-1] = nums[n-1];

        return res;
    }
