package main import ( "bufio" "fmt" "os" "strconv" "time" ) const FILE_PATH = "./input.txt" //const FILE_PATH = "./sample.txt" func LoadInput(filename string) ([]string, error) { file, err := os.Open(filename) if err != nil { return nil, err } defer file.Close() var lines []string scanner := bufio.NewScanner(file) for scanner.Scan() { lines = append(lines, scanner.Text()) } if err := scanner.Err(); err != nil { return nil, err } return lines, nil } type Vector2 struct { x int y int } type Puzzle struct { buttonA Vector2 buttonB Vector2 price Vector2 } type structuredInput = []Puzzle func TransformInput(lines []string) structuredInput { var result = make([]Puzzle, 0) var numb int var buttonA Vector2 var buttonB Vector2 var prize Vector2 var j int for i := 0; i < len(lines); i += 4 { buttonA = Vector2{} numb, _ = strconv.Atoi(lines[i][len("Button A: X+") : len("Button A: X+")+2]) buttonA.x = numb numb, _ = strconv.Atoi(lines[i][len("Button A: X+")+5 : len("Button A: X+")+8]) buttonA.y = numb buttonB = Vector2{} numb, _ = strconv.Atoi(lines[i+1][len("Button A: X+") : len("Button A: X+")+2]) buttonB.x = numb numb, _ = strconv.Atoi(lines[i+1][len("Button A: X+")+5 : len("Button A: X+")+8]) buttonB.y = numb prize = Vector2{} j = 0 for ; j < len(lines[i+2]); j++ { if lines[i+2][j] == ',' { break } } numb, _ = strconv.Atoi(lines[i+2][len("Prize: X="):j]) prize.x = numb numb, _ = strconv.Atoi(lines[i+2][j+4:]) prize.y = numb result = append(result, Puzzle{buttonA, buttonB, prize}) } return result } func calculatePuzzleSolution(puzzle Puzzle) int { var mf float64 = 0 var m int var n int // This case would be possible if a and b are multiple of each other so either b or a must be 0 this is never the case if puzzle.buttonB.x*puzzle.buttonA.y == puzzle.buttonA.x*puzzle.buttonB.y || puzzle.buttonB.x*puzzle.buttonB.y == 0 { return 0 } mf = float64(puzzle.buttonB.x*puzzle.price.y-puzzle.price.x*puzzle.buttonB.y) / float64(puzzle.buttonB.x*puzzle.buttonA.y-puzzle.buttonA.x*puzzle.buttonB.y) m = int(mf) if float64(m) != mf { return 0 } n = (puzzle.price.x - puzzle.buttonA.x*m) / puzzle.buttonB.x return m*3 + n } func Part1(input structuredInput) int { var result = 0 for _, puzzle := range input { result += calculatePuzzleSolution(puzzle) } return result } func Part2(input structuredInput) int { var result = 0 for i := 0; i < len(input); i++ { input[i].price.x += 10000000000000 input[i].price.y += 10000000000000 } for _, puzzle := range input { result += calculatePuzzleSolution(puzzle) } return result } func main() { var start time.Time var elapsed time.Duration = 0 input, err := LoadInput(FILE_PATH) if err != nil { fmt.Println("Error loading input:", err) return } structuredInput := TransformInput(input) fmt.Println("Structured Input:", structuredInput) start = time.Now() fmt.Println("Solution Part 1: ", Part1(structuredInput)) elapsed = time.Since(start) fmt.Printf("Part 1 took %s\n", elapsed) start = time.Now() fmt.Println("Solution Part 2: ", Part2(structuredInput)) elapsed = time.Since(start) fmt.Printf("Part 2 took %s\n", elapsed) }