**diff options**

Diffstat (limited to 'src/day6.rs')

-rw-r--r-- | src/day6.rs | 66 |

1 files changed, 66 insertions, 0 deletions

diff --git a/src/day6.rs b/src/day6.rs index 0c8d0d4..da48d3e 100644 --- a/src/day6.rs +++ b/src/day6.rs @@ -67,6 +67,51 @@ pub fn part1() { ); } +/// On the other hand, if the coordinates are safe, maybe the best you can do is try to find a region near as many coordinates as possible. +/// +/// For example, suppose you want the sum of the Manhattan distance to all of the coordinates to be less than 32. For each location, add up the distances to all of the given coordinates; if the total of those distances is less than 32, that location is within the desired region. Using the same coordinates as above, the resulting region looks like this: +/// +/// .......... +/// .A........ +/// .......... +/// ...###..C. +/// ..#D###... +/// ..###E#... +/// .B.###.... +/// .......... +/// .......... +/// ........F. +/// +/// In particular, consider the highlighted location 4,3 located at the top middle of the region. Its calculation is as follows, where abs() is the absolute value function: +/// +/// Distance to coordinate A: abs(4-1) + abs(3-1) = 5 +/// Distance to coordinate B: abs(4-1) + abs(3-6) = 6 +/// Distance to coordinate C: abs(4-8) + abs(3-3) = 4 +/// Distance to coordinate D: abs(4-3) + abs(3-4) = 2 +/// Distance to coordinate E: abs(4-5) + abs(3-5) = 3 +/// Distance to coordinate F: abs(4-8) + abs(3-9) = 10 +/// Total distance: 5 + 6 + 4 + 2 + 3 + 10 = 30 +/// +/// Because the total distance to all coordinates (30) is less than 32, the location is within the region. +/// +/// This region, which also includes coordinates D and E, has a total size of 16. +/// +/// Your actual region will need to be much larger than this example, though, instead including all locations with a total distance of less than 10000. +/// +/// What is the size of the region containing all locations which have a total distance to all given coordinates of less than 10000? +pub fn part2() { + let input = ::common::read_stdin_to_string(); + + let coords = input_to_coords(input); + let bounds = get_bounds(&coords); + let region_size = calculate_region_size(&coords, bounds); + + println!( + "the size of the region containing all locations which have a total distance to all given coordinates of less than 10000: {}", + region_size + ); +} + fn input_to_coords(input: String) -> Vec<(i64, i64)> { input .lines() @@ -132,6 +177,27 @@ fn calculate_areas( areas } +fn calculate_region_size( + coords: &[(i64, i64)], + (min_coord, max_coord): ((i64, i64), (i64, i64)), +) -> i64 { + let mut region_size = 0; + + for x in min_coord.0..=max_coord.0 { + for y in min_coord.1..=max_coord.1 { + let distance_sum = coords + .iter() + .fold(0, |accum, coord| accum + taxicab_distance((x, y), *coord)); + + if distance_sum < 10000 { + region_size += 1; + } + } + } + + region_size +} + fn taxicab_distance(a: (i64, i64), b: (i64, i64)) -> i64 { (cmp::max(a.0, b.0) - cmp::min(a.0, b.0)) + (cmp::max(a.1, b.1) - cmp::min(a.1, b.1)) } |