From 2232caefd9eda0fc1bf72be4a75d93c0c5b6a502 Mon Sep 17 00:00:00 2001 From: Sander in 't Hout Date: Wed, 18 Dec 2024 17:36:12 +0100 Subject: [PATCH] Add AoC 2024 day 17 part 1 solver --- assets/advent_of_code/2024_17_sample.txt | 5 + .../advent_of_code/2024/_all_solvers.dart | 1 + .../advent_of_code/2024/day_17_solver.dart | 93 +++++++++++++++++++ 3 files changed, 99 insertions(+) create mode 100644 assets/advent_of_code/2024_17_sample.txt create mode 100644 lib/solvers/advent_of_code/2024/day_17_solver.dart diff --git a/assets/advent_of_code/2024_17_sample.txt b/assets/advent_of_code/2024_17_sample.txt new file mode 100644 index 0000000..36fbf8d --- /dev/null +++ b/assets/advent_of_code/2024_17_sample.txt @@ -0,0 +1,5 @@ +Register A: 729 +Register B: 0 +Register C: 0 + +Program: 0,1,5,4,3,0 \ No newline at end of file diff --git a/lib/solvers/advent_of_code/2024/_all_solvers.dart b/lib/solvers/advent_of_code/2024/_all_solvers.dart index 5a6b3d9..1bdb038 100644 --- a/lib/solvers/advent_of_code/2024/_all_solvers.dart +++ b/lib/solvers/advent_of_code/2024/_all_solvers.dart @@ -12,3 +12,4 @@ export 'day_12_solver.dart'; export 'day_13_solver.dart'; export 'day_14_solver.dart'; export 'day_15_solver.dart'; +export 'day_17_solver.dart'; diff --git a/lib/solvers/advent_of_code/2024/day_17_solver.dart b/lib/solvers/advent_of_code/2024/day_17_solver.dart new file mode 100644 index 0000000..fa0338d --- /dev/null +++ b/lib/solvers/advent_of_code/2024/day_17_solver.dart @@ -0,0 +1,93 @@ +import 'package:h3x_devtools/solvers/advent_of_code/2024/aoc_2024_solver.dart'; + +class Day17Solver extends AdventOfCode2024Solver { + + @override + final int dayNumber = 17; + + @override + String getSolution(String input) { + String splitNewline = input.contains('\r\n\r\n') ? '\r\n\r\n' : input.contains('\r\r') ? '\r\r' : '\n\n'; + List inputParts = input.split(splitNewline); + + List registers = inputParts[0].splitLines().toList(); + int registerA = int.parse(registers[0].split('Register A: ')[1]); + int registerB = int.parse(registers[1].split('Register B: ')[1]); + int registerC = int.parse(registers[2].split('Register C: ')[1]); + + List instructions = inputParts[1].split('Program: ')[1].split(',').toIntList(); + + // Part 1 + List output = _runProgram(instructions, registerA, registerB, registerC); + + return 'Program output: ${output.join(',')}'; + } + + int test(int getal, List instructions, int initialRegisterA, int initialRegisterB, int initialRegisterC) { + List x = _runProgram(instructions, initialRegisterA, initialRegisterB, initialRegisterC); + if (x.length < instructions.length) { + return -1; + } else if (x.length > instructions.length) { + return 1; + } else { + for (int i = 0; i < instructions.length; i++) { + if (x[i] < instructions[i]) return -1; + if (x[i] > instructions[i]) return 1; + } + } + + return 0; + } + + List _runProgram(List instructions, int initialRegisterA, int initialRegisterB, int initialRegisterC) { + int registerA = initialRegisterA, registerB = initialRegisterB, registerC = initialRegisterC; + int instructionPointer = 0; + List output = []; + + while (instructionPointer <= instructions.length - 2) { + int operand = instructions[instructionPointer + 1]; + int comboOperand = _getComboOperandValue(registerA, registerB, registerC, operand); + bool updateInstructionPointer = true; + + switch (instructions[instructionPointer]) { + case 0: // adv + registerA ~/= pow(2, comboOperand); + case 1: // bxl + registerB ^= operand; + case 2: // bst + registerB = comboOperand % 8; + case 3: // jnz + if (registerA != 0) { + instructionPointer = operand; + updateInstructionPointer = false; + } + case 4: // bxc + registerB ^= registerC; + case 5: // out + output.add(comboOperand % 8); + case 6: // bdv + registerB = registerA ~/ pow(2, comboOperand); + case 7: // cdv + registerC = registerA ~/ pow(2, comboOperand); + default: + throw Exception('Could not parse instruction'); + } + + if (updateInstructionPointer) instructionPointer += 2; + } + + return output; + } + + int _getComboOperandValue(int registerA, int registerB, int registerC, int operand) { + return switch (operand) { + >= 0 && <= 3 => operand, + 4 => registerA, + 5 => registerB, + 6 => registerC, + 7 => throw Exception('Reserved, should not be seen in valid programs'), + _ => throw Exception('Invalid'), + }; + } + +}