day7, part1
This commit is contained in:
parent
e5bb9f3673
commit
cf586d1715
4 changed files with 147 additions and 1 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -38,6 +38,13 @@ dependencies = [
|
||||||
"winnow",
|
"winnow",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "day07"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"winnow",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.7.4"
|
version = "2.7.4"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[workspace]
|
[workspace]
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
members = ["day01", "day02", "day03", "day04", "day05", "day06"]
|
members = ["day01", "day02", "day03", "day04", "day05", "day06", "day07"]
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
winnow = "0.6"
|
winnow = "0.6"
|
||||||
|
|
7
day07/Cargo.toml
Normal file
7
day07/Cargo.toml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
[package]
|
||||||
|
name = "day07"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
winnow.workspace = true
|
132
day07/src/main.rs
Normal file
132
day07/src/main.rs
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
use winnow::{
|
||||||
|
PResult, Parser,
|
||||||
|
ascii::{dec_uint, newline, space1},
|
||||||
|
combinator::{eof, opt, separated, separated_pair, seq},
|
||||||
|
};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let input = std::fs::read_to_string("input").unwrap();
|
||||||
|
println!("{}", pt1(&input));
|
||||||
|
println!("{}", pt2(&input));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pt1(input: &str) -> u64 {
|
||||||
|
let mut total = 0;
|
||||||
|
let eqs = parse(input);
|
||||||
|
for eq in &eqs {
|
||||||
|
if check(eq) {
|
||||||
|
total += eq.total;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
total
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pt2(_input: &str) -> u64 {
|
||||||
|
let mut total = 0;
|
||||||
|
|
||||||
|
total
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
|
||||||
|
struct Equation {
|
||||||
|
total: u64,
|
||||||
|
factors: Vec<u64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Equation {
|
||||||
|
pub fn next(&self, cur: usize) -> Option<(usize, u64)> {
|
||||||
|
let next_idx = cur + 1;
|
||||||
|
self.factors.get(next_idx).copied().map(|v| (next_idx, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn first(&self) -> (usize, u64) {
|
||||||
|
(0, self.factors[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check(equation: &Equation) -> bool {
|
||||||
|
let mut processed = HashSet::new();
|
||||||
|
let mut q = Vec::new();
|
||||||
|
let target = equation.total;
|
||||||
|
|
||||||
|
q.push(equation.first());
|
||||||
|
while let Some(current) = q.pop() {
|
||||||
|
if !processed.contains(¤t) {
|
||||||
|
q.push(current);
|
||||||
|
}
|
||||||
|
|
||||||
|
let (cur_idx, cur_val) = current;
|
||||||
|
|
||||||
|
let mut process_top = true;
|
||||||
|
if let Some((next_idx, next_val)) = equation.next(cur_idx) {
|
||||||
|
let plus = (next_idx, cur_val + next_val);
|
||||||
|
let mul = (next_idx, cur_val * next_val);
|
||||||
|
if mul.1 <= target && !processed.contains(&mul) {
|
||||||
|
process_top = false;
|
||||||
|
q.push(mul);
|
||||||
|
}
|
||||||
|
if plus.1 <= target && !processed.contains(&plus) {
|
||||||
|
process_top = false;
|
||||||
|
q.push(plus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if process_top {
|
||||||
|
let _ = q.pop();
|
||||||
|
if cur_val == target {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
processed.insert(current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_equation(input: &mut &str) -> PResult<Equation> {
|
||||||
|
let (total, factors) = separated_pair(
|
||||||
|
dec_uint,
|
||||||
|
": ",
|
||||||
|
separated(1.., dec_uint::<_, u64, _>, space1),
|
||||||
|
)
|
||||||
|
.parse_next(input)?;
|
||||||
|
|
||||||
|
Ok(Equation { total, factors })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse(input: &str) -> Vec<Equation> {
|
||||||
|
let (equations, _): (Vec<Equation>, _) = seq!(
|
||||||
|
separated(1.., parse_equation, newline),
|
||||||
|
seq!(opt(newline), opt(eof))
|
||||||
|
)
|
||||||
|
.parse(input)
|
||||||
|
.unwrap();
|
||||||
|
equations
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
static TEST_INPUT: &str = "190: 10 19
|
||||||
|
3267: 81 40 27
|
||||||
|
83: 17 5
|
||||||
|
156: 15 6
|
||||||
|
7290: 6 8 6 15
|
||||||
|
161011: 16 10 13
|
||||||
|
192: 17 8 14
|
||||||
|
21037: 9 7 18 13
|
||||||
|
292: 11 6 16 20";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn p1() {
|
||||||
|
let v = pt1(TEST_INPUT);
|
||||||
|
assert_eq!(v, 3749)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn p2() {
|
||||||
|
assert_eq!(0, pt2(TEST_INPUT));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue