adventofcode/2024/day13/main.go

94 lines
2.2 KiB
Go

package main
import (
"fmt"
"math"
h "git.bullercodeworks.com/brian/adventofcode/helpers"
)
func main() {
inp := h.StdinToStringSlice()
part1(inp)
fmt.Println()
part2(inp)
}
func part1(inp []string) {
fmt.Println("# Part 1")
games := parseInput(inp)
var total int
for i := range games {
tokens := games[i].Solve()
if tokens > 0 {
total = total + tokens
}
}
fmt.Println("Total Tokens:", total)
}
func part2(inp []string) {
fmt.Println("# Part 2")
games := parseInput(inp)
var total int
for i := range games {
games[i].Prize.X += 10000000000000
games[i].Prize.Y += 10000000000000
tokens := games[i].Solve()
if tokens > 0 {
total = total + tokens
}
}
fmt.Println("Total Tokens:", total)
}
type Game struct {
Line1 h.Coordinate
Line2 h.Coordinate
Prize h.Coordinate
}
/*
Our answer is, in algebraic terms:
(g.Line1.X * n) + (g.Line2.X * m) = g.Prize.X
(g.Line1.Y * n) + (g.Line2.Y * m) = g.Prize.Y
where n is the number of 'A' button presses
and m is the number of 'B' button presses
Solving for n & m gives us these formulas:
n = (g.Prize.X * g.Line2.Y - g.Prize.Y * g.Line2.X) / (g.Line1.X * g.Line2.Y - g.Line2.x * g.Line1.Y)
m = (g.Prize.X - g.Line1.X * n) / g.Line2.X
Then just make sure that n and m are integers
*/
func (g *Game) Solve() int {
n := float64(g.Prize.X*g.Line2.Y-g.Prize.Y*g.Line2.X) / float64(g.Line1.X*g.Line2.Y-g.Line2.X*g.Line1.Y)
m := (float64(g.Prize.X) - float64(g.Line1.X)*n) / float64(g.Line2.X)
if math.Mod(n, 1) != 0 || math.Mod(m, 1) != 0 {
return -1
}
return int(n)*3 + int(m)
}
func parseInput(inp []string) []Game {
var res []Game
for i := 0; i < len(inp); {
var line1, line2, prize h.Coordinate
fmt.Sscanf(inp[i], "Button A: X+%d, Y+%d", &line1.X, &line1.Y)
fmt.Sscanf(inp[i+1], "Button B: X+%d, Y+%d", &line2.X, &line2.Y)
fmt.Sscanf(inp[i+2], "Prize: X=%d, Y=%d", &prize.X, &prize.Y)
g := Game{
Line1: line1, Line2: line2, Prize: prize,
}
res = append(res, g)
i = i + 4
}
return res
}
func (g Game) String() string {
res := fmt.Sprintf("Button A: X+%d, Y+%d\n", g.Line1.X, g.Line1.Y)
res = fmt.Sprintf("%sButton B: X+%d, Y+%d\n", res, g.Line2.X, g.Line2.Y)
res = fmt.Sprintf("%sPrize: X=%d, Y=%d", res, g.Prize.X, g.Prize.Y)
return res
}