mirror of
https://github.com/mx42/aoc2024.rs.git
synced 2026-01-14 05:49:53 +01:00
feat: add day 7
This commit is contained in:
16
Cargo.lock
generated
16
Cargo.lock
generated
@@ -25,6 +25,7 @@ dependencies = [
|
|||||||
"clippy",
|
"clippy",
|
||||||
"dhat",
|
"dhat",
|
||||||
"fmt",
|
"fmt",
|
||||||
|
"itertools",
|
||||||
"pico-args",
|
"pico-args",
|
||||||
"regex",
|
"regex",
|
||||||
"tinyjson",
|
"tinyjson",
|
||||||
@@ -205,6 +206,12 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "either"
|
||||||
|
version = "1.13.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fmt"
|
name = "fmt"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@@ -251,6 +258,15 @@ dependencies = [
|
|||||||
"cc",
|
"cc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itertools"
|
||||||
|
version = "0.13.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.14"
|
version = "1.0.14"
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ chrono = { version = "0.4.38", optional = true }
|
|||||||
clippy = "0.0.302"
|
clippy = "0.0.302"
|
||||||
dhat = { version = "0.3.3", optional = true }
|
dhat = { version = "0.3.3", optional = true }
|
||||||
fmt = "0.1.0"
|
fmt = "0.1.0"
|
||||||
|
itertools = "0.13.0"
|
||||||
pico-args = "0.5.0"
|
pico-args = "0.5.0"
|
||||||
regex = "1.11.1"
|
regex = "1.11.1"
|
||||||
tinyjson = "2.5.1"
|
tinyjson = "2.5.1"
|
||||||
|
|||||||
15
README.md
15
README.md
@@ -22,14 +22,15 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www.
|
|||||||
|
|
||||||
| Day | Part 1 | Part 2 |
|
| Day | Part 1 | Part 2 |
|
||||||
| :---: | :---: | :---: |
|
| :---: | :---: | :---: |
|
||||||
| [Day 1](./src/bin/01.rs) | `161.8µs` | `211.7µs` |
|
| [Day 1](./src/bin/01.rs) | `72.0µs` | `76.8µs` |
|
||||||
| [Day 2](./src/bin/02.rs) | `242.1µs` | `427.3µs` |
|
| [Day 2](./src/bin/02.rs) | `215.6µs` | `371.6µs` |
|
||||||
| [Day 3](./src/bin/03.rs) | `448.6µs` | `728.9µs` |
|
| [Day 3](./src/bin/03.rs) | `652.5µs` | `736.7µs` |
|
||||||
| [Day 4](./src/bin/04.rs) | `5.9ms` | `2.7ms` |
|
| [Day 4](./src/bin/04.rs) | `5.6ms` | `2.4ms` |
|
||||||
| [Day 5](./src/bin/05.rs) | `2.0ms` | `10.6ms` |
|
| [Day 5](./src/bin/05.rs) | `3.7ms` | `9.7ms` |
|
||||||
| [Day 6](./src/bin/06.rs) | `7.4ms` | `-` |
|
| [Day 6](./src/bin/06.rs) | `6.8ms` | `7.9s` |
|
||||||
|
| [Day 7](./src/bin/07.rs) | `43.5ms` | `3.7s` |
|
||||||
|
|
||||||
**Total: 30.82ms**
|
**Total: 11673.83ms**
|
||||||
<!--- benchmarking table --->
|
<!--- benchmarking table --->
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
9
data/examples/07.txt
Normal file
9
data/examples/07.txt
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
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
|
||||||
148
src/bin/07.rs
Normal file
148
src/bin/07.rs
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
advent_of_code::solution!(7);
|
||||||
|
|
||||||
|
use itertools::{repeat_n, Itertools};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Calib {
|
||||||
|
res: u64,
|
||||||
|
numbers: Vec<u64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
enum Ops {
|
||||||
|
Add,
|
||||||
|
Mul,
|
||||||
|
Concat,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum Equ {
|
||||||
|
Nb(u64),
|
||||||
|
Op(u64, Ops, Box<Equ>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Equ {
|
||||||
|
fn init(nbs: &[u64], ops: &[Ops]) -> Equ {
|
||||||
|
match (nbs, ops) {
|
||||||
|
([h], []) => Equ::Nb(*h),
|
||||||
|
([h, t @ ..], [op, top @ ..]) => Equ::Op(*h, *op, Box::new(Equ::init(t, top))),
|
||||||
|
_ => todo!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add(&mut self, lhs: u64) -> u64 {
|
||||||
|
match self {
|
||||||
|
Equ::Nb(x) => return *x + lhs,
|
||||||
|
Equ::Op(llhs, _, _) => *llhs += lhs,
|
||||||
|
}
|
||||||
|
self.solve()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mul(&mut self, lhs: u64) -> u64 {
|
||||||
|
match self {
|
||||||
|
Equ::Nb(x) => return *x * lhs,
|
||||||
|
Equ::Op(llhs, _, _) => *llhs *= lhs,
|
||||||
|
}
|
||||||
|
self.solve()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn concat(&mut self, lhs: u64) -> u64 {
|
||||||
|
match self {
|
||||||
|
Equ::Nb(x) => return format!("{}{}", lhs, x).parse::<u64>().unwrap(),
|
||||||
|
Equ::Op(x, _, _) => *x = format!("{}{}", lhs, x).parse::<u64>().unwrap(),
|
||||||
|
}
|
||||||
|
self.solve()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn solve(&mut self) -> u64 {
|
||||||
|
match self {
|
||||||
|
Equ::Nb(x) => *x,
|
||||||
|
Equ::Op(lhs, Ops::Add, rhs) => rhs.add(*lhs),
|
||||||
|
Equ::Op(lhs, Ops::Mul, rhs) => rhs.mul(*lhs),
|
||||||
|
Equ::Op(lhs, Ops::Concat, rhs) => rhs.concat(*lhs),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ops {
|
||||||
|
fn possible_ops_p1(l: usize) -> Vec<Vec<Ops>> {
|
||||||
|
repeat_n(vec![Ops::Add, Ops::Mul].into_iter(), l - 1)
|
||||||
|
.multi_cartesian_product()
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
fn possible_ops_p2(l: usize) -> Vec<Vec<Ops>> {
|
||||||
|
repeat_n(vec![Ops::Add, Ops::Mul, Ops::Concat].into_iter(), l - 1)
|
||||||
|
.multi_cartesian_product()
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<&str> for Calib {
|
||||||
|
type Error = ();
|
||||||
|
fn try_from(input: &str) -> Result<Self, Self::Error> {
|
||||||
|
let mut numbers: Vec<u64> = input
|
||||||
|
.chars()
|
||||||
|
.filter(|c| *c != ':')
|
||||||
|
.collect::<String>()
|
||||||
|
.split_whitespace()
|
||||||
|
.flat_map(|n| n.parse::<u64>())
|
||||||
|
.collect();
|
||||||
|
let res = numbers.remove(0);
|
||||||
|
Ok(Self { res, numbers })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Calib {
|
||||||
|
fn check_ops(&self, ops: Vec<Ops>) -> bool {
|
||||||
|
let nbs = self.numbers.clone();
|
||||||
|
let mut eq = Equ::init(nbs.as_slice(), ops.as_slice());
|
||||||
|
let res = eq.solve();
|
||||||
|
res == self.res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn solve_p1(&self) -> bool {
|
||||||
|
Ops::possible_ops_p1(self.numbers.len())
|
||||||
|
.into_iter()
|
||||||
|
.any(|ops| self.check_ops(ops))
|
||||||
|
}
|
||||||
|
fn solve_p2(&self) -> bool {
|
||||||
|
Ops::possible_ops_p2(self.numbers.len())
|
||||||
|
.into_iter()
|
||||||
|
.any(|ops| self.check_ops(ops))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part_one(input: &str) -> Option<u64> {
|
||||||
|
input
|
||||||
|
.lines()
|
||||||
|
.flat_map(Calib::try_from)
|
||||||
|
.filter_map(|c| if c.solve_p1() { Some(c.res) } else { None })
|
||||||
|
.sum::<u64>()
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part_two(input: &str) -> Option<u64> {
|
||||||
|
input
|
||||||
|
.lines()
|
||||||
|
.flat_map(Calib::try_from)
|
||||||
|
.filter_map(|c| if c.solve_p2() { Some(c.res) } else { None })
|
||||||
|
.sum::<u64>()
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_part_one() {
|
||||||
|
let result = part_one(&advent_of_code::template::read_file("examples", DAY));
|
||||||
|
assert_eq!(result, Some(3749));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_part_two() {
|
||||||
|
let result = part_two(&advent_of_code::template::read_file("examples", DAY));
|
||||||
|
assert_eq!(result, Some(11387));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user