# IDEAS(dev): # - You might not have to determine all the positions if the numbers to decode don't use them # e.g. while(number to decode NOT IN numbers decodable) { do everything } # - # NOTES(dev): # - It looks like the codes are NOT always printed in the same order. For example, if one shows up # as 'cg', it might also later show up as 'gc' in the same line. # 0: 1: 2: 3: 4: # aaaa .... aaaa aaaa .... # b c . c . c . c b c # b c . c . c . c b c # .... .... dddd dddd dddd # e f . f e . . f . f # e f . f e . . f . f # gggg .... gggg gggg .... # 5: 6: 7: 8: 9: # aaaa aaaa aaaa aaaa aaaa # b . b . . c b c b c # b . b . . c b c b c # dddd dddd .... dddd dddd # . f e f . f e f . f # . f e f . f e f . f # gggg gggg .... gggg gggg # initialize shared data: possibilities = {} all_possibilities = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g' ] # functions: def ResetData(): possibilities.clear() for letter in all_possibilities: possibilities[letter] = list(all_possibilities) def RemoveImpossibleLetters(good_letters, good_positions): # generate inverse list of good_positions bad_positions = list(all_possibilities) for position in good_positions: bad_positions.remove(position) # first, get rid of the other letters from the positions used for position in good_positions: # positions used to_remove_list = [] for l in possibilities[position]: if(not (l in good_letters)): to_remove_list.append(l) for to_remove in to_remove_list: if(to_remove in possibilities[position]): possibilities[position].remove(to_remove) # second, get rid of the good letters from all the other positions for position in bad_positions: # positions not used for to_remove in good_letters: if(to_remove in possibilities[position]): possibilities[position].remove(to_remove) def ParsePossibilities(text): text_len = len(text) # The easy ones first: if(text_len == 2): good_letters = list(text) good_positions = ['c', 'f'] RemoveImpossibleLetters(good_letters, good_positions) if(text_len == 3): good_letters = list(text) good_positions = ['a', 'c', 'f'] RemoveImpossibleLetters(good_letters, good_positions) if(text_len == 4): good_letters = list(text) good_positions = ['b', 'c', 'd', 'f'] RemoveImpossibleLetters(good_letters, good_positions) # This one straight up doesn't help: # if(text_len == 7): # good_letters = list(text) # good_positions = ['a', 'b', 'c', 'd', 'e', 'f', 'g'] # RemoveImpossibleLetters(good_letters, good_positions) # The harder ones second: if(text_len == 5): # Could be 2, 3, or 5 # MUST contain positions 'a', 'd', and 'g' in any 5-position number # MIGHT contain positions 'b' and 'f' for FIVE # 'c' and 'e' for TWO # 'c' and 'f' for THREE # if one of them is found with two others, it's either c or f # if one of them is not found with two others, it could be b or e if(text_len == 6): # Could be 0, 6, or 9 # MUST contain positions 'a', 'b', 'f', and 'g' in any 6-position number # MIGHT contain positions 'c' and 'd' for NINE # 'c' and 'e' for ZERO # 'd' and 'e' for SIX total = 0 with open('example_data', 'r') as fp: # NOTE(dev): We assume all lines are the same length for line in fp: ResetData() split_line = line.split(' | ') data = split_line[0].split() # print(data) codes = split_line[1] for val in codes.split(): if(len(val) in [2, 3, 4, 7]): total += 1 for text in data: ParsePossibilities(text.strip()) asdf = possibilities.items() asdf = list(asdf) asdf.sort() print(asdf) # part 1 answer: print(total) # # DEBUG(dev): # print(possibilities)