day 17 part 2
This commit is contained in:
98
src/day17.rs
98
src/day17.rs
@@ -1,4 +1,4 @@
|
|||||||
use std::{fmt::Write, fs::read_to_string, io::BufRead, ops::BitXor};
|
use std::{fs::read_to_string, ops::BitXor};
|
||||||
|
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
@@ -12,30 +12,21 @@ pub fn day_main() {
|
|||||||
type RiddleResult = String;
|
type RiddleResult = String;
|
||||||
|
|
||||||
fn part1(input: &str) -> RiddleResult {
|
fn part1(input: &str) -> RiddleResult {
|
||||||
let (first, second) = input.split_once("\n\n").unwrap();
|
let (a, b, c, program) = parse_input(input);
|
||||||
dbg!(first);
|
|
||||||
dbg!(second);
|
|
||||||
let mut registers = first.lines().map(|line| line.split_once(": ").unwrap().1);
|
|
||||||
|
|
||||||
let mut a = registers.next().unwrap().parse::<i64>().unwrap();
|
run(&program, a, b, c)
|
||||||
let mut b = registers.next().unwrap().parse::<i64>().unwrap();
|
.into_iter()
|
||||||
let mut c = registers.next().unwrap().parse::<i64>().unwrap();
|
.map(|it| it.to_string())
|
||||||
|
.join(",")
|
||||||
let program = second
|
}
|
||||||
.split_once(": ")
|
|
||||||
.unwrap()
|
|
||||||
.1
|
|
||||||
.split(",")
|
|
||||||
.map(|v| v.parse::<i64>().unwrap())
|
|
||||||
.collect_vec();
|
|
||||||
|
|
||||||
|
fn run(program: &Vec<i64>, mut a: i64, mut b: i64, mut c: i64) -> Vec<i64> {
|
||||||
let mut ip = 0;
|
let mut ip = 0;
|
||||||
let mut output = String::new();
|
let mut output = vec![];
|
||||||
|
|
||||||
while ip < program.len() {
|
while ip < program.len() {
|
||||||
let opcode = program[ip];
|
let opcode = program[ip];
|
||||||
let operand = program[(ip + 1) % program.len()];
|
let operand = program[(ip + 1) % program.len()];
|
||||||
// println!("a: {a}, b: {b}, c: {c}, op={opcode} {operand} (ip: {ip})");
|
|
||||||
match opcode {
|
match opcode {
|
||||||
0 => a = a / (2i64.pow(val(a, b, c, operand) as u32)),
|
0 => a = a / (2i64.pow(val(a, b, c, operand) as u32)),
|
||||||
1 => b = b.bitxor(operand),
|
1 => b = b.bitxor(operand),
|
||||||
@@ -48,26 +39,32 @@ fn part1(input: &str) -> RiddleResult {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
4 => b = b.bitxor(c),
|
4 => b = b.bitxor(c),
|
||||||
5 => output
|
5 => output.push(val(a, b, c, operand) % 8),
|
||||||
.write_fmt(format_args!("{},", val(a, b, c, operand) % 8))
|
|
||||||
.unwrap(),
|
|
||||||
6 => b = a / (2i64.pow(val(a, b, c, operand) as u32)),
|
6 => b = a / (2i64.pow(val(a, b, c, operand) as u32)),
|
||||||
7 => c = a / (2i64.pow(val(a, b, c, operand) as u32)),
|
7 => c = a / (2i64.pow(val(a, b, c, operand) as u32)),
|
||||||
_ => panic!("illegal op code {}", opcode),
|
_ => panic!("illegal op code {}", opcode),
|
||||||
}
|
}
|
||||||
ip += 2;
|
ip += 2;
|
||||||
// ip %= program.len();
|
|
||||||
// wait();
|
|
||||||
}
|
|
||||||
if output.ends_with(",") {
|
|
||||||
output.remove(output.len() - 1);
|
|
||||||
}
|
}
|
||||||
output
|
output
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wait() {
|
fn parse_input(input: &str) -> (i64, i64, i64, Vec<i64>) {
|
||||||
let stdin = std::io::stdin();
|
let (first, second) = input.split_once("\n\n").unwrap();
|
||||||
let _line1 = stdin.lock().lines().next().unwrap().unwrap();
|
let mut registers = first.lines().map(|line| line.split_once(": ").unwrap().1);
|
||||||
|
|
||||||
|
let a = registers.next().unwrap().parse::<i64>().unwrap();
|
||||||
|
let b = registers.next().unwrap().parse::<i64>().unwrap();
|
||||||
|
let c = registers.next().unwrap().parse::<i64>().unwrap();
|
||||||
|
|
||||||
|
let program = second
|
||||||
|
.split_once(": ")
|
||||||
|
.unwrap()
|
||||||
|
.1
|
||||||
|
.split(",")
|
||||||
|
.map(|v| v.parse::<i64>().unwrap())
|
||||||
|
.collect_vec();
|
||||||
|
(a, b, c, program)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn val(a: i64, b: i64, c: i64, operand: i64) -> i64 {
|
fn val(a: i64, b: i64, c: i64, operand: i64) -> i64 {
|
||||||
@@ -80,8 +77,34 @@ fn val(a: i64, b: i64, c: i64, operand: i64) -> i64 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn part2(_input: &str) -> RiddleResult {
|
fn part2(input: &str) -> RiddleResult {
|
||||||
String::new()
|
let (_, _, _, program) = parse_input(input);
|
||||||
|
solve(&program, program.len() - 1, 0).unwrap().to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn solve(program: &Vec<i64>, index: usize, a: i64) -> Option<i64> {
|
||||||
|
// if index == 0 {
|
||||||
|
// return if &run(program, a, 0, 0) == program {
|
||||||
|
// Some(a)
|
||||||
|
// } else {
|
||||||
|
// None
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
for i in 0..8 {
|
||||||
|
let next_a = a * 8 + i;
|
||||||
|
let o = run(program, next_a, 0, 0);
|
||||||
|
if o[0] == program[index] {
|
||||||
|
if index == 0 {
|
||||||
|
return Some(next_a);
|
||||||
|
} else {
|
||||||
|
let m = solve(program, index - 1, next_a);
|
||||||
|
if m.is_some() {
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -103,6 +126,17 @@ Program: 0,1,5,4,3,0
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test2() {
|
fn test2() {
|
||||||
assert_eq!(part2(TEST_INPUT.trim()), "".to_string());
|
assert_eq!(
|
||||||
|
part2(
|
||||||
|
"Register A: 2024
|
||||||
|
Register B: 0
|
||||||
|
Register C: 0
|
||||||
|
|
||||||
|
Program: 0,3,5,4,3,0
|
||||||
|
"
|
||||||
|
.trim()
|
||||||
|
),
|
||||||
|
"117440".to_string()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user