Solve 07
This commit is contained in:
parent
d21a6a6d97
commit
505e4d4eea
1 changed files with 86 additions and 0 deletions
86
src/bin/07.rs
Normal file
86
src/bin/07.rs
Normal file
|
@ -0,0 +1,86 @@
|
|||
use aoc::*;
|
||||
use std::collections::VecDeque;
|
||||
|
||||
const INPUT: &str = include_str!("../../input/07");
|
||||
|
||||
fn main() {
|
||||
assert_example!(part1, "07-test", 3749);
|
||||
println!("Part 1: {}", part1(INPUT));
|
||||
assert_example!(part2, "07-test", 11387);
|
||||
println!("Part 2: {}", part2(INPUT));
|
||||
}
|
||||
|
||||
fn part1(input: &str) -> i64 {
|
||||
parse(input)
|
||||
.filter(|e| e.is_possible(&[Operator::Add, Operator::Mul]))
|
||||
.map(|e| e.target)
|
||||
.sum()
|
||||
}
|
||||
|
||||
fn part2(input: &str) -> i64 {
|
||||
parse(input)
|
||||
.filter(|e| e.is_possible(&[Operator::Add, Operator::Mul, Operator::Concat]))
|
||||
.map(|e| e.target)
|
||||
.sum()
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
enum Operator {
|
||||
Add,
|
||||
Mul,
|
||||
Concat,
|
||||
}
|
||||
|
||||
impl Operator {
|
||||
fn eval(self, a: i64, b: i64) -> i64 {
|
||||
match self {
|
||||
Operator::Add => a + b,
|
||||
Operator::Mul => a * b,
|
||||
Operator::Concat => concat(a, b),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Equation {
|
||||
target: i64,
|
||||
numbers: Vec<i64>,
|
||||
}
|
||||
|
||||
impl Equation {
|
||||
fn is_possible(&self, operators: &[Operator]) -> bool {
|
||||
let mut numbers = VecDeque::from(self.numbers.clone());
|
||||
let acc = numbers.pop_front().unwrap();
|
||||
is_possible(operators, self.target, acc, numbers)
|
||||
}
|
||||
}
|
||||
|
||||
fn is_possible(
|
||||
operators: &[Operator],
|
||||
target: i64,
|
||||
acc: i64,
|
||||
mut remaining: VecDeque<i64>,
|
||||
) -> bool {
|
||||
if target == acc && remaining.is_empty() {
|
||||
return true;
|
||||
} else if acc > target || remaining.is_empty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
let next = remaining.pop_front().unwrap();
|
||||
|
||||
operators.iter().any(|&op| {
|
||||
let acc = op.eval(acc, next);
|
||||
is_possible(operators, target, acc, remaining.clone())
|
||||
})
|
||||
}
|
||||
|
||||
fn parse(input: &str) -> impl Iterator<Item = Equation> + use<'_> {
|
||||
input.lines().map(parse_equation)
|
||||
}
|
||||
|
||||
fn parse_equation(input: &str) -> Equation {
|
||||
let (target, numbers) = input.split_once(": ").unwrap();
|
||||
let target = target.parse().unwrap();
|
||||
let numbers = parse_ws_separated(numbers).collect();
|
||||
Equation { target, numbers }
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue