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
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:
parent
06265c2324
commit
093e724fa9
@ -11,7 +11,7 @@ jobs:
|
|||||||
name: Challenge for day
|
name: Challenge for day
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
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
|
runs-on: rust-bookworm
|
||||||
steps:
|
steps:
|
||||||
- name: Check out repository code
|
- name: Check out repository code
|
||||||
|
6
day24/Cargo.toml
Normal file
6
day24/Cargo.toml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[package]
|
||||||
|
name = "day24"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
185
day24/src/main.rs
Normal file
185
day24/src/main.rs
Normal 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)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user