aoc-2021/03_day/code.py

90 lines
1.8 KiB
Python
Raw Permalink Normal View History

2021-12-05 15:52:20 +00:00
import fileinput
data = []
for inp in fileinput.input():
val = inp.strip()
if val != '':
data.append(val)
commons = []
epsilon = []
gamma = []
charLen = len(data[0])
lineLen = len(data)
for i in range(charLen):
count = 0
for j in range(lineLen):
if data[j][i] == '1':
count += 1
status = 'lt'
#print(count, lineLen-count)
if count == (lineLen-count): status = 'eq'
if count > (lineLen-count): status = 'gt'
if status == 'gt':
most,least = '1', '0'
else:
most,least = '0', '1'
gamma.append(most)
epsilon.append(least)
commons.append((status, most, least))
g = int(''.join(gamma), 2)
e = int(''.join(epsilon), 2)
def get_distribution(nbs):
out = []
for _i in range(len(nbs[0])):
count = 0
for _j in range(len(nbs)):
if nbs[_j][_i] == '1': count += 1
status = 'lt'
if count == (len(nbs)-count): status = 'eq'
if count > (len(nbs)-count): status = 'gt'
most,least = ('1', '0') if status == 'gt' else ('0', '1')
out.append((status, most, least))
return out
def filter_item(mode, status, most, least, x, i, full):
print(f'{mode=}, {status=}, {most=}, {least=}, {x=}, {i=}, {full=}')
if mode:
if status == 'eq':
return x == '1' # oxygen
if x == most: return True
if not mode: # co2
if status == 'eq':
return x == '0'
if x == least: return True
return False
def rating(inp, mode = True):
nb = inp.copy()
i = 0
while len(nb) > 1:
distri = get_distribution(nb)
print(f'= {len(nb)} -> {nb} {distri=}')
status, most, least = distri[i]
nb = list(filter(lambda x: filter_item(mode, status, most, least, x[i], i, x), nb))
i += 1
print(f'after filter: {nb}')
return int(nb[0], 2)
print(g, e)
print(g*e)
print(commons)
o = rating(data, True)
c = rating(data, False)
print('==')
print(o) # oxygen
print(c) # CO2
print(o*c)