package io.anand.sandbox;

import java.util.ArrayList;
import java.util.HashMap;

public class MaxPopulation {

    private static class Person {
        private int birth;

        public int getBirth() {
            return birth;
        }

        public void setBirth(int birth) {
            this.birth = birth;
        }

        public int getDeath() {
            return death;
        }

        public void setDeath(int death) {
            this.death = death;
        }

        private int death;
    }

    private static int firstYear = Integer.MAX_VALUE;
    private static int lastYear  = 0;
    private ArrayList<Person>   people = new ArrayList<>();
    private static HashMap<Integer, Integer> births = new HashMap<>();
    private static HashMap<Integer, Integer> deaths = new HashMap<>();

    private static int maxPopulationYear (int start, int end)
    {
        int year, maxYear;
        int population, maxPopulation;

        year = maxYear = start;
        population = maxPopulation = 0;

        int numYears = 0;
        while (year <= end) {
            int bYear = year;
// This will not work well since we will skip the non-birth years and deaths that reduce population
// will get skipped. So we have to run through the first birth year to last birth year all years.
// for (int bYear : births.keySet()) {
            population += births.getOrDefault(bYear, 0) - deaths.getOrDefault(bYear, 0);
            if (maxPopulation < population) {
                maxPopulation = population;
                maxYear = bYear;
            }
            year++;
            numYears++;
        }
        System.out.println("Searched (" + numYears + ") years from: " + firstYear + " to: " + lastYear);
        System.out.println("Year: " + maxYear + " had maximum population of: " + maxPopulation);
        return maxYear;
    }

    private static int maxPopulationYear () {
        return maxPopulationYear(firstYear, lastYear);
    }


    // Assume -1 for death means person still alive
    private static void addPerson (int birth, int death) {
        if (firstYear > birth) firstYear = birth;
        if (lastYear < birth) lastYear = birth;
        births.put(birth, 1 + births.getOrDefault(birth, 0));
        // Count deaths for next year, so that person is counted in the last year of
        // their life. if not desired, then don't increment.
        if (death > 0)
            deaths.put(death + 1, 1 + deaths.getOrDefault(death, 0));
    }

    public static void main (String args[]) {

        /* Prepare Data
        births.put(1940, 100);
        births.put(1950, 20);
        births.put(1990, 100);

        deaths.put(1950, 10);
        deaths.put(1960, 10);
        deaths.put(1970, 30);
        deaths.put(1995, 40);
        */
        addPerson(1940, 1976);
        addPerson(1965, 2010);
        addPerson(1990, 2034);
        addPerson(1990, 1994);
        addPerson(1980, 1987);
        addPerson(1950, -1);
        addPerson(1951, 1978);
        addPerson(1967, 2004);
        addPerson(1990, 2003);
        addPerson(1956, 1978);
        addPerson(1991, 2006);
        addPerson(1999, 1999);
        addPerson(1980, 1996);
        addPerson(1998, -1);
        addPerson(1998, -1);
        addPerson(1999, 2017);
        // Prepare list by adding people to the array list


        System.out.println("Births: " + births);
        System.out.println("Deaths: " + deaths);
        maxPopulationYear();
    }
}

@@ -139,16 +139,137 @@
 erson %7B%0A
+        public Person(int birth, int death) %7B%0A            this.birth = birth;%0A            this.death = death;%0A        %7D%0A%0A
         
@@ -618,24 +618,140 @@
 e int death;
+%0A%0A        @Override%0A        public String toString() %7B%0A            return %22 %22 + birth + %22:%22 + death + %22 %22;%0A        %7D
 %0A    %7D%0A%0A    
@@ -850,16 +850,23 @@
 private 
+static 
 ArrayLis
@@ -954,85 +954,24 @@
 er%3E 
-births = new HashMap%3C%3E();%0A    private static HashMap%3CInteger, Integer%3E deaths
+yearlyPopulation
  = n
@@ -1499,22 +1499,26 @@
 bYear : 
-births
+population
 .keySet(
@@ -1552,46 +1552,24 @@
  += 
-births.getOrDefault(bYear, 0) - deaths
+yearlyPopulation
 .get
@@ -2343,36 +2343,56 @@
     
-births.put(birth, 1 + births
+yearlyPopulation.put(birth, 1 + yearlyPopulation
 .get
@@ -2590,30 +2590,40 @@
             
-deaths
+yearlyPopulation
 .put(death +
@@ -2630,22 +2630,32 @@
  1, 1 + 
-deaths
+yearlyPopulation
 .getOrDe
@@ -2668,24 +2668,131 @@
 death, 0));%0A
+        // Not needed, just for display for sanity checking.%0A        people.add(new Person(birth, death));%0A
     %7D%0A%0A    p
@@ -3631,17 +3631,16 @@
 y list%0A%0A
-%0A
         
@@ -3663,26 +3663,26 @@
 ln(%22
-Births: %22 + births
+People: %22 + people
 );%0A 
@@ -3712,26 +3712,47 @@
 ln(%22
-Deaths
+Yearly Population
 : %22 + 
-deaths
+yearlyPopulation
 );%0A 

Use single population hashmap instead of two, Also populate person array to dump it for debug, not needed for solving the problem itself.