Code exercises

1,297 views
Skip to first unread message

Jason

unread,
Nov 13, 2011, 9:23:29 PM11/13/11
to happy-pr...@googlegroups.com
Question 1: Calculate the difference between two dates.

Description:
. Create an application that can read in pairs of dates in the following format -
DD MM YYYY, DD MM YYYY

. Validate the input data, and compute the difference between the two dates in days.

. Output of the application should be of the form -
DD MM YYYY, DD MM YYYY, difference

. Where the first date is the earliest, the second date is the latest and the difference is the number of days.
. Input can be from a file, or from standard input, as the developer chooses.
. Provide test data to exercise the application.

Constraints:
The application may not make use of the Java libraries for date manipulation (for example Date, Calendar classes).
The application can limit calculation on an input range of dates from 1900 to 2010


Question 2: Toy Robot Simulator

Description:
. The application is a simulation of a toy robot moving on a square tabletop, of dimensions 5 units x 5 units.
. There are no other obstructions on the table surface.
. The robot is free to roam around the surface of the table, but must be prevented from falling to destruction. Any movement 
that would result in the robot falling from the table must be prevented, however further valid movement commands must still 
be allowed.


. Create an application that can read in commands of the following form -
PLACE X,Y,F
MOVE
LEFT
RIGHT
REPORT

. PLACE will put the toy robot on the table in position X,Y and facing NORTH, SOUTH, EAST or WEST. 
. The origin (0,0) can be considered to be the SOUTH WEST most corner.
. The first valid command to the robot is a PLACE command, after that, any sequence of commands may be issued, in any order, including another PLACE command. The application should discard all commands in the sequence until a valid PLACE command has been executed.
. MOVE will move the toy robot one unit forward in the direction it is currently facing.
. LEFT and RIGHT will rotate the robot 90 degrees in the specified direction without changing the position of the robot.
. REPORT will announce the X,Y and F of the robot. This can be in any form, but standard output is sufficient.

. A robot that is not on the table can choose the ignore the MOVE, LEFT, RIGHT and REPORT commands.
. Input can be from a file, or from standard input, as the developer chooses.
. Provide test data to exercise the application.


Constraints:
The toy robot must not fall off the table during movement. This also includes the initial placement of the toy robot. 
Any move that would cause the robot to fall must be ignored.

Example Input and Output:
a)
PLACE 0,0,NORTH
MOVE
REPORT
Output: 0,1,NORTH

b)
PLACE 0,0,NORTH
LEFT
REPORT
Output: 0,0,WEST

c)
PLACE 1,2,EAST
MOVE
MOVE
LEFT
MOVE
REPORT
Output: 3,3,NORTH

Seabook

unread,
Nov 13, 2011, 9:31:19 PM11/13/11
to happy-pr...@googlegroups.com
Hi Jason, thanks for posting some good exercises here.
I am wondering where the exercises come from?

Thanks,
Seabook

Seabook

unread,
Nov 14, 2011, 1:39:02 AM11/14/11
to happy-pr...@googlegroups.com
Question 1: Calculate the difference between two dates. Solution

Easy problem, too much coding effort. It's not good. May have some potential bugs, since I finish this in rush. And Java is very lame, there is no api to easily get the two dates different days in between.

The following one doesn't use any Date Class and Calendar method.

package com.seabook.google.algorithm2;

import java.util.HashMap;
import java.util.Map;


public class DateDifference {
    private static Map<String, Integer> numOfDaysEachMonth = new HashMap<String, Integer>();

    static {
        numOfDaysEachMonth.put("1", 31);
        numOfDaysEachMonth.put("2", 28);
        numOfDaysEachMonth.put("2L", 29);
        numOfDaysEachMonth.put("3", 31);
        numOfDaysEachMonth.put("4", 30);
        numOfDaysEachMonth.put("5", 31);
        numOfDaysEachMonth.put("6", 30);
        numOfDaysEachMonth.put("7", 31);
        numOfDaysEachMonth.put("8", 31);
        numOfDaysEachMonth.put("9", 30);
        numOfDaysEachMonth.put("10", 31);
        numOfDaysEachMonth.put("11", 30);
        numOfDaysEachMonth.put("12", 31);
    }
   
    public static void main(String[] args) {
        String date1 = "28 3 2009";
        String date2 = "28 5 2001";
        DateDifference dd = new DateDifference();
       
        int diff = dd.calculateDateDifference(date1, date2);
       
        dd.printResult(date1, date2, diff);
    }

    public int calculateDateDifference(String date1, String date2) {
        MyDate parsedDate1 = parseDate(date1);
        MyDate parsedDate2 = parseDate(date2);
        return calcDiffDays(parsedDate1, parsedDate2);
    }

