Compare commits

..

No commits in common. "8837b9762332ff0a3f0e9dc360391de1ac4649d0" and "9c86a5691d461e39e14ed9d2476e2fe44fa6bd8e" have entirely different histories.

9 changed files with 124 additions and 156 deletions

6
!NOTES_FOR_NEXT_YEAR Normal file
View File

@ -0,0 +1,6 @@
- add run() method to AOCDay, so every day can run on it's own -> enable Alt+Shit+F10 and avoid confusion
-> after wards add a "if __name__ == '__main__': day = Day(); day.run()" to the skeleton
- add download_input() and submit_solution() to AOCDay, this can be automated, so let it ...
-> submit_solution() should not submit None and keep track of past (wrong) attempts to not re-try those
- add some sort of "start_day.py", as the manual copy/create is tedious
-> maybe even download the problem description into that days .py? At least part1; adding part2 afterwards might be tricky

View File

@ -13,20 +13,24 @@ class Day(AOCDay):
] ]
] ]
def count(self, step: int = 1) -> int: def part1(self):
count = 0 count = 0
depths = self.getInput(int) depths = self.getInputListAsType(int)
for x in range(step, len(depths)): for x in range(1, len(depths)):
if depths[x] > depths[x - step]: if depths[x] > depths[x-1]:
count += 1 count += 1
return count return count
def part1(self):
return self.count()
def part2(self): def part2(self):
return self.count(3) count = 0
depths = self.getInputListAsType(int)
for x in range(3, len(depths)):
if depths[x] > depths[x-3]:
count += 1
return count
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -4,6 +4,15 @@ from tools.grid import Grid
from typing import Any, List from typing import Any, List
def getCaveMapFromInput(puzzle_input: List[str]) -> Grid:
caveMap = Grid(99)
for y, s in enumerate(puzzle_input):
for x, v in enumerate(s):
caveMap.set(Coordinate(x, y), int(v))
return caveMap
def getLowPoints(caveMap: Grid) -> List[Coordinate]: def getLowPoints(caveMap: Grid) -> List[Coordinate]:
lowPoints = [] lowPoints = []
for point in caveMap.getActiveCells(): for point in caveMap.getActiveCells():
@ -29,30 +38,20 @@ class Day(AOCDay):
inputs = [ inputs = [
[ [
(15, "test_input09"), (15, "test_input09"),
(530, "test_input09_sergej"),
(545, "input09") (545, "input09")
], ],
[ [
(1134, "test_input09"), (1134, "test_input09"),
(1019494, "test_input09_sergej"),
(950600, "input09") (950600, "input09")
] ]
] ]
def getCaveMap(self) -> Grid:
caveMap = Grid(99)
for y, s in enumerate(self.getInput()):
for x, v in enumerate(s):
caveMap.set(Coordinate(x, y), int(v))
return caveMap
def part1(self) -> Any: def part1(self) -> Any:
caveMap = self.getCaveMap() caveMap = getCaveMapFromInput(self.getInput())
return sum(caveMap.get(x) + 1 for x in getLowPoints(caveMap)) return sum(caveMap.get(x) + 1 for x in getLowPoints(caveMap))
def part2(self) -> Any: def part2(self) -> Any:
caveMap = self.getCaveMap() caveMap = getCaveMapFromInput(self.getInput())
lowPoints = getLowPoints(caveMap) lowPoints = getLowPoints(caveMap)
basins = list(sorted([getBasin(caveMap, point, set()) for point in lowPoints], key=lambda l: len(l))) basins = list(sorted([getBasin(caveMap, point, set()) for point in lowPoints], key=lambda l: len(l)))

View File

