from lib import * from collections import OrderedDict EXAMPLE = "rn=1,cm-,qp=3,cm=2,qp-,pc=4,ot=9,ab=5,pc-,pc=6,ot=7" def hash(word): # Init to 0 # Determine the ASCII code for the current character of the string. # Increase the current value by the ASCII code you just determined. Set # the current value to itself multiplied by 17. Set the current value to # the remainder of dividing itself by 256. h = 0 for c in word: v = ord(c) h += v h *= 17 h %= 256 return h def solve(input: Input, second=False): res = 0 line = input.lines()[0] for word in line.split(","): h = hash(word) res += h if not second: return res boxes = [OrderedDict() for _ in range(256)] for word in line.split(","): h = hash(word) if '=' in word: label, focal = word.split('=') box = boxes[hash(label)] if label in box: box[label] = (label, focal) else: box[label] = (label, focal) elif '-' in word: label = word.replace('-', '') box = boxes[hash(label)] if label in box: del box[label] else: raise Exception() res = 0 for i, b in enumerate(boxes): for j, label in enumerate(b): label, focal = b[label] r = (i + 1) * (j + 1) * int(focal) res += r return res def main(): DAY_INPUT = "i15.txt" print("Example 1:", solve(Input(EXAMPLE))) print("Solution 1:", solve(Input(DAY_INPUT))) assert solve(Input(DAY_INPUT)) == 511343 # 4:30 print("Example 2:", solve(Input(EXAMPLE), True)) print("Solution 2:", solve(Input(DAY_INPUT), True)) assert solve(Input(DAY_INPUT), True) == 294474 # 31:20 return if __name__ == "__main__": main()