Day 8: Resonant Collinearity
Megathread guidelines
- Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
- You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL
FAQ
- What is this?: Here is a post with a large amount of details: https://programming.dev/post/6637268
- Where do I participate?: https://adventofcode.com/
- Is there a leaderboard for the community?: We have a programming.dev leaderboard with the info on how to join in this post: https://programming.dev/post/6631465
Rust
For the first time, I can post my solution, because I actually solved it on the day :D Probably not the cleanest or optimal solution, but it does solve the problem.
Very long, looking forward to someone solving it in 5 lines of unicode :D
#[cfg(test)] mod tests { fn get_frequences(input: &str) -> Vec<char> { let mut freq = vec![]; for char in input.chars() { if char == '.' { continue; } if !freq.contains(&char) { freq.push(char); } } freq } fn find_antennas(board: &Vec<Vec<char>>, freq: char) -> Vec<(isize, isize)> { let mut antennas = vec![]; for (i, line) in board.iter().enumerate() { for (j, char) in line.iter().enumerate() { if *char == freq { antennas.push((i as isize, j as isize)); } } } antennas } fn calc_antinodes(first: &(isize, isize), second: &(isize, isize)) -> Vec<(isize, isize)> { let deltax = second.0 - first.0; let deltay = second.1 - first.1; if deltax == 0 && deltay == 0 { return vec![]; } vec![ (first.0 - deltax, first.1 - deltay), (second.0 + deltax, second.1 + deltay), ] } #[test] fn test_calc_antinodes() { let expected = vec![(0, -1), (0, 2)]; let actual = calc_antinodes(&(0, 0), &(0, 1)); for i in &expected { assert!(actual.contains(i)); } let actual = calc_antinodes(&(0, 1), &(0, 0)); for i in &expected { assert!(actual.contains(i)); } } fn calc_all_antinodes(board: &Vec<Vec<char>>, freq: char) -> Vec<(isize, isize)> { let antennas = find_antennas(&board, freq); let mut antinodes = vec![]; for (i, first) in antennas.iter().enumerate() { for second in antennas[i..].iter() { antinodes.extend(calc_antinodes(first, second)); } } antinodes } fn prune_nodes( nodes: &Vec<(isize, isize)>, height: isize, width: isize, ) -> Vec<(isize, isize)> { let mut pruned = vec![]; for node in nodes { if pruned.contains(node) { continue; } if node.0 < 0 || node.0 >= height { continue; } if node.1 < 0 || node.1 >= width { continue; } pruned.push(node.clone()); } pruned } fn print_board(board: &Vec<Vec<char>>, pruned: &Vec<(isize, isize)>) { for (i, line) in board.iter().enumerate() { for (j, char) in line.iter().enumerate() { if pruned.contains(&(i as isize, j as isize)) { print!("#"); } else { print!("{char}"); } } println!(); } } #[test] fn day8_part1_test() { let input: String = std::fs::read_to_string("src/input/day_8.txt").unwrap(); let frequencies = get_frequences(&input); let board = input .trim() .split('\n') .map(|line| line.chars().collect::<Vec<char>>()) .collect::<Vec<Vec<char>>>(); let mut all_nodes = vec![]; for freq in frequencies { let nodes = calc_all_antinodes(&board, freq); all_nodes.extend(nodes); } let height = board.len() as isize; let width = board[0].len() as isize; let pruned = prune_nodes(&all_nodes, height, width); println!("{:?}", pruned); print_board(&board, &pruned); println!("{}", pruned.len()); // 14 in test } fn calc_antinodes2(first: &(isize, isize), second: &(isize, isize)) -> Vec<(isize, isize)> { let deltax = second.0 - first.0; let deltay = second.1 - first.1; if deltax == 0 && deltay == 0 { return vec![]; } let mut nodes = vec![]; for n in 0..50 { nodes.push((first.0 - deltax * n, first.1 - deltay * n)); nodes.push((second.0 + deltax * n, second.1 + deltay * n)); } nodes } fn calc_all_antinodes2(board: &Vec<Vec<char>>, freq: char) -> Vec<(isize, isize)> { let antennas = find_antennas(&board, freq); let mut antinodes = vec![]; for (i, first) in antennas.iter().enumerate() { for second in antennas[i..].iter() { antinodes.extend(calc_antinodes2(first, second)); } } antinodes } #[test] fn day8_part2_test() { let input: String = std::fs::read_to_string("src/input/day_8.txt").unwrap(); let frequencies = get_frequences(&input); let board = input .trim() .split('\n') .map(|line| line.chars().collect::<Vec<char>>()) .collect::<Vec<Vec<char>>>(); let mut all_nodes = vec![]; for freq in frequencies { let nodes = calc_all_antinodes2(&board, freq); all_nodes.extend(nodes); } let height = board.len() as isize; let width = board[0].len() as isize; let pruned = prune_nodes(&all_nodes, height, width); println!("{:?}", pruned); print_board(&board, &pruned); println!("{}", pruned.len()); } }