From 854edb86c975530391b197084d5ba03d86ad3718 Mon Sep 17 00:00:00 2001 From: Justin Worthe Date: Mon, 12 Dec 2016 12:20:19 +0200 Subject: Perf AOC12 --- aoc12/src/main.rs | 95 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 67 insertions(+), 28 deletions(-) diff --git a/aoc12/src/main.rs b/aoc12/src/main.rs index bcd591c..e3b6038 100644 --- a/aoc12/src/main.rs +++ b/aoc12/src/main.rs @@ -5,63 +5,101 @@ use std::io::BufReader; use std::io::prelude::*; use std::fs::File; +enum Instruction { + CpyLit(i32, usize), + CpyReg(usize, usize), + Inc(usize), + Dec(usize), + Jnz(usize, i32), + Jmp(i32), + Noop +} -fn main() { - let program = read_file(); - - let mut registers: [i32; 4] = [0;4]; - registers[2] = 1; //init c to 1 - let mut pc: usize = 0; - - let cpy_lit = Regex::new(r"cpy ([-\d]+) (a|b|c|d)").unwrap(); - let cpy_reg = Regex::new(r"cpy (a|b|c|d) (a|b|c|d)").unwrap(); - let inc = Regex::new(r"inc (a|b|c|d)").unwrap(); - let dec = Regex::new(r"dec (a|b|c|d)").unwrap(); - let jnz_lit = Regex::new(r"jnz ([-\d]+) ([-\d]+)").unwrap(); - let jnz_reg = Regex::new(r"jnz (a|b|c|d) ([-\d]+)").unwrap(); +impl Instruction { + fn parse(line: &str) -> Instruction { + let cpy_lit: Regex = Regex::new(r"cpy ([-\d]+) (a|b|c|d)").unwrap(); + let cpy_reg = Regex::new(r"cpy (a|b|c|d) (a|b|c|d)").unwrap(); + let inc = Regex::new(r"inc (a|b|c|d)").unwrap(); + let dec = Regex::new(r"dec (a|b|c|d)").unwrap(); + let jnz_lit = Regex::new(r"jnz ([-\d]+) ([-\d]+)").unwrap(); + let jnz_reg = Regex::new(r"jnz (a|b|c|d) ([-\d]+)").unwrap(); - - while pc < program.len() { - let line = program[pc].as_ref(); - let mut pc_next: usize = pc+1; - if cpy_lit.is_match(line) { let cap = cpy_lit.captures(line).unwrap(); let src: i32 = cap.at(1).unwrap().parse().unwrap(); let dest = to_register_index(cap.at(2).unwrap()); - registers[dest] = src; + Instruction::CpyLit(src, dest) } else if cpy_reg.is_match(line) { let cap = cpy_reg.captures(line).unwrap(); let src = to_register_index(cap.at(1).unwrap()); let dest = to_register_index(cap.at(2).unwrap()); - registers[dest] = registers[src]; + Instruction::CpyReg(src, dest) } else if inc.is_match(line) { let cap = inc.captures(line).unwrap(); let dest = to_register_index(cap.at(1).unwrap()); - registers[dest] = registers[dest] + 1; + Instruction::Inc(dest) } else if dec.is_match(line) { let cap = dec.captures(line).unwrap(); let dest = to_register_index(cap.at(1).unwrap()); - registers[dest] = registers[dest] - 1; + Instruction::Dec(dest) } else if jnz_lit.is_match(line) { let cap = jnz_lit.captures(line).unwrap(); let condition: i32 = cap.at(1).unwrap().parse().unwrap(); let offset: i32 = cap.at(2).unwrap().parse().unwrap(); if condition != 0 { - pc_next = (pc as i32 + offset) as usize; + Instruction::Jmp(offset) + } + else { + Instruction::Noop } } else if jnz_reg.is_match(line) { let cap = jnz_reg.captures(line).unwrap(); let condition = to_register_index(cap.at(1).unwrap()); let offset: i32 = cap.at(2).unwrap().parse().unwrap(); - if registers[condition] != 0 { - pc_next = (pc as i32 + offset) as usize; - } + Instruction::Jnz(condition, offset) + } + else { + panic!("Invalid instruction line") + } + } +} + +fn main() { + let program = read_file(); + + let mut registers: [i32; 4] = [0, 0, 1, 0]; + let mut pc: usize = 0; + + while pc < program.len() { + let mut pc_next: usize = pc+1; + + match program[pc] { + Instruction::CpyLit(src, dest) => { + registers[dest] = src; + }, + Instruction::CpyReg(src, dest) => { + registers[dest] = registers[src]; + }, + Instruction::Inc(dest) => { + registers[dest] += 1; + }, + Instruction::Dec(dest) => { + registers[dest] -= 1; + }, + Instruction::Jnz(condition, offset) => { + if registers[condition] != 0 { + pc_next = (pc as i32 + offset) as usize; + } + }, + Instruction::Jmp(offset) => { + pc_next = (pc as i32 + offset) as usize + }, + Instruction::Noop => {} } pc = pc_next; @@ -81,10 +119,11 @@ fn to_register_index(name: &str) -> usize { } } -fn read_file() -> Vec { +fn read_file() -> Vec { let file = BufReader::new(File::open("input.txt").unwrap()); file.lines() - .map(|line| line.unwrap().trim().to_string()) + .map(|line| line.unwrap()) .filter(|line| line.len() > 0) + .map(|line| Instruction::parse(line.trim())) .collect() } -- cgit v1.2.3