Add day 15
This commit is contained in:
		| @@ -65,4 +65,8 @@ path = "src/day13/main.rs" | ||||
| name = "day14" | ||||
| path = "src/day14/main.rs" | ||||
|  | ||||
| [[bin]] | ||||
| name = "day15" | ||||
| path = "src/day15/main.rs" | ||||
|  | ||||
| [dependencies] | ||||
|   | ||||
							
								
								
									
										26
									
								
								day15.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								day15.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| Sensor at x=3772068, y=2853720: closest beacon is at x=4068389, y=2345925 | ||||
| Sensor at x=78607, y=2544104: closest beacon is at x=-152196, y=4183739 | ||||
| Sensor at x=3239531, y=3939220: closest beacon is at x=3568548, y=4206192 | ||||
| Sensor at x=339124, y=989831: closest beacon is at x=570292, y=1048239 | ||||
| Sensor at x=3957534, y=2132743: closest beacon is at x=3897332, y=2000000 | ||||
| Sensor at x=1882965, y=3426126: closest beacon is at x=2580484, y=3654136 | ||||
| Sensor at x=1159443, y=3861139: closest beacon is at x=2580484, y=3654136 | ||||
| Sensor at x=2433461, y=287013: closest beacon is at x=2088099, y=-190228 | ||||
| Sensor at x=3004122, y=3483833: closest beacon is at x=2580484, y=3654136 | ||||
| Sensor at x=3571821, y=799602: closest beacon is at x=3897332, y=2000000 | ||||
| Sensor at x=2376562, y=1539540: closest beacon is at x=2700909, y=2519581 | ||||
| Sensor at x=785113, y=1273008: closest beacon is at x=570292, y=1048239 | ||||
| Sensor at x=1990787, y=38164: closest beacon is at x=2088099, y=-190228 | ||||
| Sensor at x=3993778, y=3482849: closest beacon is at x=4247709, y=3561264 | ||||
| Sensor at x=3821391, y=3986080: closest beacon is at x=3568548, y=4206192 | ||||
| Sensor at x=2703294, y=3999015: closest beacon is at x=2580484, y=3654136 | ||||
| Sensor at x=1448314, y=2210094: closest beacon is at x=2700909, y=2519581 | ||||
| Sensor at x=3351224, y=2364892: closest beacon is at x=4068389, y=2345925 | ||||
| Sensor at x=196419, y=3491556: closest beacon is at x=-152196, y=4183739 | ||||
| Sensor at x=175004, y=138614: closest beacon is at x=570292, y=1048239 | ||||
| Sensor at x=1618460, y=806488: closest beacon is at x=570292, y=1048239 | ||||
| Sensor at x=3974730, y=1940193: closest beacon is at x=3897332, y=2000000 | ||||
| Sensor at x=2995314, y=2961775: closest beacon is at x=2700909, y=2519581 | ||||
| Sensor at x=105378, y=1513086: closest beacon is at x=570292, y=1048239 | ||||
| Sensor at x=3576958, y=3665667: closest beacon is at x=3568548, y=4206192 | ||||
| Sensor at x=2712265, y=2155055: closest beacon is at x=2700909, y=2519581 | ||||
							
								
								
									
										14
									
								
								day15_test.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								day15_test.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| Sensor at x=2, y=18: closest beacon is at x=-2, y=15 | ||||
| Sensor at x=9, y=16: closest beacon is at x=10, y=16 | ||||
| Sensor at x=13, y=2: closest beacon is at x=15, y=3 | ||||
| Sensor at x=12, y=14: closest beacon is at x=10, y=16 | ||||
| Sensor at x=10, y=20: closest beacon is at x=10, y=16 | ||||
| Sensor at x=14, y=17: closest beacon is at x=10, y=16 | ||||
| Sensor at x=8, y=7: closest beacon is at x=2, y=10 | ||||
| Sensor at x=2, y=0: closest beacon is at x=2, y=10 | ||||
| Sensor at x=0, y=11: closest beacon is at x=2, y=10 | ||||
| Sensor at x=20, y=14: closest beacon is at x=25, y=17 | ||||
| Sensor at x=17, y=20: closest beacon is at x=21, y=22 | ||||
| Sensor at x=16, y=7: closest beacon is at x=15, y=3 | ||||
| Sensor at x=14, y=3: closest beacon is at x=15, y=3 | ||||
| Sensor at x=20, y=1: closest beacon is at x=15, y=3 | ||||
							
								
								
									
										137
									
								
								src/day15/main.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								src/day15/main.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,137 @@ | ||||
