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

23a - dict.py 1.7 kB
Dec 23, 2020
23a.py 1.8 kB
Dec 23, 2020
23b - slow dict.py 1.8 kB
Dec 23, 2020
23b - slow list.py 2 kB
Dec 23, 2020
23b.py 1.7 kB
Dec 23, 2020

Get aoc 2020

Leave a comment

Log in with itch.io to leave a comment.