This commit is contained in:
timeshifter
2026-07-04 19:06:17 +02:00
parent 219387f8d4
commit 62d8f3227b
4 changed files with 263 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 = "day25"
version = "0.1.0"
+6
View File
@@ -0,0 +1,6 @@
[package]
name = "day25"
version = "0.1.0"
edition = "2024"
[dependencies]
+30
View File
@@ -0,0 +1,30 @@
cpy a d
cpy 7 c
cpy 362 b
inc d
dec b
jnz b -2
dec c
jnz c -5
cpy d a
jnz 0 0
cpy a b
cpy 0 a
cpy 2 c
jnz b 2
jnz 1 6
dec b
dec c
jnz c -4
inc a
jnz 1 -7
cpy 2 b
jnz c 2
jnz 1 4
dec b
dec c
jnz 1 -4
jnz 0 0
out b
jnz a -19
jnz 1 -21
+220
View File
@@ -0,0 +1,220 @@
const FILENAME: &str = "input.txt";
fn main() {
let program: Vec<_> = std::fs::read_to_string(FILENAME)
.unwrap()
.lines()
.map(Instruction::parse)
.collect();
part1(program.clone());
}
fn part1(program: Vec<Instruction>) {
let mut a = 0;
let mut output = vec![];
loop {
output.clear();
let mut registers = Registers::new();
registers.set('a', &Value::Numeric(a));
let success = run_program(&mut program.clone(), &mut registers, &mut output);
if success {
println!("{a}");
break;
}
a += 1;
}
}
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(Clone, Debug)]
enum Instruction {
Cpy(Value, Value),
Inc(Value),
Dec(Value),
Jnz(Value, Value),
Tgl(Value),
Out(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)
}
}
}
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])),
"out" => Self::Out(Value::parse(words[1])),
_ => panic!("unknown pattern: {s}"),
}
}
}
fn run_program(
program: &mut [Instruction],
registers: &mut Registers,
output: &mut Vec<usize>,
) -> bool {
let mut pointer = 0;
while let Some(instruction) = program.get(pointer) {
if output.len() == 100 {
return output
.iter()
.zip([0, 1].into_iter().cycle())
.all(|(a, b)| *a == b);
}
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),
Instruction::Out(a) => Instruction::Inc(*a),
};
pointer += 1;
}
Instruction::Out(value) => {
match value {
Value::Register(r) => {
output.push(registers.registers[Registers::get_address(*r)] as usize);
}
Value::Numeric(n) => {
output.push(*n as usize);
}
};
pointer += 1;
}
}
}
false
}