@ -37,7 +37,7 @@ class Day(AOCDay):
(701, "input13") (701, "input13")
], ],
[ [
("FPEKBEJL", "input13") ("see image above", "input13")
] ]
] ]
@ -59,7 +59,8 @@ class Day(AOCDay):
direction, axis = thisFold.split()[-1].split("=") direction, axis = thisFold.split()[-1].split("=")
fold(grid, direction, int(axis)) fold(grid, direction, int(axis))
return grid.get_aoc_ocr_string() grid.print(true_char='#')
return "see image above"
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -4,6 +4,26 @@ from tools.grid import Grid
from typing import Any, List from typing import Any, List
def getGrid(lines: List[str], multiply: bool = False) -> Grid:
size = len(lines)
g = Grid()
for y, l in enumerate(lines):
for x, v in enumerate(map(int, l)):
g.set(Coordinate(x, y), v)
if not multiply:
continue
for x2 in range(5):
for y2 in range(5):
if x2 == y2 == 0:
continue
nv = 1 + (v + x2 + y2 - 1) % 9
g.set(Coordinate(size * x2 + x, size * y2 + y), nv)
return g
class Day(AOCDay): class Day(AOCDay):
inputs = [ inputs = [
[ [
@ -16,32 +36,13 @@ class Day(AOCDay):
] ]
] ]
def getGrid(self, multiply: bool = False) -> Grid:
size = len(self.getInput())
g = Grid()
for y, l in enumerate(self.getInput()):
for x, v in enumerate(map(int, l)):
g.set(Coordinate(x, y), v)
if not multiply:
continue
for x2 in range(5):
for y2 in range(5):
if x2 == y2 == 0:
continue
nv = 1 + (v + x2 + y2 - 1) % 9
g.set(Coordinate(size * x2 + x, size * y2 + y), nv)
return g
def part1(self) -> Any: def part1(self) -> Any:
grid = self.getGrid() grid = getGrid(self.getInput())
path = grid.getPath(Coordinate(0, 0), Coordinate(grid.maxX, grid.maxY), includeDiagonal=False, weighted=True) path = grid.getPath(Coordinate(0, 0), Coordinate(grid.maxX, grid.maxY), includeDiagonal=False, weighted=True)
return sum(grid.get(c) for c in path[:-1]) return sum(grid.get(c) for c in path[:-1])
def part2(self) -> Any: def part2(self) -> Any:
grid = self.getGrid(True) grid = getGrid(self.getInput(), True)
path = grid.getPath(Coordinate(0, 0), Coordinate(grid.maxX, grid.maxY), includeDiagonal=False, weighted=True) path = grid.getPath(Coordinate(0, 0), Coordinate(grid.maxX, grid.maxY), includeDiagonal=False, weighted=True)
return sum(grid.get(c) for c in path[:-1]) return sum(grid.get(c) for c in path[:-1])

View File

@ -1,4 +1,4 @@
from collections import Counter from collections import defaultdict
from itertools import combinations from itertools import combinations
from tools.aoc import AOCDay from tools.aoc import AOCDay
from tools.coordinate import Coordinate, DistanceAlgorithm from tools.coordinate import Coordinate, DistanceAlgorithm
@ -17,7 +17,7 @@ ROTATION_PATH = [
def overlap(beacon1: Grid, beacon2: Grid) -> Union[Coordinate, None]: def overlap(beacon1: Grid, beacon2: Grid) -> Union[Coordinate, None]:
diffs = Counter() diffs = defaultdict(int)
for c1 in beacon1.getActiveCells(): for c1 in beacon1.getActiveCells():
for c2 in beacon2.getActiveCells(): for c2 in beacon2.getActiveCells():
# Interestingly adding an if statement here to break out early when already 12 matches are found # Interestingly adding an if statement here to break out early when already 12 matches are found
@ -25,9 +25,9 @@ def overlap(beacon1: Grid, beacon2: Grid) -> Union[Coordinate, None]:
# and checking the results afterwards. # and checking the results afterwards.
diffs[c1 - c2] += 1 diffs[c1 - c2] += 1
d = diffs.most_common(1)[0] for d in diffs:
if d[1] >= 12: if diffs[d] >= 12:
return d[0] return d
def converge(scanner_grids: List[Grid]) -> (Grid, List[Coordinate]): def converge(scanner_grids: List[Grid]) -> (Grid, List[Coordinate]):

View File

@ -1,8 +1,66 @@
from collections import defaultdict from collections import defaultdict
from tools.aoc import AOCDay from tools.aoc import AOCDay
from tools.coordinate import Coordinate, Cube from tools.coordinate import Coordinate
from typing import Any from typing import Any, Generator, List, Union
class Cube:
coord_ulb: Coordinate # min_coord / up left back
coord_urb: Coordinate
coord_ulf: Coordinate
coord_urf: Coordinate
coord_dlb: Coordinate
coord_drb: Coordinate
coord_dlf: Coordinate
coord_drf: Coordinate # max_coord / down right front
def __init__(self, min_coord: Coordinate, max_coord: Coordinate):
assert max_coord >= min_coord, "invalid cube spec: %s < %s" % (min_coord, max_coord)
self.coord_ulb = min_coord
self.coord_drf = max_coord
#self.coord_urb = Coordinate(self.coord_ulb.x, self.coord_drf.y, self.coord_ulb.z)
#self.coord_ulf = Coordinate(self.coord_ulb.x, self.coord_ulb.y, self.coord_drf.z)
#self.coord_urf = Coordinate(self.coord_ulb.x, self.coord_drf.y, self.coord_drf.z)
#self.coord_dlb = Coordinate(self.coord_drf.x, self.coord_ulb.y, self.coord_ulb.z)
#self.coord_drb = Coordinate(self.coord_drf.x, self.coord_drf.y, self.coord_ulb.z)
#self.coord_dlf = Coordinate(self.coord_drf.x, self.coord_ulb.y, self.coord_drf.z)
def getSize(self):
return (
(self.coord_drf.x - self.coord_ulb.x + 1)
* (self.coord_drf.y - self.coord_ulb.y + 1)
* (self.coord_drf.z - self.coord_ulb.z + 1)
)
def intersect(self, other: 'Cube') -> Union['Cube', None]:
intersect_ulr = Coordinate(
#max(self.coord_ulb.x, other.coord_ulb.x),
self.coord_ulb.x if self.coord_ulb.x > other.coord_ulb.x else other.coord_ulb.x,
#max(self.coord_ulb.y, other.coord_ulb.y),
self.coord_ulb.y if self.coord_ulb.y > other.coord_ulb.y else other.coord_ulb.y,
#max(self.coord_ulb.z, other.coord_ulb.z)
self.coord_ulb.z if self.coord_ulb.z > other.coord_ulb.z else other.coord_ulb.z,
)
intersect_drf = Coordinate(
#min(self.coord_drf.x, other.coord_drf.x),
self.coord_drf.x if self.coord_drf.x < other.coord_drf.x else other.coord_drf.x,
#min(self.coord_drf.y, other.coord_drf.y),
self.coord_drf.y if self.coord_drf.y < other.coord_drf.y else other.coord_drf.y,
#min(self.coord_drf.z, other.coord_drf.z),
self.coord_drf.z if self.coord_drf.z < other.coord_drf.z else other.coord_drf.z,
)
if intersect_ulr <= intersect_drf:
return Cube(intersect_ulr, intersect_drf)
def __str__(self):
return "Cube(<%d,%d,%d>;<%d,%d,%d>)" % (
self.coord_ulb.x, self.coord_ulb.y, self.coord_ulb.z,
self.coord_drf.x, self.coord_drf.y, self.coord_drf.z,
)
def __repr__(self):
return self.__str__()
class Day(AOCDay): class Day(AOCDay):
@ -30,23 +88,22 @@ class Day(AOCDay):
minZ, maxZ = map(int, zco.split("..")) minZ, maxZ = map(int, zco.split(".."))
new_cube = Cube(Coordinate(minX, minY, minZ), Coordinate(maxX, maxY, maxZ)) new_cube = Cube(Coordinate(minX, minY, minZ), Coordinate(maxX, maxY, maxZ))
if not part1 \ if not part1 or (new_cube.coord_ulb >= Coordinate(-50, -50, -50) and new_cube.coord_drf <= Coordinate(50, 50, 50)):
or (new_cube.top_left >= Coordinate(-50, -50, -50)
and new_cube.bottom_right <= Coordinate(50, 50, 50)):
yield state == "on", new_cube yield state == "on", new_cube
def getOnSum(self, part1: bool = False) -> int: def getOnSum(self, part1: bool = False) -> int:
cubes = defaultdict(int) cubes = defaultdict(int)
for switch_state, this_cube in self.getCubeList(part1=part1): for switch_state, this_cube in self.getCubeList(part1=part1):
for prior_cube in cubes.copy(): for prior_cube in cubes.copy():
intersect_cube = this_cube.intersection(prior_cube) intersect_cube = this_cube.intersect(prior_cube)
if intersect_cube: if intersect_cube:
cubes[intersect_cube] -= cubes[prior_cube] cubes[intersect_cube] -= cubes[prior_cube]
if switch_state: if switch_state:
cubes[this_cube] = 1 cubes[this_cube] = 1
#print(cubes)
return sum(len(cube) * on_off for cube, on_off in cubes.items()) return sum(cube.getSize() * on_off for cube, on_off in cubes.items())
def part1(self) -> Any: def part1(self) -> Any:
return self.getOnSum(part1=True) return self.getOnSum(part1=True)

View File

@ -8,7 +8,7 @@ def getTheNumberFast(pushpull, adders, subbers, part2=False):
inc = 1 inc = 1
else: else:
number_init = [9] * 14 number_init = [9] * 14
inc = -1 inc = - 1
z = int(1e9) z = int(1e9)
number = number_init.copy() number = number_init.copy()

View File

@ -1,100 +0,0 @@
6587893456954341398543210234567899875421012578932123459998764323569999996432345899989359878998654345
5476894579873210197654328757678910976532323457891012398997653212998798789521256789879498764679795456
5345679989864321349865479869799929987643498598932923987989543209876697654320145679965987653567989767
3235678999965443567976567878999898997654587678949899876878994319965498765421236789764398532479879878
0124789339897764678987878989998767898986798989298798765756989498754349899535456899879987691298568989
1235693219799865889698989990987856789997899592139679984445678987643237998646567890998698989987457899
2348789398678976789569999921976745678998985431095459873234569998765145689987899932349579768976567978
4567899976599989895478999899875435899359876545984398765145678999843234567898976543998498657697798964
7688999875487899976789298767986546789999988769873239876234567892954345678909997659876597646579899543
9799998764325578987899109654397967999879999898764346984345678921986456789319889799989986534466989542
9989879875413467998998923993239878998758999969975899876476789210987567895498779989992395421355678954
9876569974324678959987899889101989987646489459896789976567894321297678976987667879893987510134569999
8765498765456899769996798767992493499832367999789893987678965456998989989876546758789997921235678988
9874349876567998998965689656789569989753458987678962398989879599879799992965434345678986437367889876
8765456987678987987654678945679678979768667896569541239899998989965678901977321237899876545459993998
9876567898789996796543489939798989764979778965499432345789997879974589919898934348901997668567892109
9987998999896789899755569898987897653989899012378945497899965467893469898789895459919898877679954919
9898919789965678989876798767346789762399943234569767989999854359932599787698789667899769989789899897
8759105679654569878998899856235999321239854355878979879998765567893987654589678978998953599896798786
6543214598979698968899999843123568910198765467989998767899976779964599643279567899687892498945697655
7954323497898966556789987654013467892499976589099987756789987889995798732153456789576931987432398543
9899435986577942347896598732123458999987899693239865347991298999989987643012348894345899876541239432
8798949765456891238965439653234567898976798789399876456789459999879876532145457896876789987832396543
7686799887347920145976549878347698987755679899989986567897667898965987674234668999987895498743987965
6595789998967891247897656989498999876544587999879987678998778987864398765545979998998989359654599876
5434678999298932346789767896569098987623456796567898989539899876543219876656897987889874298765678987
4323576789399543456789978998789197898212345679335679999421921988754301998767986576569763189896789198
3212345789987676577899899239899976789853458789124679878999890199865492999878975432478952076999893239
4523456897898787689998789129998765698767569991012399865788799345987989899989896543578943145698994345
5635567896789898799029569098899987999878978962193987654647678976799878799998798654567899239987989469
8756678935978999898998678987799999899989989643989996543234567897898968678987698785678998998795878978
9897889123467893967899789876678999768393498959878989654346778998987654567896539876789457789654769899
6998993234679932456999899865589996543212347898765578995487899989998785678974323987992345678943456797
4349965345789531345799987643499987664324456987654456789598999878999876789865434598943567889752589895
6459876459999910239898798101989198976535967899532345678949988767899989899989545999759878997643569994
9878987767899891398989543219879239987649898998721235789039879857999994978998769899998989498957698989
7999999878986789997679654598768945798959799987632345892129967234678943567899898798767894329878987978
6989987989345679896598995987654999899898679876543566943298654123487892389989987657656789210989876569
5978996591236798789456789998743878998786567987664689954679942012456799459876799543234568921298975497
9769889432445987679345699865432459987675478998785799895799842123867898967995698432123556932967964326
8958778956759876531256789987543579876564367899896895789998763435798957899854597543012345899859873214
7643568997969765430347893987654678976444259899987924556799878976899645798643498632124556789645995403
8532456789879876321346932398767889987320145789699012345679989987896536899854987653246787896539876912
7421345678989985442457893599898994598321237894556923966889999998998745698765698764345678954321989893
6530496989498996584668999989999213469644345892349899897899999879799656789876789875456799987553598789
7699989892397987676789998979992101278955456789498756789999898765688979897987894989667976599679699667
8987979789986599987899887968989232349866667899976546689998765544567899956598923499878987698798986545
9976867678965434598999765457678945458978878999895634578987654333456989645459012398989898789987654436
8765454567897665679998654346567896567989989998764323689999765212345678932399923987698789892498742123
6874343789799779789876543213458998678999799987653212387921976924566789543989899876554678943985431012
5432102345678989999965432102349999799987678987654501276892989896677899959876798765432567899876543243
7643412456789999989878676413456899989876469898876612345999898789998998899995439876753458976987654354
7655324577897899878989654329567988764514345789987843456798766599889987689984323987764967894398766456
8786734678976799767998765567978976543101234599998954567899954349778996569876212398876878999989877767
9897645689565698757899887679999098654332345698999875678999843234567897678965104569997889798976998978
1998756789434569943535998789899129786445689997999989899998785123456998789874315678998996567895329989
2349967896513479892124569896788939896576898786789996921989632013667899892965326679019965456996210197
3959879974323569769023456975767945987687987675678985439876543124589976920976434567997894346789321256
9899989965434679658934567894556899998999876554567976545987654565697895439876565879876543235678932345
9768999899565798747895879913445678989678965423456897656898765677796796549987676789998432126799543556
6756897788979899656789989101236789676569874312345798968999879788954789678999789899987643235689699789
4346796567898998767899894212345896545456965101276789879998999899432688989989892968998754345678988999
5657893456987899878998765523466789634349876514567892989987656999543567899876901259789895466789877889
8789932678976789989579865434567898722298765423698921291296545678957678998765432345678976989898656878
9897643789865678996469876558778969810129895434789210199986534589998989349876553499899989999986543566
8987654898754567902345998669899654323345987567994391987673323467899995456987694989999999999986432345
7898765998843236899458998789998969834589998989879989876542012456945896678998989878998788898976521289
6569976987654345678967999898587897655678999898765779765432135578935789789459976568986577667898432478
9439898998765469989998987967476789767789988766434568976543234689124678992349865457997402456789543567
8998789659989598898989876653345678978999876654323456897654345691012567891998754349876212398897654678
7987679743497697767878965422234567899999875421012698998765676789323456789876542298765435678998865789
6592578932398986656467897910123456979899986534123589239876797896454567997984321059876568789999976890
9421349890199875433356789891954569456798986546254678998987898989765679545975472347998678899897989921
8210445789987654321245898799895698969897698755378999467998949678976889439986567656999789998796597532
7421234894599943210134987688789987898987549875489312359879234567987899998797678797899899989689459843
6439345943239874321345798454698976767895434976678954598762123456899999897698989989989979876568998754
6598997894999765633466954343567895456795323987889895689953234567999898789439899879876569965457998765
7987889999889876545789875212398954346789412398998789998764348789898775678919789767996498754345689896
9895678987676987986791995101457893244898901999975698789765459898799654567997637657984349843234569987
8654567896565698997892983212346789123457899899894987699986567899654523456789521749873249654445678999
7643298789434569898939865423567891012346798798795699789297978999543312978898430123965398979966989645
8964345679323458789920977674578942199967989689589999892198989998662106899986521239877987897897895434
9876798789012345699891988795689543987899876567477899943019799987543245679199542345998976545789999321
2989899893123556798789599876897659896789765435356789942165678998765358989098993556799865434668998910
1094945943238767987699432987999798765679976321234567893234569679878767899987689698899987323457897892
9943237895445898958567941098998999654789897542348788954345689456989878999865567989989865412368956789
8832146789556999543479892129987678932396789656569899995456791349897989987654349878878954323779768999
7654258997697976432358789234987467890145698767678998789767890998756399899785498765469895965689979889
8765767989989999751234689345986358943235699898989998689878999876543268799996789874399769898789898776
9979979878879987642956796569875467894346789969799987578989998987654156678998992986987656789899787545
9898998765968899799899898679989878976459894356678965467899887598721034567899321987896545678998676434
9767897654656789988778999789398989997568999234579874356789756459842125788965439999999767899876545323
8656789843234899876567899892127898987678988946698763244578942398763236999877898999899978975975432102
6545678952123678975457989942016567898789767897987653123569321987654349989989987998799989764986548726
2135678953234567894345678932123459989894356789796542012459432798789498978990196754678997653297659645
6545699975545678943234569643234569878943234598679765423498943679899987867891985653589987654398799856
7678789987656989434126678964365798569892125679569876536567894567998766756789873542357898765989923987
9989890199788999321018999765456987456789287894379987789879976898987654347898762101237789889875210198
0198931369899998732129678976569876345994399965456998897989197899599875456999854345345679998764321239
1987642456910987654334567897679985456895679876597899956791098965431986567899965456786789459875643467