From 37f0e837ab375879a1307adcdce8cc30f5800410 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Thu, 9 Dec 2021 10:17:08 -0500 Subject: [PATCH] Day 9 --- input/day9.txt | 100 +++++++++++++++++++++++++++++++++++++++++++++++++ src/day9.rs | 91 ++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 3 +- 3 files changed, 193 insertions(+), 1 deletion(-) create mode 100644 input/day9.txt create mode 100644 src/day9.rs diff --git a/input/day9.txt b/input/day9.txt new file mode 100644 index 0000000..c1cb27b --- /dev/null +++ b/input/day9.txt @@ -0,0 +1,100 @@ +9865456792345678921298765421012345678934995432127995456789987662134568999876534567895456999123983210 +2994359890156789992989896532929456799219876949246789349999876541023467899988727678976567898939874322 +3989298991238999989878989659898967895403989898999891298878965432123456789543214567897678987899965453 +9878987889347899878767879798767898943212498767988910197869896543264967899954323478998889376789876664 +8766856678956998767456767999656799995689987659877899976756789655456898998768636789879993245678998775 +6545344588967999854345458998545689989799976543456798865445678966597979459876545699765432156789329989 +7432123457898999966212347897634599878999895432345697654324567977998965346988676789896574237895498899 +8943234568999789984324556799547698767898789543486798865534678989999843215699789899989694356789987678 +9654448799987659875485669898956789656798678954587999976645789599798754334789899999878989456789886567 +8786569893498543976876789987967896741234567895698989998767993498679865645689999898769878997898765456 +9887678912987656987989899976899965430456689986789678999878992989569876856790198789653457789999854345 +7998789904599799798992999865678977321234789899894567987989789873456988767899986578942245699998765234 +6549897895678988659990986654569986532345699765903469876595678964597899898998765456990124568999952123 +7432956789789977546789874323467999654476789893212998765454578975989910999429974356889435979899843014 +8510346999898765434598753212346898965587894989329899854312368989878939899912965245678949898798767925 +4321245899999654329999862101234567897678943878999789765434457898768998769899854345789998789679879896 +5434556789898765698897543214345678998789532367987679876576568967956899856798766456799998664567989797 +6545787896789976987798654365769789999898721259876543987678679456346679643899876567899876543456797689 +7656898945899989876549775878878997899987654345987432198788789327234578954988987978943998666567986574 +8788929534789999987433989989989456789898765996954321019899893210145678969877898999995998777699875423 +9899219645678999876522397896594345789799979879895432534976989321235689998766779878989899889987764512 +8989398796789998982101236789989457998678998768779948549875378942476789987655568969876789994986542104 +7678999989990987654212945678979968987567987654567897698986568943567899988543459757654569895987673323 +2456988679891299865329896799567899999678992123456789987798779657798998777632469943212356799998765434 +1369876567789498765456789895466789898999987012357998976549989769979987654321367892101234598999879875 +0198985456667999876569999964345698767889996433767987895421299896567898865432456789233395997899989989 +1987654327456789997778998943236987656469876545678976989210378987678999876546567896546789876789999898 +9898954312347995398989567899197986543212989856789345678931267898789875987657689998658999765678999767 +8759865523456789199795456798989997672101298768990234789542456789898764598798999999899109754599987658 +8649876434568999987671237987878998783213499979321365679663477892949943679899879899978998743489998743 +9432987678678968097532348976567899654324689989452376889764598901239874699923469789467987654568989932 +8631098789789842198643469765456998785465678996543487999875678992398765789015998679323598795678979891 +6542359899897654349799598976567899987589789987976568921989999879459876789239897598909999987899356789 +7853457979998765456988987997678954198799891098998679930998798768969987894398765457898899998910245678 +8964568964329976879877535998789543239899943989649789799787649879998999965987654346797698899432349789 +9875678975439799998764424899899959445998959876439895698685434997987976799998765127896546789654678994 +2996789998598678939893212698999898956987898764321934987565423456896545678999877898987634899878899543 +3987897987696589323976104567898767899876529895210129896432101567997434567895998949999895689989978992 +4998986498989695474985323489987656789767312976821298789543212356789323489954589432978976789597656789 +9899894329878976569876765678998545678954324987942989678954323467891014567895678949869987993498767890 +8789789498967997678987886789298758989765434598969876569975434568932325789976989298757498921019889921 +7645678997656789789898999892129867999876546689878997879876545879545434678989899109843349432923997899 +8756789987545678998769456989234998910988687899989898989998786798756645989998778998732235949895986678 +9869898765434567987654345678945679999999798979998789999959897929767856799896565679641019899799875567 +3978959977756689798963233457899789987859899567989656998845998939878978999765434569852199787678954345 +2989543298987897679892101556998999876545999879876549876734349798989989998986323498963987697567893234 +1097432109598923598783242345987899965436799989995421965621234567992398967895404987654996546456789345 +2976543413459919679654653569876989875429988999986590954210156789101987856789512399869886431345898976 +9898865524567898999965775789965678976598767898997979875663247893219876745999423567989767210124567897 +4769986678978987689896989899876789987987656567899868986754356789498765535898994678998654323234788998 +3456798789989876576789998943989899999876548489989654398869767899599854524657789989129769834545678959 +2135699892598765465678987632399998932985432345678968239979878998987643212345699893298998765696889434 +4396989901459854323456896543989897891096521234567892101989999767896532101237998765987999876787998923 +5989878912398764212348998799876776789987430123979963312399989945987643212456789879876799987898967894 +6975567893987653105479999987654545678995321239899654323998767896798965434767899998765789998969556789 +9864348999876543235567899999643234989876542398788969439865449797899987645898998999654567899654345798 +7943239898997864346778998998767367899998653997677898949654338689910297656999567987743578999543102987 +6521098787698765489899987899976456789459769876566567898784213578954398997894329876542347898683219876 +6432987654569896579978996432987678996569898765433478989832102459768569698989013989421456999795339865 +7843499869678987678967987563598789987878987657321389569943212369877679549678929898732345689896949654 +7654987998789798989655987689989899998989876543210123498954534678998798934569999789654556798989898643 +8765976539895699996544398798879998999694989987321784567896645689899987897678987678966667987876789532 +9876987421934789987431239987668687896593999876534567898998756789789896789789876567898779876545678901 +7989873210125678998763459876544456798989891987545698969999867895698784898999975479989899996434799412 +6599965322334589439654568988632345679878790198657789657899978954987673457899867365678998987645689323 +5439986437645678998965679999741235698765689249878894545989989543499452349999954234567997898876898934 +6598997598786789346896799876432346987654578998989943239879996532598321298987632123459876769987897895 +7987698679897991249997989976545469876553456897699532198767897921987532457996543234567965457998956789 +9876598799989892398789978898656798765432567989578956987656799890197643568919755365778994356789345991 +4965429899876789987679856789987899887543569876456799876545678789987654578909979876799986467991234892 +3989999998785678976598768993099989997678678989567898765432345678999765699698989989893599878910126789 +2199878987654568968459899772134678999989789399878919874321234569329876789597696799931298989321345899 +3298967898123978957345989654545789999799891265989109783210237789539987899986545678920987599865456789 +5987656799357889543213478987679899987688910234594298654341546789998999998765434567939875476996768891 +9876545678968997657302367898998999654567891345896498765656756789897932359654325899898764345987899992 +0987858799878999898212456999897987653687992556789989898789867898776899498763216789799897657898956789 +1298878892989789949323789899656899432456789968999876989893978986565778999865397997679998767939345899 +2459999921094694339875698798645999754867999899998765678932989985434668999986468997544349898921234589 +3456796539123989210976988659534678967989656789999754569321299876323456889987989985431239979310125679 +4577987698999877921989876547623899978996545698789543998954398765412345678998999874310198765432457789 +5699898987987656799999965432105678989998634987678959897899459898937856789239910965621349976653567897 +6988769876576545678999876543212389997898745696599998756978999987656787890129899899435698999768678946 +9876556997432434567989987655424678976789896985489999545658789899867898991998798778945997898979989236 +7654445698521015998979899876435789435689987976567899431345698789878999989899654567899876777899896345 +9943236997732129879767789976545678923567898987689998910123597698989998976778943456798765656789765456 +8895349876545299765656687987676899212345999898789997893234986567999987755667892538569654545678996867 +6699656987856987664335496798787932101398987789899986789359975436899876544459931023498763235678989978 +4578967998967976543213345679898943214567986679998775678998765325798765432368892254797654357799678989 +3456798959878987654101277893999654323678974567987654999469965434697654321236794345698765689897577991 +1346789341989798794212368974698768634569765678996543894349987545698776450125689456799876799998456910 +0256893210395679887533457965899977545678986899987654789498987656789986543234678967987989899329967891 +2347894321234567997646567899934988678789398921098765699997898767893499767455789879976794978919878989 +7658999459495678999857678998923598789891239999239879797896409898931239876566791998765623769901989878 +8768998998989789999969899567899699897990198978999998986789212999540123987679890987654104457892398767 +9979987997678998979878943457968987956789987866789876765678923987321234599989999996543212398943987658 +0989876789567897569989632123459876545698896745998765653589899876595445678997898987985323689956988734 +1998954453456789498996545234678995434987654235987654212456789987986556799656987799876434567899879823 +9876543212345679357987654345789986524499875123598764343457897898997677897649876653987895678989954312 +2998754523456789267999865856892987612398765435679875654667976549098788985434995432198976789679875324 +1239895434579890178923988767921098201239976576799986765679989632129999876545986543249987893498765435 diff --git a/src/day9.rs b/src/day9.rs new file mode 100644 index 0000000..6baec54 --- /dev/null +++ b/src/day9.rs @@ -0,0 +1,91 @@ +use itertools::Itertools; +use std::collections::{HashSet, VecDeque}; + +pub fn day9() { + // let input = r#" + // 2199943210 + // 3987894921 + // 9856789892 + // 8767896789 + // 9899965678 + // "#; + let input = include_str!("../input/day9.txt"); + + let grid = input + .trim() + .lines() + .map(|l| { + l.trim() + .chars() + .map(|c| c.to_digit(10).unwrap()) + .collect::>() + }) + .collect::>(); + + let grid_slice = &grid.iter().map(|row| row.as_slice()).collect::>(); + + let minima = find_local_minima(grid_slice); + let sum: u32 = minima.iter().map(|(row, col)| &grid[*row][*col] + 1).sum(); + println!("p1 score sum: {}", sum); + + dbg!(find_basin_size(&(0, 1), grid_slice)); + dbg!(find_basin_size(&(0, 9), grid_slice)); + + let basins_product: i32 = minima + .iter() + .map(|pos| find_basin_size(pos, grid_slice) as i32) + .sorted_by_key(|count| -*count) + .take(3) + .product(); + println!("p2 basin score product: {}", basins_product); +} + +fn find_local_minima(grid: &[&[u32]]) -> Vec<(usize, usize)> { + let mut res = vec![]; + let rows = grid.len(); + let cols = grid[0].len(); + for row in 0..rows { + for col in 0..cols { + let cur = grid[row][col]; + let up = row == 0 || grid[row - 1][col] > cur; + let down = row == rows - 1 || grid[row + 1][col] > cur; + let left = col == 0 || grid[row][col - 1] > cur; + let right = col == cols - 1 || grid[row][col + 1] > cur; + if up && down && left && right { + res.push((row, col)); + } + } + } + res +} + +fn find_basin_size(pos: &(usize, usize), grid: &[&[u32]]) -> usize { + let rows = grid.len(); + let cols = grid[0].len(); + + let mut queue = VecDeque::from([*pos]); + let mut considered: HashSet<(usize, usize)> = HashSet::new(); + + while let Some(p) = queue.pop_front() { + let height = grid[p.0][p.1]; + if considered.contains(&p) || height == 9 { + continue; + } + considered.insert(p); + // println!("({}, {})", p.0, p.1); + if p.0 > 0 && grid[p.0 - 1][p.1] >= height { + queue.insert(0, (p.0 - 1, p.1)); + } + if p.0 < rows - 1 && grid[p.0 + 1][p.1] >= height { + queue.insert(0, (p.0 + 1, p.1)); + } + if p.1 > 0 && grid[p.0][p.1 - 1] >= height { + queue.insert(0, (p.0, p.1 - 1)); + } + if p.1 < cols - 1 && grid[p.0][p.1 + 1] >= height { + queue.insert(0, (p.0, p.1 + 1)); + } + } + + considered.len() +} diff --git a/src/main.rs b/src/main.rs index d51c103..9fd316e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,7 +8,8 @@ mod day5; mod day6; mod day7; mod day8; +mod day9; fn main() { - day8::day8(); + day9::day9(); }