2021: day09: part 1

This commit is contained in:
Antoine Martin 2021-12-09 19:39:35 +01:00
parent b5c4b72864
commit 6eb8041362
5 changed files with 241 additions and 0 deletions

100
aoc2021/input/day09.txt Normal file
View file

@ -0,0 +1,100 @@
8969799987646798965432975435334567987976999867976794468999979759865767896545699865678952123899325456
7658678998434597654321984320123458976765789998965432367998968998754556789434987654489543535698912349
6243457899325679997620195431934569765654667999993101246796856997643245679759865443356954656987894498
4102345678912998789531297659895978954213456899874512659965239876432134578998754321267899877976789987
3212466989109887678942989797659799542102345798765423867894103987543026799989866532345678999765469896
4323487893299795489899978987947689654243496789876864988943212498654135999967987765466789987654398754
5694698999987654398788967895434589879359989999987879999994467598795276789756798876567895699873219865
6788799998998975976567456899598678985498879898798989865879978939876987993145899987879954598765102987
7899899897989989875432345678998789897987968799659197654756899857989899921034999898989433459854213698
8913998766779999964321234569999897789876754678943296543434998769997797892129898789995321298765434569
9101987655767989875732345679987946689654343469764987542127899898765656789298797678976510159977675678
3212396543256878986893478999876434596543212378965698321016789999854245991987664599987621245698789789
5433495432145767897954567896985423689954301299986986432125899998762127892976553469998753457789899892
6567989543023456798966878994597434567896212989897998764234678987654679999897432348999864567997999953
7699978932124569899987989789986545678997329878798969976656789998785793599789645667898965989456789867
8988767993237678998998995678998698789865498765689654399787898999887975987689956788977899992398999879
9976458789398899687899234567999899899978987654569543219899956789998989896579899899866458943989109989
9854345679479976556954346788998999999989876543468965323987548999969498765466788956954367969878998797
8765456796567895434699459899996878998694987742556896439876439999854329654354567899875167898657897656
9896577897679966724978998943985456896513498651345689546989998898765439843212456789984356789346789843
5998678998789653219866987899876368954323489710556898768998787789876898756533568899995679891245898932
4299789349898742109654346798765458976535679921237999879867546678987989987654679978976789910234567891
5989894234969876298743234569878567899796798545346899998653434569399876599785789567987898929345688932
9878943123459865459652127999989678978998987655456789129742129679210997679897995456798987898957899543
4965431012567986798764335679598789469899998767767891019843298999429698789998932348899876767899999654
3986949143479997899865466789409892346789979879878992123969976578998539997899321467999765646978998765
2399898954567898999876567893219921235798766990999789235698895457997623456921932346998654334567899978
1299767895789999999987678999398633896899954321235695476987789598998735797899894459876543212456899899
2988956799899998989998989798976545789999896532346789569986679679439987898986789667987654201268999798
9876545788987887679899897657987656798998789987656799698785458994321299999575678978998764312349987677
8787434867976544556797623546698767987887678999767978988654356789490123985434567899799876543456997536
9643323456895433545679510134599879876765567899878969876543234899989349876423468976567998954567895215
7432102568954321234595431235678998765634345678989456998754345987879956994312469965456899996789954324
6543212349975410123489545676789769874321234789790365679976576896567898984203457896597946987898766534
7695323457897521236679686787896656965454345689621234567987687932498959876412679989989532498939878745
8986445569998934345689899998955549877965678796542347678999798940989942986567897678978901359012999987
9997556978969765456897998899643435988876789898753456789999899759878891987879976564568992459223989999
9998967889349876577896767789532123999998898999897598999988959898767790298989985323456789998939878998
9879878993212987698965656679921039876439967899999979899876545987656689349896546012367899876899767987
8867989854623999999873245567892134965323456789998765789987632496545459998765432123456998765698959876
7656799769539897895482133456954379854212597993987653999898521569632367899979643236567898754987939984
9545678998998765989321012567895459763102379932199654569765437698743458932398654387989987543656898765
8936567897899874578932123456976598765213467891034987698996548899654567891019767898999876521246789897
7623468976799765799543438967898679984324579932123498997989679998765678942423989999978988430134899998
5434578985679878997654567898939789995445698965349569876678989899876789759994596598769877321475678999
6559689643456989298775678999029895987576987896467978965457899782989899998789789429898765432386799989
7798789432345690129976789998939974599999896889878999784346998651296989876598993219989876743457898878
8989895431258789245987899987898953459878784978989989653245696542345679999457894398879987857567947566
9877987646779898659998999876567994979967643467899878964126789655456989998379965976569898967679434345
9965499867895989798999598765476789398756532456798967893235899766967998987567899879456799298989321234
9876789978954878987995459654345891296543101236987656789345678979899896798679998768345692129695433545
1988899989763567896889698743236892989754752345698545678956799998789765698789876753238789234569546656
3499949999874878945779987632123999768969643467899234589999899876578954329999875432124679945698756767
9989237999996989234567976431019888943498955989998545678989906987689965410199764321012989896799999879
8978956789997892146678986542239767832487996792987656789679215698896894321989875754123456797899989992
7867897899989921012349597953398756721276789891098767896598924599965789939878996543254597898998978991
5658998979876432124692398965986543210345996999239878965487895987654597898965987654765678949987959889
4234789767987543235789459896798765321267894878945989874356789998783456987954599875676989657995349778
2123679854987674347896569789999876543458943467956999995245894987632969876843456996787899969986234567
3012568966998989498987998677899987754567892458969899874348943986549898765652345987998999898942123679
6123456799879996579999899576789999869678943467899789965457921098798789854321234598949998677991014589
5434767959767987898998765435699987998789765598923679876767892349987698765210349899659986566789323899
8545679943854598986987654324589996689896986679013459989888999959876579894321235789898975345678946789
7676899892123999875698763215679965456965498793223598794999998799975467965452347999987654234599659899
8989986799019887654679974323467896568942349954334987653234987678894359879643458969876542123689898988
9798865678998765712578985454598987979321257895455798852109895467789234998754569653999892012567987877
7697654367897654323456798579689898989910969999579999743219654347689945679967679999549764123456896556
3598765456998768974567987689795679099899898997678987654498653201567896989898798878934965236587974449
2359987767999899765978998999964589298787656789989398765789765443489989899789897767949874347678953237
1491299879999999987889459329899999987654745894590249876899899865679876784699976456899985678789654126
0989901989789989998991399439777899898543435789931399987934999876898765633987895367899876799896543235
9877899995678978989532578998656998797632124567893989998923498989999874012346789246987989898987655345
8766798989789469878943789879546899654321012978999878999212997796799982178968992134976591997899796656
9954547878992399967899899865434678998732129899998769899929876565689875357899843239899432395698989768
7653235669991987856798999876215789987654239789987657789899765373499876567898765498798954986987878979
8762124456789996543467894989104589998768998678986545678789876212345987688959876569657995999876567999
9989012347899865432356993298913478999879876548995434345678968101356799799545987898745789865985456789
6598924456895996421245689987897567892989998756789621257989543212456893987634598999658999654986687899
7987899568934987840234567896789978921399899987898530968999964566567892396723679998767898953199789989
9876798979924987656495888934567899210198789898987649899999898788689910975435678979878997899019899975
7675356899899898767686789123679954391297698769999789799898789898799921296586789567989876798923989764
6543245698798789879899899019789995989987569543935998689765679909899892397697994345698765867894578953
8432136987657678999910998998998789778943468999899019789954234912998789998998943234989544556895678942
7543239876543457989422997867997643567892979679678929899892123893989689789989432109875432347989989431
8664345975442345678999876656789432456789895434569439998789234679876597678976543499964321235679894320
8798459864321256899987655346896563567898789212497598687679345798765326567897654989984310199998789491
9897568995438767898998643238987678689987679101789987543568996987654215458998775979996532987877578989
9987679986549878987976543129998989799986568932679876542356789099873101299439989868987543976966457577
8998790197678989756797643256899999899865457894569867421867992198764323489321098756597654965452323456
7679891998789691234598765345678923989954366789697654320378943579885654678999987643469869876321012345
4567939879896542456999975457789019878942134898789865621247894567986965699678996532398979876432123456
3459329765998653567895986568993139765899012979899876732456789678987876896599989421297989998673234568
5678909984329764678993497679954397654678923567943987654567997999799987897987678932986794569984545778
8799998965679889889989598989795986543567994578992399876799236789654398999896568943975523679995656789
9989767899789997993978999895689997562456789989989976987890145899876789998768456999854302368987789894
9879356789899876432767898764789775431634578899879765698991236799987896999654397789763213459998993912
8656244678998765321545987653459654320123456789767954019789445678998945898743235678954424668999542103
7542133569899878510126976432398797431835668892456892124689556889329236789655656789765634569987543765
6531012456789996431239954321239986545646799986587893776789678993210127898767787899879745678998955897
6542123568899987544398765510123497656656789987678954567898799654431338999978898910989656789209876789

View file

@ -0,0 +1,5 @@
2199943210
3987894921
9856789892
8767896789
9899965678

133
aoc2021/src/day09.rs Normal file
View file

@ -0,0 +1,133 @@
use std::fmt::Write;
use anyhow::{Context, Result};
const INPUT: &str = include_str!("../input/day09.txt");
pub fn run() -> Result<String> {
let mut res = String::with_capacity(128);
writeln!(res, "part 1: {}", part1(INPUT)?)?;
Ok(res)
}
fn part1(input: &str) -> Result<u64> {
let height_map: HeightMap = input.parse()?;
Ok(height_map
.low_points()
.map(|(x, y)| height_map.risk_level(x, y))
.sum())
}
#[derive(Clone, Copy)]
enum Neighbour {
Up,
Down,
Left,
Right,
}
impl Neighbour {
fn apply(&self, x: usize, y: usize, width: usize, height: usize) -> Option<(usize, usize)> {
match self {
Neighbour::Left if x > 0 => Some((x - 1, y)),
Neighbour::Right if x < width - 1 => Some((x + 1, y)),
Neighbour::Up if y > 0 => Some((x, y - 1)),
Neighbour::Down if y < height - 1 => Some((x, y + 1)),
_ => None,
}
}
const ALL: &'static [Self] = &[
Neighbour::Left,
Neighbour::Right,
Neighbour::Up,
Neighbour::Down,
];
}
#[derive(Debug)]
struct HeightMap {
heights: Vec<u8>,
width: usize,
height: usize,
}
impl HeightMap {
fn low_points(&self) -> impl Iterator<Item = (usize, usize)> + '_ {
(0..self.height)
.flat_map(|y| (0..self.width).map(move |x| (x, y)))
.filter(|&(x, y)| {
self.neighbours(x, y)
.all(|(nx, ny)| self.get(x, y) < self.get(nx, ny))
})
}
fn neighbours(&self, x: usize, y: usize) -> impl Iterator<Item = (usize, usize)> + '_ {
Neighbour::ALL
.iter()
.copied()
.filter_map(move |neighbour| neighbour.apply(x, y, self.width, self.height))
}
fn risk_level(&self, x: usize, y: usize) -> u64 {
self.get(x, y) as u64 + 1
}
fn get(&self, x: usize, y: usize) -> u8 {
self.heights[y * self.width + x]
}
}
impl std::str::FromStr for HeightMap {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self> {
let mut heights = Vec::new();
let mut height = 0;
let mut width = None;
for line in s.lines().map(str::trim) {
let line = line
.chars()
.map(|chr| {
chr.to_digit(10)
.map(|digit| digit as u8)
.with_context(|| format!("cannot parse char {} to digit", chr))
})
.collect::<Result<Vec<_>>>()?;
if width.is_none() {
width = Some(line.len());
}
height += 1;
heights.extend_from_slice(&line);
}
Ok(HeightMap {
heights,
width: width.context("0 lines parsed, width never computed")?,
height,
})
}
}
#[cfg(test)]
mod tests {
use super::*;
const PROVIDED: &str = include_str!("../input/day09_provided.txt");
#[test]
fn part1_provided() {
assert_eq!(part1(PROVIDED).unwrap(), 15);
}
#[test]
fn part1_real() {
assert_eq!(part1(INPUT).unwrap(), 522);
}
}

View file

@ -8,3 +8,4 @@ pub mod day05;
pub mod day06; pub mod day06;
pub mod day07; pub mod day07;
pub mod day08; pub mod day08;
pub mod day09;

View file

@ -10,6 +10,7 @@ use aoc2021::day05;
use aoc2021::day06; use aoc2021::day06;
use aoc2021::day07; use aoc2021::day07;
use aoc2021::day08; use aoc2021::day08;
use aoc2021::day09;
fn main() -> Result<()> { fn main() -> Result<()> {
let days: &[DayFunc] = &[ let days: &[DayFunc] = &[
@ -21,6 +22,7 @@ fn main() -> Result<()> {
day06::run, day06::run,
day07::run, day07::run,
day08::run, day08::run,
day09::run,
]; ];
aoc::run(days) aoc::run(days)