This commit is contained in:
		
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 7.7 KiB  | 
@@ -1,6 +1,6 @@
 | 
				
			|||||||
<!-- AOC TILES BEGIN -->
 | 
					<!-- AOC TILES BEGIN -->
 | 
				
			||||||
<h1 align="center">
 | 
					<h1 align="center">
 | 
				
			||||||
  2024 - 33 ⭐ - Rust
 | 
					  2024 - 34 ⭐ - Rust
 | 
				
			||||||
</h1>
 | 
					</h1>
 | 
				
			||||||
<a href="src/day1.rs">
 | 
					<a href="src/day1.rs">
 | 
				
			||||||
  <img src=".aoc_tiles/tiles/2024/01.png" width="161px">
 | 
					  <img src=".aoc_tiles/tiles/2024/01.png" width="161px">
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										68
									
								
								src/day17.rs
									
									
									
									
									
								
							
							
						
						
									
										68
									
								
								src/day17.rs
									
									
									
									
									
								
							@@ -33,8 +33,8 @@ enum Opcode {
 | 
				
			|||||||
    cdv = 7,
 | 
					    cdv = 7,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl From<usize> for Opcode {
 | 
					impl From<i64> for Opcode {
 | 
				
			||||||
    fn from(value: usize) -> Self {
 | 
					    fn from(value: i64) -> Self {
 | 
				
			||||||
        match value {
 | 
					        match value {
 | 
				
			||||||
            0 => Opcode::adv,
 | 
					            0 => Opcode::adv,
 | 
				
			||||||
            1 => Opcode::bxl,
 | 
					            1 => Opcode::bxl,
 | 
				
			||||||
@@ -97,13 +97,16 @@ struct RegisterFile<const SIZE: usize, T> {
 | 
				
			|||||||
    file: [T; SIZE],
 | 
					    file: [T; SIZE],
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<T, const SIZE: usize> RegisterFile<SIZE, T> {
 | 
					impl<T: Clone + From<i64>, const SIZE: usize> RegisterFile<SIZE, T> {
 | 
				
			||||||
    fn load(&self, reg: Register) -> &T {
 | 
					    fn load(&self, reg: Register) -> &T {
 | 
				
			||||||
        &self.file[reg as usize]
 | 
					        &self.file[reg as usize]
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    fn store(&mut self, reg: Register, val: T) {
 | 
					    fn store(&mut self, reg: Register, val: T) {
 | 
				
			||||||
        self.file[reg as usize] = val;
 | 
					        self.file[reg as usize] = val;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    fn reset(&mut self) {
 | 
				
			||||||
 | 
					        self.file.fill(0.into());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Copy, Clone)]
 | 
					#[derive(Debug, Copy, Clone)]
 | 
				
			||||||
@@ -113,9 +116,6 @@ struct Instruction {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Instruction {
 | 
					impl Instruction {
 | 
				
			||||||
    fn new(opcode: Opcode, operand: Operand) -> Self {
 | 
					 | 
				
			||||||
        Self { opcode, operand }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    fn exec(&self, m: &mut Machine) {
 | 
					    fn exec(&self, m: &mut Machine) {
 | 
				
			||||||
        match self.opcode {
 | 
					        match self.opcode {
 | 
				
			||||||
            Opcode::adv => self.adv(m),
 | 
					            Opcode::adv => self.adv(m),
 | 
				
			||||||
@@ -178,9 +178,10 @@ impl Instruction {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug)]
 | 
					#[derive(Debug)]
 | 
				
			||||||
struct Machine {
 | 
					pub struct Machine {
 | 
				
			||||||
    registers: RegisterFile<3, i64>,
 | 
					    registers: RegisterFile<3, i64>,
 | 
				
			||||||
    program: Vec<Instruction>,
 | 
					    program: Vec<Instruction>,
 | 
				
			||||||
 | 
					    program_raw: Vec<i64>,
 | 
				
			||||||
    ip: usize,
 | 
					    ip: usize,
 | 
				
			||||||
    out_file: Vec<i64>,
 | 
					    out_file: Vec<i64>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -202,6 +203,11 @@ impl Machine {
 | 
				
			|||||||
    fn jump(&mut self, addr: usize) {
 | 
					    fn jump(&mut self, addr: usize) {
 | 
				
			||||||
        self.ip = addr;
 | 
					        self.ip = addr;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    fn reset(&mut self) {
 | 
				
			||||||
 | 
					        self.registers.reset();
 | 
				
			||||||
 | 
					        self.ip = 0;
 | 
				
			||||||
 | 
					        self.out_file.clear();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn parse(input: &str) -> Machine {
 | 
					fn parse(input: &str) -> Machine {
 | 
				
			||||||
@@ -210,6 +216,7 @@ fn parse(input: &str) -> Machine {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    let mut registers: RegisterFile<3, i64> = RegisterFile { file: [0; 3] };
 | 
					    let mut registers: RegisterFile<3, i64> = RegisterFile { file: [0; 3] };
 | 
				
			||||||
    let mut program = Vec::new();
 | 
					    let mut program = Vec::new();
 | 
				
			||||||
 | 
					    let mut program_raw = Vec::new();
 | 
				
			||||||
    for line in input.lines() {
 | 
					    for line in input.lines() {
 | 
				
			||||||
        if let Some(caps) = reg_re.captures(line) {
 | 
					        if let Some(caps) = reg_re.captures(line) {
 | 
				
			||||||
            let address = (caps[1].as_bytes()[0] - b'A') as usize;
 | 
					            let address = (caps[1].as_bytes()[0] - b'A') as usize;
 | 
				
			||||||
@@ -220,10 +227,13 @@ fn parse(input: &str) -> Machine {
 | 
				
			|||||||
        if let Some(caps) = prog_re.captures(line) {
 | 
					        if let Some(caps) = prog_re.captures(line) {
 | 
				
			||||||
            let instructions = caps[1].split(',');
 | 
					            let instructions = caps[1].split(',');
 | 
				
			||||||
            for (inst, operand) in instructions.tuples() {
 | 
					            for (inst, operand) in instructions.tuples() {
 | 
				
			||||||
                let opcode: Opcode = inst.parse::<usize>().unwrap().into();
 | 
					                let opcode = inst.parse::<i64>().unwrap();
 | 
				
			||||||
                let operand = operand.parse::<i64>().unwrap().into();
 | 
					                let operand = operand.parse::<i64>().unwrap();
 | 
				
			||||||
 | 
					                program_raw.push(opcode);
 | 
				
			||||||
 | 
					                program_raw.push(operand);
 | 
				
			||||||
 | 
					                let opcode: Opcode = opcode.into();
 | 
				
			||||||
                program.push(Instruction {
 | 
					                program.push(Instruction {
 | 
				
			||||||
                    operand: opcode.interp_operand(operand),
 | 
					                    operand: opcode.interp_operand(operand as i64),
 | 
				
			||||||
                    opcode,
 | 
					                    opcode,
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -233,6 +243,7 @@ fn parse(input: &str) -> Machine {
 | 
				
			|||||||
    Machine {
 | 
					    Machine {
 | 
				
			||||||
        registers,
 | 
					        registers,
 | 
				
			||||||
        program,
 | 
					        program,
 | 
				
			||||||
 | 
					        program_raw,
 | 
				
			||||||
        out_file: Vec::new(),
 | 
					        out_file: Vec::new(),
 | 
				
			||||||
        ip: 0,
 | 
					        ip: 0,
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -245,27 +256,56 @@ pub fn part1(input: &str) -> String {
 | 
				
			|||||||
    machine.out_file.iter().map(|n| n.to_string()).join(",")
 | 
					    machine.out_file.iter().map(|n| n.to_string()).join(",")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn solve(m: &mut Machine, guess: i64, i: usize) -> Option<i64> {
 | 
				
			||||||
 | 
					    if i as usize == m.program_raw.len() {
 | 
				
			||||||
 | 
					        return Some(guess as i64);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    let program_pos = m.program_raw.len() - 1 - i;
 | 
				
			||||||
 | 
					    let goal_digit = m.program_raw[program_pos];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for digit in 0..8 {
 | 
				
			||||||
 | 
					        let local_guess = (digit << (program_pos*3)) + guess;
 | 
				
			||||||
 | 
					        m.reset();
 | 
				
			||||||
 | 
					        m.registers.store(Register::A, local_guess);
 | 
				
			||||||
 | 
					        m.run();
 | 
				
			||||||
 | 
					        if m.out_file.len() == m.program_raw.len() && m.out_file[program_pos] == goal_digit {
 | 
				
			||||||
 | 
					            if let Some(sol) = solve(m, local_guess, i+1) {
 | 
				
			||||||
 | 
					                return Some(sol)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    None
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[aoc(day17, part2)]
 | 
					#[aoc(day17, part2)]
 | 
				
			||||||
pub fn part2(input: &str) -> i64 {
 | 
					pub fn part2(input: &str) -> i64 {
 | 
				
			||||||
    0
 | 
					    let mut machine = parse(input);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return solve(&mut machine, 0, 0).expect("expected a solution");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[cfg(test)]
 | 
					#[cfg(test)]
 | 
				
			||||||
mod tests {
 | 
					mod tests {
 | 
				
			||||||
    use super::*;
 | 
					    use super::*;
 | 
				
			||||||
    const EXAMPLE: &str = "Register A: 729
 | 
					    const EXAMPLE1: &str = "Register A: 729
 | 
				
			||||||
Register B: 0
 | 
					Register B: 0
 | 
				
			||||||
Register C: 0
 | 
					Register C: 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Program: 0,1,5,4,3,0";
 | 
					Program: 0,1,5,4,3,0";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const EXAMPLE2: &str = "Register A: 2024
 | 
				
			||||||
 | 
					Register B: 0
 | 
				
			||||||
 | 
					Register C: 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Program: 0,3,5,4,3,0";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[test]
 | 
					    #[test]
 | 
				
			||||||
    fn part1_example() {
 | 
					    fn part1_example() {
 | 
				
			||||||
        assert_eq!(part1(EXAMPLE), "4,6,3,5,6,3,5,2,1,0");
 | 
					        assert_eq!(part1(EXAMPLE1), "4,6,3,5,6,3,5,2,1,0");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[test]
 | 
					    #[test]
 | 
				
			||||||
    fn part2_example() {
 | 
					    fn part2_example() {
 | 
				
			||||||
        assert_eq!(part2(EXAMPLE), 0);
 | 
					        assert_eq!(part2(EXAMPLE2), 117440);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user