77 lines
1.8 KiB
Go
77 lines
1.8 KiB
Go
package day13
|
|
|
|
import (
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
type ClawMachine struct {
|
|
Ax, Ay int
|
|
Bx, By int
|
|
Px, Py int
|
|
}
|
|
|
|
func Part1(input string) int {
|
|
clawMachines := parseInput(input)
|
|
total := 0
|
|
for _, c := range clawMachines {
|
|
x, y := solveSimEquations(c.Ax, c.Bx, c.Px, c.Ay, c.By, c.Py)
|
|
total += x*3 + y
|
|
}
|
|
return total
|
|
}
|
|
|
|
func Part2(input string) int {
|
|
clawMachines := parseInput(input)
|
|
total := 0
|
|
for _, c := range clawMachines {
|
|
prizeX, prizeY := c.Px+10000000000000, c.Py+10000000000000
|
|
det, x, y := c.Ax*c.By-c.Bx*c.Ay, prizeX*c.By-c.Bx*prizeY, c.Ax*prizeY-prizeX*c.Ay
|
|
if det != 0 && x == (x/det)*det && y == (y/det)*det {
|
|
total += (x/det)*3 + (y / det)
|
|
}
|
|
}
|
|
|
|
return total
|
|
}
|
|
|
|
func parseInput(input string) []ClawMachine {
|
|
clawMachines := strings.Split(strings.TrimSpace(input), "\n\n")
|
|
output := make([]ClawMachine, 0, len(clawMachines))
|
|
for _, c := range clawMachines {
|
|
var clawMachine ClawMachine
|
|
line := strings.Split(strings.TrimSpace(c), "\n")
|
|
|
|
re := regexp.MustCompile(`X\+(\d+), Y\+(\d+)`)
|
|
matches := re.FindStringSubmatch(line[0])
|
|
clawMachine.Ax, _ = strconv.Atoi(matches[1])
|
|
clawMachine.Ay, _ = strconv.Atoi(matches[2])
|
|
|
|
matches = re.FindStringSubmatch(line[1])
|
|
clawMachine.Bx, _ = strconv.Atoi(matches[1])
|
|
clawMachine.By, _ = strconv.Atoi(matches[2])
|
|
|
|
re = regexp.MustCompile(`X=(\d+), Y=(\d+)`)
|
|
matches = re.FindStringSubmatch(line[2])
|
|
clawMachine.Px, _ = strconv.Atoi(matches[1])
|
|
clawMachine.Py, _ = strconv.Atoi(matches[2])
|
|
|
|
output = append(output, clawMachine)
|
|
}
|
|
return output
|
|
}
|
|
|
|
func solveSimEquations(a1, b1, c1, a2, b2, c2 int) (int, int) {
|
|
det := a1*b2 - a2*b1
|
|
if det == 0 || (c1*b2-c2*b1)%det != 0 || (a1*c2-a2*c1)%det != 0 {
|
|
return 0, 0
|
|
}
|
|
x := (c1*b2 - c2*b1) / det
|
|
y := (a1*c2 - a2*c1) / det
|
|
if x < 0 || x > 100 || y < 0 || y > 100 {
|
|
return 0, 0
|
|
}
|
|
return x, y
|
|
}
|