Add D5P2 in Rust
This commit is contained in:
parent
4a1063c522
commit
f1b4cb6e94
@ -7,6 +7,10 @@ enum Operation {
|
|||||||
Multiply { x: i32, y: i32, addr: usize },
|
Multiply { x: i32, y: i32, addr: usize },
|
||||||
Input { value: i32, addr: usize },
|
Input { value: i32, addr: usize },
|
||||||
Output { value: i32 },
|
Output { value: i32 },
|
||||||
|
JumpIfTrue { value: i32, addr: i32 },
|
||||||
|
JumpIfFalse { value: i32, addr: i32 },
|
||||||
|
LessThan { first: i32, second: i32, addr: i32 },
|
||||||
|
Equals { first: i32, second: i32, addr: i32 },
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -41,12 +45,10 @@ impl Into<Mode> for &char {
|
|||||||
|
|
||||||
fn get_next(input: &Vec<i32>, pos: &mut i32, mode: Mode) -> i32 {
|
fn get_next(input: &Vec<i32>, pos: &mut i32, mode: Mode) -> i32 {
|
||||||
let value = input[*pos as usize];
|
let value = input[*pos as usize];
|
||||||
//dbg!(&mode, &pos, value);
|
|
||||||
let next = match mode {
|
let next = match mode {
|
||||||
Mode::Position => input[value as usize],
|
Mode::Position => input[value as usize],
|
||||||
Mode::Immediate => value,
|
Mode::Immediate => value,
|
||||||
};
|
};
|
||||||
//dbg!(&next);
|
|
||||||
*pos += 1;
|
*pos += 1;
|
||||||
next
|
next
|
||||||
}
|
}
|
||||||
@ -55,11 +57,10 @@ fn get_mode(raw_opcode: &Vec<char>, pos: ParameterPosition) -> Mode {
|
|||||||
raw_opcode.get::<usize>(pos.into()).unwrap_or(&'0').into()
|
raw_opcode.get::<usize>(pos.into()).unwrap_or(&'0').into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next_operation(input: &Vec<i32>, pos: &mut i32) -> Option<Operation> {
|
fn next_operation(input: &Vec<i32>, pos: &mut i32, inp: i32) -> Option<Operation> {
|
||||||
let next = get_next(input, pos, Mode::Immediate);
|
let next = get_next(input, pos, Mode::Immediate);
|
||||||
let mut raw_opcode: Vec<_> = next.to_string().chars().collect();
|
let mut raw_opcode: Vec<_> = next.to_string().chars().collect();
|
||||||
raw_opcode.reverse();
|
raw_opcode.reverse();
|
||||||
//dbg!(&raw_opcode);
|
|
||||||
match raw_opcode[0] {
|
match raw_opcode[0] {
|
||||||
'1' => Some(Operation::Add {
|
'1' => Some(Operation::Add {
|
||||||
x: get_next(input, pos, get_mode(&raw_opcode, ParameterPosition::First)),
|
x: get_next(input, pos, get_mode(&raw_opcode, ParameterPosition::First)),
|
||||||
@ -72,24 +73,65 @@ fn next_operation(input: &Vec<i32>, pos: &mut i32) -> Option<Operation> {
|
|||||||
addr: get_next(input, pos, Mode::Immediate) as usize,
|
addr: get_next(input, pos, Mode::Immediate) as usize,
|
||||||
}),
|
}),
|
||||||
'3' => Some(Operation::Input {
|
'3' => Some(Operation::Input {
|
||||||
value: 1,
|
value: inp,
|
||||||
addr: get_next(input, pos, Mode::Immediate) as usize,
|
addr: get_next(input, pos, Mode::Immediate) as usize,
|
||||||
}),
|
}),
|
||||||
'4' => Some(Operation::Output {
|
'4' => Some(Operation::Output {
|
||||||
value: get_next(input, pos, get_mode(&raw_opcode, ParameterPosition::First)),
|
value: get_next(input, pos, get_mode(&raw_opcode, ParameterPosition::First)),
|
||||||
}),
|
}),
|
||||||
|
'5' => Some(Operation::JumpIfTrue {
|
||||||
|
value: get_next(input, pos, get_mode(&raw_opcode, ParameterPosition::First)),
|
||||||
|
addr: get_next(input, pos, get_mode(&raw_opcode, ParameterPosition::Second)),
|
||||||
|
}),
|
||||||
|
'6' => Some(Operation::JumpIfFalse {
|
||||||
|
value: get_next(input, pos, get_mode(&raw_opcode, ParameterPosition::First)),
|
||||||
|
addr: get_next(input, pos, get_mode(&raw_opcode, ParameterPosition::Second)),
|
||||||
|
}),
|
||||||
|
'7' => Some(Operation::LessThan {
|
||||||
|
first: get_next(input, pos, get_mode(&raw_opcode, ParameterPosition::First)),
|
||||||
|
second: get_next(input, pos, get_mode(&raw_opcode, ParameterPosition::Second)),
|
||||||
|
addr: get_next(input, pos, Mode::Immediate),
|
||||||
|
}),
|
||||||
|
'8' => Some(Operation::Equals {
|
||||||
|
first: get_next(input, pos, get_mode(&raw_opcode, ParameterPosition::First)),
|
||||||
|
second: get_next(input, pos, get_mode(&raw_opcode, ParameterPosition::Second)),
|
||||||
|
addr: get_next(input, pos, Mode::Immediate),
|
||||||
|
}),
|
||||||
'9' => None,
|
'9' => None,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute(op: Operation, input: &mut Vec<i32>) {
|
fn execute(op: Operation, input: &mut Vec<i32>, pos: &mut i32) {
|
||||||
//dbg!(&op);
|
|
||||||
match op {
|
match op {
|
||||||
Operation::Add { x, y, addr } => input[addr as usize] = x + y,
|
Operation::Add { x, y, addr } => input[addr as usize] = x + y,
|
||||||
Operation::Multiply { x, y, addr } => input[addr as usize] = x * y,
|
Operation::Multiply { x, y, addr } => input[addr as usize] = x * y,
|
||||||
Operation::Input { value, addr } => input[addr] = value,
|
Operation::Input { value, addr } => input[addr] = value,
|
||||||
Operation::Output { value } => println!("{}", value),
|
Operation::Output { value } => {
|
||||||
|
if value != 0 {
|
||||||
|
println!("{}", value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Operation::JumpIfTrue { value, addr } => {
|
||||||
|
if value != 0 {
|
||||||
|
*pos = addr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Operation::JumpIfFalse { value, addr } => {
|
||||||
|
if value == 0 {
|
||||||
|
*pos = addr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Operation::LessThan {
|
||||||
|
first,
|
||||||
|
second,
|
||||||
|
addr,
|
||||||
|
} => input[addr as usize] = (first < second) as i32,
|
||||||
|
Operation::Equals {
|
||||||
|
first,
|
||||||
|
second,
|
||||||
|
addr,
|
||||||
|
} => input[addr as usize] = (first == second) as i32,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,9 +146,16 @@ pub fn main() {
|
|||||||
.map(|n| n.parse().unwrap())
|
.map(|n| n.parse().unwrap())
|
||||||
.collect();
|
.collect();
|
||||||
let mut pos = 0;
|
let mut pos = 0;
|
||||||
//dbg!(&input);
|
let mut part2_input = input.clone();
|
||||||
|
|
||||||
while let Some(op) = next_operation(&input, &mut pos) {
|
println!("Part 1:");
|
||||||
execute(op, &mut input);
|
while let Some(op) = next_operation(&input, &mut pos, 1) {
|
||||||
|
execute(op, &mut input, &mut pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = 0;
|
||||||
|
println!("Part 2:");
|
||||||
|
while let Some(op) = next_operation(&part2_input, &mut pos, 5) {
|
||||||
|
execute(op, &mut part2_input, &mut pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user