From 3486d23f093e0ba4614e9f88fe91c9da220de179 Mon Sep 17 00:00:00 2001 From: Fabian Schmidt Date: Wed, 30 Oct 2024 11:15:08 +0100 Subject: [PATCH] y2015d13 --- y2015/resources/13_input.txt | 56 +++++++++++ y2015/src/bin/d13.rs | 20 ++++ y2015/src/days/d13.rs | 183 +++++++++++++++++++++++++++++++++++ y2015/src/days/mod.rs | 1 + 4 files changed, 260 insertions(+) create mode 100644 y2015/resources/13_input.txt create mode 100644 y2015/src/bin/d13.rs create mode 100644 y2015/src/days/d13.rs diff --git a/y2015/resources/13_input.txt b/y2015/resources/13_input.txt new file mode 100644 index 0000000..35be357 --- /dev/null +++ b/y2015/resources/13_input.txt @@ -0,0 +1,56 @@ +Alice would gain 54 happiness units by sitting next to Bob. +Alice would lose 81 happiness units by sitting next to Carol. +Alice would lose 42 happiness units by sitting next to David. +Alice would gain 89 happiness units by sitting next to Eric. +Alice would lose 89 happiness units by sitting next to Frank. +Alice would gain 97 happiness units by sitting next to George. +Alice would lose 94 happiness units by sitting next to Mallory. +Bob would gain 3 happiness units by sitting next to Alice. +Bob would lose 70 happiness units by sitting next to Carol. +Bob would lose 31 happiness units by sitting next to David. +Bob would gain 72 happiness units by sitting next to Eric. +Bob would lose 25 happiness units by sitting next to Frank. +Bob would lose 95 happiness units by sitting next to George. +Bob would gain 11 happiness units by sitting next to Mallory. +Carol would lose 83 happiness units by sitting next to Alice. +Carol would gain 8 happiness units by sitting next to Bob. +Carol would gain 35 happiness units by sitting next to David. +Carol would gain 10 happiness units by sitting next to Eric. +Carol would gain 61 happiness units by sitting next to Frank. +Carol would gain 10 happiness units by sitting next to George. +Carol would gain 29 happiness units by sitting next to Mallory. +David would gain 67 happiness units by sitting next to Alice. +David would gain 25 happiness units by sitting next to Bob. +David would gain 48 happiness units by sitting next to Carol. +David would lose 65 happiness units by sitting next to Eric. +David would gain 8 happiness units by sitting next to Frank. +David would gain 84 happiness units by sitting next to George. +David would gain 9 happiness units by sitting next to Mallory. +Eric would lose 51 happiness units by sitting next to Alice. +Eric would lose 39 happiness units by sitting next to Bob. +Eric would gain 84 happiness units by sitting next to Carol. +Eric would lose 98 happiness units by sitting next to David. +Eric would lose 20 happiness units by sitting next to Frank. +Eric would lose 6 happiness units by sitting next to George. +Eric would gain 60 happiness units by sitting next to Mallory. +Frank would gain 51 happiness units by sitting next to Alice. +Frank would gain 79 happiness units by sitting next to Bob. +Frank would gain 88 happiness units by sitting next to Carol. +Frank would gain 33 happiness units by sitting next to David. +Frank would gain 43 happiness units by sitting next to Eric. +Frank would gain 77 happiness units by sitting next to George. +Frank would lose 3 happiness units by sitting next to Mallory. +George would lose 14 happiness units by sitting next to Alice. +George would lose 12 happiness units by sitting next to Bob. +George would lose 52 happiness units by sitting next to Carol. +George would gain 14 happiness units by sitting next to David. +George would lose 62 happiness units by sitting next to Eric. +George would lose 18 happiness units by sitting next to Frank. +George would lose 17 happiness units by sitting next to Mallory. +Mallory would lose 36 happiness units by sitting next to Alice. +Mallory would gain 76 happiness units by sitting next to Bob. +Mallory would lose 34 happiness units by sitting next to Carol. +Mallory would gain 37 happiness units by sitting next to David. +Mallory would gain 40 happiness units by sitting next to Eric. +Mallory would gain 18 happiness units by sitting next to Frank. +Mallory would gain 7 happiness units by sitting next to George. diff --git a/y2015/src/bin/d13.rs b/y2015/src/bin/d13.rs new file mode 100644 index 0000000..3c9adc9 --- /dev/null +++ b/y2015/src/bin/d13.rs @@ -0,0 +1,20 @@ +use std::fs; + +use y2015::days::d13; + +fn main() { + part1(); + part2(); +} + +fn part1() { + let root = env!("CARGO_MANIFEST_DIR"); + let content = fs::read_to_string(format!("{root}/resources/13_input.txt")).unwrap(); + println!("{}", d13::process_part1(&content)); +} + +fn part2() { + let root = env!("CARGO_MANIFEST_DIR"); + let content = fs::read_to_string(format!("{root}/resources/13_input.txt")).unwrap(); + println!("{}", d13::process_part2(&content)); +} diff --git a/y2015/src/days/d13.rs b/y2015/src/days/d13.rs new file mode 100644 index 0000000..bbb7a93 --- /dev/null +++ b/y2015/src/days/d13.rs @@ -0,0 +1,183 @@ +use core::panic; +use std::{collections::HashMap, error::Error}; + +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::>(); + let happiness = match words[2] { + "gain" => words[3].parse::().expect("Should be number"), + "lose" => -words[3].parse::().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(); + + let possible_permutations = factorial(num_people); + + let mut highest_happiness = 0; + for idx in 1..possible_permutations { + let mut happiness = 0; + let permutation = permutation(people.clone(), idx).unwrap(); + + 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 +} + +fn permutation(mut people: Vec, nth: usize) -> Result, Box> { + people.sort(); + if nth == 1 { + return Ok(people); + } + if nth > factorial(people.len()) || nth == 0 { + return Err(Box::from("Out of bounds")); + } + let mut perm = Vec::new(); + let num_unique_locations = people.len(); + let mut remainder = nth - 1; + for idx in 1..=people.len() { + let permutations = remainder / factorial(num_unique_locations - idx); + remainder %= factorial(num_unique_locations - idx); + perm.push(people[permutations].clone()); + people.remove(permutations); + } + Ok(perm) +} + +fn factorial(num: usize) -> usize { + let mut fact = 1; + for n in 1..=num { + fact *= n; + } + fact +} + +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::>(); + let happiness = match words[2] { + "gain" => words[3].parse::().expect("Should be number"), + "lose" => -words[3].parse::().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(); + + let possible_permutations = factorial(num_people); + + let mut highest_happiness = 0; + for idx in 1..possible_permutations { + let mut happiness = 0; + let permutation = permutation(people.clone(), idx).unwrap(); + + 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)] +mod tests_13 { + 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] + fn it_works() { + let result = process_part1(INPUT); + assert_eq!(result, 330); + } +} diff --git a/y2015/src/days/mod.rs b/y2015/src/days/mod.rs index 7055461..dda6b70 100644 --- a/y2015/src/days/mod.rs +++ b/y2015/src/days/mod.rs @@ -2,6 +2,7 @@ pub mod d1; pub mod d10; pub mod d11; pub mod d12; +pub mod d13; pub mod d2; pub mod d3; pub mod d4;