| use std::cmp::max; | ||||
| use std::collections::HashSet; | ||||
| use base::read_file; | ||||
|  | ||||
| #[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)] | ||||
| struct Pos(i32, i32); | ||||
|  | ||||
| #[derive(Debug, Clone)] | ||||
| struct Beacon { | ||||
|     pos: Pos, | ||||
|     beacon: Pos, | ||||
| } | ||||
|  | ||||
| #[derive(Copy, Clone, Debug)] | ||||
| struct Range { | ||||
|     start: i32, | ||||
|     end: i32, | ||||
| } | ||||
|  | ||||
| impl Range { | ||||
|     fn new(start: i32, end: i32) -> Self { | ||||
|         Range { start, end } | ||||
|     } | ||||
|  | ||||
|     fn contains(&self, number: i32) -> bool { | ||||
|         number >= self.start && number <= self.end | ||||
|     } | ||||
|  | ||||
|     fn fully_overlap(&self, other: &Range) -> bool { | ||||
|         self.contains(other.start) && self.contains(other.end) | ||||
|     } | ||||
|  | ||||
|     fn partly_overlap(&self, other: &Range) -> bool { | ||||
|         self.contains(other.start) || self.contains(other.end) | ||||
|     } | ||||
| } | ||||
|  | ||||
| struct YLine { | ||||
|     y: i32, | ||||
|     start_x: i32, | ||||
|     start_y: i32, | ||||
| } | ||||
|  | ||||
| impl Beacon { | ||||
|     fn possible_positions_into_of(&self, positions: &mut HashSet<Pos>, y: i32) { | ||||
|         let distance = self.get_distance(); | ||||
|         for x in -distance..=distance { | ||||
|             if x.abs() + (self.pos.1 - y).abs() <= distance { | ||||
|                 positions.insert(Pos(self.pos.0 + x, y)); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     fn get_distance(&self) -> i32 { | ||||
|         let Pos(px, py) = self.pos; | ||||
|         let Pos(bx, by) = self.beacon; | ||||
|         (px - bx).abs() + (py - by).abs() | ||||
|     } | ||||
| } | ||||
|  | ||||
| fn main() { | ||||
|     let lines = read_file("day15.txt"); | ||||
|     let mut beacons = vec![]; | ||||
|  | ||||
|     for line in lines { | ||||
|         beacons.push(line.split([' ', '=', ':', ',']).filter_map(|tok| tok.parse::<i32>().ok()).collect::<Vec<_>>().chunks_exact(4).map(|positions| Beacon { pos: Pos(positions[0], positions[1]), beacon: Pos(positions[2], positions[3]) }).next().unwrap()); | ||||
|     } | ||||
|  | ||||
|     let mut possible_positions = HashSet::new(); | ||||
|  | ||||
|     println!("Found {} beacons", beacons.len()); | ||||
|  | ||||
|     println!("Inserting possible positions"); | ||||
|     let y = 2000000; | ||||
|  | ||||
|     for (idx, beacon) in beacons.iter().enumerate() { | ||||
|         println!("Generating positions for beacon {}", idx); | ||||
|         beacon.possible_positions_into_of(&mut possible_positions, y); | ||||
|     } | ||||
|  | ||||
|     println!("Inserting beacons"); | ||||
|  | ||||
|     for beacon in &beacons { | ||||
|         possible_positions.remove(&beacon.pos); | ||||
|         possible_positions.remove(&beacon.beacon); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     println!("Searching for possible positions"); | ||||
|  | ||||
|     let count = possible_positions.iter().filter(|pos| pos.1 == y).count(); | ||||
|  | ||||
|     println!("Found {} at {}", count, y); | ||||
|  | ||||
|     let max = 4000001; | ||||
|     for y in 0..max { | ||||
|         if y % 1000 == 0 { | ||||
|             println!("Y is {}/{}", y, max); | ||||
|         } | ||||
|         let mut beacon_radiation = vec![]; | ||||
|         for beacon in &beacons { | ||||
|             let distance = (beacon.pos.1 - y as i32).abs(); | ||||
|             let max_distance = beacon.get_distance(); | ||||
|             if distance <= max_distance { | ||||
|                 let start_x = beacon.pos.0 - (max_distance - distance); | ||||
|                 let end_x = beacon.pos.0 + (max_distance - distance); | ||||
|                 beacon_radiation.push(Range::new(start_x, end_x)); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         beacon_radiation.sort_by(|r1, r2| r1.start.cmp(&r2.start)); | ||||
|  | ||||
|         let mut start: Option<Range> = None; | ||||
|         for range in beacon_radiation { | ||||
|             match start { | ||||
|                 None => { | ||||
|                     start = Some(range); | ||||
|                 } | ||||
|                 Some(before) => { | ||||
|                     if range.partly_overlap(&before) || (range.start - before.end) == 1 { | ||||
|                         if range.end > before.end { | ||||
|                             start = Some(Range::new(before.start, range.end)); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if let Some(sol) = start { | ||||
|             if sol.end < max { | ||||
|                 let x = sol.end + 1; | ||||
|                 println!("Possible solution: {}/{} Distress: {}", x, y, (x as i64) * 4000000 + (y as i64)); | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user