feat: added day 24 part 1 and 2
All checks were successful
Build and run challenges / Challenge for day (6) (push) Successful in 5s
Build and run challenges / Challenge for day (9) (push) Successful in 4s
Build and run challenges / Challenge for day (10) (push) Successful in 3s
Build and run challenges / Challenge for day (11) (push) Successful in 3s
Build and run challenges / Challenge for day (12) (push) Successful in 4s
Build and run challenges / Challenge for day (13) (push) Successful in 3s
Build and run challenges / Challenge for day (16) (push) Successful in 6s
Build and run challenges / Challenge for day (17) (push) Successful in 4s
Build and run challenges / Challenge for day (20) (push) Successful in 6s
Build and run challenges / Challenge for day (18) (push) Successful in 4s
Build and run challenges / Challenge for day (19) (push) Successful in 4s
Build and run challenges / Challenge for day (2) (push) Successful in 7s
Build and run challenges / Challenge for day (21) (push) Successful in 3s
Build and run challenges / Challenge for day (22) (push) Successful in 3s
Build and run challenges / Challenge for day (23) (push) Successful in 4s
Build and run challenges / Challenge for day (24) (push) Successful in 5s
Build and run challenges / Challenge for day (4) (push) Successful in 6s
Build and run challenges / Challenge for day (5) (push) Successful in 6s
Build and run challenges / Challenge for day (3) (push) Successful in 11s
Build and run challenges / Challenge for day (1) (push) Successful in 3s
Build and run challenges / Challenge for day (15) (push) Successful in 5s
Build and run challenges / Challenge for day (14) (push) Successful in 3s
Build and run challenges / Challenge for day (8) (push) Successful in 4s
Build and run challenges / Challenge for day (7) (push) Successful in 3s

Signed-off-by: Louis Vallat <contact@louis-vallat.dev>
This commit is contained in:
Louis Vallat 2025-02-15 23:38:02 +01:00
parent 06265c2324
commit 093e724fa9
Signed by: louis
SSH Key Fingerprint: SHA256:0iPwDU/PZtEy/K13Oar4TzmcunmI9H5U9IsOR3jyT/Q
3 changed files with 192 additions and 1 deletions

View File

@ -11,7 +11,7 @@ jobs:
name: Challenge for day
strategy:
matrix:
day_number: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]
day_number: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]
runs-on: rust-bookworm
steps:
- name: Check out repository code

6
day24/Cargo.toml Normal file
View File

@ -0,0 +1,6 @@
[package]
name = "day24"
version = "0.1.0"
edition = "2021"
[dependencies]

185
day24/src/main.rs Normal file
View File

