add day 23
This commit is contained in:
Generated
+7
@@ -0,0 +1,7 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "day23"
|
||||||
|
version = "0.1.0"
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
[package]
|
||||||
|
name = "day23"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
cpy 2 a
|
||||||
|
tgl a
|
||||||
|
tgl a
|
||||||
|
tgl a
|
||||||
|
cpy 1 a
|
||||||
|
dec a
|
||||||
|
dec a
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
cpy a b
|
||||||
|
dec b
|
||||||
|
cpy a d
|
||||||
|
cpy 0 a
|
||||||
|
cpy b c
|
||||||
|
inc a
|
||||||
|
dec c
|
||||||
|
jnz c -2
|
||||||
|
dec d
|
||||||
|
jnz d -5
|
||||||
|
dec b
|
||||||
|
cpy b c
|
||||||
|
cpy c d
|
||||||
|
dec d
|
||||||
|
inc c
|
||||||
|
jnz d -2
|
||||||
|
tgl c
|
||||||
|
cpy -16 c
|
||||||
|
jnz 1 c
|
||||||
|
cpy 75 c
|
||||||
|
jnz 72 d
|
||||||
|
inc a
|
||||||
|
inc d
|
||||||
|
jnz d -2
|
||||||
|
inc c
|
||||||
|
jnz c -5
|
||||||
@@ -0,0 +1,214 @@
|
|||||||
|
#[cfg(debug_assertions)]
|
||||||
|
const FILENAME: &str = "example.txt";
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
const FILENAME: &str = "input.txt";
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut program: Vec<_> = std::fs::read_to_string(FILENAME)
|
||||||
|
.unwrap()
|
||||||
|
.lines()
|
||||||
|
.map(Instruction::parse)
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
part1(&mut program);
|
||||||
|
|
||||||
|
let mut program: Vec<_> = std::fs::read_to_string(FILENAME)
|
||||||
|
.unwrap()
|
||||||
|
.lines()
|
||||||
|
.map(Instruction::parse)
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
part2(&mut program);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part2(program: &mut [Instruction]) {
|
||||||
|
let mut registers = Registers::new();
|
||||||
|
registers.set('a', &Value::Numeric(12));
|
||||||
|
|
||||||
|
run_program(program, &mut registers);
|
||||||
|
|
||||||
|
println!("{}", registers.registers[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part1(program: &mut [Instruction]) {
|
||||||
|
let mut registers = Registers::new();
|
||||||
|
registers.set('a', &Value::Numeric(7));
|
||||||
|
|
||||||
|
run_program(program, &mut registers);
|
||||||
|
|
||||||
|
println!("{}", registers.registers[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Registers {
|
||||||
|
registers: [isize; 4],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Registers {
|
||||||
|
fn set(&mut self, register: char, value: &Value) {
|
||||||
|
let address = Self::get_address(register);
|
||||||
|
match value {
|
||||||
|
Value::Register(from_register) => {
|
||||||
|
let from_address = Self::get_address(*from_register);
|
||||||
|
self.registers[address] = self.registers[from_address];
|
||||||
|
}
|
||||||
|
Value::Numeric(value) => self.registers[address] = *value,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inc(&mut self, register: char) {
|
||||||
|
let address = Self::get_address(register);
|
||||||
|
self.registers[address] += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dec(&mut self, register: char) {
|
||||||
|
let address = Self::get_address(register);
|
||||||
|
self.registers[address] -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_nonzero(&self, value: &Value) -> bool {
|
||||||
|
match value {
|
||||||
|
Value::Register(register) => {
|
||||||
|
let address = Self::get_address(*register);
|
||||||
|
self.registers[address] != 0
|
||||||
|
}
|
||||||
|
Value::Numeric(value) => *value != 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_address(register: char) -> usize {
|
||||||
|
match register {
|
||||||
|
'a' => 0,
|
||||||
|
'b' => 1,
|
||||||
|
'c' => 2,
|
||||||
|
'd' => 3,
|
||||||
|
_ => panic!("unknown register: {register}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new() -> Self {
|
||||||
|
Self { registers: [0; 4] }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum Instruction {
|
||||||
|
Cpy(Value, Value),
|
||||||
|
Inc(Value),
|
||||||
|
Dec(Value),
|
||||||
|
Jnz(Value, Value),
|
||||||
|
Tgl(Value),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
enum Value {
|
||||||
|
Register(char),
|
||||||
|
Numeric(isize),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Value {
|
||||||
|
fn parse(s: &str) -> Self {
|
||||||
|
let first_char = s.chars().next().unwrap();
|
||||||
|
if first_char.is_ascii_digit() || first_char == '-' {
|
||||||
|
Self::Numeric(s.parse().unwrap())
|
||||||
|
} else {
|
||||||
|
Self::Register(first_char)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fn is_register(&self) -> bool {
|
||||||
|
// match self {
|
||||||
|
// Value::Register(_) => true,
|
||||||
|
// Value::Numeric(_) => false,
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fn is_numeric(&self) -> bool {
|
||||||
|
// !self.is_register()
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Instruction {
|
||||||
|
fn parse(s: &str) -> Self {
|
||||||
|
let words: Vec<_> = s.split_whitespace().collect();
|
||||||
|
match words[0] {
|
||||||
|
"cpy" => Self::Cpy(Value::parse(words[1]), Value::parse(words[2])),
|
||||||
|
"inc" => Self::Inc(Value::parse(words[1])),
|
||||||
|
"dec" => Self::Dec(Value::parse(words[1])),
|
||||||
|
"jnz" => Self::Jnz(Value::parse(words[1]), Value::parse(words[2])),
|
||||||
|
"tgl" => Self::Tgl(Value::parse(words[1])),
|
||||||
|
_ => panic!("unknown pattern: {s}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run_program(program: &mut [Instruction], registers: &mut Registers) {
|
||||||
|
let mut pointer = 0;
|
||||||
|
|
||||||
|
while let Some(instruction) = program.get(pointer) {
|
||||||
|
match instruction {
|
||||||
|
Instruction::Cpy(source, value) => {
|
||||||
|
match value {
|
||||||
|
Value::Register(r) => {
|
||||||
|
registers.set(*r, source);
|
||||||
|
}
|
||||||
|
Value::Numeric(_) => (),
|
||||||
|
}
|
||||||
|
pointer += 1;
|
||||||
|
}
|
||||||
|
Instruction::Inc(value) => {
|
||||||
|
match value {
|
||||||
|
Value::Register(r) => {
|
||||||
|
registers.inc(*r);
|
||||||
|
}
|
||||||
|
Value::Numeric(_) => (),
|
||||||
|
}
|
||||||
|
pointer += 1;
|
||||||
|
}
|
||||||
|
Instruction::Dec(value) => {
|
||||||
|
match value {
|
||||||
|
Value::Register(r) => {
|
||||||
|
registers.dec(*r);
|
||||||
|
}
|
||||||
|
Value::Numeric(_) => (),
|
||||||
|
}
|
||||||
|
pointer += 1;
|
||||||
|
}
|
||||||
|
Instruction::Jnz(register, value) => {
|
||||||
|
if registers.is_nonzero(register) {
|
||||||
|
match value {
|
||||||
|
Value::Register(r) => {
|
||||||
|
let val = registers.registers[Registers::get_address(*r)];
|
||||||
|
pointer = ((pointer as isize) + val) as usize;
|
||||||
|
}
|
||||||
|
Value::Numeric(n) => {
|
||||||
|
pointer = ((pointer as isize) + *n) as usize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pointer += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Instruction::Tgl(value) => {
|
||||||
|
let val = match value {
|
||||||
|
Value::Register(r) => registers.registers[Registers::get_address(*r)],
|
||||||
|
Value::Numeric(n) => *n,
|
||||||
|
};
|
||||||
|
let instruction = match program.get_mut((pointer as isize + val) as usize) {
|
||||||
|
Some(instruction) => instruction,
|
||||||
|
None => {
|
||||||
|
pointer += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
*instruction = match instruction {
|
||||||
|
Instruction::Cpy(a, b) => Instruction::Jnz(*a, *b),
|
||||||
|
Instruction::Inc(a) => Instruction::Dec(*a),
|
||||||
|
Instruction::Dec(a) => Instruction::Inc(*a),
|
||||||
|
Instruction::Jnz(a, b) => Instruction::Cpy(*a, *b),
|
||||||
|
Instruction::Tgl(a) => Instruction::Inc(*a),
|
||||||
|
};
|
||||||
|
pointer += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user