Day 16 part 1.

This commit is contained in:
2023-11-12 16:14:45 +01:00
parent c4ae25d579
commit 8e1f42205c
4 changed files with 4799 additions and 1 deletions

View File

@@ -1,3 +1,3 @@
fn main() {
aoc_2018::tasks::day25::task1();
aoc_2018::tasks::day16::task1();
}

536
src/tasks/day16.rs Normal file
View File

@@ -0,0 +1,536 @@
use std::ops::{BitAnd, BitOr};
use itertools::Itertools;
pub fn task1() {
let count = include_str!("../../input/day16.txt")
.split_once("\n\n\n\n")
.unwrap()
.0
.split("\n\n")
.map(|sample_input| parse(sample_input))
.map(matches_count)
.filter(|count| *count >= 3)
.count();
println!("Day 16 part1: {count}");
}
fn parse(sample: &str) -> Sample {
let (before, instruction, after) = sample.lines().collect_tuple().unwrap();
let before: Vec<_> = before
.trim_start_matches("Before: [")
.trim_end_matches("]")
.split(", ")
.collect();
let before = Registers::from(before);
let after: Vec<_> = after
.trim_start_matches("After: [")
.trim_end_matches("]")
.split(", ")
.collect();
let after = Registers::from(after);
let instruction: Vec<usize> = instruction.split(" ").map(|x| x.parse().unwrap()).collect();
let instruction = Instruction {
opcode: instruction[0],
a: instruction[1],
b: instruction[2],
c: instruction[3],
};
Sample(before, instruction, after)
}
fn matches(sample: Sample, op: Op) -> bool {
op.process(sample.0, sample.1) == sample.2
}
fn matches_count(sample: Sample) -> usize {
let vec = OPS.iter().filter(|op| matches(sample, **op)).collect_vec();
vec.len()
}
const OPS: &[Op] = &[
Op::AddR,
Op::AddI,
Op::MulR,
Op::MulI,
Op::BanR,
Op::BanI,
Op::BorR,
Op::BorI,
Op::SetR,
Op::SetI,
Op::GtIR,
Op::GtRI,
Op::GtRR,
Op::EqIR,
Op::EqRI,
Op::EqRR,
];
#[derive(Copy, Clone, Debug)]
enum Op {
AddR,
AddI,
MulR,
MulI,
BanR,
BanI,
BorR,
BorI,
SetR,
SetI,
GtIR,
GtRI,
GtRR,
EqIR,
EqRI,
EqRR,
}
impl Op {
fn process(&self, registers: Registers, instruction: Instruction) -> Registers {
let mut result = registers.0.clone();
match self {
Op::AddR => {
result[instruction.c] = result[instruction.a] + result[instruction.b];
}
Op::AddI => {
result[instruction.c] = result[instruction.a] + instruction.b as i32;
}
Op::MulR => {
result[instruction.c] = result[instruction.a] * result[instruction.b];
}
Op::MulI => {
result[instruction.c] = result[instruction.a] * instruction.b as i32;
}
Op::BanR => {
result[instruction.c] = result[instruction.a].bitand(result[instruction.b]);
}
Op::BanI => {
result[instruction.c] = result[instruction.a].bitand(instruction.b as i32);
}
Op::BorR => {
result[instruction.c] = result[instruction.a].bitor(result[instruction.b]);
}
Op::BorI => {
result[instruction.c] = result[instruction.a].bitor(instruction.b as i32);
}
Op::SetR => {
result[instruction.c] = result[instruction.a];
}
Op::SetI => {
result[instruction.c] = instruction.a as i32;
}
Op::GtIR => {
result[instruction.c] = if instruction.a as i32 > result[instruction.b] {
1
} else {
0
}
}
Op::GtRI => {
result[instruction.c] = if result[instruction.a] > instruction.b as i32 {
1
} else {
0
}
}
Op::GtRR => {
result[instruction.c] = if result[instruction.a] > result[instruction.b] {
1
} else {
0
}
}
Op::EqIR => {
result[instruction.c] = if instruction.a as i32 == result[instruction.b] {
1
} else {
0
}
}
Op::EqRI => {
result[instruction.c] = if result[instruction.a] == instruction.b as i32 {
1
} else {
0
}
}
Op::EqRR => {
result[instruction.c] = if result[instruction.a] == result[instruction.b] {
1
} else {
0
}
}
}
Registers(result)
}
}
#[derive(Copy, Clone)]
struct Sample(Registers, Instruction, Registers);
#[derive(Eq, PartialEq, Copy, Clone, Debug)]
struct Registers([i32; 4]);
impl From<Vec<&str>> for Registers {
fn from(value: Vec<&str>) -> Self {
let values: Vec<_> = value.iter().map(|x| x.parse().unwrap()).collect();
Registers([values[0], values[1], values[2], values[3]])
}
}
#[derive(Copy, Clone)]
struct Instruction {
opcode: usize,
a: usize,
b: usize,
c: usize,
}
#[cfg(test)]
mod test {
use crate::tasks::day16::{matches_count, parse, Instruction, Op, Registers};
#[test]
fn example1() {
let input = "Before: [3, 2, 1, 1]\n\
9 2 1 2\n\
After: [3, 2, 2, 1]";
assert_eq!(matches_count(parse(input)), 3);
}
#[test]
fn test_AddR() {
let op = Op::AddR;
let result = op.process(
Registers([3, 4, 3, 4]),
Instruction {
opcode: 0,
a: 0,
b: 1,
c: 3,
},
);
assert_eq!(7, result.0[3]);
}
#[test]
fn test_AddI() {
let op = Op::AddI;
let result = op.process(
Registers([1, 2, 3, 4]),
Instruction {
opcode: 0,
a: 0,
b: 1337,
c: 3,
},
);
assert_eq!(1338, result.0[3]);
}
#[test]
fn test_MulR() {
let op = Op::MulR;
let result = op.process(
Registers([1, 2, 3, 4]),
Instruction {
opcode: 0,
a: 1,
b: 2,
c: 3,
},
);
assert_eq!(6, result.0[3]);
}
#[test]
fn test_MulI() {
let op = Op::MulI;
let result = op.process(
Registers([1, 2, 3, 4]),
Instruction {
opcode: 0,
a: 1,
b: 1337,
c: 3,
},
);
assert_eq!(2 * 1337, result.0[3]);
}
#[test]
fn test_BanR() {
let op = Op::BanR;
let result = op.process(
Registers([0x10101, 0x10110, 3, 4]),
Instruction {
opcode: 0,
a: 0,
b: 1,
c: 3,
},
);
assert_eq!(0x10100, result.0[3]);
}
#[test]
fn test_BanI() {
let op = Op::BanI;
let result = op.process(
Registers([0x10101, 2, 3, 4]),
Instruction {
opcode: 0,
a: 0,
b: 0x10110,
c: 3,
},
);
assert_eq!(0x10100, result.0[3]);
}
#[test]
fn test_BorR() {
let op = Op::BorR;
let result = op.process(
Registers([0x10101, 0x10110, 3, 4]),
Instruction {
opcode: 0,
a: 0,
b: 1,
c: 3,
},
);
assert_eq!(0x10111, result.0[3]);
}
#[test]
fn test_BorI() {
let op = Op::BorI;
let result = op.process(
Registers([0x10101, 2, 3, 4]),
Instruction {
opcode: 0,
a: 0,
b: 0x10110,
c: 3,
},
);
assert_eq!(0x10111, result.0[3]);
}
#[test]
fn test_SetR() {
let op = Op::SetR;
let result = op.process(
Registers([1, 2, 3, 4]),
Instruction {
opcode: 0,
a: 1,
b: 1,
c: 3,
},
);
assert_eq!(2, result.0[3]);
}
#[test]
fn test_SetI() {
let op = Op::SetI;
let result = op.process(
Registers([1, 2, 3, 4]),
Instruction {
opcode: 0,
a: 1234,
b: 1,
c: 3,
},
);
assert_eq!(1234, result.0[3]);
}
#[test]
fn test_GtIR_true() {
let op = Op::GtIR;
let result = op.process(
Registers([1, 29, 3, 4]),
Instruction {
opcode: 0,
a: 30,
b: 1,
c: 3,
},
);
assert_eq!(1, result.0[3]);
}
#[test]
fn test_GtIR_false() {
let op = Op::GtIR;
let result = op.process(
Registers([1, 1337, 3, 4]),
Instruction {
opcode: 0,
a: 1337,
b: 1,
c: 3,
},
);
assert_eq!(0, result.0[3]);
}
#[test]
fn test_GtRI_true() {
let op = Op::GtRI;
let result = op.process(
Registers([1, 2, 3, 4]),
Instruction {
opcode: 0,
a: 2,
b: 1,
c: 3,
},
);
assert_eq!(1, result.0[3]);
}
#[test]
fn test_GtRI_false() {
let op = Op::GtRI;
let result = op.process(
Registers([1, 2, 3, 4]),
Instruction {
opcode: 0,
a: 2,
b: 3,
c: 3,
},
);
assert_eq!(0, result.0[3]);
}
#[test]
fn test_GtRR_true() {
let op = Op::GtRR;
let result = op.process(
Registers([1, 2, 3, 4]),
Instruction {
opcode: 0,
a: 1,
b: 0,
c: 3,
},
);
assert_eq!(1, result.0[3]);
}
#[test]
fn test_GtRR() {
let op = Op::GtRR;
let result = op.process(
Registers([1, 2, 3, 4]),
Instruction {
opcode: 0,
a: 1,
b: 1,
c: 3,
},
);
assert_eq!(0, result.0[3]);
}
#[test]
fn test_EqIR_true() {
let op = Op::EqIR;
let result = op.process(
Registers([1, 2, 3, 4]),
Instruction {
opcode: 0,
a: 1,
b: 0,
c: 3,
},
);
assert_eq!(1, result.0[3]);
}
#[test]
fn test_EqIR_false() {
let op = Op::EqIR;
let result = op.process(
Registers([1, 2, 3, 4]),
Instruction {
opcode: 0,
a: 1,
b: 1,
c: 3,
},
);
assert_eq!(0, result.0[3]);
}
#[test]
fn test_EqRI_true() {
let op = Op::EqRI;
let result = op.process(
Registers([1, 2, 3, 4]),
Instruction {
opcode: 0,
a: 2,
b: 3,
c: 3,
},
);
assert_eq!(1, result.0[3]);
}
#[test]
fn test_EqRI_false() {
let op = Op::EqRI;
let result = op.process(
Registers([1, 2, 3, 4]),
Instruction {
opcode: 0,
a: 1,
b: 1,
c: 3,
},
);
assert_eq!(0, result.0[3]);
}
#[test]
fn test_EqRR_true() {
let op = Op::EqRR;
let result = op.process(
Registers([1, 2, 3, 4]),
Instruction {
opcode: 0,
a: 1,
b: 1,
c: 3,
},
);
assert_eq!(1, result.0[3]);
}
#[test]
fn test_EqRR_false() {
let op = Op::EqRR;
let result = op.process(
Registers([1, 2, 3, 4]),
Instruction {
opcode: 0,
a: 1,
b: 2,
c: 3,
},
);
assert_eq!(0, result.0[3]);
}
}

View File

@@ -13,6 +13,7 @@ pub mod day12;
pub mod day13;
pub mod day14;
pub mod day15;
pub mod day16;
pub mod day17;
pub mod day18;
pub mod day20;