y2024d8
This commit is contained in:
parent
2a91587ae5
commit
0dec0bbf82
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -123,6 +123,7 @@ version = "0.1.0"
|
|||||||
name = "y2024"
|
name = "y2024"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"itertools",
|
||||||
"regex",
|
"regex",
|
||||||
"utils",
|
"utils",
|
||||||
]
|
]
|
||||||
|
@ -6,3 +6,4 @@ edition = "2021"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
regex = "1.11.1"
|
regex = "1.11.1"
|
||||||
utils = { workspace = true }
|
utils = { workspace = true }
|
||||||
|
itertools = { workspace = true }
|
||||||
|
50
y2024/resources/8_input.txt
Normal file
50
y2024/resources/8_input.txt
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
....K..........................8.................z
|
||||||
|
.....n..............r...........z.................
|
||||||
|
.......................w....8.............3...E...
|
||||||
|
.....Q.....U..4.........8.........................
|
||||||
|
...............rc...w........i....................
|
||||||
|
...........K.........i..2.........................
|
||||||
|
..................4.....i.........................
|
||||||
|
K.....n....................w...........z..........
|
||||||
|
..U......Q........................I...............
|
||||||
|
..........i.....I.....Q....g....................5E
|
||||||
|
..Q......................................5........
|
||||||
|
..........c............8......w...g..........5....
|
||||||
|
.............................I.O..................
|
||||||
|
.Z.............4....b.....................k.......
|
||||||
|
..n........4......r..g..6..c.............3........
|
||||||
|
....Z............c................................
|
||||||
|
...................................x..............
|
||||||
|
.......................................O..........
|
||||||
|
...............U...................E..........5...
|
||||||
|
.....f..........................OI3......k........
|
||||||
|
..m.......o......F.......R........x...............
|
||||||
|
m...........o..v6..3...............X..............
|
||||||
|
..............H6v.....F.g.....................W...
|
||||||
|
...........o....Fb....v...............E...........
|
||||||
|
...Z.............a................................
|
||||||
|
......U6.............V............................
|
||||||
|
.9.............b..............pTk.................
|
||||||
|
.......m........V.........H1....x.................
|
||||||
|
...m.................H....................MX......
|
||||||
|
............t.a............H......................
|
||||||
|
........Z...a............v.....1..T..p.W..X.......
|
||||||
|
.............................9...x.......p........
|
||||||
|
.....J.....................V..1................0..
|
||||||
|
...........r..j..........a............pT..........
|
||||||
|
.G..................J...N......f..................
|
||||||
|
...........G......T....B........W.e...........M...
|
||||||
|
..........j.............Rk.............M..........
|
||||||
|
.........q.............MB......R.F..1..P....X...f.
|
||||||
|
............................V....o...........h....
|
||||||
|
...........................................W......
|
||||||
|
......b......u............................e.......
|
||||||
|
.............................................0....
|
||||||
|
..CA....Gt..O........................7.....e....0.
|
||||||
|
C.u......A..9J..N........................h.....e..
|
||||||
|
uj....q..........N.2..................7...........
|
||||||
|
G....N.....uJ...............................0.....
|
||||||
|
.................B................P.......h.......
|
||||||
|
...C....q...........R.........P...................
|
||||||
|
.....q..tC....2.9.....B............P....f.........
|
||||||
|
...............2.................................7
|
20
y2024/src/bin/d8.rs
Normal file
20
y2024/src/bin/d8.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
use std::fs;
|
||||||
|
|
||||||
|
use y2024::days::d8;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
part1();
|
||||||
|
part2();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part1() {
|
||||||
|
let root = env!("CARGO_MANIFEST_DIR");
|
||||||
|
let content = fs::read_to_string(format!("{root}/resources/8_input.txt")).unwrap();
|
||||||
|
println!("{}", d8::process_part1(&content));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part2() {
|
||||||
|
let root = env!("CARGO_MANIFEST_DIR");
|
||||||
|
let content = fs::read_to_string(format!("{root}/resources/8_input.txt")).unwrap();
|
||||||
|
println!("{}", d8::process_part2(&content));
|
||||||
|
}
|
227
y2024/src/days/d8.rs
Normal file
227
y2024/src/days/d8.rs
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
use itertools::Itertools;
|
||||||
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
|
pub fn process_part1(input: &str) -> usize {
|
||||||
|
let mut antennas_freq_pos = HashMap::new();
|
||||||
|
// group all antenna positions by frequency
|
||||||
|
let grid = input
|
||||||
|
.lines()
|
||||||
|
.map(|line| line.chars().collect_vec())
|
||||||
|
.collect_vec();
|
||||||
|
let width = grid[0].len();
|
||||||
|
let height = grid.len();
|
||||||
|
for (y, line) in input.lines().enumerate() {
|
||||||
|
for (x, chara) in line.chars().enumerate() {
|
||||||
|
if chara == '.' {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
antennas_freq_pos
|
||||||
|
.entry(chara)
|
||||||
|
.and_modify(|positions: &mut Vec<(isize, isize)>| {
|
||||||
|
positions.push((x as isize, y as isize))
|
||||||
|
})
|
||||||
|
.or_insert(vec![(x as isize, y as isize)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// get all combinations of 2 antennas by their frequency
|
||||||
|
// and get_antinodes
|
||||||
|
let mut antinodes = HashSet::new();
|
||||||
|
for (_freq, positions) in antennas_freq_pos {
|
||||||
|
let pairs = positions.into_iter().combinations(2);
|
||||||
|
for pair in pairs {
|
||||||
|
let (antinode_a, antinode_b) = get_antinodes(pair[0], pair[1]);
|
||||||
|
if antinode_a.0 >= 0
|
||||||
|
&& antinode_a.0 < width as isize
|
||||||
|
&& antinode_a.1 >= 0
|
||||||
|
&& antinode_a.1 < height as isize
|
||||||
|
{
|
||||||
|
antinodes.insert(antinode_a);
|
||||||
|
}
|
||||||
|
if antinode_b.0 >= 0
|
||||||
|
&& antinode_b.0 < width as isize
|
||||||
|
&& antinode_b.1 >= 0
|
||||||
|
&& antinode_b.1 < height as isize
|
||||||
|
{
|
||||||
|
antinodes.insert(antinode_b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut antinodes = antinodes.iter().collect_vec();
|
||||||
|
antinodes.sort();
|
||||||
|
antinodes.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_antinodes(
|
||||||
|
antenna_a: (isize, isize),
|
||||||
|
antenna_b: (isize, isize),
|
||||||
|
) -> ((isize, isize), (isize, isize)) {
|
||||||
|
let vec2 = ((antenna_a.0 - antenna_b.0), (antenna_a.1 - antenna_b.1));
|
||||||
|
let antinode_a = {
|
||||||
|
let antinode_a = ((antenna_a.0 + vec2.0), (antenna_a.1 + vec2.1));
|
||||||
|
if antinode_a == antenna_b {
|
||||||
|
((antenna_a.0 - vec2.0), (antenna_a.1 - vec2.1))
|
||||||
|
} else {
|
||||||
|
antinode_a
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let antinode_b = {
|
||||||
|
let antinode_b = ((antenna_b.0 + vec2.0), (antenna_b.1 + vec2.1));
|
||||||
|
if antinode_b == antenna_a {
|
||||||
|
((antenna_b.0 - vec2.0), (antenna_b.1 - vec2.1))
|
||||||
|
} else {
|
||||||
|
antinode_b
|
||||||
|
}
|
||||||
|
};
|
||||||
|
(antinode_a, antinode_b)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_reasonant_antinodes(
|
||||||
|
antenna_a: (isize, isize),
|
||||||
|
antenna_b: (isize, isize),
|
||||||
|
width: isize,
|
||||||
|
height: isize,
|
||||||
|
) -> Vec<(isize, isize)> {
|
||||||
|
let mut antinodes = HashSet::new();
|
||||||
|
antinodes.insert(antenna_a);
|
||||||
|
antinodes.insert(antenna_b);
|
||||||
|
let vec2 = ((antenna_a.0 - antenna_b.0), (antenna_a.1 - antenna_b.1));
|
||||||
|
let (mut a, mut b) = (antenna_a, antenna_b);
|
||||||
|
loop {
|
||||||
|
let antinode_a = {
|
||||||
|
let antinode_a = ((a.0 + vec2.0), (a.1 + vec2.1));
|
||||||
|
if antinode_a == b {
|
||||||
|
((a.0 - vec2.0), (a.1 - vec2.1))
|
||||||
|
} else {
|
||||||
|
antinode_a
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if antinode_a.0 >= 0 && antinode_a.0 < width && antinode_a.1 >= 0 && antinode_a.1 < height {
|
||||||
|
antinodes.insert(antinode_a);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
b = a;
|
||||||
|
a = antinode_a;
|
||||||
|
}
|
||||||
|
let (mut a, mut b) = (antenna_a, antenna_b);
|
||||||
|
loop {
|
||||||
|
let antinode_b = {
|
||||||
|
let antinode_b = ((b.0 + vec2.0), (b.1 + vec2.1));
|
||||||
|
if antinode_b == a {
|
||||||
|
((b.0 - vec2.0), (b.1 - vec2.1))
|
||||||
|
} else {
|
||||||
|
antinode_b
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if antinode_b.0 >= 0 && antinode_b.0 < width && antinode_b.1 >= 0 && antinode_b.1 < height {
|
||||||
|
antinodes.insert(antinode_b);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
a = b;
|
||||||
|
b = antinode_b;
|
||||||
|
}
|
||||||
|
antinodes.into_iter().collect_vec()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn process_part2(input: &str) -> usize {
|
||||||
|
let mut antennas_freq_pos = HashMap::new();
|
||||||
|
// group all antenna positions by frequency
|
||||||
|
let grid = input
|
||||||
|
.lines()
|
||||||
|
.map(|line| line.chars().collect_vec())
|
||||||
|
.collect_vec();
|
||||||
|
let width = grid[0].len();
|
||||||
|
let height = grid.len();
|
||||||
|
for (y, line) in input.lines().enumerate() {
|
||||||
|
for (x, chara) in line.chars().enumerate() {
|
||||||
|
if chara == '.' {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
antennas_freq_pos
|
||||||
|
.entry(chara)
|
||||||
|
.and_modify(|positions: &mut Vec<(isize, isize)>| {
|
||||||
|
positions.push((x as isize, y as isize))
|
||||||
|
})
|
||||||
|
.or_insert(vec![(x as isize, y as isize)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// get all combinations of 2 antennas by their frequency
|
||||||
|
// and get_antinodes
|
||||||
|
let mut all_antinodes: HashSet<(isize, isize)> = HashSet::new();
|
||||||
|
for (_freq, positions) in antennas_freq_pos {
|
||||||
|
let pairs = positions.into_iter().combinations(2);
|
||||||
|
for pair in pairs {
|
||||||
|
let (a, b) = (pair[0], pair[1]);
|
||||||
|
let antinodes = get_reasonant_antinodes(a, b, width as isize, height as isize);
|
||||||
|
all_antinodes.extend(antinodes.iter());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut antinodes = all_antinodes.iter().collect_vec();
|
||||||
|
antinodes.sort();
|
||||||
|
antinodes.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
const INPUT: &str = "............
|
||||||
|
........0...
|
||||||
|
.....0......
|
||||||
|
.......0....
|
||||||
|
....0.......
|
||||||
|
......A.....
|
||||||
|
............
|
||||||
|
............
|
||||||
|
........A...
|
||||||
|
.........A..
|
||||||
|
............
|
||||||
|
............";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part1() {
|
||||||
|
let result = process_part1(INPUT);
|
||||||
|
assert_eq!(result, 14);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_get_antinodes_1() {
|
||||||
|
let antenna_a = (5, 2);
|
||||||
|
let antenna_b = (7, 3);
|
||||||
|
let (antinode_a, antinode_b) = get_antinodes(antenna_a, antenna_b);
|
||||||
|
assert_eq!(antinode_a, (3, 1));
|
||||||
|
assert_eq!(antinode_b, (9, 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_get_antinodes_2() {
|
||||||
|
let antenna_a = (5, 2);
|
||||||
|
let antenna_b = (8, 1);
|
||||||
|
let (antinode_a, antinode_b) = get_antinodes(antenna_a, antenna_b);
|
||||||
|
assert_eq!(antinode_a, (2, 3));
|
||||||
|
assert_eq!(antinode_b, (11, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part2() {
|
||||||
|
let result = process_part2(INPUT);
|
||||||
|
assert_eq!(result, 34);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part2_simple() {
|
||||||
|
let input = "T.........
|
||||||
|
...T......
|
||||||
|
.T........
|
||||||
|
..........
|
||||||
|
..........
|
||||||
|
..........
|
||||||
|
..........
|
||||||
|
..........
|
||||||
|
..........
|
||||||
|
..........";
|
||||||
|
let result = process_part2(input);
|
||||||
|
assert_eq!(result, 9);
|
||||||
|
}
|
||||||
|
}
|
@ -11,3 +11,5 @@ pub mod d5;
|
|||||||
pub mod d6;
|
pub mod d6;
|
||||||
|
|
||||||
pub mod d7;
|
pub mod d7;
|
||||||
|
|
||||||
|
pub mod d8;
|
||||||
|
Loading…
Reference in New Issue
Block a user