#!/usr/bin/env python3 from pprint import pprint with open('input.txt', 'r') as f: polymer = f.read() print('Polymer length:', len(polymer)) def reacts(el_1, el_2): return el_1 != el_2 and el_1.upper() == el_2.upper() def reduce_polymer_naive(polymer): """Faster but not correct solution. Can be used for first reduction of data """ poly = list(polymer) i = 0 gap = 1 while i < len(poly): if i < 0 or i + gap >= len(poly): i += gap gap = 1 continue el = poly[i] next_el = poly[i + gap] if reacts(el, next_el): poly[i] = '-' poly[i + gap] = '-' i -= 1 gap += 2 continue i += gap gap = 1 return ''.join([el for el in poly if el != '-']) def reduce_polymer(polymer): polymer = reduce_polymer_naive(polymer) modifications = True rounds = 0 while modifications: modifications = False rounds += 1 mods = 0 new_polymer = [] skip = False for i, el in enumerate(polymer[:-1]): if skip: skip = False continue next_el = polymer[i + 1] if el != next_el and el.upper() == next_el.upper(): modifications = True mods += 1 skip = True continue new_polymer.append(el[-1]) if not skip: new_polymer.append(polymer[-1]) polymer = ''.join(new_polymer) return polymer alphabet = 'abcdefghijklmnopqrstuvwxyz' count_dict = dict() for el in alphabet: new_poly = ''.join([x for x in polymer if x not in (el, el.upper())]) count_dict[el] = len(reduce_polymer(new_poly)) print(f'Processed {el}, len: {count_dict[el]}') pprint(count_dict) min_idx = min(count_dict, key=count_dict.get) print(min_idx, count_dict[min_idx])