mirror of
https://github.com/wezm/advent-of-code.git
synced 2024-12-18 18:29:55 +00:00
Day 9 part 1
This commit is contained in:
parent
52fe8eb76f
commit
9a7817e6ff
5 changed files with 137 additions and 51 deletions
1
2019/input/day9.txt
Normal file
1
2019/input/day9.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
1102,34463338,34463338,63,1007,63,34463338,63,1005,63,53,1102,1,3,1000,109,988,209,12,9,1000,209,6,209,3,203,0,1008,1000,1,63,1005,63,65,1008,1000,2,63,1005,63,904,1008,1000,0,63,1005,63,58,4,25,104,0,99,4,0,104,0,99,4,17,104,0,99,0,0,1101,39,0,1004,1101,0,37,1013,1101,0,28,1001,1101,0,38,1005,1101,23,0,1008,1102,1,0,1020,1102,1,26,1010,1102,31,1,1009,1101,29,0,1015,1102,459,1,1024,1101,33,0,1007,1101,0,30,1016,1101,32,0,1002,1102,1,494,1027,1101,0,216,1029,1101,497,0,1026,1101,0,303,1022,1102,1,21,1018,1102,1,36,1006,1102,1,27,1014,1102,296,1,1023,1102,454,1,1025,1102,35,1,1003,1101,22,0,1017,1102,225,1,1028,1102,1,20,1011,1101,1,0,1021,1101,0,24,1000,1101,0,25,1019,1101,0,34,1012,109,13,21102,40,1,0,1008,1013,40,63,1005,63,203,4,187,1106,0,207,1001,64,1,64,1002,64,2,64,109,5,2106,0,10,4,213,1001,64,1,64,1105,1,225,1002,64,2,64,109,-3,1206,6,241,1001,64,1,64,1105,1,243,4,231,1002,64,2,64,109,-17,2108,30,4,63,1005,63,259,1106,0,265,4,249,1001,64,1,64,1002,64,2,64,109,14,2108,35,-9,63,1005,63,283,4,271,1105,1,287,1001,64,1,64,1002,64,2,64,109,13,2105,1,-2,1001,64,1,64,1106,0,305,4,293,1002,64,2,64,109,-28,1208,5,32,63,1005,63,327,4,311,1001,64,1,64,1106,0,327,1002,64,2,64,109,12,2102,1,0,63,1008,63,31,63,1005,63,353,4,333,1001,64,1,64,1105,1,353,1002,64,2,64,109,7,21102,41,1,-6,1008,1010,40,63,1005,63,373,1105,1,379,4,359,1001,64,1,64,1002,64,2,64,109,-4,2102,1,-6,63,1008,63,35,63,1005,63,403,1001,64,1,64,1105,1,405,4,385,1002,64,2,64,109,11,21107,42,43,-4,1005,1019,427,4,411,1001,64,1,64,1105,1,427,1002,64,2,64,109,-10,1206,7,445,4,433,1001,64,1,64,1105,1,445,1002,64,2,64,109,10,2105,1,1,4,451,1105,1,463,1001,64,1,64,1002,64,2,64,109,-14,21108,43,42,4,1005,1013,479,1106,0,485,4,469,1001,64,1,64,1002,64,2,64,109,12,2106,0,6,1106,0,503,4,491,1001,64,1,64,1002,64,2,64,109,-10,2107,30,-2,63,1005,63,521,4,509,1106,0,525,1001,64,1,64,1002,64,2,64,109,-7,2101,0,-4,63,1008,63,26,63,1005,63,549,1001,64,1,64,1106,0,551,4,531,1002,64,2,64,109,13,21107,44,43,-3,1005,1014,571,1001,64,1,64,1105,1,573,4,557,1002,64,2,64,109,-6,21108,45,45,1,1005,1012,591,4,579,1106,0,595,1001,64,1,64,1002,64,2,64,109,8,1205,2,609,4,601,1106,0,613,1001,64,1,64,1002,64,2,64,109,-11,1208,-6,34,63,1005,63,629,1106,0,635,4,619,1001,64,1,64,1002,64,2,64,109,-15,2107,33,9,63,1005,63,651,1106,0,657,4,641,1001,64,1,64,1002,64,2,64,109,9,1207,2,38,63,1005,63,677,1001,64,1,64,1106,0,679,4,663,1002,64,2,64,109,8,21101,46,0,0,1008,1010,45,63,1005,63,703,1001,64,1,64,1106,0,705,4,685,1002,64,2,64,109,-5,1201,-3,0,63,1008,63,32,63,1005,63,727,4,711,1106,0,731,1001,64,1,64,1002,64,2,64,109,-6,1207,8,34,63,1005,63,753,4,737,1001,64,1,64,1106,0,753,1002,64,2,64,109,29,1205,-8,765,1106,0,771,4,759,1001,64,1,64,1002,64,2,64,109,-18,1202,-6,1,63,1008,63,39,63,1005,63,797,4,777,1001,64,1,64,1106,0,797,1002,64,2,64,109,8,21101,47,0,0,1008,1018,47,63,1005,63,823,4,803,1001,64,1,64,1105,1,823,1002,64,2,64,109,-12,2101,0,-3,63,1008,63,35,63,1005,63,845,4,829,1106,0,849,1001,64,1,64,1002,64,2,64,109,-9,1201,5,0,63,1008,63,30,63,1005,63,869,1105,1,875,4,855,1001,64,1,64,1002,64,2,64,109,8,1202,-2,1,63,1008,63,34,63,1005,63,899,1001,64,1,64,1105,1,901,4,881,4,64,99,21101,27,0,1,21101,0,915,0,1105,1,922,21201,1,45467,1,204,1,99,109,3,1207,-2,3,63,1005,63,964,21201,-2,-1,1,21101,942,0,0,1106,0,922,21201,1,0,-1,21201,-2,-3,1,21102,1,957,0,1105,1,922,22201,1,-1,-2,1105,1,968,22101,0,-2,-2,109,-3,2106,0,0
|
|
@ -78,6 +78,7 @@ mod tests {
|
||||||
|
|
||||||
assert_eq!(program, &[2, 0, 0, 0, 99])
|
assert_eq!(program, &[2, 0, 0, 0, 99])
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_example4() {
|
fn test_example4() {
|
||||||
let input = "1,1,1,4,99,5,6,0,99";
|
let input = "1,1,1,4,99,5,6,0,99";
|
||||||
|
|
53
2019/src/bin/day9.rs
Normal file
53
2019/src/bin/day9.rs
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
use std::{fs, io};
|
||||||
|
|
||||||
|
use advent_of_code::computer::Computer;
|
||||||
|
use advent_of_code::input;
|
||||||
|
|
||||||
|
fn main() -> io::Result<()> {
|
||||||
|
let input = fs::read_to_string("input/day9.txt")?;
|
||||||
|
let program = input::read_separated_line(',', &input)?;
|
||||||
|
|
||||||
|
let mut computer = Computer::new('1', program.clone(), vec![1], vec![]);
|
||||||
|
computer.run(None, None);
|
||||||
|
println!("Part 1: {}", computer.output());
|
||||||
|
|
||||||
|
// let mut computer = computer::Computer::new('2', data.clone(), vec![5], vec![]);
|
||||||
|
// computer.run(None, None);
|
||||||
|
// println!("Part 2: {}", computer.output());
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_relative_example1() {
|
||||||
|
let program = vec![1102, 34915192, 34915192, 7, 4, 7, 99, 0];
|
||||||
|
let mut computer = Computer::new('T', program, vec![], vec![]);
|
||||||
|
computer.run(None, None);
|
||||||
|
|
||||||
|
assert_eq!(computer.output(), 1219070632396864);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_relative_example2() {
|
||||||
|
let program = vec![
|
||||||
|
109, 1, 204, -1, 1001, 100, 1, 100, 1008, 100, 16, 101, 1006, 101, 0, 99,
|
||||||
|
];
|
||||||
|
let mut computer = Computer::new('T', program, vec![], vec![]);
|
||||||
|
computer.run(None, None);
|
||||||
|
|
||||||
|
assert_eq!(computer.output(), 99);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_relative_example3() {
|
||||||
|
let program = vec![104, 1125899906842624, 99];
|
||||||
|
let mut computer = Computer::new('T', program, vec![], vec![]);
|
||||||
|
computer.run(None, None);
|
||||||
|
|
||||||
|
assert_eq!(computer.output(), 1125899906842624);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,32 +1,35 @@
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
use std::convert::TryFrom;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
type Address = i32;
|
type Address = i64;
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
enum Instruction {
|
enum Instruction {
|
||||||
Add(Mode, Mode),
|
Add(Mode, Mode, Mode),
|
||||||
Multiply(Mode, Mode),
|
Multiply(Mode, Mode, Mode),
|
||||||
Input,
|
Input(Mode),
|
||||||
Output(Mode),
|
Output(Mode),
|
||||||
JumpIfTrue(Mode, Mode),
|
JumpIfTrue(Mode, Mode),
|
||||||
JumpIfFalse(Mode, Mode),
|
JumpIfFalse(Mode, Mode),
|
||||||
LessThan(Mode, Mode),
|
LessThan(Mode, Mode, Mode),
|
||||||
Equals(Mode, Mode),
|
Equals(Mode, Mode, Mode),
|
||||||
|
AdjustRelativeBase(Mode),
|
||||||
Halt,
|
Halt,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
|
||||||
enum Mode {
|
enum Mode {
|
||||||
Immediate,
|
Immediate,
|
||||||
Address,
|
Address,
|
||||||
|
Relative,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Pipe {
|
pub struct Pipe {
|
||||||
queue: VecDeque<i32>,
|
queue: VecDeque<i64>,
|
||||||
last: Option<i32>,
|
last: Option<i64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum ComputeResult {
|
pub enum ComputeResult {
|
||||||
|
@ -36,57 +39,58 @@ pub enum ComputeResult {
|
||||||
|
|
||||||
pub struct Computer<I: Input, O: Output> {
|
pub struct Computer<I: Input, O: Output> {
|
||||||
name: char,
|
name: char,
|
||||||
ip: i32,
|
ip: i64,
|
||||||
memory: Vec<i32>,
|
memory: Vec<i64>,
|
||||||
input: I,
|
input: I,
|
||||||
output: O,
|
output: O,
|
||||||
|
relative_base: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Input {
|
pub trait Input {
|
||||||
fn read(&mut self) -> Option<i32>;
|
fn read(&mut self) -> Option<i64>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Output {
|
pub trait Output {
|
||||||
fn write(&mut self, value: i32);
|
fn write(&mut self, value: i64);
|
||||||
|
|
||||||
fn last_value(&self) -> i32;
|
fn last_value(&self) -> i64;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Input for Vec<i32> {
|
impl Input for Vec<i64> {
|
||||||
fn read(&mut self) -> Option<i32> {
|
fn read(&mut self) -> Option<i64> {
|
||||||
self.pop()
|
self.pop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Output for Vec<i32> {
|
impl Output for Vec<i64> {
|
||||||
fn write(&mut self, value: i32) {
|
fn write(&mut self, value: i64) {
|
||||||
self.push(value)
|
self.push(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn last_value(&self) -> i32 {
|
fn last_value(&self) -> i64 {
|
||||||
*self.last().unwrap()
|
*self.last().unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Input for Rc<RefCell<Pipe>> {
|
impl Input for Rc<RefCell<Pipe>> {
|
||||||
fn read(&mut self) -> Option<i32> {
|
fn read(&mut self) -> Option<i64> {
|
||||||
dbg!(self.borrow_mut().queue.pop_front())
|
dbg!(self.borrow_mut().queue.pop_front())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Output for Rc<RefCell<Pipe>> {
|
impl Output for Rc<RefCell<Pipe>> {
|
||||||
fn write(&mut self, value: i32) {
|
fn write(&mut self, value: i64) {
|
||||||
let mut pipe = self.borrow_mut();
|
let mut pipe = self.borrow_mut();
|
||||||
pipe.last = Some(value);
|
pipe.last = Some(value);
|
||||||
pipe.queue.push_back(value);
|
pipe.queue.push_back(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn last_value(&self) -> i32 {
|
fn last_value(&self) -> i64 {
|
||||||
self.borrow().last.unwrap()
|
self.borrow().last.unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decode(mut instruction: i32) -> Instruction {
|
fn decode(mut instruction: i64) -> Instruction {
|
||||||
let opcode = divmod(&mut instruction, 100);
|
let opcode = divmod(&mut instruction, 100);
|
||||||
|
|
||||||
match opcode {
|
match opcode {
|
||||||
|
@ -96,13 +100,15 @@ fn decode(mut instruction: i32) -> Instruction {
|
||||||
Instruction::Add(
|
Instruction::Add(
|
||||||
Mode::from(divmod(&mut instruction, 10)),
|
Mode::from(divmod(&mut instruction, 10)),
|
||||||
Mode::from(divmod(&mut instruction, 10)),
|
Mode::from(divmod(&mut instruction, 10)),
|
||||||
|
Mode::from(divmod(&mut instruction, 10)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
2 => Instruction::Multiply(
|
2 => Instruction::Multiply(
|
||||||
Mode::from(divmod(&mut instruction, 10)),
|
Mode::from(divmod(&mut instruction, 10)),
|
||||||
Mode::from(divmod(&mut instruction, 10)),
|
Mode::from(divmod(&mut instruction, 10)),
|
||||||
|
Mode::from(divmod(&mut instruction, 10)),
|
||||||
),
|
),
|
||||||
3 => Instruction::Input,
|
3 => Instruction::Input(Mode::from(divmod(&mut instruction, 10))),
|
||||||
4 => Instruction::Output(Mode::from(divmod(&mut instruction, 10))),
|
4 => Instruction::Output(Mode::from(divmod(&mut instruction, 10))),
|
||||||
5 => Instruction::JumpIfTrue(
|
5 => Instruction::JumpIfTrue(
|
||||||
Mode::from(divmod(&mut instruction, 10)),
|
Mode::from(divmod(&mut instruction, 10)),
|
||||||
|
@ -115,11 +121,14 @@ fn decode(mut instruction: i32) -> Instruction {
|
||||||
7 => Instruction::LessThan(
|
7 => Instruction::LessThan(
|
||||||
Mode::from(divmod(&mut instruction, 10)),
|
Mode::from(divmod(&mut instruction, 10)),
|
||||||
Mode::from(divmod(&mut instruction, 10)),
|
Mode::from(divmod(&mut instruction, 10)),
|
||||||
|
Mode::from(divmod(&mut instruction, 10)),
|
||||||
),
|
),
|
||||||
8 => Instruction::Equals(
|
8 => Instruction::Equals(
|
||||||
Mode::from(divmod(&mut instruction, 10)),
|
Mode::from(divmod(&mut instruction, 10)),
|
||||||
Mode::from(divmod(&mut instruction, 10)),
|
Mode::from(divmod(&mut instruction, 10)),
|
||||||
|
Mode::from(divmod(&mut instruction, 10)),
|
||||||
),
|
),
|
||||||
|
9 => Instruction::AdjustRelativeBase(Mode::from(divmod(&mut instruction, 10))),
|
||||||
99 => Instruction::Halt,
|
99 => Instruction::Halt,
|
||||||
_ => panic!("Invalid opcode: {}", opcode),
|
_ => panic!("Invalid opcode: {}", opcode),
|
||||||
}
|
}
|
||||||
|
@ -130,13 +139,17 @@ where
|
||||||
I: Input,
|
I: Input,
|
||||||
O: Output,
|
O: Output,
|
||||||
{
|
{
|
||||||
pub fn new(name: char, memory: Vec<i32>, input: I, output: O) -> Self {
|
pub fn new(name: char, mut memory: Vec<i64>, input: I, output: O) -> Self {
|
||||||
|
// HACK
|
||||||
|
let mut buffer = vec![0; 64 * 1024 * 1024];
|
||||||
|
memory.append(&mut buffer);
|
||||||
Computer {
|
Computer {
|
||||||
name,
|
name,
|
||||||
ip: 0,
|
ip: 0,
|
||||||
memory,
|
memory,
|
||||||
input,
|
input,
|
||||||
output,
|
output,
|
||||||
|
relative_base: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,41 +157,52 @@ where
|
||||||
self.name
|
self.name
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read(&self, value: i32, mode: Mode) -> i32 {
|
fn read(&self, value: i64, mode: Mode) -> i64 {
|
||||||
match mode {
|
match mode {
|
||||||
Mode::Immediate => self.memory[value as usize],
|
Mode::Immediate => self.memory[value as usize],
|
||||||
Mode::Address => self.memory[self.memory[value as usize] as usize],
|
Mode::Address => self.memory[self.memory[value as usize] as usize],
|
||||||
|
// The address a relative mode parameter refers to is itself plus the current relative base.
|
||||||
|
Mode::Relative => {
|
||||||
|
self.memory
|
||||||
|
[usize::try_from(self.relative_base + self.memory[value as usize]).unwrap()]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write(&mut self, address: Address, value: i32) {
|
fn write(&mut self, address: Address, value: i64, mode: Mode) {
|
||||||
self.memory[address as usize] = value;
|
match mode {
|
||||||
|
Mode::Immediate => panic!("attempt to write with immediate mode"),
|
||||||
|
Mode::Address => self.memory[address as usize] = value,
|
||||||
|
Mode::Relative => {
|
||||||
|
self.memory[usize::try_from(self.relative_base + address).unwrap()] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(&mut self, noun: Option<i32>, verb: Option<i32>) -> ComputeResult {
|
pub fn run(&mut self, noun: Option<i64>, verb: Option<i64>) -> ComputeResult {
|
||||||
println!("{}: resume ip = {}", self.name, self.ip);
|
println!("{}: resume ip = {}", self.name, self.ip);
|
||||||
if let Some(noun) = noun {
|
if let Some(noun) = noun {
|
||||||
self.write(1, noun);
|
self.write(1, noun, Mode::Address);
|
||||||
}
|
}
|
||||||
if let Some(verb) = verb {
|
if let Some(verb) = verb {
|
||||||
self.write(2, verb);
|
self.write(2, verb, Mode::Address);
|
||||||
}
|
}
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match decode(self.read(self.ip, Mode::Immediate)) {
|
match decode(self.read(self.ip, Mode::Immediate)) {
|
||||||
Instruction::Add(mode1, mode2) => {
|
Instruction::Add(mode1, mode2, write_mode) => {
|
||||||
let result = self.read(self.ip + 1, mode1) + self.read(self.ip + 2, mode2);
|
let result = self.read(self.ip + 1, mode1) + self.read(self.ip + 2, mode2);
|
||||||
self.write(self.read(self.ip + 3, Mode::Immediate), result);
|
self.write(self.read(self.ip + 3, Mode::Immediate), result, write_mode);
|
||||||
self.ip += 4;
|
self.ip += 4;
|
||||||
}
|
}
|
||||||
Instruction::Multiply(mode1, mode2) => {
|
Instruction::Multiply(mode1, mode2, write_mode) => {
|
||||||
let result = self.read(self.ip + 1, mode1) * self.read(self.ip + 2, mode2);
|
let result = self.read(self.ip + 1, mode1) * self.read(self.ip + 2, mode2);
|
||||||
self.write(self.read(self.ip + 3, Mode::Immediate), result);
|
self.write(self.read(self.ip + 3, Mode::Immediate), result, write_mode);
|
||||||
self.ip += 4;
|
self.ip += 4;
|
||||||
}
|
}
|
||||||
Instruction::Input => match self.input.read() {
|
Instruction::Input(write_mode) => match self.input.read() {
|
||||||
Some(value) => {
|
Some(value) => {
|
||||||
self.write(self.read(self.ip + 1, Mode::Immediate), value);
|
self.write(self.read(self.ip + 1, Mode::Immediate), value, write_mode);
|
||||||
self.ip += 2;
|
self.ip += 2;
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
|
@ -206,53 +230,60 @@ where
|
||||||
self.ip += 3;
|
self.ip += 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Instruction::LessThan(mode1, mode2) => {
|
Instruction::LessThan(mode1, mode2, write_mode) => {
|
||||||
if self.read(self.ip + 1, mode1) < self.read(self.ip + 2, mode2) {
|
if self.read(self.ip + 1, mode1) < self.read(self.ip + 2, mode2) {
|
||||||
self.write(self.read(self.ip + 3, Mode::Immediate), 1);
|
self.write(self.read(self.ip + 3, Mode::Immediate), 1, write_mode);
|
||||||
} else {
|
} else {
|
||||||
self.write(self.read(self.ip + 3, Mode::Immediate), 0);
|
self.write(self.read(self.ip + 3, Mode::Immediate), 0, write_mode);
|
||||||
}
|
}
|
||||||
self.ip += 4;
|
self.ip += 4;
|
||||||
}
|
}
|
||||||
Instruction::Equals(mode1, mode2) => {
|
Instruction::Equals(mode1, mode2, write_mode) => {
|
||||||
if self.read(self.ip + 1, mode1) == self.read(self.ip + 2, mode2) {
|
if self.read(self.ip + 1, mode1) == self.read(self.ip + 2, mode2) {
|
||||||
self.write(self.read(self.ip + 3, Mode::Immediate), 1);
|
self.write(self.read(self.ip + 3, Mode::Immediate), 1, write_mode);
|
||||||
} else {
|
} else {
|
||||||
self.write(self.read(self.ip + 3, Mode::Immediate), 0);
|
self.write(self.read(self.ip + 3, Mode::Immediate), 0, write_mode);
|
||||||
}
|
}
|
||||||
self.ip += 4;
|
self.ip += 4;
|
||||||
}
|
}
|
||||||
|
Instruction::AdjustRelativeBase(mode) => {
|
||||||
|
let base = self.read(self.ip + 1, mode);
|
||||||
|
self.relative_base += base;
|
||||||
|
self.relative_base;
|
||||||
|
self.ip += 2;
|
||||||
|
}
|
||||||
Instruction::Halt => return ComputeResult::Halted,
|
Instruction::Halt => return ComputeResult::Halted,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn output(&self) -> i32 {
|
pub fn output(&self) -> i64 {
|
||||||
self.output.last_value()
|
self.output.last_value()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Pipe {
|
impl Pipe {
|
||||||
pub fn new(queue: VecDeque<i32>) -> Self {
|
pub fn new(queue: VecDeque<i64>) -> Self {
|
||||||
Pipe { queue, last: None }
|
Pipe { queue, last: None }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push_front(&mut self, value: i32) {
|
pub fn push_front(&mut self, value: i64) {
|
||||||
self.queue.push_front(value);
|
self.queue.push_front(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn divmod(value: &mut i32, divisor: i32) -> i32 {
|
fn divmod(value: &mut i64, divisor: i64) -> i64 {
|
||||||
let res = *value % divisor;
|
let res = *value % divisor;
|
||||||
*value /= divisor;
|
*value /= divisor;
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<i32> for Mode {
|
impl From<i64> for Mode {
|
||||||
fn from(mode: i32) -> Self {
|
fn from(mode: i64) -> Self {
|
||||||
match mode {
|
match mode {
|
||||||
0 => Mode::Address,
|
0 => Mode::Address,
|
||||||
1 => Mode::Immediate,
|
1 => Mode::Immediate,
|
||||||
|
2 => Mode::Relative,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -268,7 +299,7 @@ mod tests {
|
||||||
fn test_decode() {
|
fn test_decode() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
decode(1002),
|
decode(1002),
|
||||||
Instruction::Multiply(Mode::Address, Mode::Immediate)
|
Instruction::Multiply(Mode::Address, Mode::Immediate, Mode::Address)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ pub fn read_number_list<P: AsRef<Path>>(path: P) -> io::Result<Vec<i32>> {
|
||||||
Ok(output)
|
Ok(output)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_separated_line(sep: char, line: &str) -> io::Result<Vec<i32>> {
|
pub fn read_separated_line(sep: char, line: &str) -> io::Result<Vec<i64>> {
|
||||||
line.trim()
|
line.trim()
|
||||||
.split(sep)
|
.split(sep)
|
||||||
.map(|number| {
|
.map(|number| {
|
||||||
|
|
Loading…
Reference in a new issue