Implement day 16 part 1.

This commit is contained in:
2018-12-16 11:12:32 +01:00
parent 5b87c12b5f
commit 4fa6998369
2 changed files with 4330 additions and 5 deletions

4174
2018/inputs/16.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,19 +1,157 @@
use std::io::BufRead;
use std::io::BufReader;
use std::io::Read; use std::io::Read;
use regex::Regex;
use common::Solution; use common::Solution;
#[derive(Copy, Clone, Debug)]
enum OpCode {
ADDR,
ADDI,
MULR,
MULI,
BANR,
BANI,
BORR,
BORI,
SETR,
SETI,
GTIR,
GTRI,
GTRR,
EQIR,
EQRI,
EQRR,
}
const OP_LIST: [OpCode; 16] = [
OpCode::ADDR,
OpCode::ADDI,
OpCode::MULR,
OpCode::MULI,
OpCode::BANR,
OpCode::BANI,
OpCode::BORR,
OpCode::BORI,
OpCode::SETR,
OpCode::SETI,
OpCode::GTIR,
OpCode::GTRI,
OpCode::GTRR,
OpCode::EQIR,
OpCode::EQRI,
OpCode::EQRR,
];
enum CPUErr {
InvalidRegister(i32),
}
#[derive(Default)] #[derive(Default)]
pub struct Day16 {} struct CPU {
registers: [i32; 4],
}
impl CPU {
pub fn execute(&mut self, op: OpCode, var: &[i32]) -> Result<i32, CPUErr> {
use self::OpCode::*;
let res = match op {
ADDR => self.reg(var[0])? + self.reg(var[1])?,
ADDI => self.reg(var[0])? + var[1],
MULR => self.reg(var[0])? * self.reg(var[1])?,
MULI => self.reg(var[0])? * var[1],
BANR => self.reg(var[0])? & self.reg(var[1])?,
BANI => self.reg(var[0])? & var[1],
BORR => self.reg(var[0])? | self.reg(var[1])?,
BORI => self.reg(var[0])? | var[1],
SETR => self.reg(var[0])?,
SETI => var[0],
GTRR => (self.reg(var[0])? > self.reg(var[1])?).into(),
GTIR => (var[0] > self.reg(var[1])?).into(),
GTRI => (self.reg(var[0])? > var[1]).into(),
EQRR => (self.reg(var[0])? == self.reg(var[1])?).into(),
EQIR => (var[0] == self.reg(var[1])?).into(),
EQRI => (self.reg(var[0])? == var[1]).into(),
};
self.registers[var[2] as usize] = res;
Ok(res)
}
fn reg(&self, index: i32) -> Result<i32, CPUErr> {
if let Some(val) = self.registers.get(index as usize) {
Ok(*val)
} else {
Err(CPUErr::InvalidRegister(index))
}
}
}
pub struct Day16 {
matcher: Regex,
buf: String,
}
impl Day16 { impl Day16 {
pub fn new() -> Self { pub fn new() -> Self {
Default::default() Day16 {
matcher: Regex::new(r"(\d+),? (\d+),? (\d+),? (\d+)").unwrap(),
buf: String::new(),
}
}
fn read(&mut self, reader: &mut BufRead, target: &mut [i32; 4]) -> bool {
self.buf.clear();
if let Err(_) = reader.read_line(&mut self.buf) {
return false;
}
if let Some(captures) = self.matcher.captures(&self.buf) {
for i in 0..4 {
target[i] = captures[i + 1].parse().unwrap();
}
true
} else {
false
}
} }
} }
impl Solution for Day16 { impl Solution for Day16 {
fn part1(&mut self, _input: &mut Read) -> String { fn part1(&mut self, input: &mut Read) -> String {
unimplemented!() let mut reader = BufReader::new(input);
let mut before = [0; 4];
let mut op = [0; 4];
let mut after = [0; 4];
let mut cpu: CPU = Default::default();
let mut counter = 0;
while self.read(&mut reader, &mut before) {
self.read(&mut reader, &mut op);
self.read(&mut reader, &mut after);
reader.read_line(&mut self.buf).unwrap_or(0);
let mut valid = 0;
for option in &OP_LIST {
cpu.registers = before;
if let Ok(val) = cpu.execute(*option, &op[1..4]) {
if val == after[op[3] as usize] {
valid += 1;
}
}
}
if valid >= 3 {
counter += 1;
}
}
format!("{}", counter)
} }
fn part2(&mut self, _input: &mut Read) -> String { fn part2(&mut self, _input: &mut Read) -> String {
@@ -22,4 +160,17 @@ impl Solution for Day16 {
} }
#[cfg(test)] #[cfg(test)]
mod tests {} mod tests {
use common::Solution;
use day16::Day16;
#[test]
fn sample_part1() {
let input: &[u8] = b"Before: [3, 2, 1, 1]
9 2 1 2
After: [3, 2, 2, 1]
";
let mut instance = Day16::new();
assert_eq!("1", instance.part1(&mut input.as_ref()));
}
}