ソースを参照

day 9 w/o rust and day8 bench rust

metya 4 年 前
コミット
6d9f98608f

+ 7 - 1
.gitignore

@@ -23,4 +23,10 @@ __pycache__
 /target
 
 # MacOs
-.DS_Store
+.DS_Store
+
+# Added by cargo
+#
+# already existing elements were commented out
+
+#/target

+ 7 - 0
day8_seven_segment_search/Cargo.toml

@@ -7,3 +7,10 @@ edition = "2021"
 
 [dependencies]
 counter = "0.5.2"
+
+[dev-dependencies]
+criterion = "0.3"
+
+[[bench]]
+name = "my_bench"
+harness = false

+ 10 - 0
day8_seven_segment_search/benches/my_bench.rs

@@ -0,0 +1,10 @@
+extern crate day8_seven_segment_search;
+use day8_seven_segment_search as day;
+use criterion::{criterion_group, criterion_main, Criterion};
+
+fn ben(c: &mut Criterion) {
+    c.bench_function("day8", |b| b.iter(|| day::solve_p()));
+}
+
+criterion_group!(benches, ben);
+criterion_main!(benches);

+ 57 - 0
day8_seven_segment_search/src/lib.rs

@@ -0,0 +1,57 @@
+#![allow(dead_code)]
+#![allow(unused_variables)]
+use ::counter::Counter;
+use ::std::collections::HashMap;
+
+#[inline]
+pub fn solve_p() {
+    let input: Vec<&str> = include_str!("../input.txt").lines().collect();
+    let example: Vec<&str> = include_str!("../example.txt").lines().collect();
+    let canonical_pattern = "abcefg cf acdeg acdfg bdcf abdfg abdefg acf abcdefg abcdfg";
+    let counter = canonical_pattern.chars().collect::<Counter<_>>();
+    let wires: HashMap<_, _> = canonical_pattern
+        .split_ascii_whitespace()
+        .enumerate()
+        .map(|(ind, code)| (get_key(&code, &counter), ind))
+        .collect();
+
+    let part1 = input
+        .iter()
+        .map(|line| {
+            line.split_once("|")
+                .map(|(left, right)| {
+                    right
+                        .split_ascii_whitespace()
+                        .fold(0, |acc, code| match code.chars().count() {
+                            2 | 3 | 4 | 7 => acc + 1,
+                            _ => acc,
+                        })
+                })
+                .unwrap()
+        })
+        .sum::<usize>();
+
+    let part2 = input
+        .iter()
+        .map(|line| {
+            line.split_once("|")
+                .map(|(left, right)| {
+                    let occurence = left.chars().collect::<Counter<_>>();
+                    right
+                        .split_ascii_whitespace()
+                        .fold(String::new(), |st, code| {
+                            st + &wires[&get_key(&code, &occurence)].to_string()
+                        })
+                        .parse::<usize>()
+                        .unwrap()
+                })
+                .unwrap()
+        })
+        .sum::<usize>();
+    // println!("The asnwer of part1 is: {}", part1);
+    // println!("The asnwer of part1 is: {}", part2);
+}
+
+fn get_key(code: &str, counter: &Counter<char>) -> usize {
+    code.chars().map(|ch| counter[&ch]).sum::<usize>()
+}

+ 8 - 4
day8_seven_segment_search/src/main.rs

@@ -2,8 +2,16 @@
 #![allow(unused_variables)]
 use ::counter::Counter;
 use ::std::collections::HashMap;
