Day 9: Disk Fragmenter

Megathread guidelines

  • Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
  • You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL

FAQ

  • TunaCowboy@lemmy.world
    link
    fedilink
    arrow-up
    1
    ·
    edit-2
    16 days ago

    python

    solution
    import aoc
    
    def setup():
        dm = [int(x) for x in aoc.get_lines(9, stripped=True)[0]]
        ldm = len(dm)
        d = []
        f = 0
        for i in range(0, ldm, 2):
            lfi = dm[i]
            d.extend([f] * lfi)
            f += 1
            if i + 1 < ldm:
                lfr = dm[i + 1]
                d.extend([-1] * lfr)
        return d
    
    def one():
        d = setup()
        h = 0
        t = len(d) - 1
        while h < t:
            if d[h] == -1:
                while t > h and d[t] == -1:
                    t -= 1
                if t > h:
                    d[h], d[t] = d[t], d[h]
                    t -= 1
            h += 1
        print(sum(i * v for i, v in enumerate(d) if v != -1))
    
    def two():
        d = setup()
        md = max(d)
        for fid in range(md, -1, -1):
            fis = [i for i, v in enumerate(d) if v == fid]
            if not fis:
                continue
            s, e = fis[0], fis[-1] + 1
            l, f, fi = e - s, 0, None
            for i in range(s):
                if d[i] == -1:
                    if f == 0:
                        fi = i
                    f += 1
                    if f == l:
                        break
                else:
                    f, fi = 0, None
            if fi is not None and f == l:
                d[fi:fi+l] = [fid]*l
                d[s:e] = [-1]*l
        print(sum(i * v for i, v in enumerate(d) if v != -1))
    
    one()
    two()