diff --git a/1ano/2semestre/poo/src/aula11/ex4/Company.java b/1ano/2semestre/poo/src/aula11/ex4/Company.java new file mode 100644 index 0000000..83b975e --- /dev/null +++ b/1ano/2semestre/poo/src/aula11/ex4/Company.java @@ -0,0 +1,19 @@ +package aula11.ex4; + +import java.util.LinkedList; +import java.util.Objects; + +public record Company(String code, String name, LinkedList flights) { + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Company company)) return false; + return Objects.equals(code, company.code) && Objects.equals(name, company.name) && Objects.equals(flights, company.flights); + } + + @Override + public int hashCode() { + return Objects.hash(code, name, flights); + } +} diff --git a/1ano/2semestre/poo/src/aula11/ex4/Flight.java b/1ano/2semestre/poo/src/aula11/ex4/Flight.java new file mode 100644 index 0000000..c52bec8 --- /dev/null +++ b/1ano/2semestre/poo/src/aula11/ex4/Flight.java @@ -0,0 +1,17 @@ +package aula11.ex4; + +import java.util.Objects; + +public record Flight(String code, String origin, Time departure, Time delay, Company company) { + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Flight flight)) return false; + return Objects.equals(code, flight.code) && Objects.equals(origin, flight.origin) && Objects.equals(departure, flight.departure) && Objects.equals(delay, flight.delay); + } + + @Override + public int hashCode() { + return Objects.hash(code, origin, departure, delay); + } +} diff --git a/1ano/2semestre/poo/src/aula11/ex4/FlightManager.java b/1ano/2semestre/poo/src/aula11/ex4/FlightManager.java new file mode 100644 index 0000000..9496d81 --- /dev/null +++ b/1ano/2semestre/poo/src/aula11/ex4/FlightManager.java @@ -0,0 +1,138 @@ +package aula11.ex4; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.*; +import java.io.*; +import java.util.stream.Collectors; + +public class FlightManager { + private final LinkedList companies = new LinkedList<>(); + private final LinkedList flights = new LinkedList<>(); + private String table; + private String delaysTable; + private String flightsNTable; + + public void loadCompanies(String filename) { + Scanner input; + try { + input = new Scanner(new FileReader(filename)); + input.nextLine(); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } + while(input.hasNext()){ + String line = input.nextLine(); + String[] fields = line.split("\t"); + if(fields.length != 2) + throw new RuntimeException("Invalid file format"); + this.companies.add(new Company(fields[0], fields[1], new LinkedList<>())); + } + } + + public void loadFlights(String filename) { + Scanner input; + try { + input = new Scanner(new FileReader(filename)); + input.nextLine(); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } + while (input.hasNext()) { + String line = input.nextLine(); + String[] fields = line.split("\t"); + if (fields.length != 3 && fields.length != 4) + throw new RuntimeException("Invalid file format"); + String[] timeStr = fields[0].split(":"); + Time time = new Time(Integer.parseInt(timeStr[0]), Integer.parseInt(timeStr[1])); + String code = fields[1]; + Company company = this.companies.stream().filter(c -> c.code().equals(code.substring(0, 2))).findFirst().orElse(null); + String origin = fields[2]; + String[] delayStr; + try { + delayStr = fields[3].split(":"); + } catch (IndexOutOfBoundsException e) { + delayStr = new String[]{"0", "0"}; + } + Time delay = new Time(Integer.parseInt(delayStr[0]), Integer.parseInt(delayStr[1])); + Flight flight = new Flight(code, origin, time, delay, company); + this.flights.add(flight); + Objects.requireNonNull(company).flights().add(flight); + } + } + + public void buildTable() { + StringBuilder table = new StringBuilder().append("Depart. Flight Company Origin Delay Obs\n"); + for (Flight flight : flights) + table.append(String.format("%-10s%-10s%-25s%-25s%-8s%s%n", flight.departure(), flight.code(), flight.company().name(), flight.origin(), flight.delay(), flight.delay().isZero() ? "" : "New departure: " + flight.departure().addTime(flight.delay()))); + this.table = table.toString(); + } + + public String getTable() { + return table; + } + + public void buildDelaysTable() { + StringBuilder table = new StringBuilder().append("Company Avg. Delay\n"); + LinkedHashMap delays = new LinkedHashMap<>(); + for (Company company : companies) { + Time totalTime = new Time(0, 0); + int nDelays = 0; + for (Flight flight : company.flights()) { + if (!flight.delay().isZero()) { + totalTime.addTime(flight.delay()); + nDelays++; + } + } + if (nDelays > 0) + delays.put(company.name(), Time.timeToMinsInt(totalTime) / nDelays); + } + delays = (LinkedHashMap) sortByValue(delays); + for (String compName : delays.keySet()) + table.append(String.format("%-25s%s%n", compName, Time.minsIntToTime(delays.get(compName)))); + this.delaysTable = table.toString(); + } + + public String getDelaysTable() { + return delaysTable; + } + + public void buildFlightsNTable() { + StringBuilder table = new StringBuilder().append("Origin n Flights\n"); + LinkedHashMap flightsFromOrigin = new LinkedHashMap<>(); + for (Flight flight : flights) + flightsFromOrigin.put(flight.origin(), flightsFromOrigin.getOrDefault(flight.origin(), 0) + 1); + flightsFromOrigin = (LinkedHashMap) sortByValue(flightsFromOrigin); + for (String origin : flightsFromOrigin.keySet()) + table.append(String.format("%-25s%s%n", origin, flightsFromOrigin.get(origin))); + this.flightsNTable = table.toString(); + } + + public String getFlightsNTable() { + return flightsNTable; + } + + public void storeTable(String filename) { + Path path = Path.of(filename); + try { + Files.writeString(path, getTable()); + } catch (IOException e) { + try { + Files.createFile(path); + storeTable(filename); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + } + + private static Map sortByValue(Map unsortMap) { + List> list = new LinkedList<>(unsortMap.entrySet()); + + // Sorting the list based on values + list.sort((o1, o2) -> o2.getValue().compareTo(o1.getValue()) == 0 + ? o2.getKey().compareTo(o1.getKey()) + : o2.getValue().compareTo(o1.getValue())); + return list.stream().collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> b, LinkedHashMap::new)); + } +} diff --git a/1ano/2semestre/poo/src/aula11/ex4/Main.java b/1ano/2semestre/poo/src/aula11/ex4/Main.java new file mode 100644 index 0000000..46c216f --- /dev/null +++ b/1ano/2semestre/poo/src/aula11/ex4/Main.java @@ -0,0 +1,21 @@ +package aula11.ex4; + +public class Main { + public static void main(String[] args) { + FlightManager fm = new FlightManager(); + + fm.loadCompanies("datafiles/aula11/ex4/companhias.txt"); + fm.loadFlights("datafiles/aula11/ex4/voos.txt"); + + fm.buildTable(); + System.out.println(fm.getTable()); + + fm.buildDelaysTable(); + System.out.println(fm.getDelaysTable()); + + fm.buildFlightsNTable(); + System.out.println(fm.getFlightsNTable()); + + fm.storeTable("datafiles/aula11/ex4/Infopublico.txt"); + } +} diff --git a/1ano/2semestre/poo/src/aula11/ex4/Time.java b/1ano/2semestre/poo/src/aula11/ex4/Time.java new file mode 100644 index 0000000..e9ee148 --- /dev/null +++ b/1ano/2semestre/poo/src/aula11/ex4/Time.java @@ -0,0 +1,52 @@ +package aula11.ex4; + +public class Time { + private int hour; + private int minute; + + public Time(int hour, int minute) { + if (hour < 0 || hour > 23 || minute < 0 || minute > 59) + throw new IllegalArgumentException("Invalid time"); + this.hour = hour; + this.minute = minute; + } + + public Time addTime(Time time) { + int newHour = hour + time.hour(); + int newMinute = minute + time.minute(); + if (newMinute >= 60) { + newHour++; + newMinute -= 60; + } + if (newHour >= 24) + newHour -= 24; + this.hour = newHour; + this.minute = newMinute; + return new Time(newHour, newMinute); + } + + public boolean isZero() { + return hour == 0 && minute == 0; + } + + @Override + public String toString() { + return String.format("%02d:%02d", hour, minute); + } + + public static int timeToMinsInt(Time time) { + return time.hour() * 60 + time.minute(); + } + + public static Time minsIntToTime(int mins) { + return new Time(mins/60, mins%60); + } + + public int hour() { + return hour; + } + + public int minute() { + return minute; + } +}