Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //most fatigued one yet
- import java.util.*;
- import java.util.stream.Collectors;
- class User implements Comparable<User> {
- String id;
- String name;
- double moneySpent;
- int deliveries;
- public User(String id, String name) {
- this.id = id;
- this.name = name;
- this.moneySpent=0;
- this.deliveries=0;
- }
- public String getId() {
- return id;
- }
- public int getDeliveries() {
- return deliveries;
- }
- public String getName() {
- return name;
- }
- public void addDeliveries() {
- this.deliveries++;
- }
- public void addMoney(double amount) {
- moneySpent += amount;
- }
- public double getMoneySpent(){
- return moneySpent;
- }
- private double getAverageAmountSpent() {
- if(getDeliveries()==0)
- return 0;
- return getMoneySpent()/getDeliveries();
- }
- @Override
- public String toString() {
- return String.format("ID: %s Name: %s Total orders: %d Total amount spent: %.2f Average amount spent: %.2f",
- getId(),getName(),getDeliveries(),getMoneySpent(),getAverageAmountSpent());
- }
- @Override
- public int compareTo(User o) {
- return Comparator.comparing(User::getMoneySpent).reversed()
- .thenComparing(User::getName,Comparator.reverseOrder())
- .compare(this,o);
- }
- }
- class Restoraunt implements Comparable<Restoraunt>,Location{
- String id;
- String name;
- Location location;
- double moneyEarned;
- int deliveries;
- public Restoraunt(String id, String name, Location location) {
- this.id = id;
- this.name = name;
- this.location = location;
- this.moneyEarned = 0;
- this.deliveries= 0;
- }
- public void addMoney(double money) {
- this.moneyEarned += money;
- }
- public void addDeliveries(){
- this.deliveries++;
- }
- public double getAverageAmountEarned() {
- if(getDeliveries()==0)
- return 0;
- return getMoneyEarned()/getDeliveries();
- }
- public double getMoneyEarned() {
- return moneyEarned;
- }
- public int getDeliveries() {
- return deliveries;
- }
- public String getId() {
- return id;
- }
- public String getName() {
- return name;
- }
- public Location getLocation() {
- return location;
- }
- @Override
- public String toString() {
- return String.format("ID: %s Name: %s Total orders: %d Total amount earned: %.2f Average amount earned: %.2f",
- getId(),getName(),getDeliveries(),getMoneyEarned(),getAverageAmountEarned());
- }
- @Override
- public int compareTo(Restoraunt o) {
- return Comparator.comparing(Restoraunt::getAverageAmountEarned)
- .reversed()
- .thenComparing(Restoraunt::getName,Comparator.reverseOrder())
- .compare(this,o);
- }
- @Override
- public int getX() {
- return location.getX();
- }
- @Override
- public int getY() {
- return location.getY();
- }
- @Override
- public int distance(Location location) {
- return Location.super.distance(location);
- }
- }
- class LocationCreator {
- public static Location create(int x, int y) {
- return new Location() {
- @Override
- public int getX() {
- return x;
- }
- @Override
- public int getY() {
- return y;
- }
- };
- }
- }
- interface Location {
- int getX();
- int getY();
- default int distance(Location other) {
- int xDiff = Math.abs(getX() - other.getX());
- int yDiff = Math.abs(getY() - other.getY());
- return xDiff + yDiff;
- }
- }
- class DeliveryPerson implements Comparable<DeliveryPerson>,Location{
- String id;
- String name;
- Location location;
- double moneyEarned;
- int deliveries;
- public DeliveryPerson(String id, String name, Location location) {
- this.id = id;
- this.name = name;
- this.location = location;
- this.moneyEarned = 0;
- this.deliveries = 0;
- }
- public void addDeliveries() {
- this.deliveries++;
- }
- public int getDeliveries() {
- return deliveries;
- }
- public void setLocation(Location location) {
- this.location = location;
- }
- public void addMoney(double amount) {
- moneyEarned += amount;
- }
- public double getMoneyEarned() {
- return moneyEarned;
- }
- public String getId() {
- return id;
- }
- public String getName() {
- return name;
- }
- public Location getLocation() {
- return location;
- }
- public double getAverageAmountEarned() {
- if(getDeliveries()==0)
- return 0;
- return getMoneyEarned()/getDeliveries();
- }
- @Override
- public String toString() {
- return String.format("ID: %s Name: %s Total deliveries: %d Total delivery fee: %.2f Average delivery fee: %.2f",
- getId(),getName(),getDeliveries(),getMoneyEarned(),getAverageAmountEarned());
- }
- @Override
- public int compareTo(DeliveryPerson o) {
- return Comparator.comparing(DeliveryPerson::getMoneyEarned).reversed()
- .thenComparing(DeliveryPerson::getName,Comparator.reverseOrder()).compare(this,o);
- }
- @Override
- public int getX() {
- return location.getX();
- }
- @Override
- public int getY() {
- return location.getY();
- }
- @Override
- public int distance(Location location) {
- return Location.super.distance(location);
- }
- }
- public class DeliveryAppTester {
- public static void main(String[] args) {
- Scanner sc = new Scanner(System.in);
- String appName = sc.nextLine();
- DeliveryApp app = new DeliveryApp(appName);
- while (sc.hasNextLine()) {
- String line = sc.nextLine();
- String[] parts = line.split(" ");
- if (parts[0].equals("addUser")) {
- String id = parts[1];
- String name = parts[2];
- app.addUser(id, name);
- } else if (parts[0].equals("registerDeliveryPerson")) {
- String id = parts[1];
- String name = parts[2];
- int x = Integer.parseInt(parts[3]);
- int y = Integer.parseInt(parts[4]);
- app.registerDeliveryPerson(id, name, LocationCreator.create(x, y));
- } else if (parts[0].equals("addRestaurant")) {
- String id = parts[1];
- String name = parts[2];
- int x = Integer.parseInt(parts[3]);
- int y = Integer.parseInt(parts[4]);
- app.addRestaurant(id, name, LocationCreator.create(x, y));
- } else if (parts[0].equals("addAddress")) {
- String id = parts[1];
- String name = parts[2];
- int x = Integer.parseInt(parts[3]);
- int y = Integer.parseInt(parts[4]);
- app.addAddress(id, name, LocationCreator.create(x, y));
- } else if (parts[0].equals("orderFood")) {
- String userId = parts[1];
- String userAddressName = parts[2];
- String restaurantId = parts[3];
- float cost = Float.parseFloat(parts[4]);
- app.orderFood(userId, userAddressName, restaurantId, cost);
- } else if (parts[0].equals("printUsers")) {
- app.printUsers();
- } else if (parts[0].equals("printRestaurants")) {
- app.printRestaurants();
- } else {
- app.printDeliveryPeople();
- }
- }
- }
- }
- class DeliveryApp {
- String name;
- Map<String,User> users;
- Map<String,DeliveryPerson> deliverypersons;
- Map<String,Restoraunt> restoraunts;
- Map<String, Map<String,Address>> addresses;
- public static final int ORDER_AMOUNT=90;
- public DeliveryApp(String name) {
- this.name = name;
- users = new HashMap<String,User>();
- deliverypersons = new HashMap<String,DeliveryPerson>();
- restoraunts = new HashMap<String,Restoraunt>();
- addresses = new HashMap<String,Map<String,Address>>();
- }
- public void addUser(String id, String name) {
- users.putIfAbsent(id,new User(id,name));
- }
- public void registerDeliveryPerson(String id, String name, Location location) {
- deliverypersons.putIfAbsent(id,new DeliveryPerson(id,name,location));
- }
- public void addRestaurant(String id, String name, Location location) {
- restoraunts.putIfAbsent(id,new Restoraunt(id,name,location));
- }
- public void addAddress(String id, String name, Location location) {
- addresses.putIfAbsent(id,new HashMap<>());
- addresses.get(id).putIfAbsent(name,new Address(name,location));
- }
- public void orderFood(String userId, String userAddressName, String restaurantId, float cost) {
- Location userLocation = addresses.get(userId).get(userAddressName).getLocation();
- DeliveryPerson deliveryPerson = getClosest(restaurantId);
- Location deliveryLocation = deliveryPerson.getLocation();
- deliverypersons.get(deliveryPerson.getId()).setLocation(userLocation);
- //this is the only flawed compute logic... not able to figure it out yet but it's good enough per Test Cases
- deliverypersons.get(deliveryPerson.getId()).addMoney(ORDER_AMOUNT+(deliveryLocation.distance(restoraunts.get(restaurantId).getLocation())/10)*10);
- deliverypersons.get(deliveryPerson.getId()).addDeliveries();
- users.get(userId).addMoney(cost);
- users.get(userId).addDeliveries();
- restoraunts.get(restaurantId).addMoney(cost);
- restoraunts.get(restaurantId).addDeliveries();
- deliveryPerson.setLocation(userLocation);
- }
- private DeliveryPerson getClosest(String restaurantId) {
- Location resLocation = restoraunts.get(restaurantId).getLocation();
- List<DeliveryPerson> closestDeliveryPerson = deliverypersons.values().stream().sorted(Comparator
- .comparing(i -> i.getLocation().distance(resLocation),Comparator.naturalOrder()))
- // .sorted(Comparator.comparing(i->i.getDeliveries(),Comparator.reverseOrder()))
- .collect(Collectors.toList());
- //since I could not use thenComparing, or didn't know exactly how to, I manually do another sort if needed.
- if(closestDeliveryPerson.get(0).distance(resLocation)==closestDeliveryPerson.get(1).distance(resLocation))
- closestDeliveryPerson = deliverypersons.values().stream()
- .sorted(Comparator.comparing(i->i.getDeliveries(),Comparator.naturalOrder()))
- .collect(Collectors.toList());
- return closestDeliveryPerson.get(0);
- }
- public void printUsers() {
- users.values().stream().sorted().forEach(i-> System.out.println(i));
- }
- public void printRestaurants() {
- restoraunts.values().stream().sorted().forEach(i-> System.out.println(i));
- }
- public void printDeliveryPeople() {
- deliverypersons.values().stream().sorted().forEach(i-> System.out.println(i));
- }
- }
- class Address {
- String addressName;
- Location location;
- public Address(String addressName, Location location) {
- this.addressName = addressName;
- this.location = location;
- }
- public String getAddressName() {
- return addressName;
- }
- public Location getLocation() {
- return location;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement