1
0
Fork 0

formatting and cosmetic updates to 2020.

This commit is contained in:
Gabe Venberg 2026-04-17 16:21:34 +02:00
parent 84c4cf9991
commit cd75e58f77
28 changed files with 320 additions and 287 deletions

View file

@ -2,41 +2,43 @@
import pathlib import pathlib
import sys import sys
import re
from dataclasses import dataclass
def parse(puzzle_input): def parse(puzzle_input):
"""Parse input""" """Parse input"""
return [int(string) for string in puzzle_input.splitlines()] return [int(string) for string in puzzle_input.splitlines()]
def part1(data:list[int]):
def part1(data: list[int]):
"""Solve part 1""" """Solve part 1"""
data.sort() data.sort()
while True: while True:
if len(data)<2: if len(data) < 2:
raise ValueError('no match found') raise ValueError("no match found")
s = data[0]+data[-1] s = data[0] + data[-1]
if s>2020: if s > 2020:
data.pop(-1) data.pop(-1)
elif s<2020: elif s < 2020:
data.pop(0) data.pop(0)
else: else:
return data[0]*data[-1] return data[0] * data[-1]
def part2(data): def part2(data):
"""Solve part 2""" """Solve part 2"""
data.sort() data.sort()
while True: while True:
if len(data)<3: if len(data) < 3:
raise ValueError('no match found') raise ValueError("no match found")
if data[0]+data[1]+data[-1]>2020: if data[0] + data[1] + data[-1] > 2020:
data.pop(-1) data.pop(-1)
elif data[0]+data[-1]+data[-2]<2020: elif data[0] + data[-1] + data[-2] < 2020:
data.pop(0) data.pop(0)
elif data[0]+data[1]+data[-1]==2020: elif data[0] + data[1] + data[-1] == 2020:
return data[0]*data[1]*data[-1] return data[0] * data[1] * data[-1]
else: else:
return data[0]*data[-1]*data[-2] return data[0] * data[-1] * data[-2]
def solve(puzzle_input): def solve(puzzle_input):
"""Solve the puzzle for the given input""" """Solve the puzzle for the given input"""
@ -46,6 +48,7 @@ def solve(puzzle_input):
return solution1, solution2 return solution1, solution2
if __name__ == "__main__": if __name__ == "__main__":
for path in sys.argv[1:]: for path in sys.argv[1:]:
print(f"{path}:") print(f"{path}:")

View file

@ -6,28 +6,24 @@ import day1 as aoc
PUZZLE_DIR = pathlib.Path(__file__).parent PUZZLE_DIR = pathlib.Path(__file__).parent
#these test fixtures setup the test, mainly by reading the filename into a string in this simple case.
# these test fixtures setup the test, mainly by reading the filename into a string in this simple case.
@pytest.fixture @pytest.fixture
def example1(): def example():
puzzle_input = (PUZZLE_DIR / "example1").read_text().strip() puzzle_input = (PUZZLE_DIR / "example").read_text().strip()
return aoc.parse(puzzle_input) return aoc.parse(puzzle_input)
@pytest.fixture
def example2():
puzzle_input = (PUZZLE_DIR / "example2").read_text().strip()
return aoc.parse(puzzle_input)
# @pytest.mark.skip(reason="Not implemented") def test_parse(example):
def test_parse_example1(example1):
"""Test that input is parsed properly""" """Test that input is parsed properly"""
assert example1 == [1721, 979, 366, 299, 675, 1456] assert example == [1721, 979, 366, 299, 675, 1456]
# @pytest.mark.skip(reason="Not implemented")
def test_part1_example1(example1): def test_part1(example):
"""Test part 1 on example input""" """Test part 1 on example input"""
assert aoc.part1(example1) == 514579 assert aoc.part1(example) == 514579
# @pytest.mark.skip(reason="Not implemented")
def test_part2_example2(example1): def test_part2(example):
"""Test part 2 on example input""" """Test part 2 on example input"""
assert aoc.part2(example1) == 241861950 assert aoc.part2(example) == 241861950

View file

@ -1,40 +1,52 @@
#! /usr/bin/env python3 #! /usr/bin/env python3
import pathlib import pathlib
import sys
import re import re
import sys
from dataclasses import dataclass from dataclasses import dataclass
@dataclass @dataclass
class PasswordSpec: class PasswordSpec:
first:int first: int
second:int second: int
letter:str letter: str
password:str password: str
def parse(puzzle_input: str): def parse(puzzle_input: str):
"""Parse input""" """Parse input"""
regex = re.compile(r'^(\d+)-(\d+) (\w): (\w+)$') regex = re.compile(r"^(\d+)-(\d+) (\w): (\w+)$")
toInt = lambda x: PasswordSpec(int(x[0]), int(x[1]), x[2], x[3])
def toInt(x):
return PasswordSpec(int(x[0]), int(x[1]), x[2], x[3])
return [toInt(regex.match(i).groups()) for i in puzzle_input.splitlines()] return [toInt(regex.match(i).groups()) for i in puzzle_input.splitlines()]
def part1(data): def part1(data):
"""Solve part 1""" """Solve part 1"""
test = lambda x: x.first<=x.password.count(x.letter)<=x.second
def test(x):
return x.first <= x.password.count(x.letter) <= x.second
# these two lines are equivilant. # these two lines are equivilant.
# return sum(1 for p in data if test(p)) # return sum(1 for p in data if test(p))
return len([1 for p in data if test(p)]) return len([1 for p in data if test(p)])
def test_password(passwordSpec: PasswordSpec): def test_password(passwordSpec: PasswordSpec):
if passwordSpec.password[passwordSpec.first-1]==passwordSpec.letter: if passwordSpec.password[passwordSpec.first - 1] == passwordSpec.letter:
return passwordSpec.password[passwordSpec.second-1]!=passwordSpec.letter return passwordSpec.password[passwordSpec.second - 1] != passwordSpec.letter
else: else:
return passwordSpec.password[passwordSpec.second-1]==passwordSpec.letter return passwordSpec.password[passwordSpec.second - 1] == passwordSpec.letter
def part2(data): def part2(data):
"""Solve part 2""" """Solve part 2"""
return sum(1 for p in data if test_password(p)) return sum(1 for p in data if test_password(p))
def solve(puzzle_input): def solve(puzzle_input):
"""Solve the puzzle for the given input""" """Solve the puzzle for the given input"""
data = parse(puzzle_input) data = parse(puzzle_input)
@ -43,6 +55,7 @@ def solve(puzzle_input):
return solution1, solution2 return solution1, solution2
if __name__ == "__main__": if __name__ == "__main__":
for path in sys.argv[1:]: for path in sys.argv[1:]:
print(f"{path}:") print(f"{path}:")

View file

@ -6,32 +6,28 @@ import day2 as aoc
PUZZLE_DIR = pathlib.Path(__file__).parent PUZZLE_DIR = pathlib.Path(__file__).parent
#these test fixtures setup the test, mainly by reading the filename into a string in this simple case.
# these test fixtures setup the test, mainly by reading the filename into a string in this simple case.
@pytest.fixture @pytest.fixture
def example1(): def example():
puzzle_input = (PUZZLE_DIR / "example1").read_text().strip() puzzle_input = (PUZZLE_DIR / "example").read_text().strip()
return aoc.parse(puzzle_input) return aoc.parse(puzzle_input)
@pytest.fixture
def example2():
puzzle_input = (PUZZLE_DIR / "example2").read_text().strip()
return aoc.parse(puzzle_input)
# @pytest.mark.skip(reason="Not implemented") def test_parse(example):
def test_parse_example1(example1):
"""Test that input is parsed properly""" """Test that input is parsed properly"""
assert example1 == [ assert example == [
aoc.PasswordSpec(first=1, second=3, letter='a', password='abcde'), aoc.PasswordSpec(first=1, second=3, letter="a", password="abcde"),
aoc.PasswordSpec(first=1, second=3, letter='b', password='cdefg'), aoc.PasswordSpec(first=1, second=3, letter="b", password="cdefg"),
aoc.PasswordSpec(first=2, second=9, letter='c', password='ccccccccc') aoc.PasswordSpec(first=2, second=9, letter="c", password="ccccccccc"),
] ]
# @pytest.mark.skip(reason="Not implemented")
def test_part1_example1(example1): def test_part1(example):
"""Test part 1 on example input""" """Test part 1 on example input"""
assert aoc.part1(example1) == 2 assert aoc.part1(example) == 2
# @pytest.mark.skip(reason="Not implemented")
def test_part2_example2(example1): def test_part2(example):
"""Test part 2 on example input""" """Test part 2 on example input"""
assert aoc.part2(example1) == 1 assert aoc.part2(example) == 1

View file

@ -2,25 +2,35 @@
import pathlib import pathlib
import sys import sys
import re
from dataclasses import dataclass
from pprint import pprint
def parse(puzzle_input: str): def parse(puzzle_input: str):
"""Parse input""" """Parse input"""
# returns a 2 dimentional array where true means there is a tree there. # returns a 2 dimentional array where true means there is a tree there.
return [[i=='#' for i in j] for j in puzzle_input.splitlines()] return [[i == "#" for i in j] for j in puzzle_input.splitlines()]
def part1(data): def part1(data):
"""Solve part 1""" """Solve part 1"""
return solveForSlope(data, 3, 1) return solveForSlope(data, 3, 1)
def solveForSlope(data, right: int, down: int): def solveForSlope(data, right: int, down: int):
return sum(1 for index, row in enumerate(data[::down]) if row[(right*index)%len(row)]) return sum(
1 for index, row in enumerate(data[::down]) if row[(right * index) % len(row)]
)
def part2(data): def part2(data):
"""Solve part 2""" """Solve part 2"""
return solveForSlope(data,1,1)*solveForSlope(data,3,1)*solveForSlope(data,5,1)*solveForSlope(data,7,1)*solveForSlope(data,1,2) return (
solveForSlope(data, 1, 1)
* solveForSlope(data, 3, 1)
* solveForSlope(data, 5, 1)
* solveForSlope(data, 7, 1)
* solveForSlope(data, 1, 2)
)
def solve(puzzle_input): def solve(puzzle_input):
"""Solve the puzzle for the given input""" """Solve the puzzle for the given input"""
@ -30,6 +40,7 @@ def solve(puzzle_input):
return solution1, solution2 return solution1, solution2
if __name__ == "__main__": if __name__ == "__main__":
for path in sys.argv[1:]: for path in sys.argv[1:]:
print(f"{path}:") print(f"{path}:")

View file

@ -6,38 +6,38 @@ import day3 as aoc
PUZZLE_DIR = pathlib.Path(__file__).parent PUZZLE_DIR = pathlib.Path(__file__).parent
#these test fixtures setup the test, mainly by reading the filename into a string in this simple case.
# these test fixtures setup the test, mainly by reading the filename into a string in this simple case.
@pytest.fixture @pytest.fixture
def example1(): def example():
puzzle_input = (PUZZLE_DIR / "example1").read_text().strip() puzzle_input = (PUZZLE_DIR / "example.txt").read_text().strip()
return aoc.parse(puzzle_input) return aoc.parse(puzzle_input)
@pytest.fixture
def example2():
puzzle_input = (PUZZLE_DIR / "example1").read_text().strip()
return aoc.parse(puzzle_input)
# @pytest.mark.skip(reason="Not implemented") def test_parse(example):
def test_parse_example1(example1):
"""Test that input is parsed properly""" """Test that input is parsed properly"""
assert example1 == [[False, False, True, True, False, False, False, False, False, False, False], assert example == [
[True, False, False, False, True, False, False, False, True, False, False], [False, False, True, True, False, False, False, False, False, False, False],
[False, True, False, False, False, False, True, False, False, True, False], [True, False, False, False, True, False, False, False, True, False, False],
[False, False, True, False, True, False, False, False, True, False, True], [False, True, False, False, False, False, True, False, False, True, False],
[False, True, False, False, False, True, True, False, False, True, False], [False, False, True, False, True, False, False, False, True, False, True],
[False, False, True, False, True, True, False, False, False, False, False], [False, True, False, False, False, True, True, False, False, True, False],
[False, True, False, True, False, True, False, False, False, False, True], [False, False, True, False, True, True, False, False, False, False, False],
[False, True, False, False, False, False, False, False, False, False, True], [False, True, False, True, False, True, False, False, False, False, True],
[True, False, True, True, False, False, False, True, False, False, False], [False, True, False, False, False, False, False, False, False, False, True],
[True, False, False, False, True, True, False, False, False, False, True], [True, False, True, True, False, False, False, True, False, False, False],
[False, True, False, False, True, False, False, False, True, False, True]] [True, False, False, False, True, True, False, False, False, False, True],
[False, True, False, False, True, False, False, False, True, False, True],
]
# @pytest.mark.skip(reason="Not implemented") # @pytest.mark.skip(reason="Not implemented")
def test_part1_example1(example1): def test_part1(example):
"""Test part 1 on example input""" """Test part 1 on example input"""
assert aoc.part1(example1) == 7 assert aoc.part1(example) == 7
# @pytest.mark.skip(reason="Not implemented") # @pytest.mark.skip(reason="Not implemented")
def test_part2_example2(example2): def test_part2(example):
"""Test part 2 on example input""" """Test part 2 on example input"""
assert aoc.part2(example2) == 336 assert aoc.part2(example) == 336

View file

@ -1,10 +1,10 @@
#! /usr/bin/env python3 #! /usr/bin/env python3
import pathlib import pathlib
import sys
import re import re
import sys
from dataclasses import dataclass from dataclasses import dataclass
from pprint import pprint
@dataclass @dataclass
class Passport: class Passport:
@ -17,105 +17,131 @@ class Passport:
passportId: str | None passportId: str | None
countryId: str | None countryId: str | None
def regexUnwrap(match, group:int)->str | None:
def regexUnwrap(match, group: int) -> str | None:
return match[group] if match is not None else None return match[group] if match is not None else None
def parse(puzzle_input: str)->list[Passport]:
def parse(puzzle_input: str) -> list[Passport]:
"""Parse input""" """Parse input"""
rawRecords = [i.replace('\n', ' ') for i in puzzle_input.split('\n\n')] rawRecords = [i.replace("\n", " ") for i in puzzle_input.split("\n\n")]
records = [] records = []
for rawRecord in rawRecords: for rawRecord in rawRecords:
birthYear=re.search(r'byr:(\S+)', rawRecord) birthYear = re.search(r"byr:(\S+)", rawRecord)
issueYear=re.search(r'iyr:(\S+)', rawRecord) issueYear = re.search(r"iyr:(\S+)", rawRecord)
expirationYear=re.search(r'eyr:(\S+)', rawRecord) expirationYear = re.search(r"eyr:(\S+)", rawRecord)
height=re.search(r'hgt:(\S+)', rawRecord) height = re.search(r"hgt:(\S+)", rawRecord)
hairColor=re.search(r'hcl:(\S+)', rawRecord) hairColor = re.search(r"hcl:(\S+)", rawRecord)
eyeColor=re.search(r'ecl:(\S+)', rawRecord) eyeColor = re.search(r"ecl:(\S+)", rawRecord)
passportId=re.search(r'pid:(\S+)', rawRecord) passportId = re.search(r"pid:(\S+)", rawRecord)
countryId=re.search(r'cid:(\S+)', rawRecord) countryId = re.search(r"cid:(\S+)", rawRecord)
records.append(Passport( records.append(
int(birthYear[1]) if birthYear is not None else None, Passport(
int(issueYear[1]) if issueYear is not None else None, int(birthYear[1]) if birthYear is not None else None,
int(expirationYear[1]) if expirationYear is not None else None, int(issueYear[1]) if issueYear is not None else None,
regexUnwrap(height,1), int(expirationYear[1]) if expirationYear is not None else None,
regexUnwrap(hairColor,1), regexUnwrap(height, 1),
regexUnwrap(eyeColor,1), regexUnwrap(hairColor, 1),
regexUnwrap(passportId,1), regexUnwrap(eyeColor, 1),
regexUnwrap(countryId,1), regexUnwrap(passportId, 1),
)) regexUnwrap(countryId, 1),
)
)
return records return records
def lazyCheckPassport(passport: Passport)->bool:
def lazyCheckPassport(passport: Passport) -> bool:
return ( return (
passport.birthYear is not None passport.birthYear is not None
and passport.issueYear is not None and passport.issueYear is not None
and passport.expirationYear is not None and passport.expirationYear is not None
and passport.height is not None and passport.height is not None
and passport.hairColor is not None and passport.hairColor is not None
and passport.eyeColor is not None and passport.eyeColor is not None
and passport.passportId is not None and passport.passportId is not None
) )
def part1(data): def part1(data):
"""Solve part 1""" """Solve part 1"""
return sum(1 for record in data if lazyCheckPassport(record)) return sum(1 for record in data if lazyCheckPassport(record))
def checkBirthYear(passport: Passport)->bool:
if passport.birthYear is None: return False
return (1920<=passport.birthYear<=2002)
def checkIssueYear(passport: Passport)->bool: def checkBirthYear(passport: Passport) -> bool:
if passport.issueYear is None: return False if passport.birthYear is None:
return (2010<=passport.issueYear<=2020) return False
return 1920 <= passport.birthYear <= 2002
def checkExpirationYear(passport: Passport)->bool:
if passport.expirationYear is None: return False
return (2020<=passport.expirationYear<=2030)
def checkHeight(passport: Passport)->bool: def checkIssueYear(passport: Passport) -> bool:
if passport.height is None: return False if passport.issueYear is None:
rematch = re.match(r'(\d+)((?:in)|(?:cm))', passport.height) return False
if rematch is None: return False return 2010 <= passport.issueYear <= 2020
def checkExpirationYear(passport: Passport) -> bool:
if passport.expirationYear is None:
return False
return 2020 <= passport.expirationYear <= 2030
def checkHeight(passport: Passport) -> bool:
if passport.height is None:
return False
rematch = re.match(r"(\d+)((?:in)|(?:cm))", passport.height)
if rematch is None:
return False
number = int(rematch.group(1)) number = int(rematch.group(1))
unit = rematch.group(2) unit = rematch.group(2)
if unit == 'in': if unit == "in":
return (59<=number<=76) return 59 <= number <= 76
else: else:
return (150<=number<=193) return 150 <= number <= 193
def checkHairColour(passport: Passport)->bool:
if passport.hairColor is None: return False
return (re.match(r'#[0123456789abcdef]{6}$', passport.hairColor) is not None)
def checkEyeColour(passport: Passport)->bool: def checkHairColour(passport: Passport) -> bool:
if passport.eyeColor is None: return False if passport.hairColor is None:
return (passport.eyeColor == 'amb' return False
or passport.eyeColor == 'blu' return re.match(r"#[0123456789abcdef]{6}$", passport.hairColor) is not None
or passport.eyeColor == 'brn'
or passport.eyeColor == 'gry'
or passport.eyeColor == 'grn'
or passport.eyeColor == 'hzl'
or passport.eyeColor == 'oth'
)
def checkPassportId(passport: Passport)->bool:
if passport.passportId is None: return False
return (re.match(r'[0-9]{9}$', passport.passportId) is not None)
def checkPassport(passport: Passport)->bool: def checkEyeColour(passport: Passport) -> bool:
return (checkBirthYear(passport) if passport.eyeColor is None:
and checkIssueYear(passport) return False
and checkExpirationYear(passport) return (
and checkHeight(passport) passport.eyeColor == "amb"
and checkHairColour(passport) or passport.eyeColor == "blu"
and checkEyeColour(passport) or passport.eyeColor == "brn"
and checkPassportId(passport) or passport.eyeColor == "gry"
) or passport.eyeColor == "grn"
or passport.eyeColor == "hzl"
or passport.eyeColor == "oth"
)
def checkPassportId(passport: Passport) -> bool:
if passport.passportId is None:
return False
return re.match(r"[0-9]{9}$", passport.passportId) is not None
def checkPassport(passport: Passport) -> bool:
return (
checkBirthYear(passport)
and checkIssueYear(passport)
and checkExpirationYear(passport)
and checkHeight(passport)
and checkHairColour(passport)
and checkEyeColour(passport)
and checkPassportId(passport)
)
def part2(data): def part2(data):
"""Solve part 2""" """Solve part 2"""
return sum(1 for record in data if checkPassport(record)) return sum(1 for record in data if checkPassport(record))
def solve(puzzle_input): def solve(puzzle_input):
"""Solve the puzzle for the given input""" """Solve the puzzle for the given input"""
data = parse(puzzle_input) data = parse(puzzle_input)
@ -124,6 +150,7 @@ def solve(puzzle_input):
return solution1, solution2 return solution1, solution2
if __name__ == "__main__": if __name__ == "__main__":
for path in sys.argv[1:]: for path in sys.argv[1:]:
print(f"{path}:") print(f"{path}:")

View file

@ -7,59 +7,67 @@ from day4 import Passport
PUZZLE_DIR = pathlib.Path(__file__).parent PUZZLE_DIR = pathlib.Path(__file__).parent
#these test fixtures setup the test, mainly by reading the filename into a string in this simple case.
# these test fixtures setup the test, mainly by reading the filename into a string in this simple case.
@pytest.fixture @pytest.fixture
def example1(): def example():
puzzle_input = (PUZZLE_DIR / "example1").read_text().strip() puzzle_input = (PUZZLE_DIR / "example.txt").read_text().strip()
return aoc.parse(puzzle_input) return aoc.parse(puzzle_input)
@pytest.fixture
def example2():
puzzle_input = (PUZZLE_DIR / "example2").read_text().strip()
return aoc.parse(puzzle_input)
# @pytest.mark.skip(reason="Not implemented") def test_parse(example):
def test_parse_example1(example1):
"""Test that input is parsed properly""" """Test that input is parsed properly"""
assert example1 == [Passport(birthYear=1937, assert example == [
issueYear=2017, Passport(
expirationYear=2020, birthYear=1937,
height='183cm', issueYear=2017,
hairColor='#fffffd', expirationYear=2020,
eyeColor='gry', height="183cm",
passportId='860033327', hairColor="#fffffd",
countryId='147'), eyeColor="gry",
Passport(birthYear=1929, passportId="860033327",
countryId="147",
),
Passport(
birthYear=1929,
issueYear=2013, issueYear=2013,
expirationYear=2023, expirationYear=2023,
height=None, height=None,
hairColor='#cfa07d', hairColor="#cfa07d",
eyeColor='amb', eyeColor="amb",
passportId='028048884', passportId="028048884",
countryId='350'), countryId="350",
Passport(birthYear=1931, ),
Passport(
birthYear=1931,
issueYear=2013, issueYear=2013,
expirationYear=2024, expirationYear=2024,
height='179cm', height="179cm",
hairColor='#ae17e1', hairColor="#ae17e1",
eyeColor='brn', eyeColor="brn",
passportId='760753108', passportId="760753108",
countryId=None), countryId=None,
Passport(birthYear=None, ),
Passport(
birthYear=None,
issueYear=2011, issueYear=2011,
expirationYear=2025, expirationYear=2025,
height='59in', height="59in",
hairColor='#cfa07d', hairColor="#cfa07d",
eyeColor='brn', eyeColor="brn",
passportId='166559648', passportId="166559648",
countryId=None)] countryId=None,
),
]
# @pytest.mark.skip(reason="Not implemented") # @pytest.mark.skip(reason="Not implemented")
def test_part1_example1(example1): def test_part1(example):
"""Test part 1 on example input""" """Test part 1 on example input"""
assert aoc.part1(example1) == 2 assert aoc.part1(example) == 2
# @pytest.mark.skip(reason="Not implemented") # @pytest.mark.skip(reason="Not implemented")
def test_part2_example2(example1): def test_part2(example):
"""Test part 2 on example input""" """Test part 2 on example input"""
assert aoc.part2(example1) == 2 assert aoc.part2(example) == 2

View file

@ -2,34 +2,39 @@
import pathlib import pathlib
import sys import sys
import re
from dataclasses import dataclass
from pprint import pprint
def row_to_int(string: str)->int:
return int(string.replace('F','0').replace('B','1'),2)
def col_to_int(string: str)->int: def row_to_int(string: str) -> int:
return int(string.replace('L','0').replace('R','1'),2) return int(string.replace("F", "0").replace("B", "1"), 2)
def col_to_int(string: str) -> int:
return int(string.replace("L", "0").replace("R", "1"), 2)
def parse(puzzle_input: str): def parse(puzzle_input: str):
"""Parse input""" """Parse input"""
rows_and_cols = [(row_to_int(x[:7]),col_to_int(x[7:])) for x in puzzle_input.splitlines()] rows_and_cols = [
return set([x[0]*8+x[1] for x in rows_and_cols]) (row_to_int(x[:7]), col_to_int(x[7:])) for x in puzzle_input.splitlines()
]
return set([x[0] * 8 + x[1] for x in rows_and_cols])
def part1(data): def part1(data):
"""Solve part 1""" """Solve part 1"""
return max(data) return max(data)
def part2(data): def part2(data):
"""Solve part 2""" """Solve part 2"""
for row in range(128): for row in range(128):
for col in range(8): for col in range(8):
potentialID=row*8+col potentialID = row * 8 + col
if potentialID not in data: if potentialID not in data:
if (potentialID+1 in data) and (potentialID-1 in data): if (potentialID + 1 in data) and (potentialID - 1 in data):
return potentialID return potentialID
def solve(puzzle_input): def solve(puzzle_input):
"""Solve the puzzle for the given input""" """Solve the puzzle for the given input"""
data = parse(puzzle_input) data = parse(puzzle_input)
@ -38,6 +43,7 @@ def solve(puzzle_input):
return solution1, solution2 return solution1, solution2
if __name__ == "__main__": if __name__ == "__main__":
for path in sys.argv[1:]: for path in sys.argv[1:]:
print(f"{path}:") print(f"{path}:")

