day7, part1

This commit is contained in:
Joe Ardent 2024-12-28 11:41:14 -08:00
parent e5bb9f3673
commit cf586d1715
4 changed files with 147 additions and 1 deletions

7
Cargo.lock generated
View file

@ -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"

View file

@ -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
View 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
View 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(&current) {
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));
}
}