+use std::time::Instant;
 
 fn main() {
+    let time = Instant::now();
+    solve();
+    let end = time.elapsed().as_nanos() as f64 / 1_000_000.0;
+    println!("time {:.4} ms", end)
+}
+
+fn solve() {
     let input: Vec<&str> = include_str!("../input.txt").lines().collect();
     let example: Vec<&str> = include_str!("../example.txt").lines().collect();
     let canonical_pattern = "abcefg cf acdeg acdfg bdcf abdfg abdefg acf abcdefg abcdfg";
@@ -54,7 +62,3 @@ fn main() {
 fn get_key(code: &str, counter: &Counter<char>) -> usize {
     code.chars().map(|ch| counter[&ch]).sum::<usize>()
 }
-
-fn check_example(example: &Vec<&str>, part: &dyn Fn(&Vec<&str>)) {
-    part(&example)
-}

+ 8 - 0
day9_smoke_basin/Cargo.toml

@@ -0,0 +1,8 @@
+[package]
+name = "day9_smoke_basin"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]

+ 107 - 0
day9_smoke_basin/README.md

@@ -0,0 +1,107 @@
+--- Day 9: Smoke Basin ---
+--------------------------
+
+These caves seem to be [lava tubes](https://en.wikipedia.org/wiki/Lava_tube). 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:
+
+
+
+```
+2*1*9994321*0*
+3987894921
+98*5*6789892
+8767896789
+989996*5*678
+
+```
+
+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?*
+
+
+--- Part Two ---
+----------------
+
+Next, you need to find the largest basins so you know what areas are most important to avoid.
+
+
+A *basin* is all locations that eventually flow downward to a single low point. Therefore, every low point has a basin, although some basins are very small. Locations of height `9` do not count as being in any basin, and all other locations will always be part of exactly one basin.
+
+
+The *size* of a basin is the number of locations within the basin, including the low point. The example above has four basins.
+
+
+The top-left basin, size `3`:
+
+
+
+```
+*21*99943210
+*3*987894921
+9856789892
+8767896789
+9899965678
+
+```
+
+The top-right basin, size `9`:
+
+
+
+```
+21999*43210*
+398789*4*9*21*
+985678989*2*
+8767896789
+9899965678
+
+```
+
+The middle basin, size `14`:
+
+
+
+```
+2199943210
+39*878*94921
+9*85678*9892
+*87678*96789
+9*8*99965678
+
+```
+
+The bottom-right basin, size `9`:
+
+
+
+```
+2199943210
+3987894921
+9856789*8*92
+876789*678*9
+98999*65678*
+
+```
+
+Find the three largest basins and multiply their sizes together. In the above example, this is `9 * 14 * 9 = *1134*`.
+
+
+*What do you get if you multiply together the sizes of the three largest basins?*
+
+

+ 5 - 0
day9_smoke_basin/example.txt

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

+ 100 - 0
day9_smoke_basin/input.txt

@@ -0,0 +1,100 @@
+5678998989432198943298876799876586789998999434988989999876544345789987654545678931299765458679432456
+4556987678949987899097655679767345678987898949876579899987432134889987653237889542989654323488921347
+3245696569298765678976544598653234567896567899885467799876598245678998542126898769878943212367892356
+7656789689019654569895432987743125678923456998764345689987987656789987632015789998767932103456789969
+8767898789298965698789321296532012789912367897651234993398999867897898543234567897657899344868999898
+9898909899987976987679434987432123567893458976543349892109234978935987654945678956545888956779019787
+2999312999876899876548976798543256798954578987985498789290125989124698878876789545434677897892197656
+1098929989765678987537897899674345689765989299876989687989234998995789989989895432123456998999976545
+2987898763234567895426899999965457999879999101999878576978949876789891096593987643034587899698765434
+3496987654345979971015678989876598943989898999998765465767898765678992987432398854234567934569876745
+4985499795659898965434599575989699432396797878999874323456789654567989989321239954346789123456987659
+9875324989798787896545789434798789101234986767899983212345896543459878976310198765457991014569999868
+9766219878989656789659897321679893212379875456798432101236998532598767895421239876678962195998941979
+9854398768878968998767896432567954523459864323987543212456897431999656789532345987789653979896532989
+8765498656867978979898998543459995745569876434598798654567896569898545678945478998999969867789549899
+9876986545457899656979999876598989856978987945679898767878987798767634599999567899019898656678998789
+9989978432345898789767899987987679997899199896789979878989498987656424989987678999198776547578999678
+8998764321256789995456789999976567989921099798996568989595349998843213577898789878998652123469996578
+7987653210127897654365898998765465678932989699765439995430157898632102356999896569986541012345987989
+6398865432238976543234567899901234567899876587996549899321298976543214467899954398997632123657898994
+5219976554349899432129698999893345678998765346789659798932349998654323578999876497989543234567899543
+4323987665656798921098989998789556989987654223878998687893499969875987679987988986578994547678978932
+9495999877897987892987878987678967898998743012567896546979987855987898789876599965489789659789459891
+8989892998999876789976567897567998957989432123456985434569756234598939898765498744345699967891298789
+7678793459998965678975456976456789549876543254569876324598542123459329999654399534234898898999987678
+6547689567987854769894345994347695434987656767878987765987643044678998998765987620123456789998976567
+2134578979876543456789234789234589323698787878989998987896543235799987989976798731245977898987894348
+1023456798989874767890125696345678934569898999598999199987654376789876476799987654356898987656791239
+2434587997898765889931459895456989545679999545457889298998775479898784345678998767487929876545789545
+3679679876779976789432345796587997656798789432345678987989986567987673234789769876598934987656899696
+4598798785669899996543456998798998787989699421234567896767897678976543125898654987679875898967998989
+5689987674357698999876567899899899899876568994365898965658998789985432016789543298789876789878987977
+6898998543234567899997878965956789921965434589456789984347899899876543123895432109897989898989995456
+7987899932123456789398989954345997899875325678987896543256789976987754544789549212976799997699984378
+8996998761014767891239997896456896898765456789198987632149899965599865765678998999765678986569876467
+9965987654145678910949876789587965789876567991019996543234999843479876878989576788974599875454987678
+7894398743234599999898765678998954678987878992398897755345898764567987989995435567893987654323499789
+6989219894346789987769989789989563867999989989987789976456789879679998999876323467932198763212599890
+5678923998456799976545699899876432345693299979876667896597999998998999998987212348942019874343989921
+4567894986568897895434567921987321276789129864985456997678999987897999987658301239953198765454678934
+3656789997679936789323989210995490987899298743234357898789878546786789876543212367893239887565789995
+2345678998789325679999898929876989898998987654101256789898765435545678987665325456789357997676799989
+3476789019995434569878787899989978789997987643214347999999854321236789898775434567895467898789989878
+4567892129876765698765676789998767679876987654765656789998763210145698769887655698986578969899878767
+5688943436987986997654565678987654598765498769876777899989954321234789656998767899987699656998766456
+7899894545698999876543234567896543987654329989987888989679895452345678946989878957899988997987654345
+9956789656789123987632123479987659876543213597898999876565789667458789239878989745987567689998765456
+2345678967894234696541014578898767998632101456789767987434578978569890198767897659986456578909876567
+3456789878954356986532123456789878996543212347890345898323467999998932987656789798765343469219989878
+4567896989996969897543234587990989987654323456921256789212356989897949876545678999973212458998596989
+8689965699989898798656945678991399898785434567892345892101249876786899865434567899865393567967445698
+8792123989876767679987898789789989789897545679953556789234598765645697654323798999976989998953234567
+9893439876565654567898989897678976567998976789767787896545987543234789763212346789899877899762146788
+1999598765434123456999878978567985445879987899879898987657998652101679654101235898765766794321017899
+2398987654321014567894569865379876234567898999989999698769876543213568969233346789654545689987634799
+9987898998432123798923498765456989445789999998993987569899989984623479598944567896543234568976545678
+8765659996543235689212349878579876556895698987894595456989999876534689457899698965432124589987678989
+5434347987656345678901656987689987667894987656889696579878989987678994345678969999943012679799889998
+6521236798965456789892997899893198789989876645678989698769878998789101234589456987899323569654999987
+7632345899878569898799789910999099895469985434569878997645568999893214456678967965678954578967998976
+6543656901989689987687678921398987994398996945698969876431467989965323467889899876789995678979876765
+7654567899798799976546469892987856789987889896987654986542349878976545578996791987899989789998765434
+8765678978669899865435346789896543899765678789998743297656598967897767899545932398999878999987654321
+9889889765554987654321234599787012987654885678987654198787987656899898989959893999989656798999766432
+6998999984323498765634345987652123498753234569988621019899876547999979569899789899877545987899997949
+5656789993212549876765678999543934995432123458976542323999987656898763456798656789765434876789989898
+3245678995301234987876789987659899876541012367897643434589998867897652367987545679654321345899876767
+5346889876418345698997895698998767987632123456789656565678939978998743489876434599865632346989765656
+6757895987567896789298994349898657898743246577898969996799320989987654578987645689976543559876534345
+7878934599678987892129789656798745569854768688957898789978999999898965789998786792987654667987621234
+8989321698789998943345678969959433498769879799346789698767688998789896999979897891099788789599732345
+9399934789899999874456989298743212349899989890123699545654567987678797899765998999988999995498543456
+1239895698999889965569890129654101257999897921234568932343879876587689999854349998877989654397654767
+3398789987898779897698789298765233398998765434345678921012998765434567899873234987765678965298765878
+5497679876789657789987678999874345479999876845456989532323459764323456789984749896584567994349896989
+9986545985698745678998545899985456567899987656567896543456798765436578999875698785323456789956997891
+8765439876789434567899676789876567898989998787898987654578899877748789854976987654212345679897989930
+9854323987896567678998787898998678959678999898999498767999901987659899765987998765401256798769878921
+9965214598987679789799898997679789344569989969894329898999892398767978979998999878919347987656767932
+9876329699998799897689999999569896103498767456789212959998789999898956798939389989898959876545658993
+3987898989899899954599987878979975212997656345892101345894569889999345987821278998767898765434545689
+2198987676799989323989765468998764329876543234789292456793298767893239876710367987656797654323434578
+3999997545989878939878954359899765478987832145678989667894987656789123985321459977645498967410123467
+9889998659878967899867895456789876569998953256899679998965976545993239876432598766532359978823234589
+9775879769767456798756789767898987878999866367996567899876987636789998987543679854321267898764345699
+8654569898659345986545678978987898989398765456789456999987898747898767987654678965432878929875456789
+8743453986545239875434567899876789999219876567894347898998999898989654599865679876543989434986578999
+9432012987432129854323456789765898998723987678989256987899298969678913479876789987767998745797989378
+6543123497654098765212345678954767896545698989879129876789197654599904567989894398979997656998990165
+8656934598843259876323467989653457997959789698768998695778986543489895989199965219497998797899989234
+9879899789654348985434578999942346789898994599545986434569999642376789891019876101356989989987678946
+9998778998765467897665689678799457898767895987439876545678998921235679792198989212349879978998567897
+9897669899989878998786789545678968998656789876545989656789987892346895679987654323498768967899456789
+8789456789999989659887895434567899876545457987676798767899876789457893568999876654599545656789577897
+7678345678999896543998976125678923965432346798787899879954965878967932477899987765987434346899789956
+8543234567898765432159876546789019876553456899898965989965954767898921276789998879876521235678993234
+8732145678969876643345987657893247987864579965999754296899843459899632345899879989987432346789210123
+9543234689654987754456799768985356798977678954987653124989752576789543656946965399876545457894321234
+7687657995323499767569894978976467899398789432098764349876641345689654568939873212999856567965432345
+8798767897435679898989943989989878910239896545139975668965432456799767899123982101298767878978644567

+ 100 - 0
day9_smoke_basin/input2.txt

@@ -0,0 +1,100 @@
+6546798789123567965567895323943212345892129763235999432345678976432345679987654524567998765325689236
+5435799654012459943456789519894301234679098654569898921234589765321234589878543213567899886434990135
+6656987643234767892345995439789213345899998765699787892345699876542367898765432101456789876556789296
+7767898759349978901256896798679354476999899876987656943556789997653458999897546212345678998669893989
+9899999998998899213457999977598967568998789989877545894567898989767767987969765423789789239879992468
+1998899887876778924568998765467797679998678998765436789678997978978879896459896634567892123989989567
+2997698766514567935679987654345689789877567899854323899899986769899998764367996546678943434599878998
+9876598654323678956789898865256799898765478999876412910969875657799019653235987697889655675678967899
+8765459865445789987896789954367897997654349889987567891459854345678998774134699798998787988789456789
+9879768979556789598965679875679956789765199767898778962349763256789769892034789899999898999895345689
+0999879988767893459654568996789545899976988757969989543969854367899349973125678910988999999989656789
+2399997899878932398543467898897656999899877543756799679898765698978998763238789999977899989878967893
+9989546976989321987652456789998797898798765432345678998789976789654987654349892988766999878868998912
+8878939765698939898101345892399898999679986565466799879657898996543498765656943976845998764456789101
+7767899954567998765212676901988939987543198976877899765434999899432129897967899865439898752345894342
+6656899875678969874324567899876323499654589989988999889325998798943012998978965986549765431456789493
+4345789989789657985639678998765434598767678994599898765439897687892135699999234997678987210567896989
+4236798998996546987798989999877645699878789323978789897597656576799246789852129898789598997689954678
+5345987987895439898987899899999876789999895439765678989989943465678997899643498789895459798994323456
+6559876466989598799876798789899989894698986598979789878967891234569598988954989679954345699783212367
+7798765345778999654765789679789795913797899986898999765456910123789439567969976568943234987643102398
+8999894234567898743234897545679654202986798875787899976345691345678923459998965457892195699854253989
+9989982125789987656126789423599967319875987654546678976456789467899434598987954345993989899964359878
+8779873013499876543245893212999899497954987543434569876567899878976567987656893234589878999896479868
+7669765638578998757656789109898789976543498662123478987678965989997679876545994445678967998789997656
+6549876797678969767767893298765678987652398743236567898989654598998989987656789556789349879679879745
+5432989898989659889878954987434567898921019954356789989490123567899499998767897697894212965498765432
+6321499979693245999989769876545678989892198765579899975321235679976579889978998989943209892349874321
+5432349765432134578999878987656789978789239987678998765435346793298679767899329878954399721254989510
+6546559876593456679678989198769899865678949898899899976567458989109798656788919769895988670123495432
+7677867998989567989469893239978998654889997669956789987689569878919898543567998658789876541234987543
+9988979789878978992398754345989398789992986544345993298798998657899997632699876547678987632349999654
+8999998694567989421239897659891239993101297431234889019987654346789987543987654434569999743498998767
+7899876543459993210234998998789345679219398410124678935698798759898998679876543223478999956987689878
+6598765432568996521395799765678956989398987324238799549979899878987899989987651012459998769876545989
+5439877521256789434989998654567899899987996437849989698764978989456793299875432123467899898987632193
+3214986530235678949879899767978999789356797656759878984323469994345679099986743254589967987899991012
+5423497621234799998765788978989998679218899878899767965434678963234568989987654357678956996598789134
+6765986532345699987654577899597987568909976999998756896545889652134579876598765488789449895498678945
+9876998543656789695323456789456798457899345789998745789656797841049698765439876569899239784323569656
+1997899654567896545212968994345965349978956799987656999878986532198999654323987678987997673212398967
+0198998765678985432109899893239876798767899989999789129989998783986598767534598789876798532101767898
+2999639876989876543298789679123987899754978878998991098797899899885439898645989898765696543312356789
+9899421998994987754987674578994699989543457867897892997686799998765323979769878999654987654323487899
+8798990999895798865796543456789798765432323456976799876575689876543212367998767898943299765456569989
+7656989896789999978999652346799899898431012399865679765434799987694103456799856987892123976567878979
+5445976785679899989498783456789943987652123987654789865323459998989214567989649876789034987678999567
+1239895423456789894329854567897562398543239876543498954314567899768925979876535965679123498789410456
+0198799212678998763213965678954321249884345987654567896501234689656939898765323984568965679894322345
+9987678924579997654329876789873210398765467898775688985432345794249899789543219875679986899995436756
+8656567899698998765456989892984332469876578999889899876543456789098798689784301989899997898987645667
+9543456988986889989689999921296545689987689999999901998754568899988657578965513598968999987699987878
+8654579876575679998799899890987679799998799987678922789865678999865543489654324987659989986599898989
+9797698785434457899899798792998789898759999876569934569978799899874212398987439876548778975476789999
+2999789654321236789997687679899893976543497683457896678989896789965101237896578985434567894365679989
+1299899869210234599876593568789912987675986542346789989995955699876712346987989998756788920234678979
+0988932998921347698765432455698909798796987656787892499954334578987423456898999999869899321345679768
+9877990987892656789984321023567895659989999968898931249893212567897654567899989889989995432346896556
+9866989876998797899876432345679954349879989879999545698789993479998967678910976779799989543456789345
+6755576987899899934998765456899873198967778989998996999666789589979879789799875567679979655668893239
+5444345698998932123499876898998762097854567899987989876545697678967989894598964324569868987878965698
+4321234579996541012986987999298754996532479999876878932123489789459999943987654213498757898999879987
+5210123459889953329895698992019969875321345698674567891014678992398989312498643209987546799921998766
+6332335598779894459744349989929899965499956997543456789123499101987678943459654398765434897892349854
+9455447987669799598635234579899789876988899876432356789254689219876567896598975569874323456789459763
+8976559876556678965420123498798679989977789998553678998765679429765459987997897879963212367899998672
+7898667986434579876533234987687567998765679999654589329887789598954345699896989998654323478997899431
+6799899797415689987644349876575456789854567989765695312998899987953239989745879998765444599986789520
+5679987654323578998759598765432367898765698969878789423499999876832198765634567919987655689875678991
+4789999965437679349898959886521278999898789643989898746589999985421019874323788901298766895976789989
+3498999876545789199987845995432349899999899891097987657678989995434198765435699899349877934987894679
+1237999987659896989996534987545456789998943989196599769989878989975239986745797688998999545698923488
+2546789398967895879965423498686767898987659879987439878998767967897845987899896567897678969979012567
+4598990269878954567891012569797898967898798769876321989987658956798966798998944456986567898764323457
+5679321256989766778932123459898999656789898858965452397898769345789978999997932349976456589977444868
+6898732349896987889994535678989989745677987547896543456789891234678989799986521598765343467896576789
+7986543498765698999989689989679876532456799856987765687898910123489995679865432399763212398987987998
+8997959597654579999979799999568987321238898769998989788987421379678954299876654987654523589998998967
+9219898999763457898768989878467995432545999898999399899876532567799765989987765699765787678999539456
+4398787898932348987656878953359876545676789987993256901987656678949879978599876789876998789998321345
+5987656997891259876534567942234998656889899876989347892498998789323998765432987898999899999887310156
+6987549876789345984323457910145679968999998765679458999999129895434569886753698956898792398765321235
+9876732997896469876512367891236789879899899654589999878891034989598679987864569546799689989898752376
+9765431298999598432101278954345678998765679743468789456789123679679789898985689435986567978987643457
+9854320999998987643212349765678799249876798632345679347894234567989898789876790125987878967498784567
+8765439899897697656323757976789890129997896501257896556965345689999977667987891234898989654349895878
+9876598776786569997954769987996989298698965432348997867898766789898765457898942346789497901256976989
+4998789654692498789875899998965679397589876543456789978999877895679854366799657659892346892767997992
+3459998943210989688986789879654798966467989754779899999899998954298789245789798798901237789879989891
+2469987894529877567897898764323987654356899875678999878789109760129656166899899987892345678989878792
+1998546989698765486989969765934976543234567988789999764678919871299641017910999876793456899098766689
+9876534878987654345678959899895987654745678999999989843569329792988432199899998765689768943199754578
+9985423568996643236999249989796798965656789349989878992978939654976546978778999654578978959987643467
+9876512459985432126789198765689899877767893298765456789899998769997959864568998643466899998998752578
+9984301678976321025689999864579999989878999109874345698799899898999897653459876532345789987996543499
+9875214567987532134567899543689987891989998998765456789687789997698789762345977541234599976987657567
+8765323456898653465789998654568996542399987869989567896535678987589678943459865432545789665699768978
+9876435677998754567893469765879987653459896654398678965423599866476568964567979543456796543224978989
+3987576798998765698912579876789598767598765431298789986210987654324467896789098756767897656102989491
+2097687899329976789323489998896439889987654320129891397321298864212356789892198768878987643212495320

+ 73 - 0
day9_smoke_basin/main.py

@@ -0,0 +1,73 @@
+import os, sys
+import numpy as np
+from functools import partial
+
+task_dir = os.path.dirname(__file__)
+sys.path.append(f"{task_dir}/..")
+from get_tasks import get_input, generate_readme, check_example
+
+
+def parse_input(inputs: list[str]):
+    return np.array([list(line.strip()) for line in inputs], dtype=int)
+
+
+def part1(cave: np.ndarray) -> np.ndarray:
+    centers = np.array([0, 0], dtype=int)
+    mins = np.array([], dtype=int)
+    for i in range(cave.shape[0]):
+        for j in range(cave.shape[1]):
+            if (here := cave[i, j]) == (
+                win := cave[max(0, i - 1) : i + 2, max(0, j - 1) : j + 2]
+            ).min():
+                mins = np.append(mins, here)
+                centers = np.vstack([centers, [i, j]])
+    centers = np.delete(centers, 0, 0)
+    print("The answer of part1 is:", (mins + 1).sum())
+    return centers
+
+
+def part2(cave: np.ndarray, centers_basins: np.ndarray):
+    def get_dirs(center):
+        i, j = center
+        up = max(0, i - 1), j
+        left = i, max(0, j - 1)
+        down = min(i + 1, i_size), j
+        right = i, min(j_size, j + 1)
+        return up, left, down, right
+
+    for idx, center in enumerate(centers_basins):
+        queue = []
+        i, j = center
+        i_size, j_size = cave.shape
+        i_size, j_size = i_size - 1, j_size - 1
+
+        queue.append((i, j))
+        cave[i, j] = idx + 11
+
+        while queue:
+            pos = queue.pop()
+            for dir in get_dirs(pos):
+                if cave[dir] < 9:
+                    cave[dir] = idx + 11
+                    queue.append(dir)
+    print(
+        "The answer of part2 is:",
+        np.sort(np.unique(cave[np.where(cave > 10)], return_counts=1)[1])[-3:].prod(),
+    )
+
+
+if __name__ == "__main__":
+    input, example = get_input(task_dir, 9)
+
+    example_cave = parse_input(example)
+    real_cave = parse_input(input)
+
+    check_example(example_cave, part1)
+    example_basins = part1(example_cave)
+    check_part2 = partial(part2, example_cave)
+    check_example(example_basins, check_part2)
+
+    centers_basisns = part1(real_cave)
+    part2(real_cave, centers_basisns)
+
+    generate_readme(task_dir, 9)

+ 3 - 0
day9_smoke_basin/src/main.rs

@@ -0,0 +1,3 @@
+fn main() {
+    println!("Hello, world!");
+}