Advent of Code solutions

Day 7 & 8

bwc9876.dev 47a7b2ec 1cdbe7fc

verified
+197 -15
+5
utils/src/grid.rs
··· 125 125 (self.width() - 1, self.height() - 1) 126 126 } 127 127 128 + /// Get if a given position is in this grid's bounds 129 + pub fn in_bounds(&self, pos: &Position) -> bool { 130 + pos.x >= 0 && pos.y >= 0 && pos.x < self.width() as isize && pos.y < self.height() as isize 131 + } 132 + 128 133 /// Get a value from the grid at the given position. 129 134 /// 130 135 /// # Examples
+2 -2
utils/src/pos.rs
··· 30 30 #[macro_export] 31 31 macro_rules! upos { 32 32 ($x:expr, $y:expr) => { 33 - $crate::pos::ipos!($x as isize, $y as isize) 33 + $crate::ipos!($x as isize, $y as isize) 34 34 }; 35 35 } 36 36 ··· 60 60 } 61 61 62 62 /// Create a new position at 0, 0 63 - pub fn zero() -> Self { 63 + pub const fn zero() -> Self { 64 64 Self { x: 0, y: 0 } 65 65 } 66 66
+65 -7
years/2024/src/day_7.rs
··· 1 - 2 - use advent_core::{Day, day_stuff, ex_for_day}; 1 + use advent_core::{day_stuff, ex_for_day, Day}; 3 2 4 3 pub struct Day7; 5 4 6 5 impl Day for Day7 { 6 + day_stuff!(7, "3749", "11387", Vec<(i64, Vec<i64>)>); 7 7 8 - day_stuff!(7, "", ""); 8 + fn part_1(input: Self::Input) -> Option<String> { 9 + let ans = input 10 + .into_iter() 11 + .filter_map(|(target, operands)| { 12 + let ps: u64 = 1 << (operands.len() - 1); 13 + for p in 0..=ps { 14 + let res = operands.iter().enumerate().fold(0, |acc, (i, e)| { 15 + if i == 0 { 16 + acc + *e 17 + } else if p & (1 << (i - 1)) != 0 { 18 + acc * *e 19 + } else { 20 + acc + *e 21 + } 22 + }); 23 + if res == target { 24 + return Some(target); 25 + } 26 + } 27 + None 28 + }) 29 + .sum::<i64>(); 9 30 10 - fn part_1(_input: Self::Input) -> Option<String> { 11 - None 31 + Some(ans.to_string()) 12 32 } 13 33 14 - fn part_2(_input: Self::Input) -> Option<String> { 15 - None 34 + fn part_2(input: Self::Input) -> Option<String> { 35 + let ans = input 36 + .into_iter() 37 + .filter_map(|(target, operands)| { 38 + let ps: u64 = 3_u64.pow((operands.len() - 1) as u32); 39 + for p in 0..=ps { 40 + let res = operands.iter().enumerate().fold(0, |acc, (i, e)| { 41 + if i == 0 { 42 + acc + *e 43 + } else if p / 3_u64.pow((i - 1) as u32) % 3 == 1 { 44 + acc * *e 45 + } else if p / 3_u64.pow((i - 1) as u32) % 3 == 2 { 46 + // Integer logartihm to prevent calls to to_string? 47 + format!("{acc}{e}").parse().unwrap() 48 + } else { 49 + acc + *e 50 + } 51 + }); 52 + if res == target { 53 + return Some(target); 54 + } 55 + } 56 + None 57 + }) 58 + .sum::<i64>(); 59 + 60 + Some(ans.to_string()) 61 + } 62 + 63 + fn parse_input(input: &str) -> Self::Input { 64 + input 65 + .lines() 66 + .map(|l| { 67 + let (eq, rest) = l.split_once(": ").unwrap(); 68 + ( 69 + eq.parse().unwrap(), 70 + rest.split(" ").map(|x| x.parse().unwrap()).collect(), 71 + ) 72 + }) 73 + .collect() 16 74 } 17 75 }
+83 -6
years/2024/src/day_8.rs
··· 1 + use std::collections::HashSet; 1 2 2 - use advent_core::{Day, day_stuff, ex_for_day}; 3 + use advent_core::{day_stuff, ex_for_day, Day}; 4 + use utils::tiles; 3 5 4 6 pub struct Day8; 5 7 8 + tiles!(Tile, [ 9 + '.' => Empty, 10 + ], [ 11 + Antenna(char) 12 + ], |c| { 13 + Self::Antenna(c) 14 + }); 15 + 16 + type Grid = utils::grid::Grid<Tile>; 17 + 6 18 impl Day for Day8 { 19 + day_stuff!(8, "14", "34", Grid); 20 + 21 + fn part_1(input: Self::Input) -> Option<String> { 22 + let all_antennas = input 23 + .iter() 24 + .filter_map(|(pos, t)| match *t { 25 + Tile::Empty => None, 26 + Tile::Antenna(c) => Some((pos, c)), 27 + }) 28 + .collect::<Vec<_>>(); 29 + 30 + let mut anti_nodes = HashSet::with_capacity(20); 31 + 32 + for (pos, freq) in all_antennas.iter() { 33 + all_antennas 34 + .iter() 35 + .filter(|(p, f)| p != pos && f == freq) 36 + .for_each(|(pos2, _)| { 37 + let distance = pos2.sub(pos); 38 + 39 + let anti_one = pos2.add(&distance); 40 + let anti_two = pos.sub(&distance); 41 + 42 + if input.in_bounds(&anti_one) { 43 + anti_nodes.insert(anti_one); 44 + } 45 + if input.in_bounds(&anti_two) { 46 + anti_nodes.insert(anti_two); 47 + } 48 + }) 49 + } 7 50 8 - day_stuff!(8, "", ""); 51 + Some(anti_nodes.len().to_string()) 52 + } 9 53 10 - fn part_1(_input: Self::Input) -> Option<String> { 11 - None 54 + fn part_2(input: Self::Input) -> Option<String> { 55 + let all_antennas = input 56 + .iter() 57 + .filter_map(|(pos, t)| match *t { 58 + Tile::Empty => None, 59 + Tile::Antenna(c) => Some((pos, c)), 60 + }) 61 + .collect::<Vec<_>>(); 62 + 63 + let mut anti_nodes = HashSet::with_capacity(20); 64 + 65 + for (pos, freq) in all_antennas.iter() { 66 + all_antennas 67 + .iter() 68 + .filter(|(p, f)| p != pos && f == freq) 69 + .for_each(|(pos2, _)| { 70 + anti_nodes.insert(*pos); 71 + 72 + let distance = pos2.sub(pos); 73 + 74 + let mut anti_one = pos2.add(&distance); 75 + let mut anti_two = pos.sub(&distance); 76 + 77 + while input.in_bounds(&anti_one) { 78 + anti_nodes.insert(anti_one); 79 + anti_one = anti_one.add(&distance); 80 + } 81 + while input.in_bounds(&anti_two) { 82 + anti_nodes.insert(anti_two); 83 + anti_two = anti_two.sub(&distance); 84 + } 85 + }) 86 + } 87 + 88 + Some(anti_nodes.len().to_string()) 12 89 } 13 90 14 - fn part_2(_input: Self::Input) -> Option<String> { 15 - None 91 + fn parse_input(input: &str) -> Self::Input { 92 + Grid::parse(input) 16 93 } 17 94 }
+9
years/2024/src/examples/day_7/1.txt
··· 1 + 190: 10 19 2 + 3267: 81 40 27 3 + 83: 17 5 4 + 156: 15 6 5 + 7290: 6 8 6 15 6 + 161011: 16 10 13 7 + 192: 17 8 14 8 + 21037: 9 7 18 13 9 + 292: 11 6 16 20
+9
years/2024/src/examples/day_7/2.txt
··· 1 + 190: 10 19 2 + 3267: 81 40 27 3 + 83: 17 5 4 + 156: 15 6 5 + 7290: 6 8 6 15 6 + 161011: 16 10 13 7 + 192: 17 8 14 8 + 21037: 9 7 18 13 9 + 292: 11 6 16 20
+12
years/2024/src/examples/day_8/1.txt
··· 1 + ............ 2 + ........0... 3 + .....0...... 4 + .......0.... 5 + ....0....... 6 + ......A..... 7 + ............ 8 + ............ 9 + ........A... 10 + .........A.. 11 + ............ 12 + ............
+12
years/2024/src/examples/day_8/2.txt
··· 1 + ............ 2 + ........0... 3 + .....0...... 4 + .......0.... 5 + ....0....... 6 + ......A..... 7 + ............ 8 + ............ 9 + ........A... 10 + .........A.. 11 + ............ 12 + ............