#!/usr/bin/env python # 2021 - Advent Of Code - 3 part2 import re re_parse = re.compile(r'(\d)'*12) MOST = 1 LEAST = 0 def freq_bits(buf, mode): count = [0] * 12 co2_freq = [0] * 12 oxy = [0] * 12 for line in buf: m = re_parse.match(line) for i in range(12): if m.group(i+1) == '1': count[i] += 1 for i in range(12): if count[i] >= len(buf) / 2: oxy[i] = 1 else: oxy[i] = 0 for i in range(12): if count[i] > len(buf) / 2: co2_freq[i] = 1 else: co2_freq[i] = 0 if mode == MOST: return oxy if mode == LEAST: co2_freq = [0 if x == 1 else 1 for x in oxy] return co2_freq return None def filter_pos(line_buffer, position, value): for line in line_buffer: if line[position] == value: yield line def filter_freq(buffer, freq_buf, mode): i = 0 while i in range(12) and len(buffer) > 1: buffer = list(filter_pos(buffer, i, str(freq_buf[i]))) freq_buf = freq_bits(buffer, mode) print(len(buffer)) i += 1 return buffer line_buf = [] with open('input.txt', encoding="utf-8") as f: for input_line in f: line_buf.append(input_line) gamma_count = freq_bits(line_buf, MOST) gamma_bin = "".join([str(x) for x in gamma_count]) gamma = int(gamma_bin, 2) epsilon_count = freq_bits(line_buf, LEAST) epsilon_bin = "".join([str(x) for x in epsilon_count]) epsilon = int(epsilon_bin, 2) print(f'gamma_bin {gamma_bin}, gamma: {gamma}') print(f'epsilon_bin {epsilon_bin}, epsilon: {epsilon}') oxybuf = filter_freq(line_buf, gamma_count, MOST) co2buf = filter_freq(line_buf, epsilon_count, LEAST) oxygen = int(oxybuf[0].strip(), 2) print(f'oxybuf: {oxybuf}, oxygen: {oxygen}') co2 = int(co2buf[0].strip(), 2) print(f'co2buf: {co2buf}, co2: {co2}') print(f'life support: {oxygen}, {co2} => {oxygen * co2}')