package main import ( "bufio" "fmt" "os" "strconv" "strings" ) 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 structuredInput = string func TransformInput(lines []string) structuredInput { return strings.Join(lines, "") } const PRE_FIX = "mul(" func IsNummeric(input byte) bool { return input >= '0' && input <= '9' } func ExtractNumber(input string, start_index int) (int, int, bool) { var end_index = start_index if !IsNummeric(input[start_index]) { return -1, -1, false } for i := start_index; i < len(input); i++ { if !IsNummeric(input[i]) { break } end_index = i } result, error := strconv.Atoi(input[start_index : end_index+1]) if error != nil { return -1, -1, false } return result, end_index - start_index + 1, true } func CalculateLinePart1(input string) int { var error = -1 var success = false var num1 = 0 var num2 = 0 var num_length = 0 var index = 0 var result = 0 for i := 0; i < len(input); i++ { error = -1 for j := 0; j < len(PRE_FIX) && i+j < len(input); j++ { if PRE_FIX[j] != input[i+j] { error = i + j break } } index = i + len(PRE_FIX) if error != -1 { i = error continue } num1 = 0 num2 = 0 num1, num_length, success = ExtractNumber(input, index) if !success { continue } index += num_length if input[index] != ',' { continue } index++ num2, num_length, success = ExtractNumber(input, index) if !success { continue } index += num_length if input[index] != ')' { continue } result += num1 * num2 i = index } return result } func Part1(input structuredInput) int { return CalculateLinePart1(input) } type Method struct { method string num1 int num2 int } var METHODS = map[string]func(paramters string) (bool, Method){ "mul": func(paramters string) (bool, Method) { var num_length1 = 0 var num_length2 = 0 var success = false var num1 = 0 var num2 = 0 num1, num_length1, success = ExtractNumber(paramters, 0) if !success { return false, Method{} } if len(paramters) <= num_length1 || paramters[num_length1] != ',' { return false, Method{} } num2, num_length2, success = ExtractNumber(paramters, num_length1+1) if !success { return false, Method{} } if len(paramters) > num_length1+num_length2+1 { return false, Method{} } return true, Method{"mul", num1, num2} }, "do": func(paramters string) (bool, Method) { return len(paramters) == 0, Method{"do", -1, -1} }, "don't": func(paramters string) (bool, Method) { return len(paramters) == 0, Method{"don't", -1, -1} }, } func IsMethod(line string, method_name string, start_index int) bool { if start_index+len(method_name) >= len(line) { return false } for i := 0; i < len(method_name); i++ { if line[start_index+i] != method_name[i] { return false } } return true } func CalculateLinePart2(line string) int { var result = 0 var para_start = 0 var para_end = 0 var success = false var code = make([]Method, 0) var temp Method for i := 0; i < len(line); i++ { for method := range METHODS { if !IsMethod(line, method, i) { continue } para_start = i + len(method) if line[para_start] != '(' { continue } para_end = para_start for para_end < len(line) && line[para_end] != ')' { para_end++ } if line[para_end] != ')' { continue } success, temp = METHODS[method](line[para_start+1 : para_end]) if success { code = append(code, temp) break } } } var enabled = true for _, method := range code { switch method.method { case "do": enabled = true case "don't": enabled = false case "mul": if enabled { result += method.num1 * method.num2 } } } return result } func Part2(input structuredInput) int { return CalculateLinePart2(input) } func main() { input, err := LoadInput(FILE_PATH) if err != nil { fmt.Println("Error loading input:", err) return } structuredInput := TransformInput(input) fmt.Println("Structured Input:", structuredInput) fmt.Println("Solution Part 1: ", Part1(structuredInput)) fmt.Println("Solution Part 2: ", Part2(structuredInput)) }