diff --git a/17/input.txt b/17/input.txt new file mode 100644 index 0000000..29a2bbf --- /dev/null +++ b/17/input.txt @@ -0,0 +1,5 @@ +Register A: 64012472 +Register B: 0 +Register C: 0 + +Program: 2,4,1,7,7,5,0,3,1,7,4,1,5,5,3,0 \ No newline at end of file diff --git a/17/main.go b/17/main.go new file mode 100644 index 0000000..bea1ce9 --- /dev/null +++ b/17/main.go @@ -0,0 +1,309 @@ +package main + +import ( + "bufio" + "fmt" + "math" + "os" + "strconv" + "strings" + "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 ComputerParams struct { + startA int + startB int + startC int + program []int +} + +type structuredInput = ComputerParams + +func TransformInput(lines []string) structuredInput { + var startA int + var startB int + var startC int + var numb int + var numbs []string + var program = make([]int, 0) + + startA, _ = strconv.Atoi(lines[0][len("Register A: "):]) + startB, _ = strconv.Atoi(lines[1][len("Register B: "):]) + startC, _ = strconv.Atoi(lines[2][len("Register C: "):]) + + numbs = strings.Split(lines[4][len("Program: "):], ",") + + for _, temp := range numbs { + numb, _ = strconv.Atoi(temp) + program = append(program, numb) + } + + return ComputerParams{startA, startB, startC, program} +} + +type Program struct { + a int + b int + c int + + i int + out []int +} + +const ( + ADV = iota + BXL = iota + BST = iota + JNZ = iota + BXC = iota + OUT = iota + BDV = iota + CDV = iota +) + +func getCombo(program Program, operand int) int { + if operand >= 0 && operand <= 3 { + return operand + } + + if operand == 4 { + return program.a + } + if operand == 5 { + return program.b + } + if operand == 6 { + return program.c + } + + return 0 +} + +func executeProgram(params ComputerParams) Program { + var program = Program{params.startA, params.startB, params.startC, 0, make([]int, 0)} + var opcode int + var operand int + var value int + + for program.i < len(params.program) { + opcode = params.program[program.i] + operand = params.program[program.i+1] + + switch opcode { + case ADV: + { + value = getCombo(program, operand) + program.a = int(float64(program.a) / math.Pow(2, float64(value))) + program.i += 2 + } + case BXL: + { + program.b = program.b ^ operand + program.i += 2 + } + case BST: + { + value = getCombo(program, operand) + program.b = value % 8 + program.i += 2 + } + case JNZ: + { + if program.a != 0 { + program.i = operand + } else { + program.i += 2 + } + } + case BXC: + { + program.b = program.b ^ program.c + program.i += 2 + } + case OUT: + { + program.out = append(program.out, getCombo(program, operand)%8) + program.i += 2 + } + case BDV: + { + value = getCombo(program, operand) + program.b = int(float64(program.a) / math.Pow(2, float64(value))) + program.i += 2 + } + case CDV: + { + value = getCombo(program, operand) + program.c = int(float64(program.a) / math.Pow(2, float64(value))) + program.i += 2 + } + } + } + + return program +} + +func Part1(input structuredInput) int { + var result int = 0 + input.startA = 265652340990877 + var program = executeProgram(input) + for i := 0; i < len(program.out); i++ { + fmt.Printf("%d,", program.out[i]) + } + fmt.Println() + return result +} + +var numbs = [][]int{ + []int{0, 0, 0}, + []int{0, 0, 1}, + []int{0, 1, 0}, + []int{0, 1, 1}, + []int{1, 0, 0}, + []int{1, 0, 1}, + []int{1, 1, 0}, + []int{1, 1, 1}, +} + +func clone(input []int) []int { + var result = make([]int, len(input)) + + for i, numb := range input { + result[i] = numb + } + + return result +} + +func insert(numbers []int, numb []int, position int) ([]int, bool) { + var result = clone(numbers) + for i := 0; i < len(numb); i++ { + if position+i < 0 && numb[i] == 0 { + continue + } + if numbers[position+i] != -1 && numbers[position+i] != numb[i] { + return []int{}, true + } + result[position+i] = numb[i] + } + return result, false +} + +func invs(is []int, should []int) []int { + var result = []int{0, 0, 0} + + for i := 0; i < 3; i++ { + if should[i] == 1 && is[i] == 0 || should[i] == 0 && is[i] == 1 { + result[i] = 1 + } + } + + return result +} + +func bToi(numbers []int) int { + var result = 0 + var pow = math.Pow(2, float64(len(numbers)-1)) + for i := 0; i < len(numbers); i++ { + result += numbers[i] * int(pow) + pow = pow / 2 + } + + return result +} + +func Part2(input structuredInput) int { + var result int = 0 + var poss [][]int = make([][]int, 1) + var next [][]int = make([][]int, 0) + var number []int = make([]int, 3*16) + var error bool + var position int + var temp []int + var work []int + for i := 0; i < len(number); i++ { + number[i] = -1 + } + + poss[0] = number + + for j := 15; j >= 0; j-- { + next = make([][]int, 0) + for i := 0; i < len(poss); i++ { + work = poss[i] + position = j * 3 + for m := 0; m < len(numbs); m++ { + temp, error = insert(work, numbs[m], position) + if error { + continue + } + + temp, error = insert(temp, invs(numbs[m], numbs[input.program[len(input.program)-j-1]]), position-(7-m)) + if error { + continue + } + next = append(next, temp) + } + } + poss = next + } + + var lowest int = -1 + var dec int + for i := 0; i < len(poss); i++ { + dec = bToi(poss[i]) + if lowest == -1 || lowest > dec { + lowest = dec + } + } + + result = lowest + 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) +} diff --git a/17/sample.txt b/17/sample.txt new file mode 100644 index 0000000..2ed9dda --- /dev/null +++ b/17/sample.txt @@ -0,0 +1,5 @@ +Register A: 2024 +Register B: 0 +Register C: 0 + +Program: 0,3,5,4,3,0 \ No newline at end of file