69 lines
1.7 KiB
Rust
69 lines
1.7 KiB
Rust
use std::io::{self, Read};
|
|
|
|
type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
|
|
|
|
fn get_input_string() -> io::Result<String> {
|
|
let mut buffer = String::new();
|
|
io::stdin().read_to_string(&mut buffer)?;
|
|
Ok(buffer)
|
|
}
|
|
|
|
fn main() -> Result<()> {
|
|
let program: Vec<_> = get_input_string()?
|
|
.trim()
|
|
.split(",")
|
|
.filter(|s| !s.is_empty())
|
|
.map(|n| n.parse::<usize>().unwrap())
|
|
.collect();
|
|
part1(&program);
|
|
part2(&program);
|
|
Ok(())
|
|
}
|
|
|
|
fn part1(program: &Vec<usize>) {
|
|
let data = run_program(12, 2, program.clone());
|
|
println!("Part 1: {}", data[0]);
|
|
}
|
|
|
|
fn part2(program: &Vec<usize>) {
|
|
const GOAL: usize = 19690720;
|
|
for noun in 0..=99 {
|
|
for verb in 0..=99 {
|
|
let data = run_program(noun, verb, program.clone());
|
|
if data[0] == GOAL {
|
|
println!("Part 2: noun: {} verb: {} answer: {}", noun, verb, (noun * 100) + verb);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
println!("could not find a solution");
|
|
}
|
|
|
|
fn run_program(noun: usize, verb: usize, mut program: Vec<usize>) -> Vec<usize> {
|
|
let mut pc = 0;
|
|
program[1] = noun;
|
|
program[2] = verb;
|
|
|
|
loop {
|
|
match program[pc] {
|
|
op @ 1 | op @ 2 => {
|
|
let in1 = program[program[pc + 1]];
|
|
let in2 = program[program[pc + 2]];
|
|
let out = program[pc + 3];
|
|
|
|
let value = if op == 1 {
|
|
in1 + in2
|
|
} else {
|
|
in1 * in2
|
|
};
|
|
program[out] = value;
|
|
}
|
|
99 => break,
|
|
_ => panic!("bad opcode: {}", program[pc]),
|
|
}
|
|
pc += 4;
|
|
}
|
|
|
|
program
|
|
}
|