Louis Vallat
005bdb82af
All checks were successful
Build and run challenges / Challenge for day (1) (push) Successful in 3s
Build and run challenges / Challenge for day (2) (push) Successful in 3s
Build and run challenges / Challenge for day (5) (push) Successful in 5s
Build and run challenges / Challenge for day (3) (push) Successful in 11s
Build and run challenges / Challenge for day (6) (push) Successful in 5s
Build and run challenges / Challenge for day (7) (push) Successful in 4s
Build and run challenges / Challenge for day (4) (push) Successful in 4s
Signed-off-by: Louis Vallat <contact@louis-vallat.dev>
106 lines
2.4 KiB
Rust
106 lines
2.4 KiB
Rust
use std::{env, fs};
|
|
|
|
fn read_input(path: &str) -> String {
|
|
fs::read_to_string(path).expect("Cannot read file.")
|
|
}
|
|
|
|
fn add(a: u64, b: u64) -> u64 {
|
|
a + b
|
|
}
|
|
|
|
fn mul(a: u64, b: u64) -> u64 {
|
|
a * b
|
|
}
|
|
|
|
fn concat(a: u64, b: u64) -> u64 {
|
|
format!("{a}{b}").parse().unwrap()
|
|
}
|
|
|
|
fn parse_input(input: &str) -> Vec<(u64, Vec<u64>)> {
|
|
input
|
|
.lines()
|
|
.filter(|line| !line.is_empty())
|
|
.map(|line| {
|
|
let split_line = line.split_once(": ").unwrap();
|
|
(
|
|
split_line.0.parse().unwrap(),
|
|
split_line
|
|
.1
|
|
.split_whitespace()
|
|
.map(|s| s.parse().unwrap())
|
|
.rev()
|
|
.collect(),
|
|
)
|
|
})
|
|
.collect()
|
|
}
|
|
|
|
fn is_valid(
|
|
data: &mut Vec<u64>,
|
|
acc: u64,
|
|
target: u64,
|
|
operators: &Vec<&fn(u64, u64) -> u64>,
|
|
) -> bool {
|
|
if data.is_empty() {
|
|
return target == acc;
|
|
}
|
|
|
|
if acc > target {
|
|
return false;
|
|
}
|
|
|
|
let old = data.pop().unwrap();
|
|
for operator in operators {
|
|
if is_valid(data, operator(acc, old), target, operators) {
|
|
return true;
|
|
}
|
|
}
|
|
data.push(old);
|
|
false
|
|
}
|
|
|
|
fn sum_valid(
|
|
calibration_data: &Vec<(u64, Vec<u64>)>,
|
|
operators: &Vec<&fn(u64, u64) -> u64>,
|
|
) -> u64 {
|
|
let mut sum_valid = 0;
|
|
let calibration_data = calibration_data.clone();
|
|
|
|
for calibration in calibration_data {
|
|
let mut x = calibration.1;
|
|
let acc = x.pop().unwrap();
|
|
if is_valid(&mut x, acc, calibration.0, operators) {
|
|
sum_valid += calibration.0;
|
|
}
|
|
}
|
|
|
|
sum_valid
|
|
}
|
|
|
|
fn part_1(input: &Vec<(u64, Vec<u64>)>) -> u64 {
|
|
let valid_operators = vec![&(add as fn(u64, u64) -> u64), &(mul as fn(u64, u64) -> u64)];
|
|
|
|
sum_valid(input, &valid_operators)
|
|
}
|
|
|
|
fn part_2(input: &Vec<(u64, Vec<u64>)>) -> u64 {
|
|
let valid_operators = vec![
|
|
&(add as fn(u64, u64) -> u64),
|
|
&(mul as fn(u64, u64) -> u64),
|
|
&(concat as fn(u64, u64) -> u64),
|
|
];
|
|
|
|
sum_valid(input, &valid_operators)
|
|
}
|
|
|
|
fn main() {
|
|
let args: Vec<String> = env::args().collect();
|
|
for arg in args.iter().skip(1) {
|
|
let input = read_input(&arg);
|
|
let calibration_data = parse_input(&input);
|
|
println!("[{}]", &arg);
|
|
println!("\t[Part 1] => Answer is '{}'.", part_1(&calibration_data));
|
|
println!("\t[Part 2] => Answer is '{}'.", part_2(&calibration_data));
|
|
}
|
|
}
|