Skip to content

Commit eafec20

Browse files
committed
feat(16/2024): solve second part for example using dummy brute force approach
1 parent 71700c3 commit eafec20

File tree

1 file changed

+128
-62
lines changed

1 file changed

+128
-62
lines changed

src/solutions/year2024/day17.rs

+128-62
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,19 @@ impl Solution for Day17 {
1212
program.execute(&mut register).iter().join(",")
1313
}
1414

15-
fn part_two(&self, _input: &str) -> String {
16-
String::from("0")
15+
fn part_two(&self, input: &str) -> String {
16+
let (_, program) = self.parse(input);
17+
18+
let mut i = 0;
19+
loop {
20+
let mut register = RegisterBuilder::default().a(i).build();
21+
22+
if program.execute_and_watch(&mut register) {
23+
return i.to_string();
24+
}
25+
26+
i += 1;
27+
}
1728
}
1829
}
1930

@@ -65,60 +76,102 @@ struct Program {
6576
}
6677

6778
impl Program {
68-
fn execute(&self, register: &mut Register) -> Vec<usize> {
79+
fn execute(&self, register: &mut Register) -> Vec<u8> {
6980
let mut instruction_pointer = 0;
7081
let mut output = Vec::new();
7182

7283
while let Some([opcode, operand]) = self
7384
.program
7485
.get(instruction_pointer..=instruction_pointer + 1)
7586
{
76-
let operation = InstructionType::from(*opcode);
77-
let mut do_jump = true;
87+
self.operation(
88+
opcode,
89+
operand,
90+
register,
91+
&mut instruction_pointer,
92+
&mut output,
93+
);
94+
}
7895

79-
match operation {
80-
Adv => {
81-
let combo_operand = self.combo_operand(operand, register);
82-
register.a /= 2usize.pow(combo_operand as u32);
83-
}
84-
Bdv => {
85-
let combo_operand = self.combo_operand(operand, register);
86-
register.b = register.a / 2usize.pow(combo_operand as u32);
87-
}
88-
Cdv => {
89-
let combo_operand = self.combo_operand(operand, register);
90-
register.c = register.a / 2usize.pow(combo_operand as u32);
91-
}
92-
Bxl => {
93-
let operand_usize = *operand as usize;
94-
register.b ^= operand_usize;
95-
}
96-
Bst => {
97-
let combo_operand = self.combo_operand(operand, register);
98-
register.b = combo_operand % 8;
99-
}
100-
Bxc => {
101-
register.b ^= register.c;
102-
}
103-
Jnz => {
104-
let operand_usize = *operand as usize;
105-
if register.a != 0 && instruction_pointer != operand_usize {
106-
instruction_pointer = operand_usize;
107-
do_jump = false;
108-
}
109-
}
110-
Out => {
111-
let combo_operand = self.combo_operand(operand, register);
112-
output.push(combo_operand % 8);
113-
}
96+
output
97+
}
98+
99+
fn execute_and_watch(&self, register: &mut Register) -> bool {
100+
let mut instruction_pointer = 0;
101+
let mut output = Vec::new();
102+
let expected = self.program.clone();
103+
104+
while let Some([opcode, operand]) = self
105+
.program
106+
.get(instruction_pointer..=instruction_pointer + 1)
107+
{
108+
self.operation(
109+
opcode,
110+
operand,
111+
register,
112+
&mut instruction_pointer,
113+
&mut output,
114+
);
115+
116+
if expected == output {
117+
return true;
114118
}
119+
}
120+
121+
false
122+
}
115123

116-
if do_jump {
117-
instruction_pointer += 2;
124+
fn operation(
125+
&self,
126+
opcode: &u8,
127+
operand: &u8,
128+
register: &mut Register,
129+
instruction_pointer: &mut usize,
130+
output: &mut Vec<u8>,
131+
) {
132+
let operation = InstructionType::from(*opcode);
133+
let mut do_jump = true;
134+
135+
match operation {
136+
Adv => {
137+
let combo_operand = self.combo_operand(operand, register);
138+
register.a /= 2usize.pow(combo_operand as u32);
139+
}
140+
Bdv => {
141+
let combo_operand = self.combo_operand(operand, register);
142+
register.b = register.a / 2usize.pow(combo_operand as u32);
143+
}
144+
Cdv => {
145+
let combo_operand = self.combo_operand(operand, register);
146+
register.c = register.a / 2usize.pow(combo_operand as u32);
147+
}
148+
Bxl => {
149+
let operand_usize = *operand as usize;
150+
register.b ^= operand_usize;
151+
}
152+
Bst => {
153+
let combo_operand = self.combo_operand(operand, register);
154+
register.b = combo_operand % 8;
155+
}
156+
Bxc => {
157+
register.b ^= register.c;
158+
}
159+
Jnz => {
160+
let operand_usize = *operand as usize;
161+
if register.a != 0 && *instruction_pointer != operand_usize {
162+
*instruction_pointer = operand_usize;
163+
do_jump = false;
164+
}
165+
}
166+
Out => {
167+
let combo_operand = self.combo_operand(operand, register);
168+
output.push((combo_operand % 8) as u8);
118169
}
119170
}
120171

121-
output
172+
if do_jump {
173+
*instruction_pointer += 2;
174+
}
122175
}
123176

124177
fn combo_operand(&self, operand: &u8, register: &Register) -> usize {
@@ -173,9 +226,31 @@ impl From<u8> for InstructionType {
173226
}
174227
}
175228

229+
#[derive(Default)]
230+
struct RegisterBuilder {
231+
a: usize,
232+
b: usize,
233+
c: usize,
234+
}
235+
236+
impl RegisterBuilder {
237+
fn a(&mut self, a: usize) -> &mut Self {
238+
self.a = a;
239+
self
240+
}
241+
242+
fn build(&self) -> Register {
243+
Register {
244+
a: self.a,
245+
b: self.b,
246+
c: self.c,
247+
}
248+
}
249+
}
250+
176251
#[cfg(test)]
177252
mod tests {
178-
use crate::solutions::year2024::day17::{Day17, Program, Register};
253+
use crate::solutions::year2024::day17::{Day17, Program, RegisterBuilder};
179254
use crate::solutions::Solution;
180255

181256
const EXAMPLE: &str = r#"Register A: 729
@@ -267,19 +342,18 @@ Program: 0,1,5,4,3,0"#;
267342
assert!(result.is_empty())
268343
}
269344

270-
#[derive(Default)]
271-
struct RegisterBuilder {
272-
a: usize,
273-
b: usize,
274-
c: usize,
345+
const EXAMPLE_PART_TWO: &str = r#"Register A: 2024
346+
Register B: 0
347+
Register C: 0
348+
349+
Program: 0,3,5,4,3,0"#;
350+
351+
#[test]
352+
fn part_two_example() {
353+
assert_eq!("117440", Day17.part_two(EXAMPLE_PART_TWO));
275354
}
276355

277356
impl RegisterBuilder {
278-
fn a(&mut self, a: usize) -> &mut Self {
279-
self.a = a;
280-
self
281-
}
282-
283357
fn b(&mut self, b: usize) -> &mut Self {
284358
self.b = b;
285359
self
@@ -289,13 +363,5 @@ Program: 0,1,5,4,3,0"#;
289363
self.c = c;
290364
self
291365
}
292-
293-
fn build(&self) -> Register {
294-
Register {
295-
a: self.a,
296-
b: self.b,
297-
c: self.c,
298-
}
299-
}
300366
}
301367
}

0 commit comments

Comments
 (0)