Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //STOP CORONA 2020
- //Must admit, battling the corona virus was personally easier than solving this task
- //I feel like it's 95% okay written, but 95% is far from solid accuracy when you're up against the likes of COVID-19
- import java.time.Duration;
- import java.time.LocalDateTime;
- import java.util.*;
- import java.time.Duration;
- import java.time.LocalDateTime;
- import java.util.*;
- import java.util.stream.Collectors;
- import java.util.ArrayList;
- import java.util.List;
- class UserAlreadyExistException extends Exception{
- public UserAlreadyExistException(String id) {
- super(String.format("User with id %s already exists.",id));
- }
- }
- class User {
- String id;
- String name;
- LocalDateTime coronaTimestamp;
- List<ILocation> locations;
- public User(String id, String name) {
- this.id = id;
- this.name = name;
- this.coronaTimestamp= LocalDateTime.now();
- this.locations = new ArrayList<>();
- }
- @Override
- public String toString() {
- return "User{" +
- "id='" + id + '\'' +
- ", name='" + name + '\'' +
- ", coronaTimestamp=" + coronaTimestamp;
- }
- public String getName() {
- return name;
- }
- public LocalDateTime getCoronaTimestamp() {
- return coronaTimestamp;
- }
- public String getId() {
- return id;
- }
- public void setLocations(List<ILocation> locations) {
- this.locations = locations;
- }
- public void setCoronaTimestamp(LocalDateTime coronaTimestamp) {
- this.coronaTimestamp = coronaTimestamp;
- }
- }
- class StopCoronaApp {
- Map<String,User> users;
- Map<String,List<ILocation>> locationsByUser;
- List<User> detectedCases;
- public StopCoronaApp() {
- this.users= new HashMap<>();
- this.locationsByUser = new HashMap<>();
- this.detectedCases = new ArrayList<>();
- }
- public void addUser(String name, String id) throws UserAlreadyExistException {
- if(users.containsKey(id))
- throw new UserAlreadyExistException(id);
- users.putIfAbsent(id, new User(id, name));
- }
- public void addLocations(String id, List<ILocation> locations) {
- locationsByUser.putIfAbsent(id, new ArrayList<>(locations));
- users.get(id).locations = locations;
- }
- public void detectNewCase(String id, LocalDateTime timestamp) {
- detectedCases.add(users.get(id));
- users.get(id).setCoronaTimestamp(timestamp);
- }
- public Map<User, Long> getDirectContacts (User u){
- Map<User,Long> directContacts = new HashMap<>();
- for(User user : users.values()){
- if(user.equals(u))
- continue;
- long contactsMade=0l;
- for(ILocation location : user.locations){
- contactsMade += u.locations.stream()
- .filter(i->Math.abs(Duration.between(i.getTimestamp(),
- location.getTimestamp()).toMinutes())<=5&&
- Math.abs(Math.pow((i.getLatitude()-location.getLatitude()),2)+
- Math.pow(i.getLongitude()-location.getLongitude(),2))<=4).count();
- }
- directContacts.put(user,contactsMade);
- }
- return directContacts.entrySet().stream()
- .sorted(Comparator.comparing((Map.Entry<User,Long> entry)->entry.getValue(),Comparator.reverseOrder()))
- .collect(Collectors.toMap(
- entry->entry.getKey(),
- entry->entry.getValue(),
- (e1,e2)->e1,
- LinkedHashMap::new
- ));
- }
- public Collection<User> getIndirectContacts (User u){
- Map<User,Long> directContacts = getDirectContacts(u);
- Set<User> indirectContacts = new HashSet<>();
- for(User user : directContacts.keySet()){
- Map<User,Long> directContactsFromDirectContacts = getDirectContacts(user);
- for(User indirectUser : directContactsFromDirectContacts.keySet()){
- if(directContacts.containsKey(indirectUser)){
- continue;
- }
- indirectContacts.add(indirectUser);
- }
- }
- return indirectContacts;
- }
- public void createReport() {
- int totalDirectContacts = 0;
- int totalIndirectContacts = 0;
- for(User user : detectedCases.stream().sorted(Comparator.comparing(User::getCoronaTimestamp)).collect(Collectors.toList())){
- System.out.println(String.format("%s %s %s",
- user.name,
- user.id,
- user.coronaTimestamp));
- System.out.println("Direct contacts:");
- Map<User,Long> directContacts = getDirectContacts(user);
- for(Map.Entry<User,Long> entry : directContacts.entrySet()){
- if(entry.getValue()==0)
- continue;
- System.out.println(String.format("%s %s %d",
- entry.getKey().getName(),
- entry.getKey().getId().substring(0,5).concat("***"),
- entry.getValue()));
- }
- System.out.println(String.format("Count of direct contacts: %d",
- directContacts.values().stream().mapToLong(i->i).sum()));
- totalDirectContacts+=directContacts.values().stream().mapToLong(i->i).sum();
- System.out.println("Indirect contacts:");
- for(User indirectUser : getIndirectContacts(user)){
- System.out.println(String.format("%s %s",
- indirectUser.getName(),
- indirectUser.getId().substring(0,5).concat("***")));
- }
- System.out.println(String.format("Count of indirect contacts: %d",getIndirectContacts(user).size()));
- totalIndirectContacts+=getIndirectContacts(user).size();
- }
- System.out.println(String.format("Average direct contacts: %.4f",(double)totalDirectContacts/detectedCases.size()));
- System.out.println(String.format("Average indirect contacts: %.4f",(double)totalIndirectContacts/detectedCases.size()));
- }
- }
- interface ILocation{
- double getLongitude();
- double getLatitude();
- LocalDateTime getTimestamp();
- }
- public class StopCoronaTest {
- public static double timeBetweenInSeconds(ILocation location1, ILocation location2) {
- return Math.abs(Duration.between(location1.getTimestamp(), location2.getTimestamp()).getSeconds());
- }
- public static void main(String[] args) {
- Scanner sc = new Scanner(System.in);
- StopCoronaApp stopCoronaApp = new StopCoronaApp();
- while (sc.hasNext()) {
- String line = sc.nextLine();
- String[] parts = line.split("\\s+");
- switch (parts[0]) {
- case "REG": //register
- String name = parts[1];
- String id = parts[2];
- try {
- stopCoronaApp.addUser(name, id);
- } catch (UserAlreadyExistException e) {
- System.out.println(e.getMessage());
- }
- break;
- case "LOC": //add locations
- id = parts[1];
- List<ILocation> locations = new ArrayList<>();
- for (int i = 2; i < parts.length; i += 3) {
- locations.add(createLocationObject(parts[i], parts[i + 1], parts[i + 2]));
- }
- stopCoronaApp.addLocations(id, locations);
- break;
- case "DET": //detect new cases
- id = parts[1];
- LocalDateTime timestamp = LocalDateTime.parse(parts[2]);
- stopCoronaApp.detectNewCase(id, timestamp);
- break;
- case "REP": //print report
- stopCoronaApp.createReport();
- break;
- default:
- break;
- }
- }
- }
- private static ILocation createLocationObject(String lon, String lat, String timestamp) {
- return new ILocation() {
- @Override
- public double getLongitude() {
- return Double.parseDouble(lon);
- }
- @Override
- public double getLatitude() {
- return Double.parseDouble(lat);
- }
- @Override
- public LocalDateTime getTimestamp() {
- return LocalDateTime.parse(timestamp);
- }
- };
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement