add day 9 solution

main
Christian Ulrich 2021-12-12 02:44:14 +01:00
parent 49d705beff
commit 2578a5a3e1
No known key found for this signature in database
GPG Key ID: 8241BE099775A097
4 changed files with 255 additions and 0 deletions

100
day09/input Normal file
View File

@ -0,0 +1,100 @@
4323999434356678989012399854245901359876432101298901239876569892012345896567996545678912345689998921
6319898921234589878923987653129892349989949212347892398765498765423456789469884326789923468998997890
5498767892945678967899876543256789998999898943456789987654329878534567994398765434567894579997876789
7598756789896789656799988654347897897898787899969894198969210989675679865789987645678965989986845678
9987642356789995345789999767658966956987676987898943019898921299789789989898998759789996899895434567
8765421234597893234567899878979654645696545545787892198797993459895995797967439867899989998756523456
9873210123456789145978967989989743234985432123456953987676889567994379976543123978969878987643212677
8654321234599891059899656196899820189876541034567999876545678978989457898991034989454569899876543467
8765432346789932129789543245698721278987632175679789985434899299879768909989549994323798789997654578
9876543459999943398656959366797632368999543286789679876545789349768979219978998943212345695498765679
8987654567899854987847898997987543456987655399896598987656999998657894398769876543101456789329876789
7998766678998769876236987789998787567898867899989467898789679876546796987654989654212567893210989894
6879878789439898765134896578999898678999978999876347999892498765435689996543498765323989964348994943
5667989894323949873256789459899969989799989298765276789901999976523499989432369878554899979767893212
4456998976210239954367892365797654395689990198754345890199898765434678978943458987675789989989989103
3347897654321298765458921234998753234567891259869656789989729879656789567954667898789895698794567924
2256998985434349999567890147899432145678942345998969999877610998789893457895978989899924997643457895
0197899876579569878998921356987553269789653496987898998765431239898921238989989876968999876432346796
1989921989698998767889432387898769998997654989976767999865432378997632345678998765656789997321245989
9879899998997897658978943499949898787898769878765657892976543456796543458989987654245894395460349878
8768778987986986546569765678934987656789898765454345991097694567987654567999998742134589987651298766
7656567996765987432458979899929876545689997654343234789198989798998785688958999821023678987542987654
8543457895454599543567898987898965432398789543210123678999978989109898799767898762124589998963499763
7432568976323987654678987896587898751987678954621234567899868878998969899878987654355678999654598754
6563678996454598785789876543456789899896567976542545689988759767897653978989698776456789498775679876
7674569987887679899899998954587893998765456897678766789977648956789792368994569897568992349896789987
8789678998998799987978989899998941987654347998989877899866537845678989457893556998989641239987896599
9996989469239899976567976798889432398743257789995989999654326534989878968942445989899932398998965456
9765794345999998655456985697778943469854345679954197898765410129798956899321239876787899497899999999
7654654239878899543257894986567954567965466789893246799987654397657645965490399865676798976789987878
6543210198768789954145993214456895699876587898789345678998766498543237896989988754545987545698986767
7659323498756567893239872102345696989987679987678956989999987987632126789879876543234985434767895456
8798944987643476789398765213456989878998793236567897899897899876543245998765987656129876323456789346
9997955698652345679459854323469878767899892105478898998766976987654346789654598761034987654979893234
9986896789821239896567967469598765457894999212345789999845275698766457896543469878236798899897992123
8875989899843345798999897578999854346795698923458897898732154569899598987674878989345899988756789634
7654678998764466989987789989899965234896987894567976987621013456987699698765999999456999879645899546
8463567899876577978996578898659894365689876789678965496434154789998789549896899898767898766434578957
4322456799988789467986459789548789456790245678989654398645865699899899932987998789998999654323467898
3210345989999891239874345678937578968921576789998763219856776789799999891098997656569998765634678959
4421299876789999498763234589425467899432347999899865498987887895679998789129986543467949976545689646
5542989665678998987654345678912348997543598998799986597898998954598987679298765432599234987898795431
6743976564567796598765466789323556789954689898678999986569899323987896567999877653789345698939894310
7769865433475689439876578895434667899899797654589998777476789012396543457899998789898959899323965621
9898764321234678912987889976545978998798976543478997654365692126597632349789109898967898989459875432
6969875430345799323498998797667899457657897652367898743234589987698721234589299987654987678998998745
5456989561256789534679967698799954312445679721458999892123678999899830145678989976543498899897897656
3237898762347897645789854549899543101239998932369898989294569767998764234889679885432459998786789767
6545679654456798789999753234997653212398887893456797679989678955349854345796598754101345987675679878
7656799765767899899899875123989964329987676799569986568678989844239965566897399543212659976564568999
8767949879878999956798765234567895498766565688998765454567897632198987677979987674353598989323656789
9878933989999997345987654347978987987657474567899864323456789543987798789657898765674987643212347898
2989212399899976499899765456789598999843323456798543412345897689976579896546989978786799532101234567
1099923456789897988769896567893459988732012347987632101276889798865456965435678989897899744312345678
2989894569898789876553987878932349876543123457898543242345678997655329876323468996998998765423456899
9878789678987678965432398989321956987654234567998765953456889896543212965414567895469999876536567893
8767679789876569896543459999939897899776876678929878767967996795432109876525678994356987987897678954
7654568998965456789654597899898789999897898789213989879979645689643234987987989789249876598998989865
6543457976434345678969986789787678989969959892102398998796534679865359898998995678998765459789999986
7532369865421237789998995897678459876553345943234567895679845989877899789999434567897654345678998987
8643456976510175893987654589541234985432237899765678954598759992989987678985326789999543256899987799
9754567984323234992199867678920349894321018989887899943698767921399976569876434697698954387929876545
9965678999654345689023978789321298765732147678998999892349878992349989678998556789567895998934984334
9896789698765456795434989897632349876654234567899998789759989789498798789987667898488976789949893213
8789996539876568976765699976543456987769645778998987698998795678997629899998979987569987899898789323
8678789623987878989876789987656567898998756789987654597899654578987510949879989097698998987678678934
6577678910198989099987899999878978999459867897898769986898943139995421234569992198987989766534567965
5464569923239099198798978987989989989234978976789898765567892098986532345678943469876878954323588976
6323467894549198999659767896590195678949899965878987653467894987987645456799654979765767893212789987
7467878995698987888943656987321234789998799894569876542345695986799656777898769898954456794325678999
9878989789987656567892346895499995894987676789678984321237989875678967888959998767893345689634789343
9989795678976545456789498976987889963298545798789995452345678964569898999543989656921239796545895212
8799654345987432367898569299876978954987656789896976563456789543456789212959876967892398987656954101
5698743239874321298987694398765767896799767899965698754689897632345898909899765898993987898787893212
8789842198765453456998789987654656789899879999854569869793998943458967898798654789989796789898965337
9898651019976764567899899876553234899999998999763579878892349894967898987698765678979655679929598656
8999532124987989678921999765454123689998987688932389989921498789898999876549876799768443458913459767
7987693535698998799210198754321014599997698567893499995210988679789498765434987897654312367904599898
6298989545679129898921239895932135679876542348954569874329876565699349954323698998766423778912989989
5129878996989098987892398989893234598765430567895678965498765434598998766464569239976534567899878879
4298767789998997645789997868689395987654321789989789876989954323457979887575698999988785678998767656
9987656679987673234669876546578989998865439896578999989879765545568967998786987989999876799987654343
8764346567895432123456987432446678969976546965456789998769877696678957899899876878913987891098765212
9843213457897641012349996551234569655987697892347999879656989987889345679999985467899999942139876909
9874326567999973253598987767897678934598788901256789765345699898998956798798754376788987659245989898
8765534567899654345696598988969789012479999432346789654236987649567897897649654234567898798967998767
9876645678958987656985459199459892123467987656759896543129876533456789986539867545678989987899879756
1989856789767898769874321012389943234568998767867987321013976512356899876621998656789679876789769845
0198967899878959998765453125678974345899459898978998534123497301245798765433498767896567965398654976
1987698901999239879876875234569865456789345949989987643294989212398999879754699878965459876797743988
9876569892999398767987864345678976567899276932994398784989978934567891989876789999894323987896532399
8765456789878999856998875457899987679998999899875999899876867897678910199997890123789412398965321246
9984345898768897645879987568999998793467989799989899988965456998989329988998943235694325499984210123
9765457987656789734567898979998879912399865689998789877652347899395498977899876545789434989875331234
9876569876545678923456789989987762101987754679987698768341236789219987656789998756789649878989445678
8997699997656789212345898795496543212976763567896549854210145678997697545899989867899998767898986789
7698989698767892101256987656398654323965432356789430969321234567976543234878978998999894854567997891
3569876569898976412345896546239876579876321245695321298763367898965432123458965459998763213458998942
2345965412969994324456789634123998689988432357976763497654456999976543234567898567987654101556789543
0156976323456789534567994321014569795499543568987954698767767894397654545798987678996543232345678954

54
day09/part1.nim Normal file
View File

@ -0,0 +1,54 @@
# Copyright 2021 Christian Ulrich
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# usage: ./part1 < input
import algorithm
import strutils
proc countLowPoints(prevLine, curLine, nextLine: string): int =
if curLine[0] < prevLine[0] and curLine[0] < nextLine[0] and
curLine[0] < curLine[1]:
result += int(curLine[0]) - 47
for i in 1 .. curLine.len() - 2:
if curLine[i] < curLine[i - 1] and curLine[i] < prevLine[i] and
curLine[i] < nextLine[i] and curLine[i] < curLine[i + 1]:
result += int(curLine[i]) - 47
if curLine[^1] < prevLine[^1] and curLine[^1] < nextLine[^1] and
curLine[^1] < curLine[^2]:
result += int(curLine[^1]) - 47
proc riskLevels(): int =
var lines: array[3, string]
if not readLine(stdin, lines[1]):
raise newException(ValueError, "too little input")
lines[0] = repeat('9', lines[1].len())
while readLine(stdin, lines[2]):
if lines[2].len() < 3 or lines[2].len() != lines[1].len():
raise newException(ValueError, "invalid line")
result += countLowPoints(lines[0], lines[1], lines[2])
lines.rotateLeft(1)
lines[2] = repeat('9', lines[1].len())
result += countLowPoints(lines[0], lines[1], lines[2])
proc main(): int =
try:
echo riskLevels()
except Exception as error:
echo error.msg
result = -1
when isMainModule:
quit(main())

96
day09/part2.nim Normal file
View File

@ -0,0 +1,96 @@
# Copyright 2021 Christian Ulrich
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# usage: ./part2 < input
import algorithm
import sequtils
proc lowPoints(heightMap: seq[string]): seq[tuple[x, y: int]] =
for y in 0 ..< heightMap.len():
for x in 0 ..< heightMap[y].len():
let
value = heightMap[y][x]
left = x == 0 or heightMap[y][x - 1] > value
right = x == heightMap[y].len() - 1 or heightMap[y][x + 1] > value
top = y == 0 or heightMap[y - 1][x] > value
bottom = y == heightMap.len() - 1 or heightMap[y + 1][x] > value
if left and right and top and bottom:
result.add((x, y))
proc horizontalRange(line: string, x: int): Slice[int] =
result = x .. x
while result.a != 0:
if line[result.a - 1] == '9':
break
result.a.dec()
while result.b != line.len() - 1:
if line[result.b + 1] == '9':
break
result.b.inc()
proc findRanges(line: string, prevRanges: seq[Slice[int]]): seq[Slice[int]] =
for range in prevRanges:
var x = range.a
while x <= range.b:
if line[x] != '9':
result.add(line.horizontalRange(x))
x = result[^1].b + 1
else:
x.inc()
result = result.deduplicate()
proc basinSize(heightMap: seq[string], pos: tuple[x, y: int]): int =
let hrange = heightMap[pos.y].horizontalRange(pos.x)
result = hrange.len()
var
y = pos.y
ranges = @[hrange]
while y != 0:
y.dec()
ranges = findRanges(heightMap[y], ranges)
result += ranges.foldl(a + b.len(), 0)
y = pos.y
ranges = @[hrange]
while y != heightMap.len() - 1:
y.inc()
ranges = findRanges(heightMap[y], ranges)
result += ranges.foldl(a + b.len(), 0)
proc biggestBasins(): int =
var heightMap = @[""]
if not readLine(stdin, heightMap[0]) or heightMap[0].len() == 0:
raise newException(ValueError, "invalid first line")
var line = ""
while readLine(stdin, line):
if line.len() != heightMap[0].len():
raise newException(ValueError, "invalid line")
heightMap.add(line)
let basinSizes = heightMap.lowPoints()
.mapIt(heightMap.basinSize(it))
.sorted(Descending)
if basinSizes.len() < 3:
raise newException(ValueError, "not enough basins")
result = basinSizes[0 .. 2].foldl(a * b)
proc main(): int =
try:
echo biggestBasins()
except Exception as error:
echo error.msg
result = -1
when isMainModule:
quit(main())

5
day09/testinput Normal file
View File

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