Move Assembunny CPU to common.

This commit is contained in:
2018-11-14 12:09:03 +01:00
parent 1d6edda98b
commit 0132627341
6 changed files with 121 additions and 87 deletions

View File

@@ -1,6 +1,7 @@
use std::io;
use std::ops;
use std::cmp;
use std::io::prelude::*;
/// Apply Erathostenes's sieve to the supplied array
///
@@ -61,6 +62,77 @@ pub trait Solution {
fn part2(&mut self, input: &mut io::Read) -> String;
}
#[derive(Default)]
pub struct AssemBunnyCPU {
instructions: Vec<Vec<String>>,
pub registers: [i32; 4]
}
fn register_num(value: &str) -> Option<usize>
{
match value {
"a" => Some(0),
"b" => Some(1),
"c" => Some(2),
"d" => Some(3),
_ => None,
}
}
impl AssemBunnyCPU {
fn get_value(&self, value: &str) -> i32 {
match register_num(value) {
Some(num) => self.registers[num],
None => value.parse().unwrap()
}
}
pub fn read_instructions(&mut self, input: &mut io::Read) {
let reader = io::BufReader::new(input);
for line in reader.lines() {
let contents = line.unwrap();
let parts: Vec<String> = contents.split(" ").map(|part| String::from(part)).collect();
self.instructions.push(parts);
}
}
pub fn run(&mut self)-> i32 {
let mut iptr: i32 = 0;
while iptr < self.instructions.len() as i32 {
let ref instruction = self.instructions[iptr as usize];
match instruction[0].as_ref() {
"cpy" => {
let val = self.get_value(&instruction[1]);
let dest = register_num(&instruction[2]).unwrap();
self.registers[dest] = val;
},
"jnz" => {
let val = self.get_value(&instruction[1]);
if val != 0 {
let jump: i32 = instruction[2].parse().unwrap();
iptr += jump;
continue;
}
},
"inc" => {
let dest = register_num(&instruction[1]).unwrap();
self.registers[dest] += 1;
},
"dec" => {
let dest = register_num(&instruction[1]).unwrap();
self.registers[dest] -= 1;
},
_ => panic!("Invalid instruction: {:?}", instruction),
}
iptr += 1;
}
self.get_value("a")
}
}
#[cfg(test)]
mod tests {
use super::*;