@ -0,0 +1,185 @@
use std::cmp::PartialEq;
use std::collections::{HashMap, HashSet};
use std::{env, fs};
const MAX_Z: &str = "z45";
#[derive(Debug, Eq, PartialEq, Hash, Copy, Clone)]
enum Operation {
AND,
OR,
XOR,
}
impl From<&str> for Operation {
fn from(value: &str) -> Self {
match value {
"AND" => Operation::AND,
"OR" => Operation::OR,
"XOR" => Operation::XOR,
&_ => unreachable!(),
}
}
}
#[derive(Debug)]
struct Instruction {
left: String,
operation: Operation,
right: String,
result: String,
computed: bool,
}
impl Instruction {
fn compute(&self, registers: &HashMap<String, u8>) -> Option<u8> {
let reg_left = registers.get(&self.left);
let reg_right = registers.get(&self.right);
if reg_left.is_some() && reg_right.is_some() {
match self.operation {
Operation::AND => Some(reg_left.unwrap() & reg_right.unwrap()),
Operation::OR => Some(reg_left.unwrap() | reg_right.unwrap()),
Operation::XOR => Some(reg_left.unwrap() ^ reg_right.unwrap()),
}
} else {
None
}
}
}
fn read_input(path: &str) -> String {
fs::read_to_string(path).expect("Cannot read file.")
}
fn parse_input(
input: &str,
) -> (
HashMap<String, u8>,
Vec<Instruction>,
HashMap<String, HashSet<Operation>>,
) {
let mut registers = HashMap::new();
let mut lines = input.lines();
while let Some(line) = lines.next() {
if line.is_empty() {
break;
}
let split = line.split_once(": ").unwrap();
registers.insert(split.0.to_string(), split.1.parse().unwrap());
}
let mut instructions = Vec::new();
let mut operations = HashMap::new();
while let Some(line) = lines.next() {
let mut split = line.split(" ");
let left = split.next().unwrap().to_string();
let operation = Operation::from(split.next().unwrap());
let right = split.next().unwrap().to_string();
let result = split.skip(1).next().unwrap().to_string();
instructions.push(Instruction {
left: left.clone(),
operation,
right: right.clone(),
result,
computed: false,
});
operations
.entry(left)
.or_insert(HashSet::new())
.insert(operation);
operations
.entry(right)
.or_insert(HashSet::new())
.insert(operation);
}
(registers, instructions, operations)
}
fn part_1(registers: &mut HashMap<String, u8>, instructions: &mut Vec<Instruction>) -> u128 {
while instructions.iter().any(|instruction| !instruction.computed) {
for instruction in instructions.iter_mut() {
if instruction.computed {
continue;
}
let computation = instruction.compute(registers);
if computation.is_some() {
instruction.computed = true;
registers.insert(instruction.result.clone(), computation.unwrap());
}
}
}
let mut result = 0;
for (key, value) in registers.iter().filter(|&(key, _)| key.starts_with("z")) {
result += (*value as u128) << key[1..].parse::<u128>().unwrap();
}
result
}
fn is_x_y_pair(instruction: &Instruction) -> bool {
(instruction.left.starts_with("x") && instruction.right.starts_with("y"))
|| (instruction.left.starts_with("y") && instruction.right.starts_with("x"))
}
fn part_2(
instructions: &Vec<Instruction>,
operations: &HashMap<String, HashSet<Operation>>,
) -> String {
let xa: HashSet<Operation> = HashSet::from_iter(vec![Operation::XOR, Operation::AND]);
let o: HashSet<Operation> = HashSet::from_iter(vec![Operation::OR]);
let mut anomalies = Vec::new();
for instruction in instructions {
if instruction.operation == Operation::OR {
if instruction.result != MAX_Z && operations.get(&instruction.result) != Some(&xa) {
anomalies.push(instruction.result.clone());
}
} else if instruction.operation == Operation::XOR {
if is_x_y_pair(instruction) {
if instruction.result != "z00" && operations.get(&instruction.result) != Some(&xa) {
anomalies.push(instruction.result.clone());
}
} else {
if !instruction.result.starts_with("z") {
anomalies.push(instruction.result.clone());
}
}
} else {
if is_x_y_pair(instruction) {
if ["x00", "y00"].contains(&instruction.left.as_str()) {
if operations.get(&instruction.result) != Some(&xa) {
anomalies.push(instruction.result.clone());
}
} else if operations.get(&instruction.result) != Some(&o) {
anomalies.push(instruction.result.clone());
}
} else {
if !is_x_y_pair(instruction) && operations.get(&instruction.result) != Some(&o) {
anomalies.push(instruction.result.clone());
}
}
}
}
anomalies.sort();
anomalies.join(",")
}
fn main() {
let args: Vec<String> = env::args().collect();
for arg in args.iter().skip(1) {
let input = read_input(&arg);
let (mut registers, mut instructions, operations) = parse_input(&input);
println!("[{}]", &arg);
println!(
"\t[Part 1] => Answer is '{}'.",
part_1(&mut registers, &mut instructions)
);
println!(
"\t[Part 2] => Answer is '{}'.",
part_2(&instructions, &operations)
);
}
}