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 +0,0 @@
[package]
name = "day-12"
version = "0.1.0"
authors = ["Bert Peters <bert.ljpeters@gmail.com>"]
[dependencies]

View File

@@ -1,81 +0,0 @@
use std::env;
use std::io::prelude::*;
use std::fs::File;
use std::io::BufReader;
fn register_num(value: &str) -> Option<usize>
{
match value {
"a" => Some(0),
"b" => Some(1),
"c" => Some(2),
"d" => Some(3),
_ => None,
}
}
fn get_value(value: &str, registers: &[i32; 4]) -> i32
{
match register_num(value) {
Some(num) => registers[num],
_ => value.parse().unwrap(),
}
}
fn run(program: &Vec<Vec<String>>, mut registers: [i32; 4]) -> [i32; 4]
{
let mut iptr: i32 = 0;
while iptr < program.len() as i32 {
let ref instruction = program[iptr as usize];
//println!("{} ({:?}): {:?}", iptr, registers, instruction);
match instruction[0].as_ref() {
"cpy" => {
let val = get_value(&instruction[1], &registers);
let dest = register_num(&instruction[2]).unwrap();
registers[dest] = val;
},
"jnz" => {
let val = get_value(&instruction[1], &registers);
if val != 0 {
let jump: i32 = instruction[2].parse().unwrap();
iptr += jump;
continue;
}
},
"inc" => {
let dest = register_num(&instruction[1]).unwrap();
registers[dest] += 1;
},
"dec" => {
let dest = register_num(&instruction[1]).unwrap();
registers[dest] -= 1;
},
_ => panic!("Invalid instruction: {:?}", instruction),
}
iptr += 1;
}
return registers;
}
fn main() {
let args: Vec<String> = env::args().collect();
let f = File::open(&args[1]).expect("Could not open file");
let reader = BufReader::new(f);
let mut program = Vec::new();
for line in reader.lines() {
let contents = line.unwrap();
let parts: Vec<String> = contents.split(" ").map(|part| String::from(part)).collect();
program.push(parts);
}
let result1 = run(&program, [0; 4]);
println!("Run 1: register a contains {}", result1[0]);
let result2 = run(&program, [0, 0, 1, 0]);
println!("Run 2: register a contains {}", result2[0]);
}

View File

@@ -1,6 +1,7 @@
use std::io; use std::io;
use std::ops; use std::ops;
use std::cmp; use std::cmp;
use std::io::prelude::*;
/// Apply Erathostenes's sieve to the supplied array /// Apply Erathostenes's sieve to the supplied array
/// ///
@@ -61,6 +62,77 @@ pub trait Solution {
fn part2(&mut self, input: &mut io::Read) -> String; 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)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

47
2016/src/day12.rs Normal file
View File

@@ -0,0 +1,47 @@
use std::io;
use common;
#[derive(Default)]
pub struct Day12 {
cpu: common::AssemBunnyCPU,
}
impl Day12 {
pub fn new() -> Day12 {
Default::default()
}
}
impl common::Solution for Day12 {
fn part1(&mut self, input: &mut io::Read) -> String {
self.cpu.read_instructions(input);
format!("{}", self.cpu.run())
}
fn part2(&mut self, input: &mut io::Read) -> String {
self.cpu.read_instructions(input);
self.cpu.registers[2] = 1;
format!("{}", self.cpu.run())
}
}
#[cfg(test)]
mod tests {
use super::*;
use common::Solution;
const SAMPLE_INPUT: &str = "cpy 41 a
inc a
inc a
dec a
jnz a 2
dec a";
#[test]
fn sample_part1() {
let mut instance = Day12::new();
assert_eq!("42", instance.part1(&mut SAMPLE_INPUT.as_bytes()))
}
}

View File

@@ -7,12 +7,14 @@ use std::io;
pub mod common; pub mod common;
pub mod day1; pub mod day1;
pub mod day12;
pub mod day15; pub mod day15;
pub mod day16; pub mod day16;
fn get_impl(day: i32) -> Box<common::Solution> { fn get_impl(day: i32) -> Box<common::Solution> {
match day { match day {
1 => { Box::new(day1::Day1::new()) } 1 => { Box::new(day1::Day1::new()) }
12 => { Box::new(day12::Day12::new()) }
15 => { Box::new(day15::Day15::new()) } 15 => { Box::new(day15::Day15::new()) }
16 => { Box::new(day16::Day16::new()) } 16 => { Box::new(day16::Day16::new()) }
_ => { _ => {