AdventOfCode/2021/Day8/Day8_2_Reddit.py
2022-12-09 08:29:06 +01:00

143 lines
No EOL
4 KiB
Python

def AOC_8_a():
with open("src/input8.txt") as file:
lines = file.read().splitlines()
lines = [x.split(" | ")[1].split(' ') for x in lines]
total = 0
for line in lines:
for item in line:
if len(item) == 2 or len(item) == 3 or len(item) == 4 or len(item) == 7:
total += 1
print(total)
def AOC_8_b():
with open("input.txt") as file:
lines = file.read().splitlines()
lines = [x.split(" | ") for x in lines]
total = 0
for (lefthand, righthand) in lines:
lefts = lefthand.split(' ')
digits = fill_dict(lefts)
digits["2"] = find_two(digits["1"], digits["len5"] + digits["len6"])
digits["9"] = find_nine(digits["4"], digits["len6"])
digits["len6"].remove(digits["9"])
digits["5"] = find_five(digits["2"], digits["len5"])
digits["len5"].remove(digits["2"])
digits["len5"].remove(digits["5"])
digits["3"] = find_three(digits["len5"])
digits["6"] = find_six(digits["5"], digits["len6"])
digits["len6"].remove(digits["6"])
digits["0"] = find_zero(digits["len6"])
del digits["len5"]
del digits["len6"]
number = ""
for item in righthand.split(' '):
item = "".join(sorted(item))
for key, value in digits.items():
if (value == item):
number += key
print(number)
total += int(number)
print(total)
def pd(dict):
for (key, value) in dict.items():
print(key, ": ", value)
# 0 is the last number to find, and is just the last remaining not used string
def find_zero(candidates):
return candidates[0]
# 2 is the only digit that shares a unique single segment with 1 (5 and 6 also share
# a single segment with 1, but they're thus not unique) among unknown digits. We need both len5 and len6
# to check for this uniqueness.
def find_two(segment, candidates):
az = {x: shares_only_one_segment(x, segment) for x in candidates if shares_only_one_segment(x, segment) is not None}
return least_frequent(az)
# 3 will be the only len5 segment not assigned at this point
def find_three(candidates):
return candidates[0]
# 5 is the only digit that shares three segments with 2
def find_five(segment, candidates):
for can in candidates:
if (shares_x_segments(segment, can, 3)):
return can
# 6 is the only digit that shares five segments with 5
def find_six(segment, candidates):
for can in candidates:
if (shares_x_segments(segment, can, 5)):
return can
# 9 is the only digit that shares four segments with 4
def find_nine(segment, candidates):
for can in candidates:
if (shares_x_segments(segment, can, 4)):
return can
def least_frequent(dict):
list = [value for (key, value) in dict.items()]
lowest_value = min(set(list), key=list.count)
for key, value in dict.items():
if (lowest_value == value):
return key
def shares_only_one_segment(segment, candidate):
total = 0
for a in segment:
for b in candidate:
if (a == b):
total += 1
shared = a
return shared if total == 1 else None
def shares_x_segments(segment, candidate, x):
total = 0
for seg in segment:
for can in candidate:
if (seg == can):
total += 1
return total == x
def fill_dict(lefts):
digits = {"len5": [], "len6": []}
for num in lefts:
num = "".join(sorted(num))
if (len(num) == 2):
digits["1"] = num
if (len(num) == 4):
digits["4"] = num
if (len(num) == 3):
digits["7"] = num
if (len(num) == 7):
digits["8"] = num
if (len(num) == 5):
digits["len5"].append(num)
if (len(num) == 6):
digits["len6"].append(num)
return digits
if __name__ == '__main__':
AOC_8_b()