add day 23

This commit is contained in:
timeshifter
2026-07-04 17:30:17 +02:00
parent de2b9f0ecb
commit aaa4543fc7
5 changed files with 260 additions and 0 deletions
+7
View File
@@ -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"
+6
View File
@@ -0,0 +1,6 @@
[package]
name = "day23"
version = "0.1.0"
edition = "2024"
[dependencies]
+7
View File
@@ -0,0 +1,7 @@
cpy 2 a
tgl a
tgl a
tgl a
cpy 1 a
dec a
dec a
+26
View File
@@ -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
+214
View File
@@ -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;
}
}
}
}