From 35ef072d7f5cd7180e8c158b1ab1d3719a54271f Mon Sep 17 00:00:00 2001 From: Bill Thiede Date: Wed, 8 Dec 2021 21:55:55 -0800 Subject: [PATCH] Day 9 part 1 solution --- 2021/input/2021/day9.txt | 100 ++++++++++++++++++++++++++++ 2021/src/day9.rs | 138 +++++++++++++++++++++++++++++++++++++++ 2021/src/lib.rs | 1 + 3 files changed, 239 insertions(+) create mode 100644 2021/input/2021/day9.txt create mode 100644 2021/src/day9.rs diff --git a/2021/input/2021/day9.txt b/2021/input/2021/day9.txt new file mode 100644 index 0000000..1ed5ac3 --- /dev/null +++ b/2021/input/2021/day9.txt @@ -0,0 +1,100 @@ +9976786789439313678999989767678999865435679398654323678999987654313468954569865334568916987643236789 +9754395678998754599898978954567999976556789498775413478998798743203457893479973212479425698432145799 +9843234589899866698786767943456789987687899987653104567897659957312368931298984596599934679549234689 +8654785789789979897645459892967895698798999999873215698958349876433456892987899989989895998998965899 +9865696895678989999731346799898954569999888921954524899542129986556767999976998679767699767897896789 +9876789934799998997890235689799962978999767939878436789674398898668979998865797598755589656656897994 +9997898956789987976531345679677899899987656899989547994989987798779893987654679459543478943348998923 +8998987997999995987632456789545698789498545689999759213498986649899754597643812398656569651267899434 +7999896889998754698743458997324789579597934778923978904597665431998996997532101259769778953456897645 +6798765567899643987654599765437994468986724567910989895689543210127789876543312345978989764567979967 +4987654378989756998765689976546792399654212389891296789798787631435678987654443656989999875678967898 +2098754235678999779876797987656910987543101245789945679899976543576899998765564778999932996789458929 +3989976127889987667997896798767891987654424699896832398932987656688978989896685889568899869892349310 +9868997346999875454598945699898932398765536789995431987893498767899769875959786893456789654901258921 +8754398757997654323579436989989693999896645892189546976789999989923459974349897932365696543212347893 +6543239898996543212467949876976579899987756943478969875656898694304598763201998921234789876423456789 +5432123999987954323678998765432455689299897894567899764348976543212797654512989432345998765434567892 +7521012999899876549789999897621234579109998985678998654237898754344598865623976543456899876545679921 +8633439878799987899897899998510123678998789976899899893156789765998789998734989954987932987678789540 +9864598765689998965956798679323234569876577897916789989345678989899893239845698899898921099989898432 +9998679854345999654346689598764345779765466789434598978976789998799932134956987645689542134599987656 +8998798943239876543235595439895456989887345678949987956897899987679543235977898634579763289998799867 +6899987654945998754123459910976567899996576789298976745679999896568954345989999548678975467896549878 +5979898999899986543234567891297679999987897890197545236798998765467895456791987656799987579965434989 +4656789889788998767349679999989989998799998989975432124567899865346896569942998979989998998943219898 +3546798775667899898457889998967899989654349678985421013456792964236789998899879998879899987894698767 +2124999654556999999578999887856789978993244569876534124567891098145698766679965987768798986999898756 +4019886543445678998789498656745689869789123456998975335688989987234897655567894976543567895878986545 +2129765432137999999894349743136789754698934567899996746899978976457986543456932987657678944669875436 +7439876543446789987953219865347996543567897678985987968999767896569875432345891099768989323456996557 +6545998655567896896432101965468987662378998989864699879987658899678987564676792943978993101245987698 +9656789986878995987643229877599299831499349899943012989976545798989898665687899891099765622456798789 +8967893297889689998784346987689123910976456789652127899965434567898799897798989799999865436567899893 +7898989098993568999896598998891019899897887899754335789854323459998678998929978677892987545678978932 +6989878999012456789998799989989129798789998979896467899765401568892489789219865566991297656789769991 +5978567896434568999999988664578998654698999567987568987654312456791336678997654455789998769893456989 +4564456789565689989899977553467976553487893459998679598776534587890124569898653234567899899932499879 +3412367998798799976799765432149875432346892467899795439987659698989235879679765165689998989543989967 +2101267899899899865789979574235996543556921235679899920398878969778956989469981012357897678999867898 +3213458902942998654799988765346987965698910126896998891239989754567897892398792123968958569987658919 +4323667899431299865678999875467899879899991298945987789645997643456789954999653246799542459876549201 +6454798988949987978789543987598923989987789989539976567959865432347899999898754757898931345998678912 +7565899567898765989999432399999212399876569878998765458967987541767979889769875768967890156999789323 +8787893458999994395678940998798993569765498567897654378998998652378967678943986779756799299899996547 +9898984567899989234567899895576789679854376456899989234989976543578954587892197889549898986789769756 +8999765698969878987679999784445689798765212345698762134567897665689543456789098994338987654678959897 +7689878789757767898991987643234778949854323456798743457789998778789642345678999543227699865789244998 +6567989897643456789210299753124569534999954567987654568899899899999765467889987654103456986990123469 +5478999976532345689321398921015678965987895678998865679945799998999876989996798793212568998932645567 +4369898764321234789932987932124789976996799799879978795634568987899987896765979984324579679943787699 +5456798765410123567893996893245899989875778986565989894325689976799898965434769876458689557899998789 +6568899879321235778999875789359989898764567897454598965434798765689769996323459987568789445678999897 +7679932998932446799987754568998766789832456779213457896545679874579943987899968998789893234789678965 +8998921987999967899876543479899854698901234568902345679656789863467892399998799659899932145796567973 +9867899896987899998765432456789783987892345689214696898767998654567999457987688943998643466965459892 +8756798765695678999897551235699542356789466895438789999879979865678978969896567891239894997896569789 +4348898654254768999959652357898421368996598987549899989999867979789767998765456789349989789998879675 +2123998763123456789239743568987210156987679297656789878987656899897659798765345695498878678899998423 +3239129864346579890126987679875431234898789198987997569876543988987545679892129989697666567789397674 +5498998765457678989345999893986532456789999999798998678998732567896534569989398879986553435679298786 +6987689986678799778999878912976543467895667894569989799998643488965423498878987969865432324778999897 +9876579997989891566789967109898654567973456789994679987987656567893212987569976656986541013567899998 +9765468998999932345698754398769767678962347999873598976598767779984329765467965545987656723459999999 +7654357899989993996789965987659898889653458998762987654349898899876498654389894321299867936578987899 +6543246789879879789898996986543969999784567897654998743236999999987569865234789210156978547789476789 +6432135678967865678987989987542355678996788969879876574135789987598997973123579931345899658892345699 +7687548789656654599876767895431234567899899356998765431013892393469986521034567892456789867901557789 +9798656899545433987654456987650125678967943249659896432354989989578987432145679954667898979212678994 +9898787998621012976512345798761334789458954998949999563765679878999976565358789976898997989954569313 +8999998999732135997433558999873547997378999876797698754876798767989989987467898989929876896796798901 +7899899986543249876547667898984756895489987945679549865677899654878990298998957599949765765689997899 +6789763298854658997659879987899867896999876435678939978788998743456891999979546467899854234567895998 +5678943149765867899792989976789998979899987549899598989899239654789979799868932345679972123478924987 +4789432027986878998910996765678999456789898956965467899999198765689565689657896566798763244569109876 +9899843456797899987899875654567892345798779767895345678988989876789434798798997678987654559789299954 +9999754568998998976789654563479954467997659878943234589967979987996545899899698789899765667899987832 +9998765678919987565699943242348976778976543989542199789856567699397696799943569898759876779999876521 +8989876789109875454689893101567898989975432397659988998743434569298787898759699999643998896598765430 +7976989893298755323456789232456789090986941098798767997632129678969899969898988998932449987439875421 +6895492994398943212345795467767892191999892149899656789547298989654993456987776897891234598321987632 +5999910989987653202456789578978943989898789236987646797656956996532389767996545456910123987532398943 +4687899875499854578569897989989659878767679345998334689899897898675478979885432345891435798543459654 +3496789986799875989689965395699899767654578959886123899989799999896567898765421256789545899866599975 +2345678997898976798798754234579987654323467998765335789975639878987679999854210168998766789978789989 +1456789998966987899898655123678999843212345689976547999764526567998989988975432259789987893199899899 +0267899869445698999989632016789654954301386797897678998653212349999899867997546345678998992098965789 +9469923954236789998679542124578979865716577896779989998632101239877645456789667456799659789987654567 +8999919878997999997568993295689899876897679954567896987543212349765432347898778568892345694398767678 +7887899989889999876457789989789789998998789343679964597654343598654321236789889678901299789459998789 +6576789999768798765354699979998679789659893212489873298785764789965446545899998799999987999567999893 +5454678988657669989212989767897578679943954401678994569876989999876557656999029891987686898978998942 +6213469976543457898929876456896434578894975626899789978989899997998969797898998932396545657899997653 +7534578954332598997899954345965323456789876545679679899998789896989979898967987543987432346998789767 +8945789764101239876799875697894212399899998666789456789989679765879989999656798654987621499887679988 +9767897653214398785789976989976201987989109877891345679765578954567898989545659765699710987674567899 +9878999764323987674567897978943219896579299989943456998674458943456967878931349889799831298543456789 +6989789975439876563456999867894329785498989998657569876533267932678955467893456992987542975432545699 +5497569876798765442499998758965498674356678939978998975420157893489543248954567891598659864321234568 +4323456988999654321378959967976987543234568921989987654321345789599432139896689932398769765434656899 +5435567899998766562457949878987898656045679210191099865432467897678945546789796546459879876545767899 diff --git a/2021/src/day9.rs b/2021/src/day9.rs new file mode 100644 index 0000000..49a7422 --- /dev/null +++ b/2021/src/day9.rs @@ -0,0 +1,138 @@ +//! --- Day 9: Smoke Basin --- +//! These caves seem to be lava tubes. Parts are even still volcanically active; small hydrothermal vents release smoke into the caves that slowly settles like rain. +//! +//! If you can model how the smoke flows through the caves, you might be able to avoid it and be that much safer. The submarine generates a heightmap of the floor of the nearby caves for you (your puzzle input). +//! +//! Smoke flows to the lowest point of the area it's in. For example, consider the following heightmap: +//! +//! 2199943210 +//! 3987894921 +//! 9856789892 +//! 8767896789 +//! 9899965678 +//! Each number corresponds to the height of a particular location, where 9 is the highest and 0 is the lowest a location can be. +//! +//! Your first goal is to find the low points - the locations that are lower than any of its adjacent locations. Most locations have four adjacent locations (up, down, left, and right); locations on the edge or corner of the map have three or two adjacent locations, respectively. (Diagonal locations do not count as adjacent.) +//! +//! In the above example, there are four low points, all highlighted: two are in the first row (a 1 and a 0), one is in the third row (a 5), and one is in the bottom row (also a 5). All other locations on the heightmap have some lower adjacent location, and so are not low points. +//! +//! The risk level of a low point is 1 plus its height. In the above example, the risk levels of the low points are 2, 1, 6, and 6. The sum of the risk levels of all low points in the heightmap is therefore 15. +//! +//! Find all of the low points on your heightmap. What is the sum of the risk levels of all low points on your heightmap? +//! +//! + +use std::{ + convert::Infallible, + fmt::{Debug, Error, Formatter}, + num::ParseIntError, + ops::{Index, IndexMut}, + str::FromStr, +}; + +use anyhow::Result; +use aoc_runner_derive::{aoc, aoc_generator}; +use thiserror::Error; + +struct HeightMap { + width: usize, + height: usize, + pixels: Vec, +} + +impl HeightMap { + fn low_points(&self) -> Vec { + let mut pts = Vec::new(); + for y in 0..self.height { + for x in 0..self.width { + let c = self[(x, y)]; + + if (x == 0 || c < self[(x - 1, y)]) + && (y == 0 || c < self[(x, y - 1)]) + && (x == self.width - 1 || c < self[(x + 1, y)]) + && (y == self.height - 1 || c < self[(x, y + 1)]) + { + pts.push(c); + } + } + } + pts + } +} + +impl Index<(usize, usize)> for HeightMap { + type Output = u8; + fn index(&self, (x, y): (usize, usize)) -> &Self::Output { + &self.pixels[x + y * self.width] + } +} + +impl FromStr for HeightMap { + type Err = Infallible; + + fn from_str(s: &str) -> Result { + let rows: Vec<_> = s.lines().collect(); + let width = rows[0].len(); + let height = rows.len(); + let pixels = rows + .iter() + .flat_map(|row| row.as_bytes().iter().map(|b| b - b'0')) + .collect(); + + Ok(HeightMap { + width, + height, + pixels, + }) + } +} + +#[aoc_generator(day9)] +fn parse(input: &str) -> Result { + Ok(input.parse()?) +} + +#[aoc(day9, part1)] +fn part1(input: &HeightMap) -> Result { + Ok(input.low_points().iter().map(|b| (*b + 1) as u64).sum()) +} + +/* +#[aoc(day9, part2)] +fn part2(input: &[u64]) -> Result { +todo!("part2"); +Ok(0) +} +*/ + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_part1() -> Result<()> { + let input = r#" +2199943210 +3987894921 +9856789892 +8767896789 +9899965678 +"# + .trim(); + let hm = parse(input)?; + assert_eq!(hm.low_points(), vec![1, 0, 5, 5]); + assert_eq!(part1(&hm)?, 15); + Ok(()) + } + + /* + #[test] + fn test_part2()->Result<()> { + let input = r#" + "# + .trim(); + assert_eq!(part2(&parse(input)?)?, u64::MAX); + Ok(()) + } + */ +} diff --git a/2021/src/lib.rs b/2021/src/lib.rs index 90ee83a..6c16e12 100644 --- a/2021/src/lib.rs +++ b/2021/src/lib.rs @@ -6,6 +6,7 @@ pub mod day5; pub mod day6; pub mod day7; pub mod day8; +pub mod day9; use aoc_runner_derive::aoc_lib;