    public int calcDiffDays(MyDate date1, MyDate date2) {
        if (date1.equals(date2)) {
            return 0;
        }
       
        int firstCompOrig = compareToOrgin(date1);
        int secCompOrig = compareToOrgin(date2);
       
        return Math.abs(secCompOrig - firstCompOrig);
    }
   
    // compare to 01/01/1900
    public int compareToOrgin(MyDate date1) {
        int diff = 0;
        // compare With 01-01-1900
        for (int i = 1900; i < date1.year; i++) {
            if (isLeapYear(i)) {
                diff += 366;  // if it's leap year add 366 days
            } else
                diff += 365; // normal year + 365 days
        }
       
        for (int month = 1; month < date1.month; month++) {
            String monthKey = (String) (isLeapYear(date1.year) ? month + "L" : month+"");
            diff += numOfDaysEachMonth.get(monthKey);
        }
       
        diff += date1.day - 1;
       
        return diff;
    }

    public MyDate parseDate(String date1) {
        String[] splits = date1.split(" ");

        if (splits == null || splits.length != 3) {
            throw new RuntimeException("Invalid Input: " + date1);
        }

        String dayElem = splits[0];
        String monthElem = splits[1];
        String yearElem = splits[2];

        int day, month, year;

        try {
            day = Integer.valueOf(dayElem);
            month = Integer.valueOf(monthElem);
            year = Integer.valueOf(yearElem);
        } catch (NumberFormatException nfe) {
            throw new RuntimeException("Input is invalid " + nfe.getMessage());
        }

        if (!isAValidDate(day, month, year)) {
            throw new RuntimeException("It's a not a valid date input: " + day
                    + "/" + month + "/" + year);
        }

        // Do more validation later on

        return new MyDate(day, month, year);
    }

    private boolean isAValidDate(int day, int month, int year) {
        if (day < 0 || day > 31 || month < 0 || month > 12 || year < 1900
                || year > 2010) {
            return false;
        }

        String monthKey = (String) (isLeapYear(year) ? month + "L" : month + "");
        Integer maxDays = numOfDaysEachMonth.get(monthKey);

        if (maxDays == null)
            return false;
        if (day > maxDays) {
            return false;
        }

        return true;
    }

    public void printResult(String date1Str, String date2Str, int diff) {
        MyDate date1 = parseDate(date1Str);
        MyDate date2 = parseDate(date2Str);
       
        if (date1.isEarlier(date2))
            System.out.println(date1 + " " + date2 + " " + diff);
        else
            System.out.println(date2 + " " + date1 + " " + diff);
    }

    public boolean isLeapYear(int year) {
        if (year % 100 == 0) {
            if (year % 400 == 0) {
                return true;
            }
        } else if (year % 4 == 0) {
            return true;
        }

        return false;
    }
   
}

class MyDate {
    int day;
    int month;
    int year;

    public MyDate(int day, int month, int year) {
        this.day = day;
        this.month = month;
        this.year = year;
    }

    @Override
    public boolean equals(Object dateObj) {
        MyDate date = null;
        if (dateObj instanceof MyDate) {
            date = (MyDate) dateObj;
        }
        return this.day == date.day && this.month == date.month
                && this.year == date.year;
    }

    public boolean isEarlier(MyDate date) {
        int yearDiff = this.year - date.year;
        int monthDiff = this.month - date.month;
        int dayDiff = this.day - date.day;
       
        if (yearDiff < 0) {
            return true;
        } else if (yearDiff > 0) {
            return false;
        } else {
            if (monthDiff < 0) {
                return true;
            } else if (monthDiff > 0) {
                return false;
            } else {
                if (dayDiff < 0) {
                    return true;
                }
            }
        }
       
        return false;
    }
   
    @Override
    public String toString() {
        return this.day + "/" + this.month + "/" + this.year;
    }
}

Seabook

unread,
Nov 14, 2011, 8:19:50 PM11/14/11
to happy-pr...@googlegroups.com
Question 2: Toy Robot Simulator
Good to have a try on this. May do a JavaScript version later with UI.

