Day 7 Solved
Dieser Commit ist enthalten in:
Ursprung
20ad63acaf
Commit
bd97c2e422
2 geänderte Dateien mit 190 neuen und 0 gelöschten Zeilen
9
examples/2024/07.txt
Normale Datei
9
examples/2024/07.txt
Normale Datei
|
@ -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
|
181
src/bin/2024/07.rs
Normale Datei
181
src/bin/2024/07.rs
Normale Datei
|
@ -0,0 +1,181 @@
|
|||
#![cfg_attr(debug_assertions, allow(unused_imports))]
|
||||
use std::ops::{Add, AddAssign, BitXor, Mul};
|
||||
|
||||
use advent_of_code::{
|
||||
numberlength,
|
||||
strings::{convert_to_array, parsenumber},
|
||||
};
|
||||
use advent_of_code_macros::{include_data, include_example};
|
||||
use log::*;
|
||||
use num::{pow::Pow, Integer};
|
||||
|
||||
include_data!(DATA 2024 07);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
enum Operation {
|
||||
Add,
|
||||
Multiply,
|
||||
Concat,
|
||||
}
|
||||
|
||||
impl Operation {
|
||||
fn op<
|
||||
T: Integer
|
||||
+ Add
|
||||
+ Mul
|
||||
+ Pow<u32, Output = T>
|
||||
+ std::ops::DivAssign
|
||||
+ AddAssign
|
||||
+ From<u32>
|
||||
+ Copy,
|
||||
>(
|
||||
self,
|
||||
a: T,
|
||||
b: T,
|
||||
) -> T {
|
||||
match self {
|
||||
Operation::Add => a + b,
|
||||
Operation::Multiply => a * b,
|
||||
Operation::Concat => {
|
||||
let ta = a * T::from(10).pow(numberlength(b));
|
||||
ta + b
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_data(line: &str) -> (u64, Vec<u64>) {
|
||||
let (result, numbers) = line.split_once(':').unwrap();
|
||||
|
||||
(
|
||||
parsenumber(result.trim()),
|
||||
Vec::from(convert_to_array::<_, _, ' '>(numbers, parsenumber)),
|
||||
)
|
||||
}
|
||||
|
||||
fn test_equation(result: u64, numbers: Vec<u64>, ops: Vec<Operation>) -> bool {
|
||||
let mut numberiter = numbers.iter();
|
||||
let mut opiter = ops.iter();
|
||||
let mut calcresult = numberiter.next().unwrap().clone();
|
||||
let mut next_number;
|
||||
debug_assert!(numbers.len() - 1 == ops.len());
|
||||
loop {
|
||||
next_number = numberiter.next().cloned();
|
||||
if next_number.is_none() {
|
||||
return calcresult == result;
|
||||
}
|
||||
calcresult = opiter.next().unwrap().op(calcresult, next_number.unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
fn get_ops(len: usize, conf: usize) -> Vec<Operation> {
|
||||
let mut shift = 0;
|
||||
let mut ops = Vec::with_capacity(len);
|
||||
loop {
|
||||
match (conf & (0b1 << shift)) >> shift {
|
||||
0 => ops.push(Operation::Add),
|
||||
1 => ops.push(Operation::Multiply),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
shift += 1;
|
||||
if ops.len() == len {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ops
|
||||
}
|
||||
|
||||
fn get_ops_with_concat(len: u32) -> Vec<Vec<Operation>> {
|
||||
let mut ops = Vec::with_capacity(3u64.saturating_pow(len) as usize);
|
||||
for i in [Operation::Add, Operation::Concat, Operation::Multiply] {
|
||||
if len > 1 {
|
||||
for mut oplist in get_ops_with_concat(len - 1) {
|
||||
oplist.insert(0, i);
|
||||
ops.push(oplist);
|
||||
}
|
||||
} else {
|
||||
ops.push(vec![i]);
|
||||
}
|
||||
}
|
||||
ops
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn pow2(i: usize) -> usize {
|
||||
2_u64.pow(i as u32) as usize - 1
|
||||
}
|
||||
|
||||
fn solution1(data: Vec<(u64, Vec<u64>)>) -> u64 {
|
||||
let mut output = 0;
|
||||
for line in data {
|
||||
for i in 0..=pow2(line.1.len()) {
|
||||
if test_equation(line.0, line.1.clone(), get_ops(line.1.len() - 1, i)) {
|
||||
output += line.0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
output
|
||||
}
|
||||
|
||||
fn solution2(data: Vec<(u64, Vec<u64>)>) -> u128 {
|
||||
let mut output = 0;
|
||||
for line in data {
|
||||
for ops in get_ops_with_concat((line.1.len() - 1) as u32) {
|
||||
if test_equation(line.0, line.1.clone(), ops) {
|
||||
output += line.0 as u128;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
output
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let data = convert_to_array::<_, _, '\n'>(DATA, get_data);
|
||||
println!("Found Calibration Total: {}", solution1(data.clone()));
|
||||
println!("Calibration total with Concat: {}", solution2(data.clone()));
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_test_equation() {
|
||||
for c in [
|
||||
(
|
||||
190,
|
||||
Vec::from([10, 19]),
|
||||
Vec::from([Operation::Multiply]),
|
||||
true,
|
||||
),
|
||||
(
|
||||
3267,
|
||||
Vec::from([81, 40, 27]),
|
||||
Vec::from([Operation::Add, Operation::Multiply]),
|
||||
true,
|
||||
),
|
||||
(
|
||||
3267,
|
||||
Vec::from([81, 40, 27]),
|
||||
Vec::from([Operation::Multiply, Operation::Add]),
|
||||
true,
|
||||
),
|
||||
(
|
||||
292,
|
||||
Vec::from([11, 6, 16, 20]),
|
||||
Vec::from([Operation::Add, Operation::Multiply, Operation::Add]),
|
||||
true,
|
||||
),
|
||||
(
|
||||
292,
|
||||
Vec::from([11, 6, 16, 20]),
|
||||
Vec::from([Operation::Add, Operation::Multiply, Operation::Multiply]),
|
||||
false,
|
||||
),
|
||||
] {
|
||||
assert_eq!(test_equation(c.0, c.1.into(), c.2.into()), c.3)
|
||||
}
|
||||
}
|
||||
}
|
Laden …
Tabelle hinzufügen
In neuem Issue referenzieren