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.