day 23
ok so.. 23a i just did with a list, and 23b i changed that to a dict which was effectively a linked list (cups[i] = j <=> cup j is clockwise of cup i)
'23a - dict' is my 23b solution applied to a, '23b - slow list' is my 23a solution applied to b (would take about 110h), '23b - slow dict' is that but with the list changed to a dict (would take about 80h), and 23b is that but the calculation for the destination cup is done by repeatedly subtracting 1 from the current cup value until it hits something valid, or doing that from the maximum until it hits something valid - in 23a i did this by getting the maximum of the set of valid cups, which implemented it without loops but slowed things down once it got to 1 million cups.
23a:
# input with open('23.txt', 'r') as file: input = file.read() cups = [int(c) for c in list(input)] print(cups) # function does one pass # cc is current cup (starts with cups[0]) def grab_cup(cc,cups): # get loc of current cup # x,y,z are next three cups # update cloc in case we wrap around the list cloc = cups.index(cc) x = cups.pop((cloc+1) % len(cups)) cloc = cups.index(cc) y = cups.pop((cloc+1) % len(cups)) cloc = cups.index(cc) z = cups.pop((cloc+1) % len(cups)) # cups with value under the current one under_cc = [c for c in cups if c < cc] if under_cc: # there exists a cup with value < cc # destination cup is the max available under cc dc = max(under_cc) else: # there is no cup with value < cc # destination cup is the max available that is not cc dc = max([c for c in cups if not c == cc]) # find location of dc dloc = cups.index(dc) # place x,y,z cups.insert(dloc+1,z) cups.insert(dloc+1,y) cups.insert(dloc+1,x) # get loc of current cup (might have changed) cloc = cups.index(cc) # return next cup # modulo is to ensure we don't get errors print(cups,'cc',cc,'x',x,'y',y,'z',z,'dc',dc) return cups[(cloc+1) % len(cups)] # get first current cup cc = cups[0] # and num steps done i = 0 # run 100 moves while i < 100: cc = grab_cup(cc,cups) i += 1 # fix list so 1 is the first while not cups[0] == 1: w = cups.pop(0) cups.append(w) # remove the 1 cups.pop(0) print('part a answer: ',''.join([str(c) for c in cups]))
23b:
# for timing import time # input with open('23.txt', 'r') as file: input = file.read() # grab them cups cups_list = [int(c) for c in list(input)] # add on mORE CUPS cups_list = cups_list + [i for i in range(10,1000001)] # turn it into a dict containing the next value cups = {} for i in range(0,len(cups_list)): cups[cups_list[i]] = cups_list[(i+1) % len(cups_list)] # get first current cup cc = cups_list[0] del cups_list # and num steps done i = 0 # function does one pass # cc is current cup def grab_cup(cc): # x,y,z are next three cups x = cups[cc] y = cups[x] z = cups[y] # get dc dc = cc - 1 while dc in [x,y,z]: dc -= 1 # gone too low if 0 if dc == 0: # go to max dc = 1000000 # work down if needed while dc in [x, y, z]: dc -= 1 # place x,y,z by updating next elts # ... cc, x, y, z, a ... -> ... cc, a ... # ... dc, b ... -> ... dc, x, y, z, b ... # get a and b a = cups[z] b = cups[dc] # set new nexts for cc, dc, z (unchanged for x,y,a,b) cups[cc] = a cups[dc] = x cups[z] = b # return next cup return cups[cc] tic = time.perf_counter() # run 100 moves while i < 10000000: cc = grab_cup(cc) i += 1 toc = time.perf_counter() print('moves remaining:',10000000-i,'mins elapsed:',int((toc-tic)/60),'mins left:',int(((toc-tic)/i)*(10000000-i)/60),' ',end = '\r', flush = True) # get the two cups after 1 p = cups[1] q = cups[p] print('part b answer: ',p * q,' ') print('seconds taken:',toc-tic)
Files
Get aoc 2020
aoc 2020
not a mod, just some code
Status | Released |
Category | Other |
Author | riv |
Tags | advent-of-code, advent-of-code-2020, python |
Leave a comment
Log in with itch.io to leave a comment.