mirror of
https://github.com/LeMoonStar/AoC24.git
synced 2025-07-07 21:49:59 +02:00
✨ Day 7: Part 1
This commit is contained in:
parent
6f7872ed33
commit
0ff7e66083
2 changed files with 145 additions and 11 deletions
147
src/days/d07.rs
147
src/days/d07.rs
|
@ -2,31 +2,156 @@ use super::{Answer, Day, DayImpl};
|
||||||
|
|
||||||
const CURRENT_DAY: u8 = 7;
|
const CURRENT_DAY: u8 = 7;
|
||||||
|
|
||||||
type Data = Vec<u64>;
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
enum Operator {
|
||||||
|
Add,
|
||||||
|
Multiply,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Operator {
|
||||||
|
fn calculate(&self, a: u64, b: u64) -> u64 {
|
||||||
|
match self {
|
||||||
|
Operator::Multiply => a * b,
|
||||||
|
Operator::Add => a + b,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
struct CombinationIterator<'a, T>
|
||||||
|
where
|
||||||
|
T: Sized + Clone,
|
||||||
|
{
|
||||||
|
iteration: usize,
|
||||||
|
length: u32,
|
||||||
|
possibilities: &'a [T],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T> CombinationIterator<'a, T>
|
||||||
|
where
|
||||||
|
T: Sized + Clone,
|
||||||
|
{
|
||||||
|
fn get_index_on_position(&self, position: u32) -> usize {
|
||||||
|
(if position == 0 {
|
||||||
|
self.iteration
|
||||||
|
} else {
|
||||||
|
self.iteration / (self.possibilities.len().pow(position))
|
||||||
|
}) % self.possibilities.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new(possibilities: &'a [T], length: u32) -> Self {
|
||||||
|
Self {
|
||||||
|
iteration: 0,
|
||||||
|
length,
|
||||||
|
possibilities,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T> Iterator for CombinationIterator<'a, T>
|
||||||
|
where
|
||||||
|
T: Sized + Clone,
|
||||||
|
{
|
||||||
|
type Item = Vec<T>;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
if self.get_index_on_position(self.length) != 0 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let values = (0..self.length)
|
||||||
|
.map(|p| self.possibilities[self.get_index_on_position(p)].clone())
|
||||||
|
.collect();
|
||||||
|
self.iteration += 1;
|
||||||
|
return Some(values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct CalibrationEquation {
|
||||||
|
pub result: u64,
|
||||||
|
pub parts: Vec<u64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CalibrationEquation {
|
||||||
|
fn calculate(&self, operations: Vec<Operator>) -> u64 {
|
||||||
|
let mut value = self.parts[0];
|
||||||
|
|
||||||
|
for i in 1..(self.parts.len()) {
|
||||||
|
value = operations[i - 1].calculate(value, self.parts[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
value
|
||||||
|
}
|
||||||
|
|
||||||
|
fn can_be_valid(&self) -> bool {
|
||||||
|
CombinationIterator::new(
|
||||||
|
&[Operator::Add, Operator::Multiply],
|
||||||
|
(self.parts.len() - 1) as u32,
|
||||||
|
)
|
||||||
|
.map(|o| self.calculate(o))
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.contains(&self.result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&str> for CalibrationEquation {
|
||||||
|
fn from(value: &str) -> Self {
|
||||||
|
let (first, second) = value.split_once(':').unwrap();
|
||||||
|
|
||||||
|
Self {
|
||||||
|
result: first.parse().unwrap(),
|
||||||
|
parts: second
|
||||||
|
.trim()
|
||||||
|
.split_whitespace()
|
||||||
|
.map(|v| v.parse().unwrap())
|
||||||
|
.collect(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Calibrator {
|
||||||
|
equations: Vec<CalibrationEquation>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Calibrator {
|
||||||
|
pub fn get_valid_sum(&self) -> u64 {
|
||||||
|
self.equations
|
||||||
|
.iter()
|
||||||
|
.filter(|v| v.can_be_valid())
|
||||||
|
.map(|v| v.result)
|
||||||
|
.sum()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&str> for Calibrator {
|
||||||
|
fn from(value: &str) -> Self {
|
||||||
|
Self {
|
||||||
|
equations: value.lines().map(|v| v.into()).collect(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Data = Calibrator;
|
||||||
impl DayImpl<Data> for Day<CURRENT_DAY> {
|
impl DayImpl<Data> for Day<CURRENT_DAY> {
|
||||||
fn init_test() -> (Self, Data) {
|
fn init_test() -> (Self, Data) {
|
||||||
Self::init(include_str!("test_inputs/test07.txt"))
|
Self::init(include_str!("test_inputs/test07.txt"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expected_results() -> (Answer, Answer) {
|
fn expected_results() -> (Answer, Answer) {
|
||||||
(Answer::Number(0), Answer::Number(0))
|
(Answer::Number(3749), Answer::Number(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init(input: &str) -> (Self, Data) {
|
fn init(input: &str) -> (Self, Data) {
|
||||||
(
|
(Self {}, input.into())
|
||||||
Self {},
|
|
||||||
input
|
|
||||||
.lines()
|
|
||||||
.map(|v| v.parse::<u64>().expect("error while parsing input."))
|
|
||||||
.collect(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn one(&self, data: &mut Data) -> Answer {
|
fn one(&self, data: &mut Data) -> Answer {
|
||||||
Answer::Number(data.len() as u64)
|
Answer::Number(data.get_valid_sum())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn two(&self, data: &mut Data) -> Answer {
|
fn two(&self, data: &mut Data) -> Answer {
|
||||||
Answer::Number(data.len() as u64)
|
Answer::Number(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue