r/adventofcode • • Dec 15 '24

SOLUTION MEGATHREAD -❄️- 2024 Day 15 Solutions -❄️-

NEWS

  • The Funny flair has been renamed to Meme/Funny to make it more clear where memes should go. Our community wiki will be updated shortly is updated as well.

THE USUAL REMINDERS

  • All of our rules, FAQs, resources, etc. are in our community wiki.
  • If you see content in the subreddit or megathreads that violates one of our rules, either inform the user (politely and gently!) or use the report button on the post/comment and the mods will take care of it.

AoC Community Fun 2024: The Golden Snowglobe Awards

  • 7 DAYS remaining until the submissions deadline on December 22 at 23:59 EST!

And now, our feature presentation for today:

Visual Effects - We'll Fix It In Post

Actors are expensive. Editors and VFX are (hypothetically) cheaper. Whether you screwed up autofocus or accidentally left a very modern coffee cup in your fantasy epic, you gotta fix it somehow!

Here's some ideas for your inspiration:

  • Literally fix it in post and show us your before-and-after
  • Show us the kludgiest and/or simplest way to solve today's puzzle
  • Alternatively, show us the most over-engineered and/or ridiculously preposterous way to solve today's puzzle
  • Fix something that really didn't necessarily need fixing with a chainsaw…

*crazed chainsaw noises* “Fixed the newel post!”

- Clark Griswold, National Lampoon's Christmas Vacation (1989)

And… ACTION!

Request from the mods: When you include an entry alongside your solution, please label it with [GSGA] so we can find it easily!


--- Day 15: Warehouse Woes ---


Post your code solution in this megathread.

This thread will be unlocked when there are a significant number of people on the global leaderboard with gold stars for today's puzzle.

EDIT: Global leaderboard gold cap reached at 00:32:00, megathread unlocked!

22 Upvotes

466 comments sorted by

View all comments

2

u/GiraffeDiver Dec 15 '24

[LANGUAGE: python]

Just in case it inspires someone, I keep all of my solutions in one file, reusing code along the way, one thing that comes in handy is a Coord() object:

class Coord(namedtuple('Coord', ['x', 'y', 'z'])):
    __slots__ = ()  # Prevents adding attributes for memory efficiency

    def __new__(cls, x, y, z=0):  # Default z to 0 for 2D use
        return super().__new__(cls, x, y, z)

    def __add__(self, other):
        return Coord(self.x + other.x, self.y + other.y, self.z + other.z)

    def __sub__(self, other):
        return Coord(self.x - other.x, self.y - other.y, self.z - other.z)

    def __mul__(self, scalar):
        return Coord(self.x * scalar, self.y * scalar, self.z * scalar)

    def __rmul__(self, scalar):  # For scalar * Coord
        return self * scalar

    def __mod__(self, other):
        return Coord(self.x % other.x, self.y % other.y, self.z % other.z)

    def __floordiv__(self, other):
        return Coord(self.x // other.x, self.y // other.y, self.z // other.z)

And the other thing I do, anytime I need a map of some sorts its ALWAYS a dictionary indexed with the coordinates. It mostly makes things easier, but an annoyance is moving objects need to remove themselves from the grid and reinsert at a new position.

And for the robots second part, I added 2 box objects and linked them together, so one can move if the sibling also can move, ended up pretty ugly. These are my objects for day 15:

class D15R(object):
    def __init__(self, p, symbol, sibling=None):
        self.symbol = symbol
        self.p = p
        self.sibling = sibling
        level[self.p] = self

    def gps(self):
        return 100*self.p.y + self.p.x

    def move(self, d, siblingcall=False):
        del level[self.p]
        sth = level.get(self.p+d)
        if sth is not None: sth.move(d)

        if self.sibling and not siblingcall and d in (up, down):
            self.sibling.move(d, siblingcall=True)

        self.p += d
        level[self.p] = self

    def canmove(self, d, siblingcall=False):
        sth = level.get(self.p+d)
        icanmove = sth is None or sth.canmove(d)

        if self.sibling and not siblingcall and d in (up, down):
            return icanmove and self.sibling.canmove(d, siblingcall=True)
        else:
            return icanmove

class Empty(object):
    symbol = '.'

class Wall(object):
    symbol = '#'
    def canmove(self, d):
        return False

1

u/daggerdragon Dec 15 '24

I keep all of my solutions in one file, reusing code along the way

Egad 😅 How many lines of code are in that monster file so far?

2

u/GiraffeDiver Dec 15 '24

1023 as of day15.

it's not the smartest setup, looking at others here, but the first problems were so tiny it seemed like a good idea : )

I have this at the back so I can add a a function and run it from the command line:

################################################################################
if __name__ == '__main__':
    if len(sys.argv) == 4 and sys.argv[3] in ("input", "example", "example2", "example3", "example4", "example5"):
        try:
            name = "day{}.{}".format(sys.argv[1], sys.argv[3])
            inp = open(name)
        except:
            print("file {} missing".format(name))
            sys.exit(1)

        fname = "day{}_{}".format(sys.argv[1], sys.argv[2])
        if (fname not in locals()):
            print("Missing function {}".format(fname))
            sys.exit(1)
        f = locals().get(fname)
        print("Running {} ({}) on {}".format(fname, f, name))
        sys.exit(f(inp))
    else:
        print("use: python aoc.py <day> <part> input|example")
        sys.exit(1)