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 }