package com.seabook.google.algorithm2;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class ToyRobotSimulator {
    public static Map<Direction, Point> steps = new HashMap<Direction, Point>();
    private static Map<String, Method> commands = new HashMap<String, Method>();

    static {
        steps.put(Direction.NORTH, new Point(0, 1));
        steps.put(Direction.EAST, new Point(1, 0));
        steps.put(Direction.WEST, new Point(-1, 0));
        steps.put(Direction.SOUTH, new Point(0, -1));

        try {
            commands.put("MOVE", ToyRobotSimulator.class.getDeclaredMethod(
                    "move"));
            commands.put("LEFT", ToyRobotSimulator.class.getDeclaredMethod(
            "left"));
            commands.put("RIGHT", ToyRobotSimulator.class.getDeclaredMethod(
            "right"));
            commands.put("REPORT", ToyRobotSimulator.class.getDeclaredMethod(
            "report"));
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }

    Robot robot = new Robot();

   
    public static void main(String[] args) {
        ToyRobotSimulator robotSimulator = new ToyRobotSimulator();
        Scanner in = new Scanner(System.in);
        String command = null;
        while (true) {
            command = in.nextLine();
            if ("q".equalsIgnoreCase(command)) {
                return;
            }
           
            if (!commands.containsKey(command)) {
                if (!command.startsWith("PLACE")) {
                    System.out.println("The command is not valid, " + command);
                    continue;
                }
            }
           
            if (command != null && command.trim().toLowerCase().startsWith("place")) {
                String[] splitCommands = command.split(" ");
                if (splitCommands != null && splitCommands.length == 2) {
                    String[] params = splitCommands[1].split(",");
                    if (params != null && params.length == 3) {
                        String xStr = params[0];
                        String yStr = params[1];
                        String face = params[2];
                       
                        int x, y;
                        Direction d;
                        try {
                            x = Integer.valueOf(xStr);
                            y = Integer.valueOf(yStr);
                            d = Direction.faces.get(face);
                        } catch (NumberFormatException nfe) {
                            System.out.println("The PLACE command params are not valid, " + command);
                            continue;
                        }
                       
                        robotSimulator.placeXYF(x, y, d);
                    } else {
                        System.out.println("The PLACE command params are not valid, " + command);
                        continue;
                    }
                } else {
                    System.out.println("The PLACE command params are not valid, " + command);
                    continue;
                }
            } else {
                try {
                    commands.get(command).invoke(robotSimulator);
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void placeXYF(int x, int y, Direction d) {
        robot.placeMe(new Point(x, y), d);
    }

    public void move() {
        robot.move();
    }

    public void left() {
        robot.turnLeft();
    }

    public void right() {
        robot.turnRight();
    }
   
    public void report() {
        System.out.println(robot.report());
    }

}

class TableTop {
    public static final int MAX_WIDTH = 4;
    public static final int MAX_HEIGHT = 4;

}

class Point {
    int x;
    int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public Point addPoint(Point p) {
        int newPointX = this.x + p.x;
        int newPointY = this.y + p.y;

        return new Point(newPointX, newPointY);
    }

    @Override
    public String toString() {
        return "[" + this.x + ", " + this.y + "]";
    }
}

class Robot {
    Point point;
    Direction d;

    public void placeMe(Point p, Direction d) {
        this.point = p;
        this.d = d;

        if (isOutOfRange()) {
            throw new RuntimeException("Can't place the robot to this point: "
                    + this.point);
        }
    }

    public void turnLeft() {
        switch (d) {
        case NORTH:
            d = Direction.WEST;
            break;
        case WEST:
            d = Direction.SOUTH;
            break;
        case SOUTH:
            d = Direction.EAST;
            break;
        case EAST:
            d = Direction.NORTH;
            break;
        default:
            break;
        }
    }

    public void turnRight() {
        switch (d) {
        case NORTH:
            d = Direction.EAST;
            break;
        case WEST:
            d = Direction.NORTH;
            break;
        case SOUTH:
            d = Direction.WEST;
            break;
        case EAST:
            d = Direction.SOUTH;
            break;
        default:
            break;
        }
    }

    public void move() {
        Point moveP = ToyRobotSimulator.steps.get(this.d);
        this.point = this.point.addPoint(moveP);

        if (isOutOfRange()) {
            throw new RuntimeException("Can't move the robot to this point: "
                    + this.point);
        }
    }

    public boolean isOutOfRange() {
        if (this.point.x > TableTop.MAX_WIDTH || this.point.x < 0
                || this.point.y > TableTop.MAX_HEIGHT || this.point.y < 0) {
            return true;
        }

        return false;
    }

    public String report() {
        return "[" + this.point.x + ", " + this.point.y + ", " + this.d + "]";
    }
}

enum Direction {
    NORTH, SOUTH, EAST, WEST;
   
    public static Map<String, Direction> faces = new HashMap<String, Direction>();
    static {
        faces.put("NORTH", NORTH);
        faces.put("north", NORTH);
        faces.put("N", NORTH);
        faces.put("n", NORTH);
        faces.put("SOUTH", SOUTH);
        faces.put("south", SOUTH);
        faces.put("S", SOUTH);
        faces.put("s", SOUTH);
        faces.put("EAST", EAST);
        faces.put("east", EAST);
        faces.put("E", EAST);
        faces.put("e", EAST);
        faces.put("WEST", WEST);
        faces.put("west", WEST);
        faces.put("W", WEST);
        faces.put("w", WEST);
    }
}
Reply all
Reply to author
Forward
0 new messages