94 lines
2.2 KiB
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
|
|
}
|