AdventOfCode/y2015/src/days/d13.rs

158 lines
5.2 KiB
Rust
Raw Normal View History

2024-10-30 11:15:08 +01:00
use core::panic;
2024-11-18 11:52:30 +01:00
use std::collections::HashMap;
use utils::{math::factorial, permutation};
2024-10-30 11:15:08 +01:00
pub fn process_part1(input: &str) -> i32 {
let mut happiness_table = HashMap::new();
let mut people = Vec::new();
input.lines().for_each(|line| {
let words = line.split_whitespace().collect::<Vec<&str>>();
let happiness = match words[2] {
"gain" => words[3].parse::<i32>().expect("Should be number"),
"lose" => -words[3].parse::<i32>().expect("Should be number"),
_ => panic!("Should not happen"),
};
let person = words[0].to_string();
let mut next_to = words[10].to_string();
next_to.pop();
if !people.contains(&person) {
people.push(person.clone());
}
happiness_table.insert((person, next_to), happiness);
});
let num_people = people.len();
2024-11-18 11:52:30 +01:00
let possible_permutations = factorial(num_people.try_into().unwrap());
2024-10-30 11:15:08 +01:00
let mut highest_happiness = 0;
for idx in 1..possible_permutations {
let mut happiness = 0;
2024-11-18 11:52:30 +01:00
let permutation = permutation::nth_lex(people.clone(), idx.try_into().unwrap()).unwrap();
2024-10-30 11:15:08 +01:00
for (pos, person) in permutation.clone().iter().enumerate() {
let left_neighbor = {
if pos == 0 {
permutation[num_people - 1].clone()
} else {
permutation[pos - 1].clone()
}
};
let right_neighbor = {
if pos == num_people - 1 {
permutation[0].clone()
} else {
permutation[pos + 1].clone()
}
};
let left_happiness = happiness_table
.get(&(person.to_owned(), left_neighbor))
.unwrap();
let right_happiness = happiness_table
.get(&(person.to_owned(), right_neighbor))
.unwrap();
happiness += left_happiness + right_happiness;
}
if happiness > highest_happiness {
highest_happiness = happiness;
}
}
highest_happiness
}
pub fn process_part2(input: &str) -> i32 {
let mut happiness_table = HashMap::new();
let mut people = Vec::new();
input.lines().for_each(|line| {
let words = line.split_whitespace().collect::<Vec<&str>>();
let happiness = match words[2] {
"gain" => words[3].parse::<i32>().expect("Should be number"),
"lose" => -words[3].parse::<i32>().expect("Should be number"),
_ => panic!("Should not happen"),
};
let person = words[0].to_string();
let mut next_to = words[10].to_string();
next_to.pop();
if !people.contains(&person) {
people.push(person.clone());
}
happiness_table.insert((person, next_to), happiness);
});
for person in &people {
happiness_table.insert(("Fabian".to_string(), person.to_owned()), 0);
happiness_table.insert((person.to_owned(), "Fabian".to_string()), 0);
}
people.push("Fabian".to_string());
let num_people = people.len();
2024-11-18 11:52:30 +01:00
let possible_permutations = factorial(num_people.try_into().unwrap());
2024-10-30 11:15:08 +01:00
let mut highest_happiness = 0;
for idx in 1..possible_permutations {
let mut happiness = 0;
2024-11-18 11:52:30 +01:00
let permutation = permutation::nth_lex(people.clone(), idx.try_into().unwrap()).unwrap();
2024-10-30 11:15:08 +01:00
for (pos, person) in permutation.clone().iter().enumerate() {
let left_neighbor = {
if pos == 0 {
permutation[num_people - 1].clone()
} else {
permutation[pos - 1].clone()
}
};
let right_neighbor = {
if pos == num_people - 1 {
permutation[0].clone()
} else {
permutation[pos + 1].clone()
}
};
let left_happiness = happiness_table
.get(&(person.to_owned(), left_neighbor))
.unwrap();
let right_happiness = happiness_table
.get(&(person.to_owned(), right_neighbor))
.unwrap();
happiness += left_happiness + right_happiness;
}
if happiness > highest_happiness {
highest_happiness = happiness;
}
}
highest_happiness
}
#[cfg(test)]
2024-10-30 11:34:40 +01:00
mod tests {
2024-10-30 11:15:08 +01:00
use super::*;
const INPUT: &str = "Alice would gain 54 happiness units by sitting next to Bob.
Alice would lose 79 happiness units by sitting next to Carol.
Alice would lose 2 happiness units by sitting next to David.
Bob would gain 83 happiness units by sitting next to Alice.
Bob would lose 7 happiness units by sitting next to Carol.
Bob would lose 63 happiness units by sitting next to David.
Carol would lose 62 happiness units by sitting next to Alice.
Carol would gain 60 happiness units by sitting next to Bob.
Carol would gain 55 happiness units by sitting next to David.
David would gain 46 happiness units by sitting next to Alice.
David would lose 7 happiness units by sitting next to Bob.
David would gain 41 happiness units by sitting next to Carol.";
#[test]
2024-10-30 11:34:40 +01:00
fn part1() {
2024-10-30 11:15:08 +01:00
let result = process_part1(INPUT);
assert_eq!(result, 330);
}
}