diff --git a/aoc2020/Pipfile b/aoc2020/Pipfile index 3b066fa..5518735 100644 --- a/aoc2020/Pipfile +++ b/aoc2020/Pipfile @@ -7,6 +7,7 @@ name = "pypi" [dev-packages] mypy = "" +pytest = "" [requires] python_version = "3.9" diff --git a/aoc2020/Pipfile.lock b/aoc2020/Pipfile.lock index d873b66..325e836 100644 --- a/aoc2020/Pipfile.lock +++ b/aoc2020/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "752181fd1aaa6cf905a654df10d56863fe61b74b26e95802148d225644e9bc5a" + "sha256": "ed02d1728cc686824535903ae2f5f3956ba104434c4c6e532237df55bcd69a12" }, "pipfile-spec": 6, "requires": { @@ -17,6 +17,21 @@ }, "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", @@ -45,6 +60,55 @@ ], "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", diff --git a/aoc2020/day05/solution.py b/aoc2020/day05/solution.py new file mode 100644 index 0000000..c881605 --- /dev/null +++ b/aoc2020/day05/solution.py @@ -0,0 +1,77 @@ +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()) diff --git a/aoc2020/day05/test-input b/aoc2020/day05/test-input new file mode 100644 index 0000000..b036d3e --- /dev/null +++ b/aoc2020/day05/test-input @@ -0,0 +1,3 @@ +BFFFBBFRRR +FFFBBBFRRR +BBFFBBFRLL diff --git a/aoc2020/day05/test-output b/aoc2020/day05/test-output new file mode 100644 index 0000000..3f39075 --- /dev/null +++ b/aoc2020/day05/test-output @@ -0,0 +1,3 @@ +bp=BFFFBBFRRR row=70 column=7 seat=567 +bp=FFFBBBFRRR row=14 column=7 seat=119 +bp=BBFFBBFRLL row=102 column=4 seat=820 diff --git a/aoc2020/day05/test_solution.py b/aoc2020/day05/test_solution.py new file mode 100644 index 0000000..9d6a571 --- /dev/null +++ b/aoc2020/day05/test_solution.py @@ -0,0 +1,23 @@ +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 not l.startswith("highest_seat") + ]