107 lines
2.6 KiB
Rust
107 lines
2.6 KiB
Rust
use itertools::Itertools;
|
|
|
|
#[derive(Clone, Debug, Default)]
|
|
struct Group {
|
|
packages: Vec<usize>,
|
|
weight: usize,
|
|
}
|
|
|
|
impl Group {
|
|
fn new(packages: Vec<usize>) -> Self {
|
|
let mut group = Self::default();
|
|
for package in packages {
|
|
group.add(package);
|
|
}
|
|
group
|
|
}
|
|
|
|
fn add(&mut self, package: usize) {
|
|
self.packages.push(package);
|
|
self.weight += package;
|
|
}
|
|
|
|
fn qe(&self) -> usize {
|
|
self.packages.iter().product()
|
|
}
|
|
|
|
fn len(&self) -> usize {
|
|
self.packages.len()
|
|
}
|
|
}
|
|
|
|
pub fn process_part1(input: &str) -> usize {
|
|
let packages = input
|
|
.lines()
|
|
.map(|line| line.parse::<usize>().unwrap())
|
|
.collect::<Vec<usize>>();
|
|
let group_weight = packages.iter().sum::<usize>() / 3;
|
|
let mut best_group = (usize::MAX, usize::MAX);
|
|
for k in 1..packages.len() {
|
|
let combinations = packages.clone().into_iter().combinations(k);
|
|
for combination in combinations {
|
|
let group = Group::new(combination.clone());
|
|
if group.weight == group_weight {
|
|
if group.len() < best_group.0 {
|
|
best_group = (group.len(), group.qe());
|
|
}
|
|
if group.len() == best_group.0 && group.qe() < best_group.1 {
|
|
best_group = (group.len(), group.qe());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
best_group.1
|
|
}
|
|
|
|
pub fn process_part2(input: &str) -> usize {
|
|
let packages = input
|
|
.lines()
|
|
.map(|line| line.parse::<usize>().unwrap())
|
|
.collect::<Vec<usize>>();
|
|
let group_weight = packages.iter().sum::<usize>() / 4;
|
|
let mut best_group = (usize::MAX, usize::MAX);
|
|
for k in 1..packages.len() {
|
|
let combinations = packages.clone().into_iter().combinations(k);
|
|
for combination in combinations {
|
|
let group = Group::new(combination.clone());
|
|
if group.weight == group_weight {
|
|
if group.len() < best_group.0 {
|
|
best_group = (group.len(), group.qe());
|
|
}
|
|
if group.len() == best_group.0 && group.qe() < best_group.1 {
|
|
best_group = (group.len(), group.qe());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
best_group.1
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
const INPUT: &str = "1
|
|
2
|
|
3
|
|
4
|
|
5
|
|
7
|
|
8
|
|
9
|
|
10
|
|
11";
|
|
|
|
#[test]
|
|
fn part1() {
|
|
let result = process_part1(INPUT);
|
|
assert_eq!(result, 99);
|
|
}
|
|
|
|
#[test]
|
|
fn part2() {
|
|
let result = process_part2(INPUT);
|
|
assert_eq!(result, 44);
|
|
}
|
|
}
|