Updated with day 13

This commit is contained in:
Ceferino Patino 2024-12-13 01:27:40 -06:00
commit 950eded2b1
Signed by: c4patino
SSH key fingerprint: SHA256:Wu+cU1t+7zVT9wzew/4meNmeulo66NzMqc22MdDBgXI
5 changed files with 1450 additions and 0 deletions

View file

@ -21,6 +21,7 @@ import (
"cpatino.com/advent-of-code/2024/day10"
"cpatino.com/advent-of-code/2024/day11"
"cpatino.com/advent-of-code/2024/day12"
"cpatino.com/advent-of-code/2024/day13"
)
var days = map[int]func(string) (int, int){
@ -36,6 +37,7 @@ var days = map[int]func(string) (int, int){
10: day10.Run,
11: day11.Run,
12: day12.Run,
13: day13.Run,
}
var rootCmd = &cobra.Command{

110
2024/day13/day13.go Executable file
View file

@ -0,0 +1,110 @@
package day13
import (
"bufio"
"fmt"
"math"
"os"
"regexp"
"strconv"
)
type Button struct {
X, Y int
cost int
}
type Machine struct {
A, B Button
X, Y int
}
func solveMachine(machine Machine) int {
/*
a * aX + b * bX = pX
a * aY + b * bY = pY
*/
tX := machine.X
tY := machine.Y
aX := machine.A.X
aY := machine.A.Y
bX := machine.B.X
bY := machine.B.Y
a := float64(tX*bY-tY*bX) / float64(aX*bY-aY*bX)
b := float64(tY*aX-tX*aY) / float64(aX*bY-aY*bX)
if a == math.Trunc(a) && b == math.Trunc(b) {
return int(a*3 + b)
}
return 0
}
func Part1(machines []Machine) int {
totalCost := 0
for _, machine := range machines {
totalCost += solveMachine(machine)
}
return totalCost
}
func Part2(machines []Machine) int {
for i := range machines {
machines[i].X += 10000000000000
machines[i].Y += 10000000000000
}
return Part1(machines)
}
func Run(filename string) (int, int) {
file, err := os.Open(filename)
if err != nil {
panic(err)
}
defer file.Close()
lines := ""
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
if line == "" {
continue
}
lines += fmt.Sprintf("%s\n", line)
}
machines := []Machine{}
regex := regexp.MustCompile(`Button A: X\+(\d+), Y\+(\d+)\nButton B: X\+(\d+), Y\+(\d+)\nPrize: X=(\d+), Y=(\d+)`)
matches := regex.FindAllStringSubmatch(lines, -1)
for _, machine := range matches {
fields := make([]int, 6)
for i, match := range machine[1:] {
conv, err := strconv.Atoi(match)
if err != nil {
panic(err)
}
fields[i] = conv
}
buttonA := Button{X: fields[0], Y: fields[1], cost: 3}
buttonB := Button{X: fields[2], Y: fields[3], cost: 1}
machines = append(machines, Machine{A: buttonA, B: buttonB, X: fields[4], Y: fields[5]})
}
if err := scanner.Err(); err != nil {
panic(err)
}
part1 := Part1(machines)
part2 := Part2(machines)
return part1, part2
}

44
2024/day13/day13_test.go Executable file
View file

@ -0,0 +1,44 @@
package day13
import (
"os"
"testing"
)
func TestDay13(t *testing.T) {
filename := "test.txt"
if _, err := os.Stat(filename); os.IsNotExist(err) {
t.Fatalf("test file does not exist: %v", filename)
}
part1, part2 := Run(filename)
expectedPart1 := 480
if part1 != expectedPart1 {
t.Fatalf("unexpected part1:\nwant:\t%d\ngot:\t%d", expectedPart1, part1)
}
expectedPart2 := 875318608908
if part2 != expectedPart2 {
t.Fatalf("unexpected part2:\nwant:\t%d\ngot:\t%d", expectedPart2, part2)
}
}
func TestDay13Solutions(t *testing.T) {
filename := "input.txt"
if _, err := os.Stat(filename); os.IsNotExist(err) {
t.Fatalf("test file does not exist: %v", filename)
}
part1, part2 := Run(filename)
expectedPart1 := 35997
if part1 != expectedPart1 {
t.Fatalf("unexpected part1:\nwant:\t%d\ngot:\t%d", expectedPart1, part1)
}
expectedPart2 := 82510994362072
if part2 != expectedPart2 {
t.Fatalf("unexpected part2:\nwant:\t%d\ngot:\t%d", expectedPart2, part2)
}
}

1279
2024/day13/input.txt Executable file

File diff suppressed because it is too large Load diff

15
2024/day13/test.txt Executable file
View file

@ -0,0 +1,15 @@
Button A: X+94, Y+34
Button B: X+22, Y+67
Prize: X=8400, Y=5400
Button A: X+26, Y+66
Button B: X+67, Y+21
Prize: X=12748, Y=12176
Button A: X+17, Y+86
Button B: X+84, Y+37
Prize: X=7870, Y=6450
Button A: X+69, Y+23
Button B: X+27, Y+71
Prize: X=18641, Y=10279