From 30d700694fb1bfd70e7ce2dd3c60fcafe75d70d0 Mon Sep 17 00:00:00 2001 From: Julius de Jeu Date: Sun, 5 Dec 2021 11:59:48 +0100 Subject: [PATCH] Add day 5 --- input/day05 | 500 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/day05.rs | 233 ++++++++++++++++++++++++ src/main.rs | 8 +- 3 files changed, 739 insertions(+), 2 deletions(-) create mode 100644 input/day05 create mode 100644 src/day05.rs diff --git a/input/day05 b/input/day05 new file mode 100644 index 0000000..20ffa32 --- /dev/null +++ b/input/day05 @@ -0,0 +1,500 @@ +529,822 -> 529,562 +106,230 -> 568,230 +709,377 -> 708,376 +600,544 -> 600,638 +75,351 -> 70,351 +147,959 -> 89,959 +626,911 -> 626,805 +542,816 -> 408,950 +489,224 -> 489,441 +266,583 -> 255,583 +603,145 -> 603,309 +50,871 -> 785,136 +460,412 -> 966,918 +506,920 -> 506,552 +378,515 -> 378,538 +16,467 -> 26,467 +646,219 -> 646,142 +341,461 -> 891,461 +382,253 -> 382,945 +489,344 -> 634,199 +563,19 -> 233,349 +337,894 -> 936,295 +156,413 -> 156,916 +859,986 -> 99,226 +226,768 -> 178,816 +924,58 -> 924,890 +755,236 -> 36,236 +920,399 -> 920,643 +620,12 -> 790,12 +290,236 -> 849,236 +556,649 -> 556,96 +975,195 -> 591,579 +606,438 -> 606,778 +871,203 -> 523,551 +232,521 -> 904,521 +309,206 -> 896,793 +385,988 -> 385,186 +726,974 -> 95,343 +603,336 -> 603,368 +749,184 -> 869,184 +415,558 -> 911,558 +477,550 -> 477,603 +522,415 -> 938,831 +230,951 -> 497,951 +859,275 -> 150,275 +683,455 -> 894,455 +404,42 -> 658,42 +933,767 -> 765,767 +909,298 -> 909,423 +813,312 -> 833,292 +20,15 -> 964,959 +376,362 -> 111,627 +329,336 -> 329,511 +132,915 -> 798,249 +517,560 -> 517,479 +88,595 -> 88,857 +281,678 -> 566,393 +144,961 -> 801,304 +82,871 -> 545,408 +499,849 -> 499,146 +414,785 -> 384,785 +653,839 -> 653,67 +573,634 -> 229,634 +880,283 -> 542,283 +777,189 -> 164,189 +463,97 -> 596,97 +862,865 -> 862,555 +227,780 -> 227,905 +319,214 -> 319,360 +683,569 -> 683,335 +626,703 -> 88,165 +243,810 -> 243,370 +622,506 -> 622,324 +670,151 -> 670,441 +703,808 -> 703,879 +260,597 -> 206,597 +232,13 -> 94,13 +443,680 -> 298,680 +504,368 -> 504,103 +372,341 -> 372,256 +155,799 -> 155,504 +12,47 -> 950,985 +60,500 -> 60,973 +154,783 -> 295,924 +131,348 -> 131,497 +951,388 -> 542,388 +825,164 -> 825,719 +850,351 -> 692,351 +69,955 -> 259,955 +171,701 -> 164,701 +748,457 -> 610,319 +924,170 -> 924,965 +800,599 -> 685,599 +621,40 -> 146,515 +453,423 -> 800,76 +933,394 -> 301,394 +207,647 -> 207,255 +151,568 -> 662,57 +333,763 -> 333,897 +521,847 -> 154,847 +255,696 -> 97,696 +188,687 -> 188,791 +76,382 -> 596,902 +325,637 -> 618,344 +458,949 -> 889,518 +365,136 -> 411,136 +641,248 -> 641,143 +202,518 -> 490,806 +225,40 -> 225,493 +473,311 -> 968,806 +169,854 -> 169,61 +17,887 -> 803,101 +310,766 -> 508,766 +948,12 -> 52,908 +953,739 -> 347,739 +183,727 -> 757,153 +101,21 -> 101,799 +461,619 -> 461,831 +519,390 -> 857,390 +615,860 -> 72,860 +846,87 -> 846,897 +826,896 -> 560,896 +237,206 -> 982,951 +407,825 -> 949,283 +555,705 -> 555,333 +180,101 -> 180,452 +144,31 -> 144,192 +894,175 -> 894,927 +468,57 -> 146,379 +117,66 -> 117,530 +187,748 -> 187,948 +150,232 -> 685,767 +630,249 -> 630,400 +591,679 -> 762,508 +888,177 -> 404,177 +524,692 -> 944,272 +677,104 -> 818,104 +54,232 -> 573,232 +618,629 -> 618,456 +62,128 -> 938,128 +895,113 -> 111,897 +192,165 -> 969,942 +890,896 -> 890,329 +714,643 -> 84,13 +561,268 -> 561,818 +700,534 -> 493,741 +965,582 -> 652,269 +840,526 -> 285,526 +216,86 -> 216,886 +812,275 -> 708,275 +113,902 -> 912,902 +137,173 -> 137,553 +343,598 -> 193,598 +510,380 -> 194,380 +37,974 -> 957,54 +119,801 -> 888,801 +243,11 -> 813,581 +298,463 -> 298,884 +86,869 -> 86,727 +431,899 -> 581,899 +788,862 -> 633,862 +305,781 -> 196,781 +478,421 -> 426,421 +956,47 -> 32,971 +689,802 -> 689,525 +940,94 -> 940,455 +896,207 -> 120,207 +569,360 -> 377,168 +673,281 -> 673,396 +791,839 -> 50,98 +66,787 -> 837,16 +13,887 -> 809,91 +550,745 -> 550,494 +970,901 -> 320,251 +832,49 -> 61,820 +265,577 -> 795,47 +556,211 -> 106,211 +809,216 -> 50,216 +81,630 -> 292,630 +69,973 -> 986,56 +389,240 -> 389,98 +526,748 -> 526,573 +975,885 -> 567,885 +665,492 -> 665,407 +169,726 -> 926,726 +609,896 -> 609,560 +599,398 -> 403,202 +436,367 -> 436,907 +859,268 -> 308,268 +369,331 -> 525,331 +116,19 -> 116,691 +457,845 -> 452,840 +43,117 -> 828,902 +839,938 -> 839,282 +344,154 -> 975,154 +492,952 -> 186,952 +450,94 -> 450,650 +823,897 -> 743,897 +787,112 -> 787,75 +196,921 -> 233,958 +969,976 -> 73,80 +593,873 -> 354,634 +51,838 -> 630,838 +523,822 -> 718,822 +990,235 -> 807,235 +355,789 -> 15,789 +465,919 -> 609,919 +662,185 -> 455,185 +722,406 -> 722,346 +20,283 -> 20,270 +608,440 -> 283,440 +215,756 -> 215,956 +324,275 -> 866,817 +319,181 -> 319,445 +397,272 -> 50,619 +281,354 -> 266,354 +915,858 -> 915,64 +815,723 -> 340,248 +873,760 -> 873,532 +677,145 -> 458,364 +409,106 -> 54,106 +867,585 -> 704,585 +100,617 -> 100,34 +708,707 -> 418,707 +535,812 -> 535,841 +294,571 -> 294,851 +824,590 -> 234,590 +534,317 -> 938,317 +13,133 -> 13,245 +784,74 -> 130,728 +907,916 -> 668,677 +526,767 -> 849,767 +930,96 -> 824,96 +399,33 -> 399,348 +910,404 -> 910,690 +455,348 -> 455,737 +741,464 -> 685,464 +169,296 -> 952,296 +947,388 -> 491,844 +964,336 -> 964,230 +614,71 -> 240,71 +877,957 -> 877,896 +37,381 -> 37,871 +184,772 -> 149,772 +928,120 -> 928,772 +926,434 -> 394,966 +984,130 -> 138,976 +906,346 -> 376,876 +697,220 -> 697,166 +431,301 -> 130,301 +419,549 -> 419,227 +714,14 -> 714,303 +257,644 -> 127,644 +186,950 -> 975,161 +95,671 -> 601,671 +189,109 -> 314,109 +858,701 -> 627,701 +47,155 -> 467,575 +334,767 -> 334,395 +609,482 -> 609,647 +980,334 -> 497,334 +162,723 -> 399,723 +962,961 -> 45,44 +473,296 -> 452,296 +155,49 -> 155,612 +379,497 -> 552,324 +640,606 -> 414,606 +889,604 -> 889,616 +564,273 -> 47,790 +181,770 -> 656,770 +451,281 -> 969,281 +124,289 -> 59,289 +359,106 -> 359,730 +535,644 -> 33,142 +486,651 -> 399,651 +722,453 -> 944,453 +920,46 -> 223,46 +369,954 -> 369,387 +455,430 -> 455,752 +57,22 -> 973,938 +337,887 -> 337,313 +546,586 -> 471,586 +762,908 -> 762,194 +885,259 -> 402,742 +889,348 -> 889,111 +885,963 -> 741,819 +340,72 -> 340,822 +139,683 -> 664,158 +814,28 -> 814,908 +115,623 -> 137,623 +546,69 -> 211,69 +151,620 -> 151,183 +656,674 -> 464,482 +206,445 -> 187,464 +105,375 -> 105,216 +352,952 -> 352,832 +964,840 -> 826,978 +392,201 -> 392,428 +400,536 -> 400,798 +283,62 -> 71,62 +70,818 -> 893,818 +111,252 -> 721,252 +952,101 -> 124,929 +75,248 -> 75,52 +299,83 -> 962,746 +680,344 -> 680,524 +13,987 -> 989,11 +844,809 -> 755,898 +402,294 -> 977,869 +302,403 -> 692,793 +86,11 -> 202,11 +413,766 -> 124,766 +689,146 -> 967,146 +311,88 -> 717,88 +574,810 -> 432,668 +666,330 -> 914,330 +22,988 -> 986,24 +849,921 -> 849,563 +434,441 -> 136,143 +185,896 -> 469,612 +53,553 -> 53,916 +554,51 -> 554,956 +28,116 -> 857,945 +756,933 -> 759,936 +985,953 -> 963,953 +339,396 -> 339,194 +813,763 -> 813,124 +321,561 -> 795,87 +809,759 -> 503,759 +291,94 -> 300,94 +624,652 -> 601,675 +115,461 -> 560,906 +194,653 -> 194,148 +728,695 -> 728,409 +95,472 -> 95,885 +806,503 -> 223,503 +260,610 -> 260,874 +73,130 -> 772,829 +963,15 -> 11,967 +661,409 -> 978,92 +293,982 -> 293,249 +839,17 -> 839,668 +138,518 -> 138,471 +749,348 -> 749,177 +624,176 -> 835,387 +943,88 -> 57,974 +88,610 -> 552,610 +939,500 -> 909,530 +629,48 -> 440,48 +903,612 -> 96,612 +379,914 -> 209,914 +51,22 -> 51,263 +985,975 -> 66,56 +39,120 -> 699,780 +465,93 -> 967,93 +765,954 -> 765,918 +405,315 -> 710,315 +819,881 -> 45,107 +531,111 -> 355,287 +883,443 -> 659,443 +288,46 -> 763,521 +768,615 -> 768,662 +357,53 -> 848,544 +351,782 -> 351,317 +641,944 -> 938,647 +360,905 -> 982,283 +359,117 -> 359,554 +937,467 -> 937,281 +716,963 -> 55,963 +257,299 -> 550,299 +28,14 -> 952,938 +326,988 -> 326,65 +787,227 -> 501,513 +356,162 -> 736,162 +668,562 -> 668,292 +463,850 -> 36,850 +979,105 -> 979,662 +314,24 -> 682,24 +898,406 -> 780,406 +199,43 -> 572,43 +730,120 -> 156,120 +613,573 -> 217,573 +541,489 -> 948,896 +359,921 -> 845,921 +174,365 -> 616,365 +962,179 -> 962,42 +516,92 -> 101,92 +695,233 -> 61,233 +17,24 -> 978,985 +223,409 -> 223,719 +489,815 -> 637,815 +346,249 -> 955,858 +101,687 -> 461,687 +243,427 -> 334,518 +849,915 -> 203,269 +11,758 -> 535,758 +76,788 -> 804,60 +659,343 -> 649,343 +756,602 -> 756,548 +543,593 -> 543,788 +36,65 -> 950,979 +522,96 -> 157,96 +839,600 -> 797,600 +571,704 -> 210,704 +704,361 -> 704,409 +374,799 -> 974,199 +870,826 -> 64,20 +30,618 -> 30,196 +394,260 -> 394,934 +793,65 -> 815,65 +126,769 -> 756,769 +443,636 -> 443,749 +909,573 -> 831,495 +22,884 -> 891,15 +337,286 -> 337,454 +261,607 -> 210,556 +314,837 -> 314,774 +869,432 -> 869,957 +482,81 -> 475,74 +966,94 -> 103,957 +759,102 -> 655,206 +956,95 -> 956,714 +765,681 -> 765,520 +817,959 -> 201,959 +301,378 -> 725,802 +56,867 -> 421,867 +775,657 -> 430,657 +340,57 -> 565,57 +615,632 -> 958,289 +265,342 -> 138,469 +804,654 -> 810,654 +782,306 -> 782,483 +399,683 -> 982,683 +593,781 -> 796,781 +638,752 -> 638,323 +122,243 -> 122,843 +890,83 -> 54,919 +376,552 -> 376,380 +271,403 -> 302,403 +684,221 -> 16,889 +286,618 -> 424,480 +738,693 -> 138,93 +629,750 -> 629,284 +734,364 -> 734,738 +916,934 -> 19,37 +801,342 -> 954,495 +237,516 -> 606,885 +680,591 -> 65,591 +661,230 -> 756,230 +163,371 -> 163,496 +374,759 -> 859,759 +945,513 -> 705,753 +239,517 -> 239,916 +548,796 -> 72,320 +441,351 -> 441,402 +129,315 -> 793,979 +892,137 -> 819,137 +799,957 -> 799,731 +649,468 -> 626,468 +974,299 -> 974,629 +828,954 -> 88,214 +369,277 -> 312,277 +943,360 -> 943,314 +610,644 -> 610,647 +172,913 -> 460,625 +145,61 -> 888,804 +813,693 -> 582,693 +857,848 -> 49,40 +660,252 -> 387,252 +250,723 -> 25,723 +340,186 -> 621,186 +144,96 -> 144,372 +351,804 -> 366,804 +875,600 -> 752,600 +475,490 -> 865,880 +26,46 -> 944,964 +405,712 -> 125,712 +711,676 -> 178,143 +488,446 -> 348,306 +170,440 -> 170,105 +970,981 -> 119,130 +284,772 -> 416,772 +850,148 -> 749,148 +898,955 -> 898,947 +677,109 -> 787,219 +534,650 -> 534,696 +730,216 -> 730,814 +514,89 -> 130,89 +380,199 -> 291,288 +931,110 -> 678,363 +226,537 -> 453,764 +954,228 -> 954,988 +847,338 -> 315,338 +316,989 -> 974,331 +666,554 -> 224,554 +53,868 -> 551,370 +614,548 -> 614,924 +191,837 -> 561,837 +605,639 -> 240,274 +906,28 -> 906,957 \ No newline at end of file diff --git a/src/day05.rs b/src/day05.rs new file mode 100644 index 0000000..a57a4a9 --- /dev/null +++ b/src/day05.rs @@ -0,0 +1,233 @@ +use std::cmp::Ordering; +use std::collections::HashMap; +use crate::Day; + +pub struct Day05 { + vents: Vec, +} + +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug)] +struct Path { + start: Coordinate, + end: Coordinate, + covers: Vec, +} + +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)] +struct Coordinate { + x: i64, + y: i64, +} + +impl Day for Day05 { + fn init(content: String) -> Self { + let paths = content.lines().map(str_to_vent).collect::>(); + Self { + vents: paths, + } + } + + fn part1(&self) -> String { + let new_vents = self.vents.iter().filter(|p| p.is_straight()).cloned().collect::>(); + let mut m = HashMap::new(); + for vent in &new_vents { + for cover in &vent.covers { + let m = m.entry(cover).or_insert(0); + *m += 1; + } + } + + format!("{}", m.values().copied().filter(|x| *x >= 2).count()) + } + + fn part2(&self) -> String { + let mut m = HashMap::new(); + for vent in &self.vents { + for cover in &vent.covers { + let m = m.entry(cover).or_insert(0); + *m += 1; + } + } + + format!("{}", m.values().copied().filter(|x| *x >= 2).count()) + } +} + +impl Path { + #[cfg(test)] + fn covers_diag(&self, target: &Coordinate) -> bool { + let dir = self.start.dir_to(&self.end).coord_diff(); + // println!("{:?}, {:?}, {:?}", self.start, self.end, dir); + let mut coord = (&self.start).clone(); + while coord != self.end { + if coord == target.clone() { + return true; + } + coord.x += dir.0; + coord.y += dir.1; + } + + false + } + + fn is_straight(&self) -> bool { + self.start.x == self.end.x || self.start.y == self.end.y + } +} + +impl Coordinate { + fn dir_to(&self, other: &Coordinate) -> Direction { + return if self.x < other.x { + match self.y.cmp(&other.y) { + Ordering::Less => Direction::SE, + Ordering::Equal => Direction::E, + Ordering::Greater => Direction::NE, + } + } else if self.x == other.x { + match self.y.cmp(&other.y) { + Ordering::Less => Direction::S, + Ordering::Equal => panic!("why are the start and end equal??"), + Ordering::Greater => Direction::N, + } + } else if self.y < other.y { + Direction::SW + } else if self.y == other.y { + Direction::W + } else { + Direction::NW + }; + } + + #[cfg(test)] + fn new(x: i64, y: i64) -> Self { + Coordinate { x, y } + } + + fn from_vec(v: &[i64]) -> Self { + Coordinate { x: v[0], y: v[1] } + } +} + +#[derive(Eq, PartialEq, Debug)] +enum Direction { + NE, + NW, + SE, + SW, + N, + E, + W, + S, +} + +impl Direction { + fn coord_diff(&self) -> (i64, i64) { + match self { + Direction::NE => (1, -1), + Direction::NW => (-1, -1), + Direction::SE => (1, 1), + Direction::SW => (-1, 1), + Direction::N => (0, -1), + Direction::E => (1, 0), + Direction::W => (-1, 0), + Direction::S => (0, 1), + } + } +} + +fn str_to_vent(st: &str) -> Path { + let mut v = st.split(" -> "); + let a = v.next().unwrap(); + let b = v.next().unwrap(); + let start = a.split(',').map(|x| x.parse().unwrap()).collect::>(); + let end = b.split(',').map(|x| x.parse().unwrap()).collect::>(); + let start = Coordinate::from_vec(&start); + let end = Coordinate::from_vec(&end); + + let dir = start.dir_to(&end).coord_diff(); + let mut covers = vec![]; + let mut c = start.clone(); + + while c != end { + covers.push(c.clone()); + c.x += dir.0; + c.y += dir.1; + } + covers.push(end.clone()); + + Path { + start, + end, + covers, + } +} + +#[cfg(test)] +mod tests { + use crate::Day05; + use crate::day05::{Coordinate, Direction, Path}; + use crate::day::Day; + + const INPUT: &str = r"0,9 -> 5,9 +8,0 -> 0,8 +9,4 -> 3,4 +2,2 -> 2,1 +7,0 -> 7,4 +6,4 -> 2,0 +0,9 -> 2,9 +3,4 -> 1,4 +0,0 -> 8,8 +5,5 -> 8,2"; + + #[test] + fn covers_test_1() { + let start = Coordinate { x: 0, y: 0 }; + let end = Coordinate { x: 3, y: 0 }; + let path = Path { start, end, covers: vec![] }; + assert!(path.covers_diag(&Coordinate { x: 2, y: 0 })); + } + + #[test] + fn covers_test_2() { + let start = Coordinate { x: 0, y: 0 }; + let end = Coordinate { x: 0, y: 3 }; + let path = Path { start, end, covers: vec![] }; + assert!(path.covers_diag(&Coordinate { x: 0, y: 2 })); + } + + #[test] + fn directions() { + assert_eq!(Coordinate::new(5, 5).dir_to(&Coordinate::new(0, 0)), Direction::NW); + assert_eq!(Coordinate::new(5, 5).dir_to(&Coordinate::new(9, 9)), Direction::SE); + assert_eq!(Coordinate::new(5, 5).dir_to(&Coordinate::new(9, 0)), Direction::NE); + assert_eq!(Coordinate::new(5, 5).dir_to(&Coordinate::new(0, 9)), Direction::SW); + assert_eq!(Coordinate::new(5, 5).dir_to(&Coordinate::new(0, 5)), Direction::W); + assert_eq!(Coordinate::new(5, 5).dir_to(&Coordinate::new(5, 0)), Direction::N); + assert_eq!(Coordinate::new(5, 5).dir_to(&Coordinate::new(9, 5)), Direction::E); + assert_eq!(Coordinate::new(5, 5).dir_to(&Coordinate::new(5, 9)), Direction::S); + } + + #[test] + fn part1_test() { + let d = Day05::init(INPUT.to_string()); + assert_eq!("5", d.part1()); + } + + #[test] + fn part2_test() { + let d = Day05::init(INPUT.to_string()); + assert_eq!("12", d.part2()); + } + + #[test] + fn part1_real() { + let d = Day05::init(crate::load_input("05")); + assert_eq!("6564", d.part1()); + } + + #[test] + fn part2_real() { + let d = Day05::init(crate::load_input("05")); + assert_eq!("19172", d.part2()); + } +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 58a20c0..5258c4f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ use crate::day01::Day01; use crate::day02::Day02; use crate::day03::Day03; use crate::day04::Day04; +use crate::day05::Day05; use crate::day::Day; mod day; @@ -12,6 +13,7 @@ mod day01; mod day02; mod day03; mod day04; +mod day05; fn load_input(day: &str) -> String { read_to_string(format!("./input/day{}", day)).expect("Could not load input") @@ -46,9 +48,11 @@ fn main() { .multiple(true)) .get_matches(); - let days: Vec> = vec![Box::new(Day01::init(load_input("01"))), Box::new(Day02::init(load_input("02"))), + let days: Vec> = vec![Box::new(Day01::init(load_input("01"))), + Box::new(Day02::init(load_input("02"))), Box::new(Day03::init(load_input("03"))), - Box::new(Day04::init(load_input("04")))]; + Box::new(Day04::init(load_input("04"))), + Box::new(Day05::init(load_input("05")))]; let _verbosity = matches.occurrences_of("v"); if matches.is_present("all") {