Updated with day 13
This commit is contained in:
parent
25a7062706
commit
950eded2b1
5 changed files with 1450 additions and 0 deletions
|
|
@ -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
110
2024/day13/day13.go
Executable 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
44
2024/day13/day13_test.go
Executable 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
1279
2024/day13/input.txt
Executable file
File diff suppressed because it is too large
Load diff
15
2024/day13/test.txt
Executable file
15
2024/day13/test.txt
Executable 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue