Dag 7 aoc klaar, basically een soort 3-sat
This commit is contained in:
@@ -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);
|
|
||||||
if line.iter().fold(1, |p, n| p * n) > original_target {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut target = original_target;
|
let mut target = original_target;
|
||||||
let mut i = line.len() as i32 - 1;
|
|
||||||
|
|
||||||
while i >= 0 {
|
for (i, number) in line.iter().enumerate().rev() {
|
||||||
let modulo = target % line[i as usize];
|
if i == 0 && target == *number {
|
||||||
|
return Some(original_target);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if target % number == 0 {
|
||||||
|
if check(target - number, &line[..i]).is_some() {
|
||||||
|
return Some(original_target);
|
||||||
|
}
|
||||||
|
|
||||||
|
target /= number;
|
||||||
} else {
|
} else {
|
||||||
target -= line[i as usize];
|
target -= number;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if target < 0 {
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
i -= 1;
|
let mut whole_s = whole.to_string();
|
||||||
}
|
let tail_s = tail.to_string();
|
||||||
|
|
||||||
if target == 0 {
|
let whole_split = whole_s.split_off(whole_s.len() - tail_s.len());
|
||||||
Some(original_target)
|
|
||||||
|
if whole_split == tail_s {
|
||||||
|
Some(whole_s.parse().unwrap_or_default())
|
||||||
} 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user