|
| 1 | +package com.adventofcode.flashk.day13; |
| 2 | + |
| 3 | +import com.adventofcode.flashk.common.Vector2; |
| 4 | + |
| 5 | +import java.util.regex.Matcher; |
| 6 | +import java.util.regex.Pattern; |
| 7 | + |
| 8 | +public class Machine { |
| 9 | + |
| 10 | + private static final Pattern BUTTONS_PATTERN = Pattern.compile("X\\+(\\d*), Y\\+(\\d*)"); |
| 11 | + private static final Pattern PRIZE_PATTERN = Pattern.compile("X=(\\d*), Y=(\\d*)"); |
| 12 | + |
| 13 | + private static final int TOKENS_A = 3; |
| 14 | + private static final int TOKENS_B = 1; |
| 15 | + |
| 16 | + private final Vector2 buttonA; |
| 17 | + private final Vector2 buttonB; |
| 18 | + private final Vector2 prizePosition; |
| 19 | + private final long prizePositionBX; |
| 20 | + private final long prizePositionBY; |
| 21 | + |
| 22 | + public Machine(String buttonA, String buttonB, String prize){ |
| 23 | + this.buttonA = initializeVector(buttonA); |
| 24 | + this.buttonB = initializeVector(buttonB); |
| 25 | + this.prizePosition = initializeVector(prize); |
| 26 | + this.prizePositionBX = prizePosition.getX() + 10000000000000L; |
| 27 | + this.prizePositionBY = prizePosition.getY() + 10000000000000L; |
| 28 | + |
| 29 | + } |
| 30 | + |
| 31 | + private Vector2 initializeVector(String entry) { |
| 32 | + if(entry.startsWith("Button")) { |
| 33 | + Matcher matcher = BUTTONS_PATTERN.matcher(entry); |
| 34 | + if(matcher.find()){ |
| 35 | + int xPos = Integer.parseInt(matcher.group(1)); |
| 36 | + int yPos = Integer.parseInt(matcher.group(2)); |
| 37 | + return new Vector2(xPos, yPos); |
| 38 | + } |
| 39 | + } else if(entry.startsWith("Prize")) { |
| 40 | + Matcher matcher = PRIZE_PATTERN.matcher(entry); |
| 41 | + if(matcher.find()){ |
| 42 | + int xPos = Integer.parseInt(matcher.group(1)); |
| 43 | + int yPos = Integer.parseInt(matcher.group(2)); |
| 44 | + return new Vector2(xPos, yPos); |
| 45 | + } |
| 46 | + } |
| 47 | + |
| 48 | + throw new IllegalArgumentException("Invalid entry"); |
| 49 | + } |
| 50 | + |
| 51 | + public void testMovement() { |
| 52 | + Vector2 initialPosition = new Vector2(0, 0); |
| 53 | + Vector2 finalPositionA = new Vector2(80 * buttonA.getX(), 80 * buttonA.getY()); |
| 54 | + Vector2 finalPositionB = new Vector2(40 * buttonB.getX(), 40 * buttonB.getY()); |
| 55 | + |
| 56 | + initialPosition.transform(finalPositionA); |
| 57 | + initialPosition.transform(finalPositionB); |
| 58 | + } |
| 59 | + |
| 60 | + public long optimize() { |
| 61 | + |
| 62 | + int minTokens = Integer.MAX_VALUE; |
| 63 | + |
| 64 | + for(int buttonAPresses = 0; buttonAPresses <= 100; buttonAPresses++) { |
| 65 | + for(int buttonBPresses = 0; buttonBPresses <= 100; buttonBPresses++) { |
| 66 | + Vector2 initialPosition = new Vector2(0, 0); |
| 67 | + Vector2 finalPositionA = new Vector2(buttonAPresses * buttonA.getX(), buttonAPresses * buttonA.getY()); |
| 68 | + Vector2 finalPositionB = new Vector2(buttonBPresses * buttonB.getX(), buttonBPresses * buttonB.getY()); |
| 69 | + |
| 70 | + initialPosition.transform(finalPositionA); |
| 71 | + initialPosition.transform(finalPositionB); |
| 72 | + |
| 73 | + if(initialPosition.equals(prizePosition)) { |
| 74 | + int tokens = buttonAPresses * TOKENS_A + buttonBPresses * TOKENS_B; |
| 75 | + minTokens = Math.min(minTokens, tokens); |
| 76 | + } |
| 77 | + } |
| 78 | + } |
| 79 | + |
| 80 | + return minTokens != Integer.MAX_VALUE ? minTokens : -1; |
| 81 | + } |
| 82 | + |
| 83 | + public long optimizeB() { |
| 84 | + |
| 85 | + // Ecuación lineal con dos incógnitas |
| 86 | + |
| 87 | + long axpy = buttonA.getX() * prizePositionBY; |
| 88 | + long aypx = buttonA.getY() * prizePositionBX; |
| 89 | + long axby = (long) buttonA.getX() * buttonB.getY(); |
| 90 | + long aybx = (long) buttonA.getY() * buttonB.getX(); |
| 91 | + |
| 92 | + long b = (axpy - aypx) / (axby - aybx); |
| 93 | + long a = (prizePositionBX - b * buttonB.getX()) / buttonA.getX(); |
| 94 | + |
| 95 | + long posX = a * buttonA.getX() + b * buttonB.getX(); |
| 96 | + long posY = a * buttonA.getY() + b * buttonB.getY(); |
| 97 | + |
| 98 | + if(posX == prizePositionBX && posY == prizePositionBY) { |
| 99 | + return a * TOKENS_A + b * TOKENS_B; |
| 100 | + } else { |
| 101 | + return -1; |
| 102 | + } |
| 103 | + |
| 104 | + } |
| 105 | + |
| 106 | +} |
0 commit comments