Advertisement
mgostih

AOC 2019 Day 2 (First solution only)

Dec 2nd, 2019
787
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 2.68 KB | None | 0 0
  1. use std::io::{self, BufRead};
  2.  
  3. #[derive(Debug)]
  4. enum EmulationError {
  5.     UnknownOpcode(usize),
  6.     MemoryAccess(usize),
  7.     Overflow,
  8. }
  9.  
  10. fn produce_program(s: &str) -> Vec<usize> {
  11.     s.split(',').flat_map(|v| v.parse()).collect()
  12. }
  13.  
  14. fn execute_program(program: &mut [usize]) -> Result<&mut [usize], EmulationError> {
  15.     for i in (0..program.len()).step_by(4) {
  16.         match program[i] {
  17.             // direct indexing is fine because we are always in bound due to the for loop
  18.             99 => break,
  19.             1 => binary_op(program, (i + 1, i + 2, i + 3), |x, y| {
  20.                 x.checked_add(y).ok_or(EmulationError::Overflow)
  21.             })?,
  22.             2 => binary_op(program, (i + 1, i + 2, i + 3), |x, y| {
  23.                 x.checked_mul(y).ok_or(EmulationError::Overflow)
  24.             })?,
  25.             x => return Err(EmulationError::UnknownOpcode(x)),
  26.         }
  27.     }
  28.     Ok(program)
  29. }
  30.  
  31. fn read_mem(program: &mut [usize], pos: usize) -> Result<usize, EmulationError> {
  32.     program
  33.         .get(pos)
  34.         .copied()
  35.         .ok_or(EmulationError::MemoryAccess(pos))
  36. }
  37.  
  38. fn write_mem(program: &mut [usize], pos: usize, val: usize) -> Result<(), EmulationError> {
  39.     *program
  40.         .get_mut(pos)
  41.         .ok_or(EmulationError::MemoryAccess(pos))? = val;
  42.     Ok(())
  43. }
  44.  
  45. fn binary_op<F>(
  46.     program: &mut [usize],
  47.     (i1, i2, o): (usize, usize, usize),
  48.     mut f: F,
  49. ) -> Result<(), EmulationError>
  50. where
  51.     F: FnMut(usize, usize) -> Result<usize, EmulationError>,
  52. {
  53.     let (i1, i2, o) = (
  54.         read_mem(program, i1)?,
  55.         read_mem(program, i2)?,
  56.         read_mem(program, o)?,
  57.     );
  58.     let val = f(read_mem(program, i1)?, read_mem(program, i2)?)?;
  59.     write_mem(program, o, val)
  60. }
  61.  
  62. fn main() {
  63.     assert_eq!(
  64.         execute_program(&mut [1, 0, 0, 0, 99]).unwrap(),
  65.         &[2, 0, 0, 0, 99]
  66.     );
  67.  
  68.     assert_eq!(
  69.         execute_program(&mut [2, 3, 0, 3, 99]).unwrap(),
  70.         &[2, 3, 0, 6, 99]
  71.     );
  72.  
  73.     assert_eq!(
  74.         execute_program(&mut [2, 4, 4, 5, 99, 0]).unwrap(),
  75.         &[2, 4, 4, 5, 99, 9801]
  76.     );
  77.  
  78.     assert_eq!(
  79.         execute_program(&mut [1, 1, 1, 4, 99, 5, 6, 0, 99]).unwrap(),
  80.         &[30, 1, 1, 4, 2, 5, 6, 0, 99]
  81.     );
  82.  
  83.     let i = io::stdin();
  84.     let mut stdin = i.lock();
  85.     let mut input = String::new();
  86.     stdin.read_line(&mut input).expect("Error reading stdin.");
  87.     let mut data = produce_program(&input);
  88.     // before running the program, replace position 1 with the value 12 and replace position 2 with the value 2.
  89.     data[1] = 12;
  90.     data[2] = 2;
  91.  
  92.     println!(
  93.         "The first part has answer: {}",
  94.         execute_program(&mut data.clone()).unwrap()[0]
  95.     );
  96. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement