Skip to content

Commit e6bf9b2

Browse files
committed
Day 7
1 parent ee8d7d4 commit e6bf9b2

File tree

3 files changed

+87
-2
lines changed

3 files changed

+87
-2
lines changed

README.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,10 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www.
2727
| [Day 3](./src/bin/03.rs) | `561.0µs` | `565.5µs` |
2828
| [Day 4](./src/bin/04.rs) | `560.8µs` | `161.9µs` |
2929
| [Day 5](./src/bin/05.rs) | `344.6µs` | `323.6µs` |
30-
| [Day 6](./src/bin/06.rs) | `492.2µs` | `118.9ms` |
30+
| [Day 6](./src/bin/06.rs) | `488.0µs` | `119.9ms` |
31+
| [Day 7](./src/bin/07.rs) | `186.7µs` | `101.6ms` |
3132

32-
**Total: 122.70ms**
33+
**Total: 225.49ms**
3334
<!--- benchmarking table --->
3435

3536
---

data/examples/07.txt

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
190: 10 19
2+
3267: 81 40 27
3+
83: 17 5
4+
156: 15 6
5+
7290: 6 8 6 15
6+
161011: 16 10 13
7+
192: 17 8 14
8+
21037: 9 7 18 13
9+
292: 11 6 16 20

src/bin/07.rs

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
use rayon::iter::ParallelIterator;
2+
use itertools::Itertools;
3+
use rayon::prelude::ParallelString;
4+
5+
advent_of_code::solution!(7);
6+
7+
fn parse_and_solve<F>(input: &str, equation_checker: F) -> u64
8+
where F: Fn(&u64, &[u64], &u64) -> bool + Sync
9+
{
10+
input.par_lines()
11+
.map(|line| {
12+
let mut split = line.split_whitespace();
13+
let Some(expected) = split.next() else { panic!() };
14+
let expected = expected[0..expected.len() - 1].parse::<u64>().unwrap();
15+
let terms = split.map(|num| num.parse::<u64>().unwrap()).collect_vec();
16+
(terms, expected)
17+
})
18+
.filter_map(|(terms, expected)| {
19+
if equation_checker(&terms[0], &terms[1..], &expected) { Some(expected) } else { None }
20+
})
21+
.sum()
22+
}
23+
24+
fn is_valid_equation(current_term: &u64, terms: &[u64], expected: &u64) -> bool {
25+
if terms.is_empty() {
26+
return current_term == expected;
27+
}
28+
29+
let next_term = terms[0];
30+
let new_terms = &terms[1..];
31+
[current_term * next_term, current_term + next_term].iter()
32+
.filter(|term| *term <= expected)
33+
.any(|term| is_valid_equation(term, new_terms, expected))
34+
}
35+
36+
fn is_valid_equation_with_concat(current_term: &u64, terms: &[u64], expected: &u64) -> bool {
37+
if terms.is_empty() {
38+
return current_term == expected;
39+
}
40+
41+
let next_term = terms[0];
42+
let new_terms = &terms[1..];
43+
[
44+
current_term * next_term,
45+
current_term + next_term,
46+
(current_term.to_string() + &next_term.to_string()).parse().unwrap(),
47+
].iter()
48+
.filter(|term| *term <= expected)
49+
.any(|term| is_valid_equation_with_concat(term, new_terms, expected))
50+
}
51+
52+
pub fn part_one(input: &str) -> Option<u64> {
53+
Some(parse_and_solve(input, is_valid_equation))
54+
}
55+
56+
pub fn part_two(input: &str) -> Option<u64> {
57+
Some(parse_and_solve(input, is_valid_equation_with_concat))
58+
}
59+
60+
#[cfg(test)]
61+
mod tests {
62+
use super::*;
63+
64+
#[test]
65+
fn test_part_one() {
66+
let result = part_one(&advent_of_code::template::read_file("examples", DAY));
67+
assert_eq!(result, Some(3749));
68+
}
69+
70+
#[test]
71+
fn test_part_two() {
72+
let result = part_two(&advent_of_code::template::read_file("examples", DAY));
73+
assert_eq!(result, Some(11387));
74+
}
75+
}

0 commit comments

Comments
 (0)