View file

@ -6,28 +6,24 @@ import day5 as aoc
PUZZLE_DIR = pathlib.Path(__file__).parent PUZZLE_DIR = pathlib.Path(__file__).parent
#these test fixtures setup the test, mainly by reading the filename into a string in this simple case.
# these test fixtures setup the test, mainly by reading the filename into a string in this simple case.
@pytest.fixture @pytest.fixture
def example1(): def example():
puzzle_input = (PUZZLE_DIR / "example1").read_text().strip() puzzle_input = (PUZZLE_DIR / "example.txt").read_text().strip()
return aoc.parse(puzzle_input) return aoc.parse(puzzle_input)
@pytest.fixture
def example2():
puzzle_input = (PUZZLE_DIR / "input").read_text().strip()
return aoc.parse(puzzle_input)
# @pytest.mark.skip(reason="Not implemented") def test_parse(example):
def test_parse_example1(example1):
"""Test that input is parsed properly""" """Test that input is parsed properly"""
assert example1 == {119, 357, 567, 820} assert example == {119, 357, 567, 820}
# @pytest.mark.skip(reason="Not implemented")
def test_part1_example1(example1): def test_part1(example):
"""Test part 1 on example input""" """Test part 1 on example input"""
assert aoc.part1(example1) == 820 assert aoc.part1(example) == 820
# @pytest.mark.skip(reason="Not implemented")
def test_part2_example2(example2): def test_part2(example):
"""Test part 2 on example input""" """Test part 2 on example input"""
assert aoc.part2(example2) == 640 assert aoc.part2(example) == 640

View file

@ -2,15 +2,14 @@
import pathlib import pathlib
import sys import sys
import re
from dataclasses import dataclass
from pprint import pprint
def parse(puzzle_input: str): def parse(puzzle_input: str):
"""Parse input""" """Parse input"""
records = [[list(y) for y in x.splitlines()] for x in puzzle_input.split('\n\n')] records = [[list(y) for y in x.splitlines()] for x in puzzle_input.split("\n\n")]
return records return records
def part1(data): def part1(data):
"""Solve part 1""" """Solve part 1"""
results = [] results = []
@ -21,6 +20,7 @@ def part1(data):
results.append(len(result)) results.append(len(result))
return sum(results) return sum(results)
def part2(data): def part2(data):
"""Solve part 2""" """Solve part 2"""
results = [] results = []
@ -31,6 +31,7 @@ def part2(data):
results.append(len(result)) results.append(len(result))
return sum(results) return sum(results)
def solve(puzzle_input): def solve(puzzle_input):
"""Solve the puzzle for the given input""" """Solve the puzzle for the given input"""
data = parse(puzzle_input) data = parse(puzzle_input)
@ -39,6 +40,7 @@ def solve(puzzle_input):
return solution1, solution2 return solution1, solution2
if __name__ == "__main__": if __name__ == "__main__":
for path in sys.argv[1:]: for path in sys.argv[1:]:
print(f"{path}:") print(f"{path}:")

