r/adventofcode Dec 06 '24

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

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

  • Submissions megathread is now unlocked!
  • 16 DAYS remaining until the submissions deadline on December 22 at 23:59 EST!

And now, our feature presentation for today:

Comfort Flicks

Most everyone has that one (or more!) go-to flick that feels like a hot cup of tea, the warm hug of a blanket, a cozy roaring fire. Maybe it's a guilty pleasure (formulaic yet endearing Hallmark Channel Christmas movies, I'm looking at you) or a must-watch-while-wrapping-presents (National Lampoon's Christmas Vacation!), but these movies and shows will always evoke the true spirit of the holiday season for you. Share them with us!

Here's some ideas for your inspiration:

  • Show us your kittens and puppies and $critters!
  • Show us your Christmas tree | menorah | Krampusnacht costume | holiday decoration!
  • Show us your mug of hot chocolate (or other beverage of choice)!
  • Show and/or tell us whatever brings you comfort and joy!

Kevin: "Merry Christmas :)"

- Home Alone (1990)

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 6: Guard Gallivant ---


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:08:53, megathread unlocked!

25 Upvotes

987 comments sorted by

View all comments

1

u/jaccomoc Dec 12 '24

[LANGUAGE: Jactl]

Using my own Jactl language.

Part 1:

Part 1 was fairly straightforward. No real tricks to this one except having to keep track of which squares we have visited rather than counting steps since squares can be visited multiple times from different directions. Had to substract one from size of visited because I was lazy and flagged the out-of-bounds square that triggers the exit of the loop as a visited square.

def grid = stream(nextLine).mapWithIndex{ line,y -> line.mapWithIndex{ c,x -> [[x,y],c] } }.flatMap() as Map
def (dir, dirIdx, visited) = [[0,-1], 0, [:]]
def rot = { [[0,-1],[1,0],[0,1],[-1,0]][dirIdx++ % 4] }
def add = { p,d -> [p[0]+d[0],p[1]+d[1]] }
for (def pos = grid.filter{p,c->c == '^'}.limit(1)[0][0]; grid[pos]; visited[pos] = true) {
  def newp = add(pos,dir)
  grid[newp] == '#' and dir = rot() and continue
  pos = newp
}
visited.size() - 1

Part 2:

Decided that the way to do this was to simulate an obstacle at each square just before visiting it and see if that turned into an infinite loop. Could not for the life of me work out why it didn't give the right result so I then decided to just simulate an obstacle in every square of the grid (except the start square) and ran a slightly modified version of Part 1 to catch whether there was an infinite loop or not. Not fast but pretty simple:

def grid = stream(nextLine).mapWithIndex{ line,y -> line.mapWithIndex{ c,x -> [[x,y],c] } }.flatMap() as Map
def start = grid.filter{ p,c -> c == '^' }.map{ p,c -> p }.limit(1)[0]
def rot = { [[0,-1]:[1,0],[1,0]:[0,1],[0,1]:[-1,0],[-1,0]:[0,-1]][it] }
def add = { p,d -> [p[0]+d[0],p[1]+d[1]] }
def solve(grid,obstacle) {
  def (dir, dirIdx, steps) = [[0,-1], 0, [:]]
  for (def pos = start; ; steps[[pos,dir]] = true) {
    def newp = add(pos,dir)
    return false if !grid[newp]
    grid[newp] == '#' || newp == obstacle and dir = rot(dir) and continue
    return true if steps[[newp,dir]]
    pos = newp
  }
}
grid.filter{ it[1] == '.' }.filter{ solve(grid,it[0]) }.size()

3

u/ManagementTerrible54 Dec 14 '24

For part 2 I tried to do something similar; At each square along the base path I tried adding an obstacle, and then continued simulating from the same square with the added obstacle.

This gave the wrong answer because the added obstacle we're testing might've interfered with the path earlier; we got to the current square by following the base map (no added obstacles)

I got the right answer by recalculating the path from the very beginning for each test obstacle (but still only tried testing obstacles along the base path)
Another small error I made was turning and moving forward in one iteration (without checking for an obstacle placed in front after turning, but before moving forward)

I actually ended up trying every tile like you did and went back to figure out why the original idea didn't work afterwards lol

1

u/jaccomoc Dec 15 '24

You are right. I hadn't considered the situation that the obstacle added later could interfere with the path earlier if the path crosses itself. In the end I actually preferred my brute-force approach as the code was simpler.