interview-preparation / what-we-do

0 stars 8 forks source link

[Moderate] interview questions #22 #149

Closed rygh4775 closed 5 years ago

rygh4775 commented 5 years ago

image

GyuminLee commented 5 years ago

Approach

Solution1. Resizable Array


public class Grid {
    private boolean[][] grid;
    private Ant ant = new Ant();

    public Grid() {
        grid = new boolean[1][1];
    }

    /* 
     * Copy old values into new array, with an offset/shift applied to the row and column
     */
    private void copyWithShift(boolean[][] oldGrid, boolean[][] newGrid, int shiftRow, int shiftColumn) {
        for(int r = 0; r < oldGrid.length; r++) {
            for(int c = 0; c < oldGrid[0].length; c++) {
                newGrid[r + shiftRow][c + shiftColumn] = oldGrid[r][c];
            }
        }
    }

    /*
     * Ensure that the given position will fit on the array. If necessary, double
     * the size of the matrix, copy the oldvalues over, and adjust the ant's 
     * position so that it's in a positive range.
     */
    private void ensureFit(Position position) {
        int shiftRow = 0;
        int shiftColumn = 0;

        //Calculate new number of rows
        int numRows = grid.length;
        if(position.row < 0) {
            shiftRow = numRows;
            numRows *= 2;
        } else if (position.row >= numRows) {
            numRows *= 2;
        }
        // Calcuate new number of columns
        int numColumns = grid[0].length;
        if(position.column < 0) {
            shiftColumn = numColumns;
            numColumns *= 2;
        } else if(position.column >= numColumns) {
            numColumns *= 2;
        }

        //Grow array, if necessary. Shift ant's position too
        if(numRows != grid.length || numColumns != grid[0].length) {
            boolean[][] newGrid = new boolean[numRows][numColumns];
            copyWithShift(grid, newGrid, shiftRow, shiftColumn);
            ant.adjustPosition(shiftRow, shiftColumn);
            grid = newGrid;
        }
    }
    /*
     * Flip color of cells
     */
    private void flip(Position position) {
        int row = position.row;
        int column = position.column;
        grid[row][column] = grid[row][column] ? false : true;
    }
    /*
     * Move ant.
     */
    public void move() {
        ant.turn(grid[ant.position.row][ant.position.column]);
        flip(ant.position);
        ant.move();
        ensureFit(ant.position);
    }

    /*
     * Print board
     */
    public String toString() {
        StringBuilder sb = new StringBuilder();
        for(int r = 0; r < grid.length; r++) {
            for(int c = 0; c < grid[0].length; c++) {
                if(r == ant.position.row && c == ant.position.column) {
                    sb.append(ant.orientation);
                } else if(grid[r][c]) {
                    sb.append("X");
                } else {
                    sb.append("_");
                }
            }
            sb.append("\n");
        }
        sb.append("Ant: " + ant.orientation + ". \n");
        return sb.toString();
    }
}

public class Ant {
    public Position position = new Position(0,0);
    public Orientation orientation = Orientation.right;

    public void turn(boolean clockwise) {
        orientation = orientation.getTurn(clockwise);
    }

    public void move() {
        if(orientation == Orientation.left) {
            position.column--;
        } else if(orientation == Orientation.right) {
            position.column++;
        } else if(orientation == Orientation.up) {
            position.row--;
        } else if(orientation == Orientation.down) {
            position.row++;
        }
    }

    public void adjustPosition(int shiftRow, int shiftColumn) {
        position.row += shiftRow;
        position.column += shiftColumn;
    }
}

public enum Orientation {
    left, up, right, down;

    public Orientation getTurn(boolean clockwise) {
        if(this == left) {
            return clockwise ? up : down; 
        } else if(this == up) {
            return clockwise ? right : left; 
        } else if(this == right) {
            return clockwise ? down : up; 
        } else { //down
            return clockwise ? left : right; 
        }
    }

    @Override
    public String toString() {
        // TODO Auto-generated method stub
        if(this == left) {
            return "\u2190"; 
        } else if(this == up) {
            return "\u2191"; 
        } else if(this == right) {
            return "\u2192"; 
        } else { //down
            return "\u2193"; 

        }
    }
}

public class Position {
    public int row;
    public int column;

    public Position(int row, int column) {
        this.row = row;
        this.column = column;
    }
}

Solution2.HashSet

public class Board {
    private HashSet<Position> whites = new HashSet<Position>();
    private Ant ant = new Ant();
    private Position topLeftCorner = new Position(0, 0);
    private Position bottomRightCorner = new Position(0,0);

    public Board() {}
        /*
         * Move ant
         */
        public void move() {
            ant.turn(isWhite(ant.position)); // Turn
            flip(ant.position);
            ant.move();
            ensureFit(ant.position);
        }

        /*
         * Flip color of cells
         */
        private void flip(Position position) {
            if(whites.contains(position)) {
                whites.remove(position);
            } else {
                whites.add(position.clone());
            }
        }

        /*
         * Grow grid by tracking the most top-left and bottom-right positions
         */
        private void ensureFit(Position position) {
            int row = position.row;
            int column = position.column;

            topLeftCorner.row = Math.min(topLeftCorner.row, row);
            topLeftCorner.column = Math.min(topLeftCorner.column, column);

            bottomRightCorner.row = Math.max(bottomRightCorner.row, row);
            bottomRightCorner.column = Math.max(bottomRightCorner.column, column);
        }

        /*
         * Check if cell is white
         */
        public boolean isWhite(Position p) {
            return whites.contains(p);
        }

        /*
         * Check if cell is white
         */
        public boolean isWhite(int row, int column) {
            return whites.contains(new Position(row, column));
        }

        /*
         * Print board
         */
        public String toString() {
            StringBuilder sb = new StringBuilder();
            int rowMin = topLeftCorner.row;
            int rowMax = bottomRightCorner.row;
            int colMin = topLeftCorner.column;
            int colMax = bottomRightCorner.column;

            for(int r = rowMin; r <= rowMax; r++) {
                for(int c = colMin; c <= colMax; c++) {
                    if(r == ant.position.row && c == ant.position.column) {
                        sb.append(ant.orientation);
                    } else if(isWhite(r, c)) {
                        sb.append("X");
                    } else {
                        sb.append("_");
                    }
                }
                sb.append("/n");
            }
            sb.append("Ant: " + ant.orientation +". \n");
            return sb.toString();
        }

}

public class Position {
    public int row;
    public int column;

    public Position(int row, int column) {
        this.row = row;
        this.column = column;
    }

    @Override
    public boolean equals(Object obj) {
        if( obj instanceof Position) {
            Position p = (Position) obj;
            return p.row == row && p.column == column;
        }
        return false;
    }

    @Override
    public int hashCode() {
        /*
         * There are many options for hash function... 
         */
        return (row*31) ^ column;
    }

    public Position clone() {
        return new Position(row, column);
    }
}
GyuminLee commented 5 years ago

Result1. Resizable Array

image

Result2. HashSet

image