Compare commits

..

1 Commits
main ... day07

Author SHA1 Message Date
earnest ma 6b0dfeb78c
2022/day07: WIP
ci/woodpecker/pr/woodpecker Pipeline was successful Details
2022-12-10 12:02:51 -05:00
45 changed files with 1160 additions and 1457 deletions

View File

@ -1,4 +0,0 @@
# Do not edit this file. To specify the files to encrypt, create your own
# .gitattributes file in the directory where your files are.
* !filter !diff
*.gpg binary

View File

@ -1 +0,0 @@
„^`Iýß)x%@î$øn:¡ Gßež0ý<30>ÈäX—(‡Ñ˜Œ=âC3'p0Äctaná)™—ïoɱ±4Âl9¥ïÚ<C3AF><11>]/ƒ®gò¢¥ \ˆ¹x±7'¤ÒÀí¾lÝ5ç´1Ò¼ŽÍ,‡SfT—ó-ëlâ±½msË*ÜÚJï-ÿ<>©«8I^2Ôm½€TâŽÁ­ewþ×Ï)¬öHŠ½Í¿JÖd_9¥ñaæG‰Ë£ëu¤QHMM_ýwl˜S´ö_芕Ö*÷«¡MeDUÎûÙZb¨a§É#áMOO¾Gˆü@D¹záu@åma,Û7ª×uU¥Ä»É)( ¹‰¿…ÒzdQ@—}Ö“ž‚¦

1
.gitattributes vendored
View File

@ -1 +0,0 @@
*.txt filter=git-crypt diff=git-crypt

View File

@ -6,18 +6,9 @@ pipeline:
when:
event: push
branch: main
secrets: [ gpg_keyfile ]
commands:
- apk add --no-cache git-crypt python3 poetry just
- echo "$GPG_KEYFILE" | base64 -d > tmp
- git-crypt unlock tmp
- rm tmp
- echo "===== 2015 ====="
- cd 2015
- apk add --no-cache python3 poetry just
- echo "===== 2022 ====="
- cd 2022
- poetry install --no-interaction --no-root
- just
- cd ..
# - echo "===== 2022 ====="
# - cd 2022
# - poetry install --no-interaction --no-root
# - just

0
2015/.gitignore vendored
View File

View File

@ -1,12 +0,0 @@
# check
default: check
# show this help (just --list)
help:
just --list
# lint and run tests
check:
poetry run black . --check
poetry run pytest

View File

@ -1 +0,0 @@
# Advent of Code, 2015 (in 2023, for fun)

View File

@ -1,32 +0,0 @@
#!/usr/bin/env python3
from typing import TextIO
f = open("day01.txt", "r")
floors = f.read().strip()
def part1() -> int:
return 0 + floors.count("(") - floors.count(")")
def part2() -> int:
position = 1
current = 0
for a in floors:
if a == "(":
current += 1
else:
current -= 1
if current == -1:
return position
position += 1
if __name__ == "__main__":
print(part1())
print(part2())

Binary file not shown.

View File

@ -1,11 +0,0 @@
#!/usr/bin/env python3
from day01 import *
def test_part1() -> None:
assert part1() == 74
def test_part2() -> None:
assert part2() == 1795

View File

@ -1,42 +0,0 @@
#!/usr/bin/env python3
import functools, operator
from typing import TextIO
def part1(dimensions: TextIO) -> int:
total = 0
for line in dimensions:
line = line.strip().split("x")
line = [int(i) for i in line]
s_area = [2 * line[0] * line[1], 2 * line[1] * line[2], 2 * line[0] * line[2]]
total += min(s_area) // 2
total += sum(s_area)
return total
def part2(dimensions: TextIO) -> int:
total = 0
for line in dimensions:
line = line.strip().split("x")
line = [int(i) for i in line]
line = sorted(line)
total += (2 * line[0]) + (2 * line[1])
total += functools.reduce(operator.mul, line)
return total
if __name__ == "__main__":
f = open("day02.txt", "r")
print(part1(f))
f = open("day02.txt", "r")
print(part2(f))

Binary file not shown.

View File

@ -1,11 +0,0 @@
from day02 import *
def test_part1() -> None:
with open("day02.txt", "r") as f:
assert part1(f) == 1598415
def test_part2() -> None:
with open("day02.txt", "r") as f:
assert part2(f) == 3812909

View File

@ -1,64 +0,0 @@
#!/usr/bin/env python3
from typing import TextIO
grid: dict[tuple[int, int], bool] = {(0, 0): True}
instr: dict[str, tuple[int, int]] = {
">": (0, 1),
"<": (0, -1),
"^": (1, 0),
"v": (-1, 0),
}
f = open("day03.txt", "r")
directions = f.read().strip()
def part1() -> int:
houses = 1
current = (0, 0)
for char in directions:
current = (current[0] + instr[char][0], current[1] + instr[char][1])
if current not in grid:
grid[current] = True
houses += 1
return houses
def part2() -> int:
# reset grid
grid = {(0, 0): True}
houses = 1
current_santa = (0, 0)
current_robo = (0, 0)
for i in range(0, len(directions), 2):
current_santa = (
current_santa[0] + instr[directions[i]][0],
current_santa[1] + instr[directions[i]][1],
)
if current_santa not in grid:
grid[current_santa] = True
houses += 1
if i + 1 < len(directions):
current_robo = (
current_robo[0] + instr[directions[i + 1]][0],
current_robo[1] + instr[directions[i + 1]][1],
)
if current_robo not in grid:
grid[current_robo] = True
houses += 1
return houses
if __name__ == "__main__":
print(part1())
print(part2())

Binary file not shown.

View File

@ -1,11 +0,0 @@
#!/usr/bin/env python3
from day03 import *
def test_part1() -> None:
assert part1() == 2572
def test_part2() -> None:
assert part2() == 2631

View File

@ -1,38 +0,0 @@
#!/usr/bin/env python3
import hashlib
f = open("day04.txt", "r")
pin = f.read().strip()
def part1() -> int:
num = 1
while True:
res = hashlib.md5(f"{pin}{num}".encode("UTF-8")).hexdigest()
# print(num, res)
if res[0:5] == "00000":
return num
num += 1
def part2() -> int:
num = 1
while True:
res = hashlib.md5(f"{pin}{num}".encode("UTF-8")).hexdigest()
# print(num, res)
if res[0:6] == "000000":
return num
num += 1
if __name__ == "__main__":
print(part1())
print(part2())

Binary file not shown.

View File

@ -1,11 +0,0 @@
#!/usr/bin/env python3
from day04 import *
def test_part1() -> None:
assert part1() == 346386
def test_part2() -> None:
assert part2() == 9958218

View File

@ -1,95 +0,0 @@
#!/usr/bin/env python3
from typing import TextIO
def nice_or_naughty(string: str) -> int:
"""0 for naughty and 1 for nice"""
# count vowels
cv = (
string.count("a")
+ string.count("e")
+ string.count("i")
+ string.count("o")
+ string.count("u")
)
if cv < 3:
return 0
# twice in a row
dbl = 0
for ch in range(0, len(string)):
if len(string) > ch + 1 and string[ch] == string[ch + 1]:
dbl += 1
if dbl == 0:
return 0
# naughty strings
n = ("ab", "cd", "pq", "xy")
for x in n:
if x in string:
return 0
return 1
def nn2(string: str) -> int:
# first
a = 0 # we can only have 0 or 1, because of the return
# not anymore b/c it's BOTH, but whatever
for c in range(0, len(string) - 1):
pair = string[c : c + 2]
# print("pair is", pair)
for d in range(c + 2, len(string) - 1): # , len(string) - 2):
# print("trying to match", pair, string[d : d + 2])
if d + 1 < len(string) and string[d : d + 2] == pair:
# print("yay")
a += 1
break
else: # ?? huuhhh? https://stackoverflow.com/questions/653509/breaking-out-of-nested-loops
continue
break
# second
b = 0
for c in range(0, len(string) - 2):
if string[c] == string[c + 2]:
b += 1
break
if a == 1 and b == 1:
return 1
return 0
def part1(file: TextIO) -> int:
count = 0
for string in file:
count += nice_or_naughty(string.strip())
return count
def part2(file: TextIO) -> int:
count = 0
for string in file:
count += nn2(string.strip())
return count
if __name__ == "__main__":
with open("day05.txt", "r") as f:
print(part1(f))
with open("day05.txt", "r") as f:
print(part2(f))

Binary file not shown.

View File

@ -1,13 +0,0 @@
#!/usr/bin/env python3
from day05 import *
def test_part1() -> None:
with open("day05.txt", "r") as f:
assert part1(f) == 238
def test_part2() -> None:
with open("day05.txt", "r") as f:
assert part2(f) == 69

View File

@ -1,92 +0,0 @@
#!/usr/bin/env python3
from typing import TextIO
grid: dict[tuple, bool] = {}
newgrid: dict[tuple, int] = {}
def part1(instructions: TextIO) -> int:
for ins in instructions:
ins = ins.strip().split()
# print(ins)
command = ins[0:2]
if len(ins) == 5:
fr = tuple([int(x) for x in ins[2].split(",")])
else:
fr = tuple([int(x) for x in ins[1].split(",")])
to = tuple([int(x) for x in ins[-1].split(",")])
if command == ["turn", "off"]:
for x in range(fr[0], to[0] + 1):
for y in range(fr[1], to[1] + 1):
if (x, y) in grid:
del grid[(x, y)]
elif command == ["turn", "on"]:
for x in range(fr[0], to[0] + 1):
for y in range(fr[1], to[1] + 1):
if (x, y) not in grid:
grid[(x, y)] = True
else: # Toggle
for x in range(fr[0], to[0] + 1):
for y in range(fr[1], to[1] + 1):
if (x, y) not in grid:
grid[(x, y)] = True
else:
del grid[(x, y)]
return len(grid)
def part2(instructions: TextIO) -> int:
for ins in instructions:
ins = ins.strip().split()
command = ins[0:2]
if len(ins) == 5:
fr = tuple([int(x) for x in ins[2].split(",")])
else:
fr = tuple([int(x) for x in ins[1].split(",")])
to = tuple([int(x) for x in ins[-1].split(",")])
if command == ["turn", "off"]:
for x in range(fr[0], to[0] + 1):
for y in range(fr[1], to[1] + 1):
if (x, y) not in newgrid:
newgrid[(x, y)] = 0
elif newgrid[(x, y)] != 0:
newgrid[(x, y)] -= 1
elif command == ["turn", "on"]:
for x in range(fr[0], to[0] + 1):
for y in range(fr[1], to[1] + 1):
if (x, y) not in newgrid:
newgrid[(x, y)] = 1
else:
newgrid[(x, y)] += 1
else: # Toggle
for x in range(fr[0], to[0] + 1):
for y in range(fr[1], to[1] + 1):
if (x, y) not in newgrid:
newgrid[(x, y)] = 2
else:
newgrid[(x, y)] += 2
return sum(newgrid.values())
if __name__ == "__main__":
with open("day06.txt", "r") as f:
print(part1(f))
with open("day06.txt", "r") as f:
print(part2(f))

Binary file not shown.

View File

@ -1,13 +0,0 @@
#!/usr/bin/env python3
from day06 import *
def test_part1() -> None:
with open("day06.txt", "r") as f:
assert part1(f) == 400410
def test_part2() -> None:
with open("day06.txt", "r") as f:
assert part2(f) == 15343601

View File

@ -1,79 +0,0 @@
#!/usr/bin/env python3
from typing import TextIO
import itertools
circuit: dict[str, int] = {}
class Continue(Exception):
pass
def part1(instructions: TextIO) -> int:
ins: list[str] = []
# process all instructions into a list
for l in instructions:
ins.append(l.strip())
# repeat until the list is empty
while len(ins) != 0:
for connection in ins:
cpart = connection.split()
# print(cpart, sep="")
cpart.remove("->")
# Exclude the destination
try:
# possibles = list(itertools.filterfalse(str.isupper, cpart))[:-1]
for p in range(len(cpart) - 1):
if not cpart[p].isnumeric() and not cpart[p].isupper():
if cpart[p] in circuit:
# Get the value?
# This error can be ignored, lol
cpart[p] = circuit[cpart[p]]
else:
# We can't do anything for this
raise Continue
except Continue:
continue
# assignment
if len(cpart) == 2:
circuit[cpart[1]] = int(cpart[0])
elif "NOT" in cpart:
circuit[cpart[-1]] = (
~int(cpart[1]) & 0xFFFF
) # see notes for why you can't just use ~
elif "AND" in cpart:
circuit[cpart[-1]] = int(cpart[0]) & int(cpart[2])
elif "OR" in cpart:
circuit[cpart[-1]] = int(cpart[0]) | int(cpart[2])
elif "LSHIFT" in cpart:
circuit[cpart[-1]] = int(cpart[0]) << int(cpart[2])
elif "RSHIFT" in cpart:
circuit[cpart[-1]] = int(cpart[0]) >> int(cpart[2])
ins.remove(connection)
# print(circuit)
return circuit["a"]
def part2(f: TextIO):
circuit["b"] = circuit["a"]
for k in list(circuit.keys()):
if k != "b":
del circuit[k]
return part1(f)
if __name__ == "__main__":
with open("day07.txt", "r") as f:
print(part1(f))
with open("day07.txt", "r") as f:
print(part2(f))

Binary file not shown.

View File

@ -1,13 +0,0 @@
#!/usr/bin/env python3
from day07 import *
def test_part1() -> None:
with open("day07.txt", "r") as f:
assert part1(f) == 956
def test_part2() -> None:
with open("day07.txt", "r") as f:
assert part2(f) == 40149

212
2015/poetry.lock generated
View File

@ -1,212 +0,0 @@
# This file is automatically @generated by Poetry 1.4.2 and should not be changed by hand.
[[package]]
name = "black"
version = "23.3.0"
description = "The uncompromising code formatter."
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "black-23.3.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:0945e13506be58bf7db93ee5853243eb368ace1c08a24c65ce108986eac65915"},
{file = "black-23.3.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:67de8d0c209eb5b330cce2469503de11bca4085880d62f1628bd9972cc3366b9"},
{file = "black-23.3.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:7c3eb7cea23904399866c55826b31c1f55bbcd3890ce22ff70466b907b6775c2"},
{file = "black-23.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32daa9783106c28815d05b724238e30718f34155653d4d6e125dc7daec8e260c"},
{file = "black-23.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:35d1381d7a22cc5b2be2f72c7dfdae4072a3336060635718cc7e1ede24221d6c"},
{file = "black-23.3.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:a8a968125d0a6a404842fa1bf0b349a568634f856aa08ffaff40ae0dfa52e7c6"},
{file = "black-23.3.0-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:c7ab5790333c448903c4b721b59c0d80b11fe5e9803d8703e84dcb8da56fec1b"},
{file = "black-23.3.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:a6f6886c9869d4daae2d1715ce34a19bbc4b95006d20ed785ca00fa03cba312d"},
{file = "black-23.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f3c333ea1dd6771b2d3777482429864f8e258899f6ff05826c3a4fcc5ce3f70"},
{file = "black-23.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:11c410f71b876f961d1de77b9699ad19f939094c3a677323f43d7a29855fe326"},
{file = "black-23.3.0-cp37-cp37m-macosx_10_16_x86_64.whl", hash = "sha256:1d06691f1eb8de91cd1b322f21e3bfc9efe0c7ca1f0e1eb1db44ea367dff656b"},
{file = "black-23.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50cb33cac881766a5cd9913e10ff75b1e8eb71babf4c7104f2e9c52da1fb7de2"},
{file = "black-23.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:e114420bf26b90d4b9daa597351337762b63039752bdf72bf361364c1aa05925"},
{file = "black-23.3.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:48f9d345675bb7fbc3dd85821b12487e1b9a75242028adad0333ce36ed2a6d27"},
{file = "black-23.3.0-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:714290490c18fb0126baa0fca0a54ee795f7502b44177e1ce7624ba1c00f2331"},
{file = "black-23.3.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:064101748afa12ad2291c2b91c960be28b817c0c7eaa35bec09cc63aa56493c5"},
{file = "black-23.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:562bd3a70495facf56814293149e51aa1be9931567474993c7942ff7d3533961"},
{file = "black-23.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:e198cf27888ad6f4ff331ca1c48ffc038848ea9f031a3b40ba36aced7e22f2c8"},
{file = "black-23.3.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:3238f2aacf827d18d26db07524e44741233ae09a584273aa059066d644ca7b30"},
{file = "black-23.3.0-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:f0bd2f4a58d6666500542b26354978218a9babcdc972722f4bf90779524515f3"},
{file = "black-23.3.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:92c543f6854c28a3c7f39f4d9b7694f9a6eb9d3c5e2ece488c327b6e7ea9b266"},
{file = "black-23.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a150542a204124ed00683f0db1f5cf1c2aaaa9cc3495b7a3b5976fb136090ab"},
{file = "black-23.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:6b39abdfb402002b8a7d030ccc85cf5afff64ee90fa4c5aebc531e3ad0175ddb"},
{file = "black-23.3.0-py3-none-any.whl", hash = "sha256:ec751418022185b0c1bb7d7736e6933d40bbb14c14a0abcf9123d1b159f98dd4"},
{file = "black-23.3.0.tar.gz", hash = "sha256:1c7b8d606e728a41ea1ccbd7264677e494e87cf630e399262ced92d4a8dac940"},
]
[package.dependencies]
click = ">=8.0.0"
mypy-extensions = ">=0.4.3"
packaging = ">=22.0"
pathspec = ">=0.9.0"
platformdirs = ">=2"
tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
[package.extras]
colorama = ["colorama (>=0.4.3)"]
d = ["aiohttp (>=3.7.4)"]
jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
uvloop = ["uvloop (>=0.15.2)"]
[[package]]
name = "click"
version = "8.1.3"
description = "Composable command line interface toolkit"
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"},
{file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"},
]
[package.dependencies]
colorama = {version = "*", markers = "platform_system == \"Windows\""}
[[package]]
name = "colorama"
version = "0.4.6"
description = "Cross-platform colored terminal text."
category = "dev"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
files = [
{file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
]
[[package]]
name = "exceptiongroup"
version = "1.1.1"
description = "Backport of PEP 654 (exception groups)"
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "exceptiongroup-1.1.1-py3-none-any.whl", hash = "sha256:232c37c63e4f682982c8b6459f33a8981039e5fb8756b2074364e5055c498c9e"},
{file = "exceptiongroup-1.1.1.tar.gz", hash = "sha256:d484c3090ba2889ae2928419117447a14daf3c1231d5e30d0aae34f354f01785"},
]
[package.extras]
test = ["pytest (>=6)"]
[[package]]
name = "iniconfig"
version = "2.0.0"
description = "brain-dead simple config-ini parsing"
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"},
{file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"},
]
[[package]]
name = "mypy-extensions"
version = "1.0.0"
description = "Type system extensions for programs checked with the mypy type checker."
category = "dev"
optional = false
python-versions = ">=3.5"
files = [
{file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"},
{file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
]
[[package]]
name = "packaging"
version = "23.1"
description = "Core utilities for Python packages"
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"},
{file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"},
]
[[package]]
name = "pathspec"
version = "0.11.1"
description = "Utility library for gitignore style pattern matching of file paths."
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "pathspec-0.11.1-py3-none-any.whl", hash = "sha256:d8af70af76652554bd134c22b3e8a1cc46ed7d91edcdd721ef1a0c51a84a5293"},
{file = "pathspec-0.11.1.tar.gz", hash = "sha256:2798de800fa92780e33acca925945e9a19a133b715067cf165b8866c15a31687"},
]
[[package]]
name = "platformdirs"
version = "3.5.0"
description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "platformdirs-3.5.0-py3-none-any.whl", hash = "sha256:47692bc24c1958e8b0f13dd727307cff1db103fca36399f457da8e05f222fdc4"},
{file = "platformdirs-3.5.0.tar.gz", hash = "sha256:7954a68d0ba23558d753f73437c55f89027cf8f5108c19844d4b82e5af396335"},
]
[package.extras]
docs = ["furo (>=2023.3.27)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"]
test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"]
[[package]]
name = "pluggy"
version = "1.0.0"
description = "plugin and hook calling mechanisms for python"
category = "dev"
optional = false
python-versions = ">=3.6"
files = [
{file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"},
{file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"},
]
[package.extras]
dev = ["pre-commit", "tox"]
testing = ["pytest", "pytest-benchmark"]
[[package]]
name = "pytest"
version = "7.3.1"
description = "pytest: simple powerful testing with Python"
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "pytest-7.3.1-py3-none-any.whl", hash = "sha256:3799fa815351fea3a5e96ac7e503a96fa51cc9942c3753cda7651b93c1cfa362"},
{file = "pytest-7.3.1.tar.gz", hash = "sha256:434afafd78b1d78ed0addf160ad2b77a30d35d4bdf8af234fe621919d9ed15e3"},
]
[package.dependencies]
colorama = {version = "*", markers = "sys_platform == \"win32\""}
exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""}
iniconfig = "*"
packaging = "*"
pluggy = ">=0.12,<2.0"
tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""}
[package.extras]
testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"]
[[package]]
name = "tomli"
version = "2.0.1"
description = "A lil' TOML parser"
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
]
[metadata]
lock-version = "2.0"
python-versions = "^3.10"
content-hash = "2b5bd9324c636cd6b2c16bcc51cc5acefdd3824f096891b1817113cdc1fcf33b"

View File

@ -1,18 +0,0 @@
[tool.poetry]
name = "2015"
version = "0.1.0"
description = ""
authors = ["Your Name <you@example.com>"]
readme = "README.md"
[tool.poetry.dependencies]
python = "^3.10"
[tool.poetry.group.dev.dependencies]
black = "^23.3.0"
pytest = "^7.3.1"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

97
2022/day07.py Normal file
View File

@ -0,0 +1,97 @@
#!/usr/bin/env python3
from typing import TextIO
def join(cwd: list, upto: int) -> str:
path = ""
for i in range(upto + 1):
path = path + "/" + cwd[i]
return path
def part1(t_out: TextIO) -> int:
files = {}
cwd = ""
tot = 0
line = t_out.readline().strip()
while line != "":
# parse commands here
print(line)
print(files)
if line == "$ cd /":
cwd = "/"
line = t_out.readline().strip()
elif line == "$ cd ..":
cwd = "/" + cwd.strip("/")[:-1][:-1]
line = t_out.readline().strip()
elif line.split()[:2] == ["$", "cd"]:
if not cwd == "/":
cwd += f"/{line.split()[2]}"
else:
cwd += f"{line.split()[2]}"
line = t_out.readline().strip()
print(">", cwd)
if line == "$ ls":
line = t_out.readline().strip()
while line != "" and line.split()[0] != "$":
lspl = line.split()
# print("here", lspl)
if lspl[0] == "dir": # mkdir
if not cwd == "/":
files[f"{cwd}/{lspl[1]}"] = 0
else:
files[f"{cwd}{lspl[1]}"] = 0
print(files)
else:
# print(cwd, len(cwd.split("/")))
if len(cwd.split("/")) not in (1, 2): # not like /aaa, has multiple
recdirs = cwd.split("/")[1:]
ls = []
for i in range(len(recdirs)):
ls.append(join(recdirs, i))
print(ls)
for path in ls:
files[path] += int(lspl[0])
elif (
len(cwd.split("/")) == 2 and cwd.split("/")[1] != ""
): # only one of /a, not root
# print(cwd, "run only /[...]")
files[cwd] += int(lspl[0])
tot += int(lspl[0]) # "/" case here
# PARSE HERE!!
# file: add to both current folder dict and previous
# from thinking in bed: full path as key, add to each in for...
line = t_out.readline().strip()
print(files)
print("total", tot)
sum = 0
for i in files:
if files[i] < 100000:
sum += files[i]
return sum
print(part1(open("day07.txt")))

1060
2022/day07.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,95 +0,0 @@
#!/usr/bin/env python3
from typing import TextIO
# left
# right
# up
# down
trees = []
def part1(heights: TextIO) -> int:
visible = 0
for row in heights:
trees.append([int(num) for num in row.strip()])
for row in range(len(trees)):
for tree in range(len(trees[row])):
if tree in (
0,
len(trees[row]) - 1,
) or row in (0, len(trees) - 1):
visible += 1
elif (
all(x < trees[row][tree] for x in trees[row][:tree])
or all(x < trees[row][tree] for x in trees[row][tree + 1 :])
or all(trees[row][tree] > trees[x][tree] for x in range(row))
or all(
trees[row][tree] > trees[x][tree]
for x in range(row + 1, len(trees))
)
):
visible += 1
return visible
def part2() -> int:
scores = []
for row in range(len(trees)):
for c in range(len(trees[row])):
left = 0
right = 0
up = 0
down = 0 # ??
if c in (
0,
len(trees[row]) - 1,
) or row in (0, len(trees) - 1):
continue # score will be 0 anyways, disregard
# left score
for x in reversed(trees[row][:c]):
if trees[row][c] > x:
left += 1
else:
left += 1
break
# right score
for x in trees[row][c + 1 :]:
if trees[row][c] > x:
right += 1
else:
right += 1
break
# up
for x in reversed(range(row)):
if trees[row][c] > trees[x][c]:
up += 1
else:
up += 1
break
# down
for x in range(row + 1, len(trees)):
if trees[row][c] > trees[x][c]:
down += 1
else:
down += 1
break
scores.append(left * right * up * down)
return max(scores)
if __name__ == "__main__":
print(part1(open("day08.txt")))
print(part2())

View File

@ -1,99 +0,0 @@
404310113342042430523206553054613026452223317713352040314520532034136044035422242052404520323121423
120022131035104020413264056552251024207112052153646716635163015540126546334604634352130343204203212
114444043404350333465355412140536532335724647116565610572546474626506052303052063065052530351012030
212240414554223531015555065165021520410363021033163304514155663733352116600665403462501544352500033
324144130111224105125305614015103771206061460425505011635353313773273343325122626415203015344311232
113245430241150240464126012614135430370003075735010164413125456766205302613425655024334411031155403
441245002130523346005210411662277072426351216071200446765701447237330324567025204602342520044502121
214045553122025654652221354616163561012500762010384874262074144065234401637722263412266464251452314
420554052436551160102504245073471242400253801258004372606111667766236046654353552356241642235535400
230444034403653045355316273427144521155460537330375254634265217831710133466511570022515061342332314
215330305636623403455371527067601715250678103470620507380025232122252031461570076036342312211025412
152531154664324333510065716166433534816054420634864077383448250450766671674224724566465113516230555
214332343546262452365454705617472281546633211772075171047360414071436550632720021764434561305210301
111443005611044613477737043746056557178022072372401206038184673647422320773366100676006211551510212
133313521334520014277727658110473505777283286103991788280475205774027243280366061162025220015443455
155404252050544375401645717463634684248661783289138494563725362778686756122861113531553244022156404
101264441110131756443257557872335606716942314559648922296471179061870856246756574324520340610552502
552345216103355364312158072306454410946149736569151493634487672710443362287688034427626033035266435
032116136355447236216431376728258285654613995348237354962282338329733408310145842020562245054642441
224363655451243141363087456580326751652471257429153117112342588642859256252141665722503521125022565
203656402177710126565314466702484652152875481365818345352121487714962821315157703464343750046056642
556042122224622324270101114885994351144861589211656115175234527658398149331284812500044434453264665
333402317273401421323318415855844499641764213948757537893227517242385296970317342824206711503004500
341045445002443367084450562962259886574728664877676766689484955395194385797583863611332250124025511
530441155216276525375870173389743919985448259629562325456237285529598688811050240824703721074602060
320021441136216827813607342916845194696625696785568454728524752386544154132864251748117643644612016
356236015127477502168551236473444979246675949449587984562945859468987964451443376640177554302403555
521032161450418348764563917129159623593365988455562286236885389659621188427923285451742156213351116
161327255665606701821864175493119539272489637754729983857664245665796727199928145136462257620362465
324256011240774073378929732467468357478524626995373968674237767743387885552216853467388044247756643
342275312602047038565615877434724873572784389557789777857693948752846554139723438258054200025014665
051242516637708146638198373275222758924486548779744574439965559638384373152521363134036477637737533
643152555635778437871298236855485688298578349488385645847564753765967563925377954286572876073532255
052252355510464443878597562686999366353446874577654743895687373779864325297372128203202721414431575
003626454683627045725543215594452394956436955758673339474559874959389629573279978978206522053161354
627516237702078544682942119397343558584845947957956986767739349699889797692213624665730454802067156
200457151510133551651137637224323537736454384779467644967339586954746668462789875763614758041306350
335154370506881211537946276895249658859666595888979499974679997597784647296794417997582782381025574
417013603706282285595672445598476844553485594594694865577988599545878778554434654896767653370600163
151076753567166396584462282676939868463579768879699478585698835334464668886671938943507604626741055
316424603540766436474549593426596456855354984858479546978868766769885893482223982736645038024543705
004215748043040351658449499986735473677885875695647795765956883964888467568526739498861211513560376
277541056808037332121324298298467888439897499685669789559864468637637659443647357982947036001076457
301501750655275336942638945358964763536465468989488667796645858846573465972686416787340853151245644
712676410408042175645992725856638455389978885467555675756857577896385395967245722641824067046404672
127263578732604583334129426765554856475867757556696788664596649687355745252374587569983167874135470
372567082480204357437552435378439546954796599589886886999448548554873566373887522667838861416626063
504053336576743468622556295365645349984889785678558796559694969799447958394395964464961434514564147
064634031154473874813798648457894764786965996797567598577449556796733655629459883126531875350855667
400242382466736377478123774763774843994888788596767997699956676943467867843525339987287625323107646
574363428370183567442332638863797996446594766875586998755697498794589458457898531351415551433522556
412167557672308712367589426397979758975789888776586986996554696687355758873775853874897420702317101
770303703378804536976332878328747387584568459887597696678765458466869646823658768383568726667515101
452233157246118285247999798264378649666585777768676869779576767654376979948352929633336613662437752
445720367378533569416697754293496373467957556998785966978548459859767957423835655379853826412537652
743314715884636853952588482996464655775879867757788958998964888966363788982234644268286248732605364
421252340411081749754123523897998635856478675875579877695848758757598799352859935972592464121200154
240060534144421235633966383826944588955556569877797756857998594637769364656894472644372534212151333
030406408132303595787173445575575686448657959549968444868588895645466777395756386243943041550563144
273114334761050642652349846942498578754978859865947785499768464999467827979546133588431400553072571
545140256541065084978642274659978546685549897854997987959494546787556536925383718147440765477035264
213551156551872738118554524476466757347767578664548796858878373885346253453663631131187832513353720
031302225003187455433275258559853476398764745884957978785699446894568423546775622669458815340346707
622067430504086108575211657573256737949367744989999457768543933556446848583667956928715425470730162
242111564658304088777519536233444248435478893367596684875833738467857765957226924427228481325217576
364055473230737526383625952385867723976677963779587753646766774437577338682519314383352032477133503
321304645532064452197673316923724578983475574649393989787463485775923766996461422676353215802454115
233105015700144131749152169592849597799334664843639757588555464399727868723189114371617811204424461
200116461554525361612654498296559659356483355845588365383658756592935783639172813284867400343573434
063667611325433422432889612288938865635845895684777885359355942764253445159748552521586663111276320
602227464555468655756429585352455445365885785394937349896765628578363566623445953670505237256637361
565061226117741561827365137945864958743698627664964883854386585344264536463794276685706331233201162
022104543457075344433186746554898622888662879483534875732366545699493494249416960261188772111451356
436620604222365732527426815953936962792895744565572436255439745543587676567692850112721235162354066
131524412733104587364628695894553856954929535227798584623638988936368718849285573225440174764501540
542435561362065510830610739646131257342496749563278998673868857392617956152266780580611770145235126
403602071007077303754367568233894922487258962426625788335236293726841614813262288087316403413301325
653365633721421431240238511233988284565865357732839935658824268124333235971843281322245237465244640
306442137750441441547377231538498282333378867895866774269433657996442236932105133474315101276433026
026362613577242456258634050671963436933444863559863424588962566983574869370120588454323506304034454
324415624033560610606167505705335537131257342423913353449125925341756615871358508731521557026114366
444331064667665623244155236812366396427328522481655365283852878951317624280585607560532023416160531
356100663130344012403254770320017162464663432371564992618187659799885888814177114132251720346235260
335255502200627412653317161700362276552642826696514719212976746877872577501286045667131741121615252
432342461115176570456177856545043415022291419917157172495246595828707718465323075462216735351424603
052014513044443630413221560860665817858636725794462229844935048786680202681024216170152252502634130
020320466436640542335164431658623622013245024685776848188641088056885388363367731111662103514422342
243313636453126262451331254501288620001007675817755413767166283281358125642646705337503156330264143
322052011503256425407127570260816542455843672731851386601352556410113100252536057366522542640013024
122243505446640664755657664365330525660042002157156113773258264460845541635501120634115505113335223
400325240315062161366031440416477741684364564857378773141186841270761406731633364031611642530523212
033035153153462216052744630367426463087060858055232515783208471176613722677126341566006053644200442
235202335236553544540304237444375273744171216804617062750281644425671760635002322246613220112112312
424551125551101552103143451563560236361153202606118476772167626160624534653670012136420410040115003
433115113101302300404521334255672566234211040710503455555073775502462316364453256460002143312311050
113231445145014641142635155170110005103066306721236312425606163376276006132006331601341420241440202
124001123533434316253543204160331101266365020140476416102251147360064153500112411356634011134351330
004034442142153246064264662030666771573157310340000724745700036734054206654603230345313434140344030
321402405400252420216445132115124427151235102635446313422013474177203430646340442422400002232222342

View File

@ -1,12 +0,0 @@
#!/usr/bin/env python3
from day08 import *
def test_part1() -> None:
with open("day08.txt") as f:
assert part1(f) == 1538
def test_part2() -> None:
assert part2() == 496125

View File

@ -1,12 +0,0 @@
# check
default: check
# show this help (just --list)
help:
just --list
# lint and run tests
check:
poetry run black . --check
poetry run pytest

View File

@ -1,61 +0,0 @@
#!/usr/bin/env python3
from typing import TextIO
import re
# Part 2: Overlaps
a = {
"one": "o1e",
"two": "t2o",
"three": "t3e",
"four": "f4r",
"five": "f5e",
"six": "s6x",
"seven": "s7n",
"eight": "e8t",
"nine": "n9e",
"ten": "t10e",
}
def calc(line: str) -> int:
e = re.findall(r"\d", line)
try:
first, *_, last = e
except ValueError:
first, last = e[0], e[0]
return int("".join([first, last]))
def part1(f: TextIO) -> int:
values: int = 0
for line in f:
line = line.strip()
values += calc(line)
return values
def part2(f: TextIO) -> int:
values: int = 0
for line in f:
line = line.strip()
for w, r in a.items():
line = line.replace(w, r)
values += calc(line)
return values
if __name__ == "__main__":
with open("day01.txt") as f:
print(part1(f))
with open("day01.txt") as f:
print(part2(f))

View File

@ -1,13 +0,0 @@
#!/usr/bin/env python3
from day01 import *
def test_part1() -> None:
with open("day01.txt") as p:
assert part1(p) == 54601
def test_part2() -> None:
with open("day01.txt") as p:
assert part2(p) == 54078

View File

@ -1,83 +0,0 @@
#!/usr/bin/env python3
from typing import TextIO
p = {"red": 12, "green": 13, "blue": 14}
p2 = []
def part1(f: TextIO) -> int:
games: int = 0
for line in f:
line = line.strip()
id_ = int(line.split(":")[0].split()[1])
line = line.split("; ")
line[0] = line[0].split(": ")[1] # remove the Game #:
clues = []
f_p2 = [] # for part 2
for c in range(len(line)):
clues.append(line[c].split(", "))
f_p2.append(clues[-1])
p2.append(f_p2)
flag = True
for peek in clues:
# for each, if type is over
# set to false, exit early and do not add the game id
for t in peek:
t = t.split()
t[0] = int(t[0])
if t[0] > p[t[1]]:
flag = False
break
if flag is False:
break
if flag is True:
games += id_
return games
def mult(p: list) -> int:
pr = 1
for item in p:
pr *= item
return pr
def part2(games: list) -> int:
sum_ = 0
for game in games:
mins: dict[str, int] = {}
for clues in game:
for clue in clues:
clue = clue.split()
clue[0] = int(clue[0])
if clue[1] in mins:
mins[clue[1]] = max(mins[clue[1]], clue[0])
else:
mins[clue[1]] = clue[0]
sum_ += mult(list(mins.values()))
return sum_
if __name__ == "__main__":
with open("day02.txt") as f:
print(part1(f))
print(part2(p2))

View File

@ -1,12 +0,0 @@
#!/usr/bin/env python3
from day02 import *
def test_part1() -> None:
with open("day02.txt") as f:
assert part1(f) == 2810
def test_part2() -> None:
assert part2(p2) == 69110

View File

@ -1,190 +0,0 @@
#!/usr/bin/env python3
from typing import TextIO
import re
schematic: list[str] = []
# line {int: {(a,b): num}, ...}
gears: dict[int, dict[tuple[int, int], int]] = {}
def get_adjacent(l: int, co: tuple[int, int]) -> bool:
for i in range(co[0], co[1]):
# check below
if (
l + 1 < len(schematic)
and not schematic[l + 1][i].isdigit()
and schematic[l + 1][i] != "."
):
return True
# check above
if l != 0 and not schematic[l - 1][i].isdigit() and schematic[l - 1][i] != ".":
return True
# if first num check left
if (
i != 0
and i == co[0]
and not schematic[l][i - 1].isdigit()
and schematic[l][i - 1] != "."
):
return True
# if last num check right
if (
i + 1 < len(schematic[l])
and i == co[1] - 1
and not schematic[l][i + 1].isdigit()
and schematic[l][i + 1] != "."
):
return True
# all check diag
# U L
if (
l != 0
and i != 0
and not schematic[l - 1][i - 1].isdigit()
and schematic[l - 1][i - 1] != "."
):
return True
# U R
if (
l != 0
and i + 1 < len(schematic[l])
and not schematic[l - 1][i + 1].isdigit()
and schematic[l - 1][i + 1] != "."
):
return True
# D L
if (
l + 1 < len(schematic)
and i != 0
and not schematic[l + 1][i - 1].isdigit()
and schematic[l + 1][i - 1] != "."
):
return True
# D R
if (
l + 1 < len(schematic)
and i + 1 < len(schematic[l])
and not schematic[l + 1][i + 1].isdigit()
and schematic[l + 1][i + 1] != "."
):
return True
return False
def part1(file: TextIO) -> int:
sum_: int = 0
for line in file:
schematic.append(line.strip())
for l in range(len(schematic)):
nums = re.finditer(r"\d+", schematic[l])
for n in nums:
if l in gears:
gears[l][n.span()] = int(n.group(0))
else:
gears[l] = {n.span(): int(n.group(0))}
if get_adjacent(l, n.span()):
sum_ += int(n.group(0))
return sum_
def find_num(l, c) -> tuple[int, tuple[int, int, int]]:
for coord in gears[l]:
if c in range(coord[0], coord[1] + 1):
return (
gears[l][coord],
(l, coord[0], coord[1]),
) # line pos (same coordinates on 2 diff lines)
raise ValueError
def part2() -> int:
ratios: int = 0
for l in range(len(schematic)):
for c in range(len(schematic[l])):
if schematic[l][c] == "*":
nums: list[int] = []
used_c: list[tuple[int, int, int]] = []
# start parsing for digits
# check below
if l + 1 < len(schematic) and schematic[l + 1][c].isdigit():
a = find_num(l + 1, c)
if a[1] not in used_c:
nums.append(a[0])
used_c.append(a[1])
# check above
if l != 0 and schematic[l - 1][c].isdigit():
a = find_num(l - 1, c)
if a[1] not in used_c:
nums.append(a[0])
used_c.append(a[1])
# check left
if c != 0 and schematic[l][c - 1].isdigit():
a = find_num(l, c - 1)
if a[1] not in used_c:
nums.append(a[0])
used_c.append(a[1])
# check right
if c + 1 < len(schematic[l]) and schematic[l][c + 1].isdigit():
a = find_num(l, c + 1)
if a[1] not in used_c:
nums.append(a[0])
used_c.append(a[1])
# all check diag
# U L
if l != 0 and c != 0 and schematic[l - 1][c - 1].isdigit():
a = find_num(l - 1, c - 1)
if a[1] not in used_c:
nums.append(a[0])
used_c.append(a[1])
# U R
if (
l != 0
and c + 1 < len(schematic[l])
and schematic[l - 1][c + 1].isdigit()
):
a = find_num(l - 1, c + 1)
if a[1] not in used_c:
nums.append(a[0])
used_c.append(a[1])
# D L
if (
l + 1 < len(schematic)
and c != 0
and schematic[l + 1][c - 1].isdigit()
):
a = find_num(l + 1, c - 1)
if a[1] not in used_c:
nums.append(a[0])
used_c.append(a[1])
# D R
if (
l + 1 < len(schematic)
and c + 1 < len(schematic[l])
and schematic[l + 1][c + 1].isdigit()
):
a = find_num(l + 1, c + 1)
if a[1] not in used_c:
nums.append(a[0])
used_c.append(a[1])
if len(nums) == 2:
ratios += nums[0] * nums[1]
if len(nums) > 2:
raise ValueError
return ratios
if __name__ == "__main__":
with open("day03.txt") as f:
print(part1(f))
print(part2()) # not 75089990 too low

View File

@ -1,10 +0,0 @@
from day03 import *
def test_part1() -> None:
with open("day03.txt") as f:
assert part1(f) == 546312
def test_part2() -> None:
assert part2() == 87449461

View File

@ -1,58 +0,0 @@
import re
nums: list[list[int]] = []
wins: list[list[int]] = []
copies: dict[int, int] = {}
def part1() -> int:
points: int = 0
for n in range(len(nums)):
x = list(filter(lambda y: y in wins[n], nums[n]))
if len(x) != 0:
points += 2 ** (len(x) - 1)
return points
def part2(c: int) -> int:
# base case
if len(nums) == c:
return sum(copies.values())
else:
if c not in copies:
copies[c] = 1
else:
copies[c] += 1
x = list(filter(lambda y: y in wins[c], nums[c]))
if len(x) != 0:
for y in range(1, len(x) + 1):
if c + y not in copies:
copies[c + y] = 1 * copies[c]
else:
copies[c + y] += 1 * copies[c]
return part2(c + 1)
def proc() -> None:
with open("day04.txt") as f:
for line in f:
line = line.strip()
n = line.split(": ")[1].split(" | ")[0]
w = line.split(": ")[1].split(" | ")[1]
nums.append(re.findall(r"\d+", n))
wins.append(re.findall(r"\d+", w))
if __name__ == "__main__":
proc()
print(part1())
print(part2(0))

View File

@ -1,11 +0,0 @@
from day04 import *
proc()
def test_part1() -> None:
assert part1() == 24542
def test_part2() -> None:
assert part2(0) == 8736438

View File

@ -1,15 +0,0 @@
[tool.poetry]
name = "2023"
version = "0.1.0"
description = ""
authors = ["Your Name <you@example.com>"]
readme = "README.md"
[tool.poetry.dependencies]
python = "^3.11"
pytest = "^7.4.3"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"