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…
Reference in a new issue