import tester.Tester; // represents a road trip class RoadTrip { String driver1; String driver2; ILoDirection directions; RoadTrip(String driver1, String driver2, ILoDirection directions) { this.driver1 = driver1; this.driver2 = driver2; this.directions = directions; } } // lists of directions interface ILoDirection { } //an empty list of directions class MtLoDirection implements ILoDirection { } //a non-empty list of directions class ConsLoDirection implements ILoDirection { Direction first; ILoDirection rest; ConsLoDirection(Direction first, ILoDirection rest) { this.first = first; this.rest = rest; } } // represents a direction class Direction { String description; int miles; // how many miles this instruction is Direction(String description, int miles) { this.description = description; this.miles = miles; } // is the distance left to go on this Direction less than this.miles? boolean needsSplitting(int distanceLeft) { return this.miles > distanceLeft; } // remove miles from this Direction's distance because it needs splitting Direction shrink(int milesToRemove) { return new Direction(this.description, this.miles - milesToRemove); } // how much a driver would have left on their part after driving this direction int distanceLeft(int leftToDrive) { return leftToDrive - this.miles; } } // represents a chunk of a road trip class RoadTripChunk { String driver; ILoDirection directions; RoadTripChunk(String driver, ILoDirection directions) { this.driver = driver; this.directions = directions; } // Convenience constructor RoadTripChunk(String driver, Direction dir) { this.driver = driver; this.directions = new ConsLoDirection(dir, new MtLoDirection()); } // does this chunk have the given driver? boolean hasDriver(String driver) { return this.driver.equals(driver); } // add direction to front of directions RoadTripChunk addDir(Direction dir) { return new RoadTripChunk(this.driver, new ConsLoDirection(dir, this.directions)); } } //lists of road trip chunks interface ILoRoadTripChunk { // add this direction driven by driver to the front of the list ILoRoadTripChunk addDirection(String driver, Direction dir); } //an empty list of road trip chunks class MtLoRoadTripChunk implements ILoRoadTripChunk { // create non-empty road trip chunk list public ILoRoadTripChunk addDirection(String driver, Direction dir) { return new ConsLoRoadTripChunk(new RoadTripChunk(driver, dir), this); } } //a non-empty list of road trip chunks class ConsLoRoadTripChunk implements ILoRoadTripChunk { RoadTripChunk first; ILoRoadTripChunk rest; ConsLoRoadTripChunk(RoadTripChunk first, ILoRoadTripChunk rest) { this.first = first; this.rest = rest; } // create add dir to first if driver matches, otherwise create new section public ILoRoadTripChunk addDirection(String driver, Direction dir) { if (first.hasDriver(driver)) { return new ConsLoRoadTripChunk(this.first.addDir(dir), this.rest); } else { return new ConsLoRoadTripChunk(new RoadTripChunk(driver, dir), this); } } }