Compare commits
8 Commits
5e782cf3d7
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| c9e877e98b | |||
| c9d83911ac | |||
| 6cbcfec987 | |||
| 8ed21157a0 | |||
| d800679291 | |||
| ae98a486a9 | |||
| 9e21d8d9c8 | |||
| 42bab0cb9e |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -3,3 +3,4 @@ cookies.txt
|
|||||||
**/input
|
**/input
|
||||||
__pycache__
|
__pycache__
|
||||||
.venv
|
.venv
|
||||||
|
toy_input
|
||||||
19
day10/common.py
Normal file
19
day10/common.py
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
from typing import TypeAlias
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
class Operation(Enum):
|
||||||
|
NOOP = 'noop'
|
||||||
|
ADDX = 'addx'
|
||||||
|
|
||||||
|
Instruction: TypeAlias = tuple[Operation, int|None]
|
||||||
|
|
||||||
|
def parse(filename: str) -> list[Instruction]:
|
||||||
|
instructions = []
|
||||||
|
with open(filename) as f:
|
||||||
|
while line:=f.readline().strip("\n"):
|
||||||
|
oper = line.split()
|
||||||
|
if len(oper) > 1:
|
||||||
|
instructions.append((Operation(oper[0]), int(oper[1])))
|
||||||
|
else:
|
||||||
|
instructions.append((Operation(oper[0]), None))
|
||||||
|
return instructions
|
||||||
33
day10/part1.py
Executable file
33
day10/part1.py
Executable file
@@ -0,0 +1,33 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
from common import parse, Operation, Instruction
|
||||||
|
|
||||||
|
def tick(instruction: Instruction, clock: int, x: int) -> tuple[int,int]:
|
||||||
|
match instruction[0]:
|
||||||
|
case Operation.NOOP:
|
||||||
|
return clock+1, x
|
||||||
|
case Operation.ADDX:
|
||||||
|
return clock+2, x+ instruction[1]
|
||||||
|
|
||||||
|
def solve(input: list[Instruction])->int:
|
||||||
|
clock = 0
|
||||||
|
x = 1
|
||||||
|
current_x = x
|
||||||
|
important_ticks = [20,60,100,140,180,220]
|
||||||
|
signal_strengths = []
|
||||||
|
for instruction in input:
|
||||||
|
clock, x = tick(instruction, clock, x)
|
||||||
|
if important_ticks != [] and clock >= important_ticks[0]:
|
||||||
|
print(important_ticks[0], current_x)
|
||||||
|
signal_strengths.append(current_x * important_ticks.pop(0))
|
||||||
|
current_x = x
|
||||||
|
print(signal_strengths)
|
||||||
|
return sum(signal_strengths)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print(solve(parse("input")))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
3
day2/common.py
Normal file
3
day2/common.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
def parse(filename: str) -> list[tuple[str, str]]:
|
||||||
|
with open(filename) as f:
|
||||||
|
return [tuple(a[:-1].split()) for a in f.readlines()]
|
||||||
37
day2/part1.py
Normal file
37
day2/part1.py
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
from common import parse
|
||||||
|
|
||||||
|
|
||||||
|
def round(game: tuple[str, str]) -> int:
|
||||||
|
if game[0] == "A":
|
||||||
|
if game[1] == "X":
|
||||||
|
return 1 + 3
|
||||||
|
elif game[1] == "Y":
|
||||||
|
return 2 + 6
|
||||||
|
else:
|
||||||
|
return 3 + 0
|
||||||
|
elif game[0] == "B":
|
||||||
|
if game[1] == "X":
|
||||||
|
return 1 + 0
|
||||||
|
elif game[1] == "Y":
|
||||||
|
return 2 + 3
|
||||||
|
else:
|
||||||
|
return 3 + 6
|
||||||
|
else:
|
||||||
|
if game[1] == "X":
|
||||||
|
return 1 + 6
|
||||||
|
elif game[1] == "Y":
|
||||||
|
return 2 + 0
|
||||||
|
else:
|
||||||
|
return 3 + 3
|
||||||
|
|
||||||
|
|
||||||
|
def solve(strategy: list[tuple[str, str]]) -> int:
|
||||||
|
return sum(map(round, strategy))
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print(solve(parse("input")))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
37
day2/part2.py
Normal file
37
day2/part2.py
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
from common import parse
|
||||||
|
|
||||||
|
|
||||||
|
def round(game: tuple[str, str]) -> int:
|
||||||
|
if game[0] == "A":
|
||||||
|
if game[1] == "X":
|
||||||
|
return 3
|
||||||
|
elif game[1] == "Y":
|
||||||
|
return 3 + 1
|
||||||
|
else:
|
||||||
|
return 6 + 2
|
||||||
|
elif game[0] == "B":
|
||||||
|
if game[1] == "X":
|
||||||
|
return 1
|
||||||
|
elif game[1] == "Y":
|
||||||
|
return 3 + 2
|
||||||
|
else:
|
||||||
|
return 6 + 3
|
||||||
|
else:
|
||||||
|
if game[1] == "X":
|
||||||
|
return 2
|
||||||
|
elif game[1] == "Y":
|
||||||
|
return 3 + 3
|
||||||
|
else:
|
||||||
|
return 6 + 1
|
||||||
|
|
||||||
|
|
||||||
|
def solve(strategy: list[tuple[str, str]]) -> int:
|
||||||
|
return sum(map(round, strategy))
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print(solve(parse("input")))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
1
day3/common.py
Normal file
1
day3/common.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
# Nothing in common
|
||||||
22
day3/part1.py
Normal file
22
day3/part1.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
from string import ascii_lowercase
|
||||||
|
|
||||||
|
|
||||||
|
def parse(filename: str) -> list[tuple[str, str]]:
|
||||||
|
with open(filename) as f:
|
||||||
|
return list(map(lambda x: (x[0 : int((len(x) - 1) / 2)], x[int((len(x) - 1) / 2) : -1]), f.readlines()))
|
||||||
|
|
||||||
|
|
||||||
|
def convert(char: str) -> int:
|
||||||
|
return ord(char) - 96 if char in ascii_lowercase else ord(char) - 38
|
||||||
|
|
||||||
|
|
||||||
|
def solve(bagpacks: list[tuple[str, str]]) -> int:
|
||||||
|
return sum(map(convert, [(filter(lambda x: x in bagpack[1], bagpack[0])).__next__() for bagpack in bagpacks]))
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print(solve(parse("input")))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
38
day3/part2.py
Normal file
38
day3/part2.py
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
from string import ascii_lowercase
|
||||||
|
|
||||||
|
|
||||||
|
def parse(filename: str) -> list[tuple[str, str, str]]:
|
||||||
|
groups = []
|
||||||
|
i = 0
|
||||||
|
group = []
|
||||||
|
with open(filename) as f:
|
||||||
|
for line in f.readlines():
|
||||||
|
if i % 3 == 0 and i != 0:
|
||||||
|
groups.append(group)
|
||||||
|
group = []
|
||||||
|
group.append(line[:-1])
|
||||||
|
i += 1
|
||||||
|
groups.append(group)
|
||||||
|
return tuple(groups)
|
||||||
|
|
||||||
|
|
||||||
|
def convert(char: str) -> int:
|
||||||
|
return ord(char) - 96 if char in ascii_lowercase else ord(char) - 38
|
||||||
|
|
||||||
|
|
||||||
|
def common_character(group: tuple[str, str, str]) -> str:
|
||||||
|
assert len(group) == 3
|
||||||
|
b1, b2, b3 = group
|
||||||
|
return filter(lambda c: c in b2 and c in b3, b1).__next__()
|
||||||
|
|
||||||
|
|
||||||
|
def solve(groups: list[tuple[str, str, str]]) -> int:
|
||||||
|
return sum(map(convert, map(common_character, groups)))
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print(solve(parse("input")))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
29
day4/common.py
Normal file
29
day4/common.py
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import re
|
||||||
|
from typing import NamedTuple
|
||||||
|
|
||||||
|
|
||||||
|
class Range(NamedTuple):
|
||||||
|
first: int
|
||||||
|
last: int
|
||||||
|
|
||||||
|
def __contains__(self, other: Range) -> bool:
|
||||||
|
return self.first <= other.first and self.last >= other.last
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.first}-{self.last}"
|
||||||
|
|
||||||
|
def overlaps_with(self, other: Range) -> bool:
|
||||||
|
return Range(other.first, other.first) in self or Range(other.last, other.last) in self
|
||||||
|
|
||||||
|
|
||||||
|
def parse(filename: str) -> list[tuple[Range, Range]]:
|
||||||
|
pairs = []
|
||||||
|
with open(filename) as f:
|
||||||
|
while line := f.readline():
|
||||||
|
if match := re.match(r"(\d+)-(\d+),(\d+)-(\d+)", line):
|
||||||
|
pairs.append(
|
||||||
|
(Range(int(match.group(1)), int(match.group(2))), Range(int(match.group(3)), int(match.group(4))))
|
||||||
|
)
|
||||||
|
return pairs
|
||||||
13
day4/part1.py
Normal file
13
day4/part1.py
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
from common import Range, parse
|
||||||
|
|
||||||
|
|
||||||
|
def solve(input: list[tuple[Range, Range]]) -> int:
|
||||||
|
return len(list(filter(lambda x: x[0] in x[1] or x[1] in x[0], input)))
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print(solve(parse("input")))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
13
day4/part2.py
Normal file
13
day4/part2.py
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
from common import Range, parse
|
||||||
|
|
||||||
|
|
||||||
|
def solve(input: list[tuple[Range, Range]]) -> int:
|
||||||
|
return len(list(filter(lambda x: x[0].overlaps_with(x[1]) or x[1].overlaps_with(x[0]), input)))
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print(solve(parse("input")))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
54
day5/common.py
Normal file
54
day5/common.py
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import re
|
||||||
|
from copy import deepcopy
|
||||||
|
|
||||||
|
|
||||||
|
def parse(filename: str) -> tuple[list[list[str]], list[tuple[int, int, int]]]:
|
||||||
|
stacks_of_crates = []
|
||||||
|
operations = []
|
||||||
|
finalised_stacks = False
|
||||||
|
with open(filename) as f:
|
||||||
|
while not finalised_stacks:
|
||||||
|
row = f.readline()[:-1]
|
||||||
|
if re.match(r"(\s{3}|\[.\])\s?", row):
|
||||||
|
crates = []
|
||||||
|
while row != "":
|
||||||
|
crate = row[0:3]
|
||||||
|
crates.append(crate[1])
|
||||||
|
row = row[4:]
|
||||||
|
for idx, crate in enumerate(crates):
|
||||||
|
if crate != " ":
|
||||||
|
if idx < len(stacks_of_crates):
|
||||||
|
stacks_of_crates[idx].append(crate)
|
||||||
|
else:
|
||||||
|
stacks_of_crates.append([crate])
|
||||||
|
else:
|
||||||
|
if idx >= len(stacks_of_crates):
|
||||||
|
stacks_of_crates.append([])
|
||||||
|
else:
|
||||||
|
finalised_stacks = True
|
||||||
|
numbers = re.findall(r" \d ", row)
|
||||||
|
last = int(numbers[len(numbers) - 1])
|
||||||
|
assert last == len(stacks_of_crates)
|
||||||
|
f.readline()
|
||||||
|
while line := f.readline():
|
||||||
|
if match := re.match(r"move (\d+) from (\d) to (\d)", line):
|
||||||
|
operations.append((int(match.group(1)), int(match.group(2)), int(match.group(3))))
|
||||||
|
return list(map(lambda x: list(reversed(x)), stacks_of_crates)), operations
|
||||||
|
|
||||||
|
|
||||||
|
def pretty_print(stacks: list[list[str]]) -> None:
|
||||||
|
max_len = max(map(len, stacks))
|
||||||
|
the_stacks = deepcopy(stacks)
|
||||||
|
for idx, stack in enumerate(the_stacks):
|
||||||
|
for i in range(max_len - len(stack)):
|
||||||
|
the_stacks[idx].append(" ")
|
||||||
|
for i in range(max_len):
|
||||||
|
for j in range(len(the_stacks)):
|
||||||
|
char = the_stacks[j].pop()
|
||||||
|
if char != " ":
|
||||||
|
print(f"[{char}]", end=" ")
|
||||||
|
else:
|
||||||
|
print(" ", end=" ")
|
||||||
|
print("")
|
||||||
|
print("".join([f" {a} " for a in range(1, len(the_stacks) + 1)]))
|
||||||
|
pass
|
||||||
26
day5/part1.py
Normal file
26
day5/part1.py
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
from common import parse # , pretty_print
|
||||||
|
|
||||||
|
|
||||||
|
def move(stacks: list[list[str]], operation: tuple[int, int, int]) -> list[list[str]]:
|
||||||
|
# print(f"move {operation[0]} from {operation[1]} to {operation[2]}")
|
||||||
|
for i in range(operation[0]):
|
||||||
|
num = stacks[operation[1] - 1].pop()
|
||||||
|
stacks[operation[2] - 1].append(num)
|
||||||
|
return stacks
|
||||||
|
|
||||||
|
|
||||||
|
def solve(input: tuple[list[list[str]], list[tuple[int, int, int]]]) -> str:
|
||||||
|
stacks, operations = input
|
||||||
|
# pretty_print(stacks)
|
||||||
|
for operation in operations:
|
||||||
|
stacks = move(stacks, operation)
|
||||||
|
# pretty_print(stacks)
|
||||||
|
return "".join(map(lambda x: x[len(x) - 1] if len(x) != 0 else "", stacks))
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print(solve(parse("input")))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
27
day5/part2.py
Normal file
27
day5/part2.py
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
from common import parse # , pretty_print
|
||||||
|
|
||||||
|
|
||||||
|
def move(stacks: list[list[str]], operation: tuple[int, int, int]) -> list[list[str]]:
|
||||||
|
# print(f"move {operation[0]} from {operation[1]} to {operation[2]}")
|
||||||
|
dst = operation[2] - 1
|
||||||
|
orig = operation[1] - 1
|
||||||
|
stacks[dst] += stacks[orig][len(stacks[orig]) - operation[0] : len(stacks[orig])]
|
||||||
|
stacks[orig] = stacks[orig][: len(stacks[orig]) - operation[0]]
|
||||||
|
return stacks
|
||||||
|
|
||||||
|
|
||||||
|
def solve(input: tuple[list[list[str]], list[tuple[int, int, int]]]) -> str:
|
||||||
|
stacks, operations = input
|
||||||
|
# pretty_print(stacks)
|
||||||
|
for operation in operations:
|
||||||
|
stacks = move(stacks, operation)
|
||||||
|
# pretty_print(stacks)
|
||||||
|
return "".join(map(lambda x: x[len(x) - 1] if len(x) != 0 else "", stacks))
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print(solve(parse("input")))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
11904
day5/trac.log
Normal file
11904
day5/trac.log
Normal file
File diff suppressed because it is too large
Load Diff
3
day6/common.py
Normal file
3
day6/common.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
def parse(filename: str):
|
||||||
|
with open(filename) as f:
|
||||||
|
return f.readline()[:-1]
|
||||||
20
day6/part1.py
Normal file
20
day6/part1.py
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
from common import parse
|
||||||
|
|
||||||
|
|
||||||
|
def all_different_characters(input: str) -> bool:
|
||||||
|
return all(map(lambda c: input.count(c) == 1, input))
|
||||||
|
|
||||||
|
|
||||||
|
def solve(input: str) -> int:
|
||||||
|
i = 0
|
||||||
|
while i < len(input) and not all_different_characters(input[i : i + 4]):
|
||||||
|
i += 1
|
||||||
|
return i + 4
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print(solve(parse("input")))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
20
day6/part2.py
Normal file
20
day6/part2.py
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
from common import parse
|
||||||
|
|
||||||
|
|
||||||
|
def all_different_characters(input: str) -> bool:
|
||||||
|
return all(map(lambda c: input.count(c) == 1, input))
|
||||||
|
|
||||||
|
|
||||||
|
def solve(input: str) -> int:
|
||||||
|
i = 0
|
||||||
|
while i < len(input) and not all_different_characters(input[i : i + 14]):
|
||||||
|
i += 1
|
||||||
|
return i + 14
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print(solve(parse("input")))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
71
day7/common.py
Normal file
71
day7/common.py
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import re
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class File:
|
||||||
|
name: str
|
||||||
|
size: int
|
||||||
|
|
||||||
|
def __equals__(self, other):
|
||||||
|
return self.name == other.name and self.size == other.size
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Folder:
|
||||||
|
name: str
|
||||||
|
parent: Folder | None
|
||||||
|
children: list[Folder | File]
|
||||||
|
|
||||||
|
def __equals__(self, other):
|
||||||
|
return self.name == other.name and self.parent == other.parent
|
||||||
|
|
||||||
|
@property
|
||||||
|
def full_name(self):
|
||||||
|
if self.parent is None:
|
||||||
|
return "/"
|
||||||
|
else:
|
||||||
|
return self.parent.full_name + f"/{self.name}"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def size(self):
|
||||||
|
return sum(map(lambda x: x.size, self.children))
|
||||||
|
|
||||||
|
def __lt__(self, other):
|
||||||
|
return self.size < other.size
|
||||||
|
|
||||||
|
|
||||||
|
def pretty_print(folder: Folder, depth: int = 0) -> None:
|
||||||
|
print("".join([" " for i in range(depth + 1)]), end="- ")
|
||||||
|
print(f"{folder.name} (dir)")
|
||||||
|
for object in folder.children:
|
||||||
|
if type(object) is Folder:
|
||||||
|
pretty_print(object, depth + 1)
|
||||||
|
else:
|
||||||
|
print("".join([" " for i in range(depth + 2)]), end="- ")
|
||||||
|
print(f"{object.name} (file, size={object.size})")
|
||||||
|
|
||||||
|
|
||||||
|
def parse(filename: str) -> Folder:
|
||||||
|
filesystem = Folder(name="/", parent=None, children=[])
|
||||||
|
with open(filename) as f:
|
||||||
|
f.readline()
|
||||||
|
current = filesystem
|
||||||
|
while line := f.readline()[:-1]:
|
||||||
|
if line[0] == "$":
|
||||||
|
if match := re.match(r"\$ cd (.+)", line):
|
||||||
|
folder_name = match.group(1)
|
||||||
|
if folder_name != "..":
|
||||||
|
current = filter(lambda x: x.name == folder_name, current.children).__next__()
|
||||||
|
else:
|
||||||
|
current = current.parent
|
||||||
|
else:
|
||||||
|
if match := re.match(r"(\d+) ((?:\w|.)+)", line):
|
||||||
|
fichier = File(name=match.group(2), size=int(match.group(1)))
|
||||||
|
current.children.append(fichier)
|
||||||
|
elif match := re.match(r"dir (\w+)", line):
|
||||||
|
folder = Folder(name=match.group(1), parent=current, children=[])
|
||||||
|
current.children.append(folder)
|
||||||
|
return filesystem
|
||||||
18
day7/part1.py
Executable file
18
day7/part1.py
Executable file
@@ -0,0 +1,18 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
from common import Folder, parse
|
||||||
|
|
||||||
|
|
||||||
|
def solve(folder: Folder) -> int:
|
||||||
|
childrens_sizes = sum(map(lambda x: solve(x), filter(lambda y: type(y) is Folder, folder.children)))
|
||||||
|
if folder.size >= 100000:
|
||||||
|
return childrens_sizes
|
||||||
|
else:
|
||||||
|
return folder.size + childrens_sizes
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print(solve(parse("input")))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
25
day7/part2.py
Executable file
25
day7/part2.py
Executable file
@@ -0,0 +1,25 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
from common import Folder, parse
|
||||||
|
|
||||||
|
|
||||||
|
def folders_big_enough(folder: Folder, threshold: int) -> list[Folder]:
|
||||||
|
if folder.size < threshold:
|
||||||
|
return []
|
||||||
|
else:
|
||||||
|
folder_list = [folder]
|
||||||
|
for child in filter(lambda x: type(x) is Folder, folder.children):
|
||||||
|
folder_list += folders_big_enough(child, threshold)
|
||||||
|
return folder_list
|
||||||
|
|
||||||
|
|
||||||
|
def solve(folder: Folder) -> int:
|
||||||
|
threshold = 30000000 - (70000000 - folder.size)
|
||||||
|
return min(sorted(folders_big_enough(folder, threshold))).size
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print(solve(parse("input")))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
3
day8/common.py
Normal file
3
day8/common.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
def parse(filename: str) -> list[list[int]]:
|
||||||
|
with open(filename) as f:
|
||||||
|
return [[int(i) for i in line.strip("\n")] for line in f.readlines()]
|
||||||
27
day8/part1.py
Executable file
27
day8/part1.py
Executable file
@@ -0,0 +1,27 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
from common import parse
|
||||||
|
|
||||||
|
|
||||||
|
def is_visible(forest: list[list[int]], x: int, y: int) -> bool:
|
||||||
|
height = forest[y][x]
|
||||||
|
west = forest[y][0:x]
|
||||||
|
east = forest[y][x + 1 :]
|
||||||
|
north = [forest[i][x] for i in range(y)]
|
||||||
|
south = [forest[i][x] for i in range(y + 1, len(forest))]
|
||||||
|
return any(map(lambda x: x == [] or max(x) < height, (west, east, north, south)))
|
||||||
|
|
||||||
|
|
||||||
|
def solve(input: list[list[int]]) -> int:
|
||||||
|
count = 0
|
||||||
|
for y, line in enumerate(input):
|
||||||
|
for x, tree in enumerate(line):
|
||||||
|
count += 1 if is_visible(input, x, y) else 0
|
||||||
|
return count
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print(solve(parse("input")))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
57
day8/part2.py
Executable file
57
day8/part2.py
Executable file
@@ -0,0 +1,57 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
from common import parse
|
||||||
|
|
||||||
|
|
||||||
|
def scenic_score(forest: list[list[int]], x: int, y: int) -> int:
|
||||||
|
height = forest[y][x]
|
||||||
|
sw = se = sn = ss = 0
|
||||||
|
west = reversed(forest[y][0:x])
|
||||||
|
for w in west:
|
||||||
|
if w < height:
|
||||||
|
sw += 1
|
||||||
|
continue
|
||||||
|
elif w == height:
|
||||||
|
sw += 1
|
||||||
|
break
|
||||||
|
east = forest[y][x + 1 :]
|
||||||
|
for e in east:
|
||||||
|
if e < height:
|
||||||
|
se += 1
|
||||||
|
continue
|
||||||
|
elif e == height:
|
||||||
|
se += 1
|
||||||
|
break
|
||||||
|
north = reversed([forest[i][x] for i in range(y)])
|
||||||
|
for n in north:
|
||||||
|
if n < height:
|
||||||
|
sn += 1
|
||||||
|
continue
|
||||||
|
elif n == height:
|
||||||
|
sn += 1
|
||||||
|
break
|
||||||
|
south = [forest[i][x] for i in range(y + 1, len(forest))]
|
||||||
|
for s in south:
|
||||||
|
if s < height:
|
||||||
|
ss += 1
|
||||||
|
continue
|
||||||
|
elif s == height:
|
||||||
|
ss += 1
|
||||||
|
break
|
||||||
|
|
||||||
|
return sw * se * sn * ss
|
||||||
|
|
||||||
|
|
||||||
|
def solve(input: list[list[int]]) -> int:
|
||||||
|
maxi = 0
|
||||||
|
for y, line in enumerate(input):
|
||||||
|
for x, tree in enumerate(input):
|
||||||
|
maxi = max(maxi, scenic_score(input, x, y))
|
||||||
|
return maxi
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print(solve(parse("input")))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
day=$1
|
day=$1
|
||||||
mkdir day${day}
|
mkdir day${day}
|
||||||
|
cp template/* day${day}
|
||||||
curl -o day${day}/input --cookie ~/AdventOfCode/2022/cookies.txt https://adventofcode.com/2022/day/$day/input
|
curl -o day${day}/input --cookie ~/AdventOfCode/2022/cookies.txt https://adventofcode.com/2022/day/$day/input
|
||||||
|
|||||||
3
template/common.py
Normal file
3
template/common.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
def parse(filename: str):
|
||||||
|
with open(filename) as f:
|
||||||
|
return [line[:-1] for line in f.readlines()]
|
||||||
14
template/part1.py
Executable file
14
template/part1.py
Executable file
@@ -0,0 +1,14 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
from common import parse
|
||||||
|
|
||||||
|
|
||||||
|
def solve(input):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print(solve(parse("input")))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user