feat: added day 17 part 1 and 2
All checks were successful
Build and run challenges / Challenge for day (1) (push) Successful in 3s
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 3s
Build and run challenges / Challenge for day (13) (push) Successful in 3s
Build and run challenges / Challenge for day (14) (push) Successful in 3s
Build and run challenges / Challenge for day (17) (push) Successful in 3s
Build and run challenges / Challenge for day (6) (push) Successful in 5s
Build and run challenges / Challenge for day (3) (push) Successful in 11s
Build and run challenges / Challenge for day (7) (push) Successful in 4s
Build and run challenges / Challenge for day (15) (push) Successful in 3s
Build and run challenges / Challenge for day (16) (push) Successful in 3s
Build and run challenges / Challenge for day (2) (push) Successful in 3s
Build and run challenges / Challenge for day (4) (push) Successful in 4s
Build and run challenges / Challenge for day (5) (push) Successful in 5s
Build and run challenges / Challenge for day (8) (push) Successful in 3s
Build and run challenges / Challenge for day (9) (push) Successful in 3s
All checks were successful
Build and run challenges / Challenge for day (1) (push) Successful in 3s
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 3s
Build and run challenges / Challenge for day (13) (push) Successful in 3s
Build and run challenges / Challenge for day (14) (push) Successful in 3s
Build and run challenges / Challenge for day (17) (push) Successful in 3s
Build and run challenges / Challenge for day (6) (push) Successful in 5s
Build and run challenges / Challenge for day (3) (push) Successful in 11s
Build and run challenges / Challenge for day (7) (push) Successful in 4s
Build and run challenges / Challenge for day (15) (push) Successful in 3s
Build and run challenges / Challenge for day (16) (push) Successful in 3s
Build and run challenges / Challenge for day (2) (push) Successful in 3s
Build and run challenges / Challenge for day (4) (push) Successful in 4s
Build and run challenges / Challenge for day (5) (push) Successful in 5s
Build and run challenges / Challenge for day (8) (push) Successful in 3s
Build and run challenges / Challenge for day (9) (push) Successful in 3s
Signed-off-by: Louis Vallat <contact@louis-vallat.dev>
This commit is contained in:
parent
7542e61ed5
commit
83e13c5774
@ -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]
|
||||
day_number: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]
|
||||
runs-on: rust-bookworm
|
||||
steps:
|
||||
- name: Check out repository code
|
||||
|
6
day17/Cargo.toml
Normal file
6
day17/Cargo.toml
Normal file
@ -0,0 +1,6 @@
|
||||
[package]
|
||||
name = "day17"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
134
day17/src/main.rs
Normal file
134
day17/src/main.rs
Normal file
@ -0,0 +1,134 @@
|
||||
use std::collections::HashSet;
|
||||
use std::{env, fs};
|
||||
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, PartialOrd)]
|
||||
enum Instruction {
|
||||
Adv(u64), // Division A = A / 2^x
|
||||
Bdv(u64), // Division B = A / 2^x
|
||||
Cdv(u64), // Division C = A / 2^x
|
||||
Bst(u64), // Combo % 8 B = x % 8
|
||||
Jnz(u64), // Jump if not 0. if A != 0 { jump to x }
|
||||
Out(u64), // Print x % 8 echo(x % 8)
|
||||
Bxl(u64), // Bitwise XOR B = B XOR x
|
||||
Bxc, // Bitwise XOR B = B XOR C
|
||||
}
|
||||
|
||||
fn read_input(path: &str) -> String {
|
||||
fs::read_to_string(path).expect("Cannot read file.")
|
||||
}
|
||||
|
||||
fn parse_input(input: &str) -> (Vec<Instruction>, Vec<String>, u64, u64, u64) {
|
||||
let mut instructions = Vec::new();
|
||||
|
||||
let mut lines = input.lines();
|
||||
let a = lines.next().unwrap()[12..].parse::<u64>().unwrap();
|
||||
let b = lines.next().unwrap()[12..].parse::<u64>().unwrap();
|
||||
let c = lines.next().unwrap()[12..].parse::<u64>().unwrap();
|
||||
|
||||
lines.next();
|
||||
let raw_program = lines.next().unwrap()[9..]
|
||||
.split(',')
|
||||
.map(|s| s.to_string())
|
||||
.collect::<Vec<String>>();
|
||||
for a in raw_program.chunks(2) {
|
||||
let operand = a[1].parse().unwrap();
|
||||
instructions.push(match a[0].as_str() {
|
||||
"0" => Instruction::Adv(operand),
|
||||
"1" => Instruction::Bxl(operand),
|
||||
"2" => Instruction::Bst(operand),
|
||||
"3" => Instruction::Jnz(operand),
|
||||
"4" => Instruction::Bxc,
|
||||
"5" => Instruction::Out(operand),
|
||||
"6" => Instruction::Bdv(operand),
|
||||
"7" => Instruction::Cdv(operand),
|
||||
_ => unreachable!(),
|
||||
})
|
||||
}
|
||||
|
||||
(instructions, raw_program, a, b, c)
|
||||
}
|
||||
|
||||
fn get_value_for_operand(operand: u64, a: u64, b: u64, c: u64) -> u64 {
|
||||
match operand {
|
||||
0..=3 => operand,
|
||||
4 => a,
|
||||
5 => b,
|
||||
6 => c,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn run_program(instructions: &Vec<Instruction>, mut a: u64, mut b: u64, mut c: u64) -> Vec<String> {
|
||||
let mut output = Vec::new();
|
||||
let mut pc = 0;
|
||||
while pc < instructions.len() {
|
||||
let instruction = instructions[pc];
|
||||
match instruction {
|
||||
Instruction::Adv(x) => a = a / 2_u64.pow(get_value_for_operand(x, a, b, c) as u32),
|
||||
Instruction::Bdv(x) => b = a / 2_u64.pow(get_value_for_operand(x, a, b, c) as u32),
|
||||
Instruction::Cdv(x) => c = a / 2_u64.pow(get_value_for_operand(x, a, b, c) as u32),
|
||||
Instruction::Bst(x) => b = get_value_for_operand(x, a, b, c) % 8,
|
||||
Instruction::Out(x) => output.push((get_value_for_operand(x, a, b, c) % 8).to_string()),
|
||||
Instruction::Bxl(x) => b = b ^ x,
|
||||
Instruction::Bxc => b = b ^ c,
|
||||
Instruction::Jnz(x) => {
|
||||
if a != 0 {
|
||||
pc = x as usize
|
||||
}
|
||||
}
|
||||
}
|
||||
match instruction {
|
||||
Instruction::Jnz(_) => {
|
||||
if a == 0 {
|
||||
pc += 1
|
||||
}
|
||||
}
|
||||
_ => pc += 1,
|
||||
}
|
||||
}
|
||||
output
|
||||
}
|
||||
|
||||
fn find_quine(instruction: &Vec<Instruction>, raw_program: &Vec<String>) -> u64 {
|
||||
let mut solution = u64::MAX;
|
||||
|
||||
let mut seen = HashSet::new();
|
||||
let mut queue = vec![0];
|
||||
while let Some(mut possibility) = queue.pop() {
|
||||
possibility <<= 3;
|
||||
for x in possibility..(possibility + 8) {
|
||||
let output = run_program(instruction, x, 0, 0);
|
||||
if !output.is_empty()
|
||||
&& *output.first().unwrap() == raw_program[raw_program.len() - output.len()]
|
||||
{
|
||||
if raw_program.len() == output.len() {
|
||||
if x < solution {
|
||||
solution = x;
|
||||
}
|
||||
} else if !seen.contains(&x) {
|
||||
seen.insert(x);
|
||||
queue.push(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
solution
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
for arg in args.iter().skip(1) {
|
||||
let input = read_input(&arg);
|
||||
let (instructions, raw_program, a, b, c) = parse_input(&input);
|
||||
println!("[{}]", &arg);
|
||||
println!(
|
||||
"\t[Part 1] => Answer is '{}'.",
|
||||
run_program(&instructions, a, b, c).join(",")
|
||||
);
|
||||
println!(
|
||||
"\t[Part 2] => Answer is '{}'.",
|
||||
find_quine(&instructions, &raw_program)
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user