Home > Mobile >  Writing function findEpidemics
Writing function findEpidemics

Time:10-17

I need to make a function public Collection findEpidemics(List diagnoses, int k, int n) that determines if a disease is a epidemic, and returns a list of the diseases that are epidemic. We say a disease is a epidemic if it occurs more than n times during k consecutive days. The Diagnosis class is public Diagnosis(Disease disease, int day) and has functions getDisease() and getDay().

The list diagnoses looks something like this:

Disease cholera = new Disease("cholera");
Disease dengue = new Disease("dengue");
List<Diagnosis> diagnoses = Arrays.asList(
new Diagnosis(cholera, 0), // registered cholera on day 0
new Diagnosis(cholera, 0),
new Diagnosis(cholera, 1),
new Diagnosis(dengue, 2),
new Diagnosis(dengue, 2),
// we have a gap here 
new Diagnosis(cholera, 6),

So what I've done is making a hashmap collect that contains all the occurrences of the diseases for each day so it may for example look like this: {{cholera, 0}=2, {cholera, 1}=1, {dengue, 2}=2, {cholera, 6}=1}

 public Collection<String> findEpidemics(List<Diagnosis> diagnoses, int k, int n) {
    
     // first we count occurences 
     Map<DiagnosisMetric, Long> collect = diagnoses.stream().
            collect(Collectors.groupingBy(DiagnosisMetric::new, counting()));
    
   // check for epidemic 
   for(int i=0; i<collect.size(); i  ){
     for(int j=0; j<k; j  ){
          ???
    }
  }

}

I'm kind of stuck on the part of checking if a disease is a epidemic so I'm stuck on how I can loop over the hashmap and check if the occurrence of a certain disease is more then n for those k consecutive days.

CodePudding user response:

After you get the mapping, you can continue checking for the pandemic using sliding window over the list of the entries.

    public static void findEpidemics(List<Diagnosis> diagnoses, int k, int n) {
        Map<DiagnosisMetric, Long> collect = diagnoses.stream().collect(Collectors.groupingBy(DiagnosisMetric::new, counting()));
        Map<String, List<Map.Entry<DiagnosisMetric, Long>>> diseaseByName = collect.entrySet().stream().collect(Collectors.groupingBy(diagnosisMetricLongEntry -> diagnosisMetricLongEntry.getKey().getDiagnosis().getDisease().getName()));
        List<String> pandemics = diseaseByName.entrySet().stream().collect(Collectors.partitioningBy(e -> isPandemic(e, n, k))).getOrDefault(true, Collections.emptyList()).stream().map(m -> m.getKey()).collect(Collectors.toList());
        System.out.println(pandemics);
    }

    public static boolean isPandemic(Map.Entry<String, List<Map.Entry<DiagnosisMetric, Long>>> e, int n, int k) {
        List<Map.Entry<DiagnosisMetric, Long>> collect = e.getValue().stream().sorted(Comparator.comparingInt(o -> o.getKey().getDiagnosis().getDay())).collect(Collectors.toList());
        int s = collect.size();
        Long sum = 0L;
        if(s < k) {
            return false;
        }
        Queue<Long> q = new ArrayDeque<>();
        for(int i = 0; i < k; i  ) {
            Long value = collect.get(i).getValue();
            q.add(value);
            sum  = value;
            if(sum > n) {
                return true;
            }
        }
        for(int j = k; j < s; j  ) {
            Long value = collect.get(j).getValue();
            Long lastValue = q.poll();
            sum = sum - lastValue;
            q.add(value);
            sum  = value;
            if(sum > n) {
                return true;
            }
        }
        return false;
    }

The implementation is rather rudimentary, but you can use Sliding window technique for this.

  • Related