add 25
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 = "day25"
|
||||||
|
version = "0.1.0"
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
[package]
|
||||||
|
name = "day25"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user