import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


class Day15 {
	
	//private final static String FILENAME = ".\\InputDay15.txt";
	private final static Pattern PATTERN = Pattern.compile("(?<name>.+): capacity (?<cap>-??\\d+), durability (?<dur>-??\\d+), flavor (?<flav>-??\\d+), texture (?<tex>-??\\d+), calories (?<cal>-??\\d+)");
	
	private List<Ingredient> recipe = new ArrayList<>(); 
	
	class Ingredient{
		String name;
		int capacity;
		int durability;
		int flavor;
		int texture;
		int calories;
		
		public Ingredient(String s) {
			Matcher m=PATTERN.matcher(s);
			
			if(m.matches()) {
				name = m.group("name");
				capacity = Integer.parseInt(m.group("cap"));
				durability = Integer.parseInt(m.group("dur"));
				flavor = Integer.parseInt(m.group("flav"));
				texture = Integer.parseInt(m.group("tex"));
				calories = Integer.parseInt(m.group("cal"));
			}
		}
		
		public int getTotalCapacity(int amount) {
			return capacity * amount;
		}
		
		public int getTotalDurability(int amount) {
			return durability * amount;
		}
		
		public int getTotalFlavor(int amount) {
			return flavor * amount;
		}
		
		public int getTotalTexture(int amount) {
			return texture * amount;
		}
		
		public int getTotalCalories(int amount) {
			return calories * amount;
		}
		
		
		@Override
		public String toString() {
			return String.format("%s: capacity %d, durability %d, flavor %d, texture %d, calories %d", name, capacity, durability, flavor, texture, calories);
		}
	}
	
	public Day15() {
		List<String> data = new ArrayList<>();
		data.add("Frosting: capacity 4, durability -2, flavor 0, texture 0, calories 5");
		data.add("Candy: capacity 0, durability 5, flavor -1, texture 0, calories 8");
		data.add("Butterscotch: capacity -1, durability 0, flavor 5, texture 0, calories 6");
		data.add("Sugar: capacity 0, durability 0, flavor -2, texture 2, calories 1");
		
		for(String s : data) {
			Ingredient i = new Ingredient(s);
			recipe.add(i);
		}
		
	}
	
	public static void main(String[] args) {
		Day15 day15 = new Day15();
		
		day15.doPart1();
		day15.doPart2();
		
	}

	public void doPart1() {
		long startTime = System.currentTimeMillis();
		int maxScore = maxScore(recipe);
		long endTime = System.currentTimeMillis();
		
		System.out.println("Max Cookie Score: " + maxScore + " Calculation took: " + (((double)(endTime-startTime))/1000) + "s");
	}
	
	public void doPart2() {
		long startTime = System.currentTimeMillis();
		int maxScore = maxScore2(recipe);
		long endTime = System.currentTimeMillis();
		
		System.out.println("Max Cookie Score with 500 calories: " + maxScore + " Calculation took: " + (((double)(endTime-startTime))/1000) + "s");
		
	}
	
	
	public int score(List<Integer> amounts) {
		int cap = 0;
		int dur = 0;
		int flav = 0;
		int tex = 0;
		for(int i=0; i<recipe.size(); i++) {
			cap += recipe.get(i).getTotalCapacity(amounts.get(i));
			dur += recipe.get(i).getTotalDurability(amounts.get(i));
			flav += recipe.get(i).getTotalFlavor(amounts.get(i));
			tex += recipe.get(i).getTotalTexture(amounts.get(i));
		}
		cap = (cap < 0) ? 0 : cap;
		dur = (dur < 0) ? 0 : dur;
		flav = (flav < 0) ? 0 : flav;
		tex = (tex < 0) ? 0 : tex;
	
		return cap * dur * flav * tex;
	}
	
	public int getCalories(List<Integer> amounts) {
		int cal = 0;
		for(int i=0; i<recipe.size(); i++) {
			cal += recipe.get(i).getTotalCalories(amounts.get(i));
		}
		return cal;
	}
	
	public int maxScore(List<Ingredient> recipe) {
		int maxScore = Integer.MIN_VALUE;
		for(int i=0; i <= 100; i++) {
			for(int j=0; j<=100; j++) {
				for(int k=0; k<=100; k++) {
					for(int l=0; l <= 100; l++) {
						if((i+j+k+l) == 100) {
							List<Integer> amounts = new ArrayList<>();
							amounts.add(i);
							amounts.add(j);
							amounts.add(k);
							amounts.add(l);
							int score = score(amounts);
							if (score > maxScore) {
								maxScore = score;
							}
						}
					}
				}
			}
		}
		return maxScore;
	}
	
	public int maxScore2(List<Ingredient> recipe) {
		int maxScore = Integer.MIN_VALUE;
		for(int i=0; i <= 100; i++) {
			for(int j=0; j<=100; j++) {
				for(int k=0; k<=100; k++) {
					for(int l=0; l <= 100; l++) {
						if((i+j+k+l) == 100) {
							List<Integer> amounts = new ArrayList<>();
							amounts.add(i);
							amounts.add(j);
							amounts.add(k);
							amounts.add(l);
							int score = score(amounts);
							if ((getCalories(amounts) == 500) && (score > maxScore)) {
								maxScore = score;
							}
						}
					}
				}
			}
		}
		return maxScore;
	}
	
}
