Dag 7 aoc klaar, basically een soort 3-sat

This commit is contained in:
2024-12-10 15:22:12 +01:00
parent 05998b3b4f
commit 9e513412c1

View File

@@ -1,69 +1,101 @@
use nom::{ use nom::{
bytes::complete::tag, bytes::complete::tag,
character::complete::{i32, multispace1}, character::complete::{i64, multispace1},
multi::separated_list1, multi::separated_list1,
sequence::separated_pair, sequence::separated_pair,
IResult, IResult,
}; };
fn parse(input: &str) -> IResult<&str, Vec<(i32, Vec<i32>)>> { fn parse(input: &str) -> IResult<&str, Vec<(i64, Vec<i64>)>> {
let (input, result) = separated_list1( let (input, result) = separated_list1(
multispace1, multispace1,
separated_pair(i32, tag(": "), separated_list1(tag(" "), i32)), separated_pair(i64, tag(": "), separated_list1(tag(" "), i64)),
)(input)?; )(input)?;
Ok((input, result)) Ok((input, result))
} }
fn check(original_target: i32, line: &[i32]) -> Option<i32> { fn check(original_target: i64, line: &[i64]) -> Option<i64> {
//dbg!(original_target, &line); let mut target = original_target;
if line.iter().fold(1, |p, n| p * n) > original_target {
for (i, number) in line.iter().enumerate().rev() {
if i == 0 && target == *number {
return Some(original_target);
}
if target % number == 0 {
if check(target - number, &line[..i]).is_some() {
return Some(original_target);
}
target /= number;
} else {
target -= number;
}
}
None
}
fn solve_1(input: &str) -> i64 {
let (_, lines) = parse(input).unwrap();
lines.into_iter().fold(0, |result, line| {
check(line.0, &line.1[..]).unwrap_or_default() + result
})
}
fn check_2(original_target: i64, numbers: &[i64]) -> Option<i64> {
if let Some((i, number)) = numbers.iter().enumerate().rev().next() {
if i == 0 && original_target == *number {
return Some(original_target);
}
if original_target % number == 0 {
if check_2(original_target / number, &numbers[..i]).is_some() {
return Some(original_target);
}
}
if original_target - number >= 0 {
if check_2(original_target - number, &numbers[..i]).is_some() {
return Some(original_target);
}
}
if let Some(head) = disconcat(original_target, *number) {
if check_2(head, &numbers[..i]).is_some() {
return Some(original_target);
}
}
}
None
}
fn disconcat(whole: i64, tail: i64) -> Option<i64> {
if tail > whole {
return None; return None;
} }
let mut target = original_target; let mut whole_s = whole.to_string();
let mut i = line.len() as i32 - 1; let tail_s = tail.to_string();
while i >= 0 { let whole_split = whole_s.split_off(whole_s.len() - tail_s.len());
let modulo = target % line[i as usize];
if modulo == 0 { if whole_split == tail_s {
target /= line[i as usize]; Some(whole_s.parse().unwrap_or_default())
let plus_result = check(target - line[i as usize], &line[0..i as usize]);
if plus_result.is_some() {
return plus_result;
}
} else {
target -= line[i as usize];
}
if target < 0 {
return None;
}
i -= 1;
}
if target == 0 {
Some(original_target)
} else { } else {
None None
} }
} }
fn solve_1(input: &str) -> i32 { fn solve_2(input: &str) -> i64 {
let (_, lines) = parse(input).unwrap(); let (_, lines) = parse(input).unwrap();
lines.into_iter().fold(0, |result, line| { lines.into_iter().fold(0, |result, (target, numbers)| {
dbg!(&line); check_2(target, &numbers[..]).unwrap_or_default() + result
result + check(line.0, &line.1[..]).unwrap_or_default()
}) })
} }
fn solve_2(input: &str) {}
fn main() { fn main() {
println!("Hello, this is Patrick!"); println!("Hello, this is Patrick!");
@@ -73,6 +105,7 @@ fn main() {
println!("The total calibration result is {}", result_1); println!("The total calibration result is {}", result_1);
let result_2 = solve_2(input); let result_2 = solve_2(input);
println!("The new total calibration result is {}", result_2);
} }
#[cfg(test)] #[cfg(test)]
@@ -87,5 +120,8 @@ mod tests {
} }
#[test] #[test]
fn test_2() {} fn test_2() {
let test_input = include_str!("../test.txt");
assert_eq!(solve_2(test_input), 11387);
}
} }