add day 12

This commit is contained in:
timeshifter
2026-07-01 19:31:30 +02:00
parent aba4ab49db
commit 3aff343f90
5 changed files with 196 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 = "day12"
version = "0.1.0"
+6
View File
@@ -0,0 +1,6 @@
[package]
name = "day12"
version = "0.1.0"
edition = "2024"
[dependencies]
+6
View File
@@ -0,0 +1,6 @@
cpy 41 a
inc a
inc a
dec a
jnz a 2
dec a
+23
View File
@@ -0,0 +1,23 @@
cpy 1 a
cpy 1 b
cpy 26 d
jnz c 2
jnz 1 5
cpy 7 c
inc d
dec c
jnz c -2
cpy a c
inc a
dec b
jnz b -2
cpy c b
dec d
jnz d -6
cpy 19 c
cpy 11 d
inc a
dec d
jnz d -2
dec c
jnz c -5
+154
View File
@@ -0,0 +1,154 @@
#[cfg(debug_assertions)]
const FILENAME: &str = "example.txt";
#[cfg(not(debug_assertions))]
const FILENAME: &str = "input.txt";
fn main() {
let program: Vec<_> = std::fs::read_to_string(FILENAME)
.unwrap()
.lines()
.map(Instruction::parse)
.collect();
part1(&program);
part2(&program);
}
struct Registers {
registers: [usize; 4],
}
impl Registers {
fn set(&mut self, register: char, source: &Source) {
let address = Self::get_address(register);
match source {
Source::Register(from_register) => {
let from_address = Self::get_address(*from_register);
self.registers[address] = self.registers[from_address];
}
Source::Value(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: &Source) -> bool {
match value {
Source::Register(register) => {
let address = Self::get_address(*register);
self.registers[address] != 0
}
Source::Value(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] }
}
fn value_a(&self) -> usize {
let address = Self::get_address('a');
self.registers[address]
}
}
fn part1(program: &[Instruction]) {
let mut registers = Registers::new();
run_program(program, &mut registers);
println!("{}", registers.value_a());
}
fn part2(program: &[Instruction]) {
let mut registers = Registers::new();
registers.set('c', &Source::Value(1));
run_program(program, &mut registers);
println!("{}", registers.value_a());
}
fn run_program(program: &[Instruction], registers: &mut Registers) {
let mut pointer = 0;
while let Some(instruction) = program.get(pointer) {
match instruction {
Instruction::Cpy(source, register) => {
registers.set(*register, source);
pointer += 1;
}
Instruction::Inc(register) => {
registers.inc(*register);
pointer += 1;
}
Instruction::Dec(register) => {
registers.dec(*register);
pointer += 1;
}
Instruction::Jnz(register, offset) => {
if registers.is_nonzero(register) {
pointer = (pointer as isize + offset) as usize;
} else {
pointer += 1;
}
}
}
}
}
#[derive(Debug)]
enum Instruction {
Cpy(Source, char),
Inc(char),
Dec(char),
Jnz(Source, isize),
}
#[derive(Debug)]
enum Source {
Register(char),
Value(usize),
}
impl Source {
fn parse(s: &str) -> Self {
let first_char = s.chars().next().unwrap();
if first_char.is_ascii_digit() {
Self::Value(s.parse().unwrap())
} else {
Self::Register(first_char)
}
}
}
impl Instruction {
fn parse(s: &str) -> Self {
let words: Vec<_> = s.split_whitespace().collect();
dbg!(&words);
match words[0] {
"cpy" => Self::Cpy(Source::parse(words[1]), words[2].chars().next().unwrap()),
"inc" => Self::Inc(words[1].chars().next().unwrap()),
"dec" => Self::Dec(words[1].chars().next().unwrap()),
"jnz" => Self::Jnz(Source::parse(words[1]), words[2].parse().unwrap()),
_ => panic!("unknown pattern: {s}"),
}
}
}