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