View file

@ -6,50 +6,33 @@ import day6 as aoc
PUZZLE_DIR = pathlib.Path(__file__).parent PUZZLE_DIR = pathlib.Path(__file__).parent
#these test fixtures setup the test, mainly by reading the filename into a string in this simple case.
# these test fixtures setup the test, mainly by reading the filename into a string in this simple case.
@pytest.fixture @pytest.fixture
def example1(): def example():
puzzle_input = (PUZZLE_DIR / "example1").read_text().strip() puzzle_input = (PUZZLE_DIR / "example.txt").read_text().strip()
return aoc.parse(puzzle_input) return aoc.parse(puzzle_input)
@pytest.fixture
def example2():
puzzle_input = (PUZZLE_DIR / "example2").read_text().strip()
return aoc.parse(puzzle_input)
# @pytest.mark.skip(reason="Not implemented") # @pytest.mark.skip(reason="Not implemented")
def test_parse_example1(example1): def test_parse(example):
"""Test that input is parsed properly""" """Test that input is parsed properly"""
assert example1 == [ assert example == [
[ [["a", "b", "c"]],
['a', 'b', 'c'] [["a"], ["b"], ["c"]],
], [["a", "b"], ["a", "c"]],
[ [["a"], ["a"], ["a"], ["a"]],
['a'], [["b"]],
['b'], ]
['c']
],
[
['a', 'b'],
['a', 'c']
],
[
['a'],
['a'],
['a'],
['a']
],
[
['b']
]
]
# @pytest.mark.skip(reason="Not implemented") # @pytest.mark.skip(reason="Not implemented")
def test_part1_example1(example1): def test_part1(example):
"""Test part 1 on example input""" """Test part 1 on example input"""
assert aoc.part1(example1) == 11 assert aoc.part1(example) == 11
# @pytest.mark.skip(reason="Not implemented") # @pytest.mark.skip(reason="Not implemented")
def test_part2_example2(example1): def test_part2(example):
"""Test part 2 on example input""" """Test part 2 on example input"""
assert aoc.part2(example1) == 6 assert aoc.part2(example) == 6

View file

0
2020/template/input.txt Normal file
View file

View file

@ -2,9 +2,6 @@
import pathlib import pathlib
import sys import sys
import re
from dataclasses import dataclass
from pprint import pprint
def parse(puzzle_input: str): def parse(puzzle_input: str):
"""Parse input""" """Parse input"""

View file

@ -2,32 +2,27 @@
import pathlib import pathlib
import pytest import pytest
import template as aoc import temp as aoc
PUZZLE_DIR = pathlib.Path(__file__).parent PUZZLE_DIR = pathlib.Path(__file__).parent
#these test fixtures setup the test, mainly by reading the filename into a string in this simple case. #these test fixtures setup the test, mainly by reading the filename into a string in this simple case.
@pytest.fixture @pytest.fixture
def example1(): def example():
puzzle_input = (PUZZLE_DIR / "example1").read_text().strip() puzzle_input = (PUZZLE_DIR / "example.txt").read_text().strip()
return aoc.parse(puzzle_input)
@pytest.fixture
def example2():
puzzle_input = (PUZZLE_DIR / "example2").read_text().strip()
return aoc.parse(puzzle_input) return aoc.parse(puzzle_input)
@pytest.mark.skip(reason="Not implemented") @pytest.mark.skip(reason="Not implemented")
def test_parse_example1(example1): def test_parse_example(example):
"""Test that input is parsed properly""" """Test that input is parsed properly"""
assert example1 == ... assert example == ...
@pytest.mark.skip(reason="Not implemented") @pytest.mark.skip(reason="Not implemented")
def test_part1_example1(example1): def test_part1_example(example):
"""Test part 1 on example input""" """Test part 1 on example input"""
assert aoc.part1(example1) == ... assert aoc.part1(example) == ...
@pytest.mark.skip(reason="Not implemented") @pytest.mark.skip(reason="Not implemented")
def test_part2_example2(example2): def test_part2_example(example):
"""Test part 2 on example input""" """Test part 2 on example input"""
assert aoc.part2(example2) == ... assert aoc.part2(example) == ...