diff options
Diffstat (limited to '2024')
| -rw-r--r-- | 2024/src/day17.cpp | 58 |
1 files changed, 52 insertions, 6 deletions
diff --git a/2024/src/day17.cpp b/2024/src/day17.cpp index f0d1010..a4af373 100644 --- a/2024/src/day17.cpp +++ b/2024/src/day17.cpp | |||
| @@ -57,10 +57,10 @@ read_file(string_view filename) | |||
| 57 | return { registers, program }; | 57 | return { registers, program }; |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | void | 60 | vector<unsigned long> |
| 61 | part1(const tuple<registers_type, program_type>& data) | 61 | run(registers_type registers, const program_type& program) |
| 62 | { | 62 | { |
| 63 | auto [registers, program] = data; | 63 | vector<unsigned long> out; |
| 64 | 64 | ||
| 65 | for ( unsigned long ip = 0; ip < program.size(); ) { | 65 | for ( unsigned long ip = 0; ip < program.size(); ) { |
| 66 | const auto opcode = program.at(ip++); | 66 | const auto opcode = program.at(ip++); |
| @@ -86,7 +86,7 @@ part1(const tuple<registers_type, program_type>& data) | |||
| 86 | registers['B'] ^= registers['C']; | 86 | registers['B'] ^= registers['C']; |
| 87 | break; | 87 | break; |
| 88 | case 5: | 88 | case 5: |
| 89 | cout << (value & 7) << ','; | 89 | out.push_back(value & 7); |
| 90 | break; | 90 | break; |
| 91 | case 6: | 91 | case 6: |
| 92 | registers['B'] = registers['A'] >> value; | 92 | registers['B'] = registers['A'] >> value; |
| @@ -95,16 +95,62 @@ part1(const tuple<registers_type, program_type>& data) | |||
| 95 | registers['C'] = registers['A'] >> value; | 95 | registers['C'] = registers['A'] >> value; |
| 96 | break; | 96 | break; |
| 97 | default: | 97 | default: |
| 98 | cout << "Error" << endl; | 98 | throw runtime_error("Error"); |
| 99 | return; | ||
| 100 | } | 99 | } |
| 101 | } | 100 | } |
| 101 | return out; | ||
| 102 | } | ||
| 103 | |||
| 104 | void | ||
| 105 | part1(const tuple<registers_type, program_type>& data) | ||
| 106 | { | ||
| 107 | auto [registers, program] = data; | ||
| 108 | |||
| 109 | auto result = run(registers, program); | ||
| 110 | |||
| 111 | copy(result.begin(), result.end(), ostream_iterator<unsigned long>(cout, ",")); | ||
| 102 | cout << endl; | 112 | cout << endl; |
| 103 | } | 113 | } |
| 104 | 114 | ||
| 115 | optional<unsigned long> | ||
| 116 | find_register_a(const registers_type& registers, const program_type& program, size_t pos) | ||
| 117 | { | ||
| 118 | if ( pos > program.size() ) { | ||
| 119 | return registers.at('A'); | ||
| 120 | } | ||
| 121 | |||
| 122 | for ( unsigned long i = 0; i != 8; ++i ) { | ||
| 123 | auto registers_copy = registers; | ||
| 124 | |||
| 125 | registers_copy['A'] <<= 3UL; | ||
| 126 | registers_copy['A'] |= i; | ||
| 127 | |||
| 128 | const auto try_run = run(registers_copy, program); | ||
| 129 | |||
| 130 | if ( try_run.front() == program[program.size() - pos] ) { | ||
| 131 | if ( auto result = find_register_a(registers_copy, program, pos + 1) ) { | ||
| 132 | return *result; | ||
| 133 | } | ||
| 134 | } | ||
| 135 | } | ||
| 136 | return nullopt; | ||
| 137 | } | ||
| 138 | |||
| 139 | void | ||
| 140 | part2(const tuple<registers_type, program_type>& data) | ||
| 141 | { | ||
| 142 | auto [registers, program] = data; | ||
| 143 | |||
| 144 | registers['A'] = 0; | ||
| 145 | if ( auto result = find_register_a(registers, program, 1) ) { | ||
| 146 | cout << *result << endl; | ||
| 147 | } | ||
| 148 | } | ||
| 149 | |||
| 105 | int | 150 | int |
| 106 | main() | 151 | main() |
| 107 | { | 152 | { |
| 108 | auto data = read_file("data/day17.txt"); | 153 | auto data = read_file("data/day17.txt"); |
| 109 | part1(data); | 154 | part1(data); |
| 155 | part2(data); | ||
| 110 | } | 156 | } |
