day-05.rs (3584B)
1 fn main() {
2 let input = std::fs::read_to_string("input.txt")
3 .unwrap()
4 .trim()
5 .split(",")
6 .map(|op| op.parse::<i32>().unwrap())
7 .collect::<Vec<i32>>();
8 println!("Rust:");
9 println!("Part 1: {}", part_1(&input));
10 println!("Part 2: {}", part_2(&input));
11 }
12
13 fn computer(program: &Vec<i32>, input: i32) -> Vec<i32> {
14 let mut program = program.clone();
15 let mut output = vec![];
16 let mut pc = 0;
17
18 let get_param = |loc: usize, im_mode, program: &Vec<i32>| -> i32 {
19 if im_mode {
20 program[loc]
21 } else {
22 program[program[loc] as usize]
23 }
24 };
25
26 loop {
27 let op_code = program[pc] % 100;
28 let im_mode_1 = (program[pc] % 1000) / 100 > 0;
29 let im_mode_2 = (program[pc] % 10000) / 1000 > 0;
30 // Third parameter is location to write to, and will never be immediate
31 // mode.
32 match op_code {
33 1 => {
34 let res_loc = program[pc + 3];
35 let param_1 = get_param(pc + 1, im_mode_1, &program);
36 let param_2 = get_param(pc + 2, im_mode_2, &program);
37 program[res_loc as usize] = param_1 + param_2;
38 pc += 4;
39 }
40 2 => {
41 let res_loc = program[pc + 3];
42 let param_1 = get_param(pc + 1, im_mode_1, &program);
43 let param_2 = get_param(pc + 2, im_mode_2, &program);
44 program[res_loc as usize] = param_1 * param_2;
45 pc += 4;
46 }
47 3 => {
48 let res_loc = program[pc + 1];
49 program[res_loc as usize] = input;
50 pc += 2;
51 }
52 4 => {
53 let param_1 = get_param(pc + 1, im_mode_1, &program);
54 output.push(param_1);
55 pc += 2;
56 }
57 5 => {
58 let param_1 = get_param(pc + 1, im_mode_1, &program);
59 let param_2 = get_param(pc + 2, im_mode_2, &program);
60 if param_1 != 0 {
61 pc = param_2 as usize;
62 } else {
63 pc += 3;
64 }
65 }
66 6 => {
67 let param_1 = get_param(pc + 1, im_mode_1, &program);
68 let param_2 = get_param(pc + 2, im_mode_2, &program);
69 if param_1 == 0 {
70 pc = param_2 as usize;
71 } else {
72 pc += 3;
73 }
74 }
75 7 => {
76 let res_loc = program[pc + 3];
77 let param_1 = get_param(pc + 1, im_mode_1, &program);
78 let param_2 = get_param(pc + 2, im_mode_2, &program);
79 program[res_loc as usize] = if param_1 < param_2 { 1 } else { 0 };
80 pc += 4;
81 }
82 8 => {
83 let res_loc = program[pc + 3];
84 let param_1 = get_param(pc + 1, im_mode_1, &program);
85 let param_2 = get_param(pc + 2, im_mode_2, &program);
86 program[res_loc as usize] = if param_1 == param_2 { 1 } else { 0 };
87 pc += 4;
88 }
89 99 => {
90 break;
91 }
92 _ => {
93 println!("Unknown op {}", op_code);
94 println!("{}", program[pc]);
95 panic!();
96 }
97 }
98 }
99
100 output
101 }
102
103 fn part_1(input: &Vec<i32>) -> i32 {
104 *computer(&input, 1).last().unwrap()
105 }
106
107 fn part_2(input: &Vec<i32>) -> i32 {
108 *computer(&input, 5).last().unwrap()
109 }