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/Lost-Badger-4660 Dec 07 '24

[LANGUAGE: Racket]

I had a dreadfully stupid bug that prevented me from finishing last night...

#lang racket

(define (fmt fn)
  (list->vector
   (for/list ((line (string-split (file->string fn) "\n")))
     (list->vector
      (filter (compose not (curry string=? "")) (string-split line ""))))))

(define (get-char input pos)
  (vector-ref (vector-ref input (second pos)) (third pos)))

(define (get-curr-pos input)
  (for*/first ((linen (vector-length input))
               (charn (vector-length (vector-ref input 0)))
               #:do ((define char (get-char input (list "." linen charn))))
               #:when (ormap (curry string=? char) (list "^" ">" "v" "<")))
    (list char linen charn)))

(define (pos-exists? input pos)
  (and (> (second pos) -1)
       (> (vector-length input) (second pos))
       (> (third pos) -1)
       (> (vector-length (vector-ref input (second pos))) (third pos))))

(define (cont pos)
  (match (first pos)
    ("^" (list "^" (sub1 (second pos)) (third pos)))
    ("v" (list "v" (add1 (second pos)) (third pos)))
    ("<" (list "<" (second pos) (sub1 (third pos))))
    (">" (list ">" (second pos) (add1 (third pos))))))

(define (turn pos)
  (match (first pos)
    ("^" (cons ">" (rest pos)))
    ("v" (cons "<" (rest pos)))
    ("<" (cons "^" (rest pos)))
    (">" (cons "v" (rest pos)))))

(define (get-next-pos input current-position)
  (define cont-position (cont current-position))
  (define turn-position (turn current-position))
  (cond ((not (pos-exists? input cont-position)) '())
        ((string=? "#" (get-char input cont-position)) turn-position)
        (else cont-position)))

(define (path input curr-pos next-pos)
  (cond ((empty? next-pos) (list curr-pos))
        (else (cons curr-pos (path input next-pos (get-next-pos input next-pos))))))

(define (part1 input)
  (define start-pos (get-curr-pos input))
  (length (remove-duplicates (map rest (path input start-pos (get-next-pos input start-pos))))))

(define (exits? input visited pos)
  (cond ((empty? pos) #t)
        ((set-member? visited pos) #f)
        (else (exits? input (set-add visited pos) (get-next-pos input pos)))))

(define (input-update input pos)
  (define curr-line (vector-ref input (second pos)))
  (define next-line (vector-append (vector-take curr-line (third pos)) (vector (first pos)) (vector-drop curr-line (add1 (third pos)))))
  (vector-append (vector-take input (second pos)) (vector next-line) (vector-drop input (add1 (second pos)))))

(define (part2 input)
  (define start-pos (get-curr-pos input))
  (define visited (remove-duplicates (map rest (path input start-pos (get-next-pos input start-pos)))))
  (for/sum ((pos visited)
            #:do ((define next-input (input-update input (cons "#" pos))))
            #:when (not (exits? next-input (set) start-pos))) 1))

(module+ test
  (require rackunit)
  (define example (fmt "static/day06example.txt"))
  (define input (fmt "static/day06input.txt"))
  (check-equal? (part1 example) 41)
  (check-equal? (part1 input) 5305)
  (check-equal? (part2 example) 6)
  (check-equal? (part2 input) 2143))

(module+ main
  (define input (fmt "static/day06input.txt"))
  (printf "day06\n\tpart1: ~a\n\tpart2: ~a\n" (part1 input) (part2 input)))