Day 5 part 1 and 2
This commit is contained in:
		
							parent
							
								
									d2198c8046
								
							
						
					
					
						commit
						d144372ea4
					
				
					 1 changed files with 243 additions and 0 deletions
				
			
		
							
								
								
									
										243
									
								
								src/day5.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										243
									
								
								src/day5.rs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,243 @@
 | 
			
		|||
use std;
 | 
			
		||||
use std::convert::TryInto;
 | 
			
		||||
 | 
			
		||||
fn get_modes(x: i32) -> (i32, i32, i32, i32) {
 | 
			
		||||
    (
 | 
			
		||||
        x as i32 % 100,
 | 
			
		||||
        (x as i32 / 100) % 10,
 | 
			
		||||
        (x as i32 / 1000) % 10,
 | 
			
		||||
        x as i32 / 10000,
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn get_param(input: Vec<i32>, mode: i32, idx: usize) -> i32 {
 | 
			
		||||
    match mode {
 | 
			
		||||
        0 => {
 | 
			
		||||
            let new_idx: usize = input[idx as usize].try_into().unwrap();
 | 
			
		||||
            input[new_idx]
 | 
			
		||||
        }
 | 
			
		||||
        1 => input[idx],
 | 
			
		||||
        _ => panic!("invalid input"),
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn set_param(input: &mut Vec<i32>, mode: i32, idx: i32, value: i32) -> () {
 | 
			
		||||
    match mode {
 | 
			
		||||
        0 => {
 | 
			
		||||
            let new_idx: usize = input[idx as usize].try_into().unwrap();
 | 
			
		||||
            input[new_idx] = value;
 | 
			
		||||
        }
 | 
			
		||||
        _ => {
 | 
			
		||||
            panic!("invalid mode for output");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn compute_intcode_extended(p: &mut Vec<i32>, input: i32) -> (Vec<i32>, Vec<i32>) {
 | 
			
		||||
    let mut idx = 0;
 | 
			
		||||
    let mut output: Vec<i32> = Vec::new();
 | 
			
		||||
 | 
			
		||||
    while idx < p.len() - 1 {
 | 
			
		||||
        let (opcode, m1, m2, m3) = get_modes(p[idx]);
 | 
			
		||||
        match opcode {
 | 
			
		||||
            1 => {
 | 
			
		||||
                let left = get_param(p.to_vec(), m1, idx + 1);
 | 
			
		||||
                let right = get_param(p.to_vec(), m2, idx + 2);
 | 
			
		||||
                let res = left + right;
 | 
			
		||||
                set_param(p, m3, idx as i32 + 3, res);
 | 
			
		||||
                idx += 4;
 | 
			
		||||
            }
 | 
			
		||||
            2 => {
 | 
			
		||||
                let left = get_param(p.to_vec(), m1, idx + 1);
 | 
			
		||||
                let right = get_param(p.to_vec(), m2, idx + 2);
 | 
			
		||||
                let res = left * right;
 | 
			
		||||
                set_param(p, m3, idx as i32 + 3, res);
 | 
			
		||||
                idx += 4;
 | 
			
		||||
            }
 | 
			
		||||
            3 => {
 | 
			
		||||
                let new_idx: usize = p[idx as usize + 1].try_into().unwrap();
 | 
			
		||||
                p[new_idx] = input;
 | 
			
		||||
                idx += 2;
 | 
			
		||||
            }
 | 
			
		||||
            4 => {
 | 
			
		||||
                let value = get_param(p.to_vec(), m1, idx + 1);
 | 
			
		||||
                output.push(value);
 | 
			
		||||
                idx += 2;
 | 
			
		||||
            }
 | 
			
		||||
            5 => {
 | 
			
		||||
                let left = get_param(p.to_vec(), m1, idx + 1);
 | 
			
		||||
                let right = get_param(p.to_vec(), m2, idx + 2);
 | 
			
		||||
                if left != 0 {
 | 
			
		||||
                    idx = right as usize;
 | 
			
		||||
                } else {
 | 
			
		||||
                    idx += 3;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            6 => {
 | 
			
		||||
                let left = get_param(p.to_vec(), m1, idx + 1);
 | 
			
		||||
                let right = get_param(p.to_vec(), m2, idx + 2);
 | 
			
		||||
                if left == 0 {
 | 
			
		||||
                    idx = right as usize;
 | 
			
		||||
                } else {
 | 
			
		||||
                    idx += 3;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            7 => {
 | 
			
		||||
                let left = get_param(p.to_vec(), m1, idx + 1);
 | 
			
		||||
                let right = get_param(p.to_vec(), m2, idx + 2);
 | 
			
		||||
                set_param(p, m3, idx as i32 + 3, (left < right) as i32);
 | 
			
		||||
                idx += 4;
 | 
			
		||||
            }
 | 
			
		||||
            8 => {
 | 
			
		||||
                let left = get_param(p.to_vec(), m1, idx + 1);
 | 
			
		||||
                let right = get_param(p.to_vec(), m2, idx + 2);
 | 
			
		||||
                set_param(p, m3, idx as i32 + 3, (left == right) as i32);
 | 
			
		||||
                idx += 4;
 | 
			
		||||
            }
 | 
			
		||||
            99 => {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            _ => panic!("invalid opcode: {}", opcode),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    (p.to_vec(), output.to_vec())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn main() -> std::io::Result<()> {
 | 
			
		||||
    let input: Vec<i32> = std::include_str!("../day5-input.txt")
 | 
			
		||||
        .trim()
 | 
			
		||||
        .split(",")
 | 
			
		||||
        .map(|x| x.parse().ok().expect(&format!("{} not a number", x)))
 | 
			
		||||
        .collect();
 | 
			
		||||
 | 
			
		||||
    let (_, output) = compute_intcode_extended(&mut input.clone(), 1);
 | 
			
		||||
    println!("part 1 = {}", output.last().unwrap());
 | 
			
		||||
 | 
			
		||||
    let (_, output) = compute_intcode_extended(&mut input.clone(), 5);
 | 
			
		||||
    println!("part 2 = {}", output[0]);
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn test_halt() {
 | 
			
		||||
    let (result, _) = compute_intcode_extended(&mut vec![99], 1);
 | 
			
		||||
    assert_eq!(result, vec![99]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn test_write_to_memory() {
 | 
			
		||||
    let (result, _) = compute_intcode_extended(&mut vec![3, 3, 99, 0], 20);
 | 
			
		||||
    assert_eq!(20, result[3]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn test_write_to_output() {
 | 
			
		||||
    let (_, output) = compute_intcode_extended(&mut vec![4, 2, 99], 1);
 | 
			
		||||
    assert_eq!(99, output[0]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn test_add() {
 | 
			
		||||
    let (result, _) = compute_intcode_extended(&mut vec![1, 2, 2, 0, 99], 1);
 | 
			
		||||
    assert_eq!(4, result[0]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn test_mul() {
 | 
			
		||||
    let (result, _) = compute_intcode_extended(&mut vec![2, 2, 4, 0, 99], 1);
 | 
			
		||||
    assert_eq!(396, result[0]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn test_immediate_mode() {
 | 
			
		||||
    let (result, output) = compute_intcode_extended(&mut vec![1102, 2, 4, 0, 99], 1);
 | 
			
		||||
    assert_eq!(8, result[0]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn test_position_mode_equal() {
 | 
			
		||||
    let (result, output) =
 | 
			
		||||
        compute_intcode_extended(&mut vec![3, 9, 8, 9, 10, 9, 4, 9, 99, -1, 8], 8);
 | 
			
		||||
    assert_eq!(1, output[0]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn test_position_mode_not_equal() {
 | 
			
		||||
    let (result, output) =
 | 
			
		||||
        compute_intcode_extended(&mut vec![3, 9, 8, 9, 10, 9, 4, 9, 99, -1, 8], 10);
 | 
			
		||||
    assert_eq!(0, output[0]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn test_position_mode_less_than() {
 | 
			
		||||
    let (result, output) =
 | 
			
		||||
        compute_intcode_extended(&mut vec![3, 9, 7, 9, 10, 9, 4, 9, 99, -1, 8], 3);
 | 
			
		||||
    assert_eq!(1, output[0]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn test_position_mode_greater_than() {
 | 
			
		||||
    let (result, output) =
 | 
			
		||||
        compute_intcode_extended(&mut vec![3, 9, 7, 9, 10, 9, 4, 9, 99, -1, 8], 10);
 | 
			
		||||
    assert_eq!(0, output[0]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn test_immediate_mode_equal() {
 | 
			
		||||
    let (result, output) = compute_intcode_extended(&mut vec![3, 3, 1108, -1, 8, 3, 4, 3, 99], 8);
 | 
			
		||||
    assert_eq!(1, output[0]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn test_immediate_mode_not_equal() {
 | 
			
		||||
    let (result, output) = compute_intcode_extended(&mut vec![3, 3, 1108, -1, 8, 3, 4, 3, 99], 10);
 | 
			
		||||
    assert_eq!(0, output[0]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn test_immediate_mode_less_than() {
 | 
			
		||||
    let (result, output) = compute_intcode_extended(&mut vec![3, 3, 1107, -1, 8, 3, 4, 3, 99], 3);
 | 
			
		||||
    assert_eq!(1, output[0]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn test_immediate_mode_greater_than() {
 | 
			
		||||
    let (result, output) = compute_intcode_extended(&mut vec![3, 3, 1107, -1, 8, 3, 4, 3, 99], 10);
 | 
			
		||||
    assert_eq!(0, output[0]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn test_position_jump_zero() {
 | 
			
		||||
    let (result, output) = compute_intcode_extended(
 | 
			
		||||
        &mut vec![3, 12, 6, 12, 15, 1, 13, 14, 13, 4, 13, 99, -1, 0, 1, 9],
 | 
			
		||||
        0,
 | 
			
		||||
    );
 | 
			
		||||
    assert_eq!(0, output[0]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn test_position_jump_one() {
 | 
			
		||||
    let (result, output) = compute_intcode_extended(
 | 
			
		||||
        &mut vec![3, 12, 6, 12, 15, 1, 13, 14, 13, 4, 13, 99, -1, 0, 1, 9],
 | 
			
		||||
        100,
 | 
			
		||||
    );
 | 
			
		||||
    assert_eq!(1, output[0]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn test_immediate_jump_zero() {
 | 
			
		||||
    let (result, output) = compute_intcode_extended(
 | 
			
		||||
        &mut vec![3, 3, 1105, -1, 9, 1101, 0, 0, 12, 4, 12, 99, 1],
 | 
			
		||||
        0,
 | 
			
		||||
    );
 | 
			
		||||
    assert_eq!(0, output[0]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn test_immediate_jump_one() {
 | 
			
		||||
    let (result, output) = compute_intcode_extended(
 | 
			
		||||
        &mut vec![3, 3, 1105, -1, 9, 1101, 0, 0, 12, 4, 12, 99, 1],
 | 
			
		||||
        100,
 | 
			
		||||
    );
 | 
			
		||||
    assert_eq!(1, output[0]);
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue