Cleanup whoops

cat-town
Dan Buch 2 years ago
parent 1d827b517b
commit d2405f75d8
Signed by: meatballhat
GPG Key ID: A12F782281063434

@ -1,13 +0,0 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
[dev-packages]
mypy = ""
pytest = ""
[requires]
python_version = "3.9"

@ -1,156 +0,0 @@
{
"_meta": {
"hash": {
"sha256": "ed02d1728cc686824535903ae2f5f3956ba104434c4c6e532237df55bcd69a12"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.9"
},
"sources": [
{
"name": "pypi",
"url": "https://pypi.org/simple",
"verify_ssl": true
}
]
},
"default": {},
"develop": {
"attrs": {
"hashes": [
"sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6",
"sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==20.3.0"
},
"iniconfig": {
"hashes": [
"sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3",
"sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"
],
"version": "==1.1.1"
},
"mypy": {
"hashes": [
"sha256:0a0d102247c16ce93c97066443d11e2d36e6cc2a32d8ccc1f705268970479324",
"sha256:0d34d6b122597d48a36d6c59e35341f410d4abfa771d96d04ae2c468dd201abc",
"sha256:2170492030f6faa537647d29945786d297e4862765f0b4ac5930ff62e300d802",
"sha256:2842d4fbd1b12ab422346376aad03ff5d0805b706102e475e962370f874a5122",
"sha256:2b21ba45ad9ef2e2eb88ce4aeadd0112d0f5026418324176fd494a6824b74975",
"sha256:72060bf64f290fb629bd4a67c707a66fd88ca26e413a91384b18db3876e57ed7",
"sha256:af4e9ff1834e565f1baa74ccf7ae2564ae38c8df2a85b057af1dbbc958eb6666",
"sha256:bd03b3cf666bff8d710d633d1c56ab7facbdc204d567715cb3b9f85c6e94f669",
"sha256:c614194e01c85bb2e551c421397e49afb2872c88b5830e3554f0519f9fb1c178",
"sha256:cf4e7bf7f1214826cf7333627cb2547c0db7e3078723227820d0a2490f117a01",
"sha256:da56dedcd7cd502ccd3c5dddc656cb36113dd793ad466e894574125945653cea",
"sha256:e86bdace26c5fe9cf8cb735e7cedfe7850ad92b327ac5d797c656717d2ca66de",
"sha256:e97e9c13d67fbe524be17e4d8025d51a7dca38f90de2e462243ab8ed8a9178d1",
"sha256:eea260feb1830a627fb526d22fbb426b750d9f5a47b624e8d5e7e004359b219c"
],
"index": "pypi",
"markers": "python_version >= '3.5'",
"version": "==0.790"
},
"mypy-extensions": {
"hashes": [
"sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d",
"sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"
],
"version": "==0.4.3"
},
"packaging": {
"hashes": [
"sha256:24e0da08660a87484d1602c30bb4902d74816b6985b93de36926f5bc95741858",
"sha256:78598185a7008a470d64526a8059de9aaa449238f280fc9eb6b13ba6c4109093"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==20.8"
},
"pluggy": {
"hashes": [
"sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0",
"sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==0.13.1"
},
"py": {
"hashes": [
"sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3",
"sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==1.10.0"
},
"pyparsing": {
"hashes": [
"sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1",
"sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"
],
"markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==2.4.7"
},
"pytest": {
"hashes": [
"sha256:1969f797a1a0dbd8ccf0fecc80262312729afea9c17f1d70ebf85c5e76c6f7c8",
"sha256:66e419b1899bc27346cb2c993e12c5e5e8daba9073c1fbce33b9807abc95c306"
],
"index": "pypi",
"markers": "python_version >= '3.6'",
"version": "==6.2.1"
},
"toml": {
"hashes": [
"sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b",
"sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"
],
"markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==0.10.2"
},
"typed-ast": {
"hashes": [
"sha256:07d49388d5bf7e863f7fa2f124b1b1d89d8aa0e2f7812faff0a5658c01c59aa1",
"sha256:14bf1522cdee369e8f5581238edac09150c765ec1cb33615855889cf33dcb92d",
"sha256:240296b27397e4e37874abb1df2a608a92df85cf3e2a04d0d4d61055c8305ba6",
"sha256:36d829b31ab67d6fcb30e185ec996e1f72b892255a745d3a82138c97d21ed1cd",
"sha256:37f48d46d733d57cc70fd5f30572d11ab8ed92da6e6b28e024e4a3edfb456e37",
"sha256:4c790331247081ea7c632a76d5b2a265e6d325ecd3179d06e9cf8d46d90dd151",
"sha256:5dcfc2e264bd8a1db8b11a892bd1647154ce03eeba94b461effe68790d8b8e07",
"sha256:7147e2a76c75f0f64c4319886e7639e490fee87c9d25cb1d4faef1d8cf83a440",
"sha256:7703620125e4fb79b64aa52427ec192822e9f45d37d4b6625ab37ef403e1df70",
"sha256:8368f83e93c7156ccd40e49a783a6a6850ca25b556c0fa0240ed0f659d2fe496",
"sha256:84aa6223d71012c68d577c83f4e7db50d11d6b1399a9c779046d75e24bed74ea",
"sha256:85f95aa97a35bdb2f2f7d10ec5bbdac0aeb9dafdaf88e17492da0504de2e6400",
"sha256:8db0e856712f79c45956da0c9a40ca4246abc3485ae0d7ecc86a20f5e4c09abc",
"sha256:9044ef2df88d7f33692ae3f18d3be63dec69c4fb1b5a4a9ac950f9b4ba571606",
"sha256:963c80b583b0661918718b095e02303d8078950b26cc00b5e5ea9ababe0de1fc",
"sha256:987f15737aba2ab5f3928c617ccf1ce412e2e321c77ab16ca5a293e7bbffd581",
"sha256:9ec45db0c766f196ae629e509f059ff05fc3148f9ffd28f3cfe75d4afb485412",
"sha256:9fc0b3cb5d1720e7141d103cf4819aea239f7d136acf9ee4a69b047b7986175a",
"sha256:a2c927c49f2029291fbabd673d51a2180038f8cd5a5b2f290f78c4516be48be2",
"sha256:a38878a223bdd37c9709d07cd357bb79f4c760b29210e14ad0fb395294583787",
"sha256:b4fcdcfa302538f70929eb7b392f536a237cbe2ed9cba88e3bf5027b39f5f77f",
"sha256:c0c74e5579af4b977c8b932f40a5464764b2f86681327410aa028a22d2f54937",
"sha256:c1c876fd795b36126f773db9cbb393f19808edd2637e00fd6caba0e25f2c7b64",
"sha256:c9aadc4924d4b5799112837b226160428524a9a45f830e0d0f184b19e4090487",
"sha256:cc7b98bf58167b7f2db91a4327da24fb93368838eb84a44c472283778fc2446b",
"sha256:cf54cfa843f297991b7388c281cb3855d911137223c6b6d2dd82a47ae5125a41",
"sha256:d003156bb6a59cda9050e983441b7fa2487f7800d76bdc065566b7d728b4581a",
"sha256:d175297e9533d8d37437abc14e8a83cbc68af93cc9c1c59c2c292ec59a0697a3",
"sha256:d746a437cdbca200622385305aedd9aef68e8a645e385cc483bdc5e488f07166",
"sha256:e683e409e5c45d5c9082dc1daf13f6374300806240719f95dc783d1fc942af10"
],
"version": "==1.4.2"
},
"typing-extensions": {
"hashes": [
"sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918",
"sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c",
"sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f"
],
"version": "==3.7.4.3"
}
}
}

@ -1,49 +0,0 @@
import sys
import typing
def main() -> int:
inputs = [int(s) for s in sys.stdin.read().split()]
for i, j in _find_2020_pairs(inputs):
print(f"pair: {i} * {j} == {i * j}")
for i, j, k in _find_2020_triplets(inputs):
print(f"triplet: {i} * {j} * {k} == {i * j * k}")
return 0
def _find_2020_pairs(
inputs: typing.List[int],
) -> typing.Generator[typing.Tuple[int, ...], None, None]:
found = []
for i, in0 in enumerate(inputs):
for j, in1 in enumerate(inputs):
if i == j:
continue
if in0 + in1 == 2020:
to_yield = tuple(sorted([in0, in1]))
if to_yield not in found:
yield to_yield
found.append(to_yield)
def _find_2020_triplets(
inputs: typing.List[int],
) -> typing.Generator[typing.Tuple[int, ...], None, None]:
found = []
for i, in0 in enumerate(inputs):
for j, in1 in enumerate(inputs):
for k, in2 in enumerate(inputs):
if i == j or i == k:
continue
if in0 + in1 + in2 == 2020:
to_yield = tuple(sorted([in0, in1, in2]))
if to_yield not in found:
yield to_yield
found.append(to_yield)
if __name__ == "__main__":
sys.exit(main())

@ -1,53 +0,0 @@
import sys
def main() -> int:
n_valid = 0
total = 0
for pol_pas in [PolicyPassword.fromstring(s) for s in sys.stdin.readlines(False)]:
if pol_pas.is_valid():
n_valid += 1
total += 1
print(f"{n_valid}/{total} valid")
return 0
class Policy:
def __init__(self, char: str, pos1: int, pos2: int):
self.char = char
self.pos1 = pos1
self.pos2 = pos2
@classmethod
def fromstring(cls, input_string) -> "Policy":
parts = [s.strip() for s in input_string.split(" ")][:2]
pos = [int(s) for s in parts[0].split("-")][:2]
return cls(parts[1], pos[0], pos[1])
def is_valid(self, password: str) -> bool:
matches = 0
for pos in (self.pos1 - 1, self.pos2 - 1):
if password[pos] == self.char:
matches += 1
return matches == 1
class PolicyPassword:
def __init__(self, policy: "Policy", password: str):
self.policy = policy
self.password = password
@classmethod
def fromstring(cls, input_string: str) -> "PolicyPassword":
parts = [s.strip() for s in input_string.split(":")][:2]
return cls(Policy.fromstring(parts[0]), parts[1])
def is_valid(self) -> bool:
return self.policy.is_valid(self.password)
if __name__ == "__main__":
sys.exit(main())

@ -1,52 +0,0 @@
import functools
import sys
import typing
class Loc(typing.NamedTuple):
x: int
y: int
def main() -> int:
forest_frame = [list(line.strip()) for line in sys.stdin.readlines()]
frame_width = len(forest_frame[0])
frame_height = len(forest_frame)
all_trees_encountered = []
for slope in [
Loc(x=1, y=1),
Loc(x=3, y=1),
Loc(x=5, y=1),
Loc(x=7, y=1),
Loc(x=1, y=2),
]:
loc = Loc(x=0, y=0)
trees_encountered = 0
while loc.y <= (frame_height - 1):
at_loc = forest_frame[loc.y][loc.x]
if at_loc == "#":
trees_encountered += 1
next_x = (loc.x + slope.x) % frame_width
next_y = loc.y + slope.y
next_loc = Loc(x=next_x, y=next_y)
loc = next_loc
print(
f"(slope right={slope.x} down={slope.y}) trees encountered: {trees_encountered}"
)
all_trees_encountered.append(trees_encountered)
trees_encountered_product = functools.reduce(
lambda x, y: x * y, all_trees_encountered
)
print(f"trees encountered product: {trees_encountered_product}")
return 0
if __name__ == "__main__":
sys.exit(main())

@ -1,115 +0,0 @@
import sys
import typing
def main() -> int:
checked = []
for passport in _read_passports(sys.stdin):
if passport is None:
checked.append(False)
continue
checked.append(passport.is_valid())
print(f"total={len(checked)} valid={checked.count(True)}")
return 0
NoneString = typing.Optional[str]
VALID_EYE_COLORS = ("amb", "blu", "brn", "gry", "grn", "hzl", "oth")
class Passport:
byr: NoneString = None
cid: NoneString = None
ecl: NoneString = None
eyr: NoneString = None
hcl: NoneString = None
hgt: NoneString = None
iyr: NoneString = None
pid: NoneString = None
def is_valid(self) -> bool:
return (
self._is_year_in_range(self.byr, range(1920, 2003))
and self._is_year_in_range(self.iyr, range(2010, 2021))
and self._is_year_in_range(self.eyr, range(2020, 2031))
and self._has_valid_height()
and self._has_valid_hair_color()
and self.ecl in VALID_EYE_COLORS
and self._has_valid_passport_id()
)
def _has_valid_height(self) -> bool:
if self.hgt is None:
return False
height_value = 0
height_value_string = self.hgt.replace("cm", "").replace("in", "")
if not height_value_string.isdigit():
return False
height = int(height_value_string)
if self.hgt.endswith("cm") and height in range(150, 194):
return True
elif self.hgt.endswith("in") and height in range(59, 77):
return True
return False
def _has_valid_hair_color(self) -> bool:
if self.hcl is None:
return False
if not self.hcl.startswith("#"):
return False
hair_value = self.hcl.replace("#", "")
if len(hair_value) != 6:
return False
try:
_ = int(hair_value, 16)
return True
except ValueError:
return False
def _has_valid_passport_id(self) -> bool:
return (
self.pid is not None
and len(self.pid) == 9
and all([s.isdigit() for s in list(self.pid)])
)
def _is_year_in_range(self, value: NoneString, yr_range: range) -> bool:
if value is None:
return False
if len(value) != 4:
return False
if not value.isdigit():
return False
return int(value) in yr_range
def _read_passports(
instream: typing.TextIO,
) -> typing.Generator[typing.Optional[Passport], None, None]:
cur = Passport()
for i, line in enumerate(instream):
line = line.strip()
if line == "":
yield cur
cur = Passport()
for pair in line.split():
attr, value = pair.split(":", 1)
setattr(cur, attr, value)
yield cur
if __name__ == "__main__":
sys.exit(main())

@ -1,77 +0,0 @@
import sys
import typing
def main() -> int:
highest_seat = 0
taken_seats = set()
for line in sys.stdin:
line = line.strip()
if line == "":
continue
seat = _locate_seat(line)
if seat.number > highest_seat:
highest_seat = seat.number
taken_seats.add(seat.number)
print(f"bp={line} row={seat.row} column={seat.col} seat={seat.number}")
seat_number: typing.Optional[int] = None
n_found = 0
for candidate_seat in range(0, (127 * 8) + 1):
if candidate_seat in taken_seats:
continue
if (candidate_seat - 1) in taken_seats and (candidate_seat + 1) in taken_seats:
seat_number = candidate_seat
n_found += 1
print(f"highest_seat={highest_seat} seat_number={seat_number} n_found={n_found}")
return 0
class Seat:
row: int
column: int
def __init__(self, row: int = 0, col: int = 0):
self.row = row
self.col = col
@property
def number(self) -> int:
return (self.row * 8) + self.col
def _locate_seat(bp: str) -> Seat:
rows = list(range(0, 128))
cols = list(range(0, 8))
row_part = list(bp[:7])
col_part = list(bp[7:])
return Seat(
row=_bisect(rows, [{"F": 0, "B": 1}[s] for s in row_part]),
col=_bisect(cols, [{"L": 0, "R": 1}[s] for s in col_part]),
)
def _bisect(initial_selection: typing.List[int], bisections: typing.List[int]) -> int:
selection = initial_selection[:]
for bisection in bisections:
halfway = int(len(selection) / 2)
selection = [selection[:halfway], selection[halfway:]][bisection]
return selection[0]
if __name__ == "__main__":
sys.exit(main())

@ -1,3 +0,0 @@
BFFFBBFRRR
FFFBBBFRRR
BBFFBBFRLL

@ -1,3 +0,0 @@
bp=BFFFBBFRRR row=70 column=7 seat=567
bp=FFFBBBFRRR row=14 column=7 seat=119
bp=BBFFBBFRLL row=102 column=4 seat=820

@ -1,21 +0,0 @@
import sys
from pathlib import Path
import pytest
from solution import main
HERE = Path(__file__).absolute().parent
def test_solution(capsys):
with (HERE / "test-input").open() as infile:
sys.stdin = infile
main()
expected_output = (HERE / "test-output").read_text().splitlines()
assert expected_output == [
l for l in capsys.readouterr().out.splitlines() if l.startswith("counts_sum=")
]

@ -1,42 +0,0 @@
import sys
import typing
def main() -> int:
counts_sum = sum([c for c in _iter_group_counts(sys.stdin)])
print(f"counts_sum={counts_sum}")
return 0
def _iter_group_counts(instream: typing.TextIO) -> typing.Generator[int, None, None]:
for i, group in enumerate(_iter_groups(instream)):
answers = set(list(group[0]))
print(f"i={i} initial={answers}")
for answers_text in group[1:]:
to_add = set(list(answers_text))
answers = answers.intersection(set(list(answers_text)))
print(f"i={i} added={to_add} result={answers}")
print(f"i={i} final={answers} n={len(answers)}")
yield len(answers)
def _iter_groups(instream):
cur_group = []
for line in instream:
line = line.strip()
if line == "":
yield cur_group
cur_group = []
continue
cur_group.append(line)
yield cur_group
if __name__ == "__main__":
sys.exit(main())

@ -1,15 +0,0 @@
abc
a
b
c
ab
ac
a
a
a
a
b

@ -1,21 +0,0 @@
import sys
from pathlib import Path
import pytest
from solution import main
HERE = Path(__file__).absolute().parent
def test_solution(capsys):
with (HERE / "test-input").open() as infile:
sys.stdin = infile
main()
expected_output = (HERE / "test-output").read_text().splitlines()
assert expected_output == [
l for l in capsys.readouterr().out.splitlines() if l.startswith("counts_sum")
]
Loading…
Cancel
Save