mirror of
https://github.com/System-End/2024-Advent-of-Code.git
synced 2026-04-19 16:28:16 +00:00
how did i do these?
This commit is contained in:
parent
e9703fb111
commit
90f07bdbf9
4 changed files with 222 additions and 15 deletions
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,53 @@
|
|||
78760345801298896321001230110976301870134341034545687
|
||||
69671236989367765410678345221885432963233452127632796
|
||||
10589987670456001323569896336797010154324569498101845
|
||||
23478678561032132124428987445788923245013478545613932
|
||||
12034569432983045034310176596657654356932103456754301
|
||||
06123765301874126965223456780345543267843212769861212
|
||||
67610854322965437876104320691275676189732301890770023
|
||||
98545921013456946766782111234987089078721450321981167
|
||||
23434530145697854325693003435672128569670965492843298
|
||||
10127647654787765014234512345965432154589876782194587
|
||||
01018758943439890143109671236878941003432106543087656
|
||||
10129667872108743232198780987567650012343267890989943
|
||||
78734531231065654651015697898232109871054154901077830
|
||||
69632340345676544543234506701145696780567063212566321
|
||||
12541256543989035672103215012098785991278343103455410
|
||||
01230167612108120780043454123210034876369752101769511
|
||||
43456898909817431891012763204987121765459861019878700
|
||||
32197899768746532982367874215672100894312772923467011
|
||||
44089432897655673675498985365523456783203689876554322
|
||||
43476521784554984566780189474310327894104501298458943
|
||||
32562340603443295432110276589210016765067898347457654
|
||||
41001456512782106798023345341232108778754106756346655
|
||||
58989867425691065897654301250343419689603245891258743
|
||||
67670198304781478654761298765430589576512231230969512
|
||||
50501078213210569763890181056521677433443100945872402
|
||||
41432189362387659812083212347893478922109811876721321
|
||||
32343276651096543202144307438982560013078320125630430
|
||||
21054565789823430143435698729861011224565410432145561
|
||||
78769834658712894354998705610154398348901565589006776
|
||||
69876765541006765267888214567863287657652651671217889
|
||||
56945454532214890122379823098978101098343780980368923
|
||||
47834503654323012001456702112109780123210891276456914
|
||||
32322112567410163100014511003498898194541201345567805
|
||||
01012012398789654011723621014586767087687632436679876
|
||||
01201034498218765327898734765675432101598543567987015
|
||||
32789125567309014456783349898987013216967845678872126
|
||||
45694876323418123242124456787016524567856934569543034
|
||||
34543945410567032103023456689145434787643021078676545
|
||||
67432876509878749854510965670236543694532122189089496
|
||||
78761789034569858987627874321987231243231821672102387
|
||||
89450321123988567546596765345698100340100910565201256
|
||||
44321450210676875654587034276765657654327823434389855
|
||||
32340565012363966703456123189894398789016434325670765
|
||||
01051876765454567812890012007654289430145045410581678
|
||||
98762998898323234906721063218723176521032156921892569
|
||||
45101237012210105415430874349812067898149867865433454
|
||||
36788946543101076010987965456701098778928766456521043
|
||||
29897654218760187623875478309898105667810610347876542
|
||||
10898743009451296874566329214321234354320521298985031
|
||||
01734542112321345987017812105670985012131494567874120
|
||||
45629610321030996506323901078987876543012383456923454
|
||||
30018723478945887215489765212985432692105672321012765
|
||||
21167634569876774345677894303876501783234561030109876
|
||||
|
|
@ -5,26 +5,116 @@ from pathlib import Path
|
|||
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
||||
|
||||
import AOC_Helpers as utils
|
||||
import re
|
||||
import itertools
|
||||
import collections
|
||||
import math
|
||||
|
||||
def problem1(input: str) -> int | str:
|
||||
def problem1(input: str) -> int:
|
||||
output: int = 0
|
||||
lines = utils.read_lines(input)
|
||||
# Add your solution logic here
|
||||
|
||||
f = input.strip()
|
||||
|
||||
k = []
|
||||
file = 0
|
||||
for i, val in enumerate(f):
|
||||
if i % 2 == 0:
|
||||
k.extend([file] * int(val))
|
||||
file += 1
|
||||
else:
|
||||
k.extend(["."] * int(val))
|
||||
|
||||
empty_cache = [idx for idx, num in enumerate(k) if num == "."]
|
||||
|
||||
for i in range(len(k) - 1, 0, -1):
|
||||
if k[i] != ".":
|
||||
idx = empty_cache.pop(0)
|
||||
k[idx], k[i] = k[i], k[idx]
|
||||
if all(x == "." for x in k[k.index("."):]):
|
||||
break
|
||||
|
||||
output = sum(idx * num for idx, num in enumerate(k) if num != ".")
|
||||
return output
|
||||
|
||||
def problem2(input: str) -> int | str:
|
||||
def problem2(input: str) -> int:
|
||||
output: int = 0
|
||||
lines = utils.read_lines(input)
|
||||
# Add your solution logic here
|
||||
f = input.strip()
|
||||
|
||||
def print_output_visual(l):
|
||||
for i, (val, length) in enumerate(l):
|
||||
if val == None:
|
||||
print(f"{'.' * length}", end="")
|
||||
else:
|
||||
print(str(val) * length, end="")
|
||||
|
||||
k = [] # list of ranges
|
||||
file = 0
|
||||
for i, val in enumerate(f):
|
||||
if i % 2 == 0:
|
||||
k.append((file, int(val)))
|
||||
file += 1
|
||||
else:
|
||||
k.append((None, int(val)))
|
||||
|
||||
def find_empties(l):
|
||||
return [(idx, num) for idx, num in enumerate(l) if num[0] == None]
|
||||
|
||||
checked_maxes = set()
|
||||
|
||||
def find_max_of_non_checked(l):
|
||||
return sorted([(num, idx) for idx, num in enumerate(l) if num not in checked_maxes and num[0]], key=lambda x: x[0], reverse=True)
|
||||
|
||||
def combine_empty(l):
|
||||
new_l = []
|
||||
for i, (val, length) in enumerate(l):
|
||||
if val == None:
|
||||
if i > 0 and l[i-1][0] == None:
|
||||
new_l[-1] = (None, new_l[-1][1] + length)
|
||||
else:
|
||||
new_l.append((None, length))
|
||||
else:
|
||||
new_l.append((val, length))
|
||||
return new_l
|
||||
|
||||
while len(ncm := find_max_of_non_checked(k)) > 0:
|
||||
max_val, max_idx = ncm[0]
|
||||
checked_maxes.add(max_val)
|
||||
empties = find_empties(k)
|
||||
for idx, (_, length) in empties:
|
||||
if max_idx < idx: continue
|
||||
if length == max_val[1]:
|
||||
k[idx] = max_val
|
||||
k[max_idx] = (None, max_val[1])
|
||||
break
|
||||
if length > max_val[1]:
|
||||
k[idx] = max_val
|
||||
k[max_idx] = (None, max_val[1])
|
||||
k.insert(idx + 1, (None, length - max_val[1]))
|
||||
break
|
||||
k = combine_empty(k)
|
||||
|
||||
def calc_checksum_of_range(pos: int, r: tuple[int, int]) -> int:
|
||||
if r[0] == None:
|
||||
return 0
|
||||
return sum((pos + i) * r[0] for i in range(r[1]))
|
||||
|
||||
i = 0
|
||||
for idx, val in enumerate(k):
|
||||
output += calc_checksum_of_range(i, val)
|
||||
i += val[1]
|
||||
return output
|
||||
|
||||
def run_tests():
|
||||
test_cases = [
|
||||
("2333133121414131402", 1928),
|
||||
("12345", 40),
|
||||
("90909", 0),
|
||||
("", 0),
|
||||
("101010", 0)
|
||||
]
|
||||
|
||||
for i, (input_str, expected) in enumerate(test_cases):
|
||||
result = problem1(input_str)
|
||||
assert result == expected, f"Test case {i + 1} failed: expected {expected}, got {result}"
|
||||
print(f"Test case {i + 1} passed")
|
||||
|
||||
if __name__ == "__main__":
|
||||
input_path = utils.get_input_file(Path(__file__).resolve().parent / "data", 9)
|
||||
print(problem1(input_path))
|
||||
print(problem2(input_path))
|
||||
print(problem1(utils.read_file(input_path)))
|
||||
print(problem2(utils.read_file(input_path)))
|
||||
run_tests()
|
||||
|
|
@ -13,14 +13,77 @@ import math
|
|||
def problem1(input: str) -> int | str:
|
||||
output: int = 0
|
||||
lines = utils.read_lines(input)
|
||||
# Add your solution logic here
|
||||
|
||||
# Parse the topographic map
|
||||
map_height = len(lines)
|
||||
map_width = len(lines[0])
|
||||
topographic_map = [[int(height) for height in line] for line in lines]
|
||||
|
||||
# Directions for moving up, down, left, right
|
||||
directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
|
||||
|
||||
def bfs(start):
|
||||
queue = collections.deque([start])
|
||||
visited = set([start])
|
||||
reachable_nines = 0
|
||||
|
||||
while queue:
|
||||
x, y = queue.popleft()
|
||||
current_height = topographic_map[x][y]
|
||||
|
||||
for dx, dy in directions:
|
||||
nx, ny = x + dx, y + dy
|
||||
if 0 <= nx < map_height and 0 <= ny < map_width and (nx, ny) not in visited:
|
||||
next_height = topographic_map[nx][ny]
|
||||
if next_height == current_height + 1:
|
||||
if next_height == 9:
|
||||
reachable_nines += 1
|
||||
queue.append((nx, ny))
|
||||
visited.add((nx, ny))
|
||||
|
||||
return reachable_nines
|
||||
|
||||
# Find all trailheads and calculate their scores
|
||||
for i in range(map_height):
|
||||
for j in range(map_width):
|
||||
if topographic_map[i][j] == 0:
|
||||
output += bfs((i, j))
|
||||
|
||||
return output
|
||||
|
||||
def problem2(input: str) -> int | str:
|
||||
output: int = 0
|
||||
lines = utils.read_lines(input)
|
||||
# Add your solution logic here
|
||||
|
||||
# Parse the topographic map
|
||||
map_height = len(lines)
|
||||
map_width = len(lines[0])
|
||||
topographic_map = [[int(height) for height in line] for line in lines]
|
||||
|
||||
# Directions for moving up, down, left, right
|
||||
directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
|
||||
|
||||
def dfs(x, y, visited):
|
||||
if topographic_map[x][y] == 9:
|
||||
return 1
|
||||
|
||||
count = 0
|
||||
for dx, dy in directions:
|
||||
nx, ny = x + dx, y + dy
|
||||
if 0 <= nx < map_height and 0 <= ny < map_width and (nx, ny) not in visited:
|
||||
if topographic_map[nx][ny] == topographic_map[x][y] + 1:
|
||||
visited.add((nx, ny))
|
||||
count += dfs(nx, ny, visited)
|
||||
visited.remove((nx, ny))
|
||||
|
||||
return count
|
||||
|
||||
# Find all trailheads and calculate their ratings
|
||||
for i in range(map_height):
|
||||
for j in range(map_width):
|
||||
if topographic_map[i][j] == 0:
|
||||
visited = set([(i, j)])
|
||||
output += dfs(i, j, visited)
|
||||
|
||||
return output
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue