diff --git a/src/bin/13.rs b/src/bin/13.rs new file mode 100644 index 000000000..d19a874 --- /dev/null +++ b/src/bin/13.rs @@ -0,0 +1,97 @@ +use hashbrown::{HashMap, HashSet}; +use itertools::Itertools; +use lazy_static::lazy_static; +use regex::Regex; + +lazy_static! { + static ref RE: Regex = Regex::new(r#"(?P\w+) would (?P\w{4}) (?P\d+) happiness units by sitting next to (?P\w+)"#).unwrap(); +} + +#[derive(Debug, PartialEq, Hash)] +struct Line { + person: String, + other: String, + amount: i32, +} + +impl From<&str> for Line { + fn from(value: &str) -> Self { + let cap = RE.captures(value).unwrap(); + + let person = cap["person"].to_string(); + let other = cap["other"].to_string(); + let mut amount = cap["amount"].parse().unwrap(); + if let "lose" = &cap["relation"] { + amount *= -1; + }; + + Line { + person, + other, + amount, + } + } +} + +fn solve(input: &str, insert_myself: bool) -> u32 { + let mut map = HashMap::new(); + let mut set = HashSet::new(); + for line in input.split('\n') { + let parsed = Line::from(line); + map.insert( + (parsed.person.to_string(), parsed.other.to_string()), + parsed.amount, + ); + set.insert(parsed.person.to_string()); + } + + if insert_myself { + for p in set.iter() { + map.insert((p.to_string(), "Matej".to_string()), 0); + map.insert(("Matej".to_string(), p.to_string()), 0); + } + set.insert("Matej".to_string()); + } + + set.iter() + .permutations(set.len()) + .map(|x| { + x.iter() + .cycle() + .take(set.len() + 1) + .tuple_windows() + .map(|(a, b)| { + map.get(&(a.to_string(), b.to_string())).unwrap() + + map.get(&(b.to_string(), a.to_string())).unwrap() + }) + .sum::() + }) + .max() + .unwrap() as u32 +} + +pub fn part_one(input: &str) -> Option { + Some(solve(input, false)) +} +pub fn part_two(input: &str) -> Option { + Some(solve(input, true)) +} +fn main() { + let input = &aoc::read_file("inputs", 13); + aoc::solve!(1, part_one, input); + aoc::solve!(2, part_two, input); +} +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn test_part_one() { + let input = aoc::read_file("test_inputs", 13); + assert_eq!(part_one(&input.trim()), Some(330)); + } + #[test] + fn test_part_two() { + let input = aoc::read_file("test_inputs", 13); + assert_eq!(part_two(&input.trim()), Some(286)); + } +} diff --git a/src/test_inputs/13.txt b/src/test_inputs/13.txt new file mode 100644 index 000000000..b67c3c6 --- /dev/null +++ b/src/test_inputs/13.txt @@ -0,0 +1,12 @@ +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.