SHARE
TWEET

Untitled

a guest Jan 21st, 2020 262 in 147 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. use std::convert::From;
  2. use std::fs::File;
  3. use std::io::Read;
  4.  
  5. use itertools::iproduct;
  6.  
  7. struct IntcodeMachine {
  8.     pointer: usize,
  9.     state: Vec<usize>,
  10. }
  11.  
  12. impl IntcodeMachine {
  13.     fn new(state: Vec<usize>) -> Self {
  14.         IntcodeMachine {pointer: 0, state: state}
  15.     }
  16.  
  17.     fn execute(&mut self) {
  18.         while let Some(&opcode) = self.state.get(self.pointer) {
  19.             match opcode.into() {
  20.                 Opcode::Invalid => {
  21.                     panic!("Encountered invalid opcode '{}' at position '{}", opcode, self.pointer);
  22.                 },
  23.                 Opcode::Halt => {
  24.                     break;
  25.                 },
  26.                 opcode @ _ => {
  27.                     let ptr_a = self.state.get(self.pointer + 1);
  28.                     let ptr_b = self.state.get(self.pointer + 2);
  29.                     let ptr_out = self.state.get(self.pointer + 3);
  30.  
  31.                     if let (Some(&ptr_a), Some(&ptr_b), Some(&ptr_out)) = (ptr_a, ptr_b, ptr_out) {
  32.                         let a = self.state.get(ptr_a);
  33.                         let b = self.state.get(ptr_b);
  34.  
  35.                         if let (Some(a), Some(b)) = (a, b) {
  36.                             let result = match opcode {
  37.                                 Opcode::Add => a + b,
  38.                                 Opcode::Multiply => a * b,
  39.                                 _ => unreachable!(),
  40.                             };
  41.  
  42.                             self.state[ptr_out] = result;
  43.                         } else {
  44.                             panic!("One of the arguments contains an invalid address");
  45.                         }
  46.                     } else {
  47.                         panic!("Not enough arguments for opcode '{:?}' at position '{}", opcode, self.pointer);
  48.                     }
  49.  
  50.                     self.pointer += 4;
  51.                 }
  52.             }
  53.         }
  54.  
  55.         self.get_state(0)
  56.     }
  57.  
  58.     fn get_state(&self, pos: usize) -> usize {
  59.         self.state[pos]
  60.     }
  61.  
  62.     fn set_state(&mut self, pos: usize, val: usize) {
  63.         self.state[pos] = val;
  64.     }
  65. }
  66.  
  67. #[derive(Debug)]
  68. enum Opcode {
  69.     Add,
  70.     Multiply,
  71.     Halt,
  72.     Invalid,
  73. }
  74.  
  75. impl From<usize> for Opcode {
  76.     fn from(opcode: usize) -> Opcode {
  77.         match opcode {
  78.             1 => Opcode::Add,
  79.             2 => Opcode::Multiply,
  80.             99 => Opcode::Halt,
  81.             _ => Opcode::Invalid,
  82.         }
  83.     }
  84. }
  85.  
  86. fn part1(input: Vec<usize>) -> usize {
  87.     let mut machine = IntcodeMachine::new(input);
  88.     machine.set_state(1, 12);
  89.     machine.set_state(2, 2);
  90.  
  91.     machine.execute()
  92. }
  93.  
  94. fn part2(input: Vec<usize>) -> usize {
  95.     for inputs in iproduct!(0..100, 0..100) {
  96.         let mut machine = IntcodeMachine::new(input.clone());
  97.         machine.set_state(1, inputs.0);
  98.         machine.set_state(2, inputs.1);
  99.  
  100.         if machine.execute() == 19690720 {
  101.             return inputs.0 * 100 + inputs.1;
  102.         }
  103.     }
  104.  
  105.     panic!("No solution found");
  106. }
  107.  
  108. fn main() {
  109.     let mut input = File::open("input.txt").unwrap();
  110.     let mut content = String::new();
  111.  
  112.     input.read_to_string(&mut content).unwrap();
  113.  
  114.     let input: Vec<_> = content.lines().next().unwrap()
  115.                                .split(',')
  116.                                .map(|v| v.parse::<usize>().unwrap())
  117.                                .collect();
  118.  
  119.     println!("The answer to part 1 is: {}", part1(input.clone()));
  120.     println!("The answer to part 2 is: {}", part2(input.clone()));
  121. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top