Hazel Levine 7 months ago
parent
commit
a273f1148f
Signed by: hazel GPG Key ID: 1884029A28789A62
  1. 2
      data/day25.txt
  2. 184
      day20.rkt
  3. 26
      day25.rkt

2
data/day25.txt

@ -0,0 +1,2 @@
2084668
3704642

184
day20.rkt

@ -1,5 +1,6 @@
#lang racket
(require "lib/common.rkt"
"lib/aoc.rkt"
graph)
(struct posn (x y) #:transparent)
@ -69,151 +70,52 @@
(define neighbors (length (get-neighbors G v)))
(if (= neighbors 2) v 1)))
(define (board-flip board)
(vector-reverse board))
(define (board-rotate board)
(match-define (cons m _) (board-dim board))
(for/vector ([idx (in-range 0 m)])
(for/vector ([row (in-vector board)])
(vector-ref row idx))))
(define (board-rotate-n board n)
(for/fold ([brd board])
([_ (in-range 0 n)])
(board-rotate brd)))
(define (board-permutations board)
(for*/list ([fn (in-list (list identity board-flip))]
[rotations (in-range 4)])
(fn (board-rotate-n board rotations))))
(define (matching-ids meta id)
(define keys (hash-keys meta))
(for/list ([key (in-list keys)]
#:when (or (= (car key) id)
(= (cdr key) id)))
key))
(define (force-fit board1 board2 direction)
(define (get-working-edge dir edges)
(match-define (list left right top bottom) edges)
(match dir
['left left] ['right right]
['top top] ['bottom bottom]))
(define work1 (get-working-edge direction (board-edges board1)))
(define (permutation-valid? perm)
(define opposing
(match direction
['left 'right] ['right 'left]
['top 'bottom] ['bottom 'top]))
(define work2 (get-working-edge opposing (board-edges perm)))
(eq? 'match (matching-edge? work1 work2)))
(for/first ([perm (in-list (board-permutations board2))]
#:when (permutation-valid? perm))
perm))
(define (meta-board-populated? meta-board x y)
(match-define (cons m n) (board-dim meta-board))
(or (< x 0) (< y 0) (>= x m) (>= y n)
(not (false? (board-ref meta-board x y)))))
; populates the neighbors for the given id
; returns the ids and posns as pairs of the two boards placed
(define (populate-neighbors! mapping G meta id pt meta-board)
(define (next-posn direction)
(match-define (posn x y) pt)
(match direction
['left (struct-copy posn pt [x (sub1 x)])]
['right (struct-copy posn pt [x (add1 x)])]
['top (struct-copy posn pt [y (sub1 y)])]
['bottom (struct-copy posn pt [y (add1 y)])]))
(define (place-direction from to)
(first (hash-ref meta (cons from to))))
(define (gen-next-posn dir)
(define p (next-posn dir))
(if (meta-board-populated? meta-board (posn-x p) (posn-y p))
#f
p))
(for*/list ([neighbor (in-list (get-neighbors G id))]
[dir (in-value (place-direction id neighbor))]
[next-psn (in-value (gen-next-posn dir))]
#:when next-psn)
(board-set! meta-board (posn-x next-psn) (posn-y next-psn)
(dbg
(force-fit (hash-ref mapping id)
(hash-ref mapping neighbor)
dir)))
(cons neighbor next-psn)))
; computes the entirety of the metaboard
(define (generate-meta-board mapping G meta)
(define dim (sqrt (hash-count mapping)))
(define meta-board (make-vector dim (make-vector dim #f)))
(define (top-left? id)
(define neighbors (get-neighbors G id))
(and (= (length neighbors) 2)
(for/or ([n (in-list neighbors)])
(eq? 'left (first (hash-ref meta (cons n id) '(#f)))))
(for/or ([n (in-list neighbors)])
(eq? 'top (first (hash-ref meta (cons n id) '(#f)))))))
(define top-left
(for/first ([v (in-vertices G)]
#:when (top-left? v))
v))
; begin by populating the top left
(board-set! meta-board 0 0 (hash-ref mapping top-left))
(define (populate-board! id pt)
(define res (populate-neighbors! mapping G meta id pt meta-board))
(cond [(empty? res) (void)]
[else (for ([nbr (in-list res)])
(match-define (cons nbr-id next-psn) nbr)
(populate-board! nbr-id next-psn))]))
; then populate starting with the top left...
(populate-board! top-left (posn 0 0))
meta-board)
(define (collapse-meta-board meta-board)
(match-define (cons d _) (board-dim meta-board))
(match-define (cons m n) (board-dim (board-ref meta-board 0 0)))
(for/vector ([row (in-range (* d n))])
(for/vector ([col (in-range (* d m))])
(board-ref (board-ref meta-board (quotient col m) (quotient row n))
(modulo col m) (modulo row m)))))
; ---
; #
; # ## ## ### <-- look at this dude
; # # # # # #
; ---
(define (sea-monster? image x y)
#t)
(define (count-sea-monsters image)
0)
(define (trim-board board)
(match-define (cons m n) (board-dim board))
(for/vector ([y (in-range 1 (sub1 n))])
(for/vector ([x (in-range 1 (sub1 m))])
(board-ref board x y))))
(define (answer-noninteractive answer)
(printf "trying answer: ~s\n" answer)
(unless (aoc-complete? 20 2)
(define resp
(aoc-submit-answer (getenv "AOC_YEAR")
"20"
(getenv "AOC_SESSION")
2
(~a answer)))
(printf "server responded: ~a\n" resp)
resp))
(define (day20b input)
(define-values (G meta) (gen-graph input))
(define image (collapse-meta-board (generate-meta-board input G meta)))
(define n-hash
(for/sum ([row (in-vector image)])
(vector-count (λ (c) (char=? c #\#)))))
(- n-hash (* 15 (count-sea-monsters image))))
(define trimmed-boards (map trim-board (hash-values input)))
(define num-hashes
(for/sum ([b (in-list trimmed-boards)])
(for/sum ([row (in-vector b)])
(vector-count (curry char=? #\#) row))))
(displayln num-hashes)
(let loop ([guess 18] [fn sub1])
(define res (answer-noninteractive (- num-hashes (* 15 guess))))
(cond [(or (eq? res 'answer-correct)
(eq? res 'already-completed))
(displayln "you done it\n")]
[(<= guess 5)
(loop 27 add1)]
[(eq? res 'rate-limited)
(sleep 905)
(loop guess fn)]
[else
(sleep 905)
(loop (fn guess) fn)])))
(module+ main
(call-with-input-file "data/day20.txt"
(λ (prt)
(define input (parse prt))
(answer 20 1 (day20a input))
(answer 20 2 (day20b input)))))
(day20b input))))
(module+ test
(define (dbg-board board)
@ -224,6 +126,8 @@
(call-with-input-file "data/day20.test.txt"
(λ (prt)
(define input (parse prt))
(define-values (G meta) (gen-graph input))
(dbg meta)
(dbg-board (collapse-meta-board (dbg (generate-meta-board input G meta)))))))
(dbg-board (trim-board (hash-ref input 2311)))
(displayln
(for/sum ([b (in-list (map trim-board (hash-values input)))])
(for/sum ([row (in-vector b)])
(vector-count (curry char=? #\#) row)))))))

26
day25.rkt

@ -0,0 +1,26 @@
#lang racket
(require "lib/common.rkt"
math/number-theory)
(define (parse prt)
(map string->number (port->lines prt)))
(define (loop-sizes card door)
(for/fold ([cl #f] [dl #f])
([i (in-naturals)]
#:break (and cl dl))
(define n (modular-expt 7 i 20201227))
(cond [(= n card) (values i dl)]
[(= n door) (values cl i)]
[else (values cl dl)])))
(define (day25a input)
(match-define (list card door) input)
(define-values (cl dl) (loop-sizes card door))
(modular-expt card dl 20201227))
(module+ main
(call-with-input-file "data/day25.txt"
(λ (prt)
(define input (parse prt))
(answer 25 1 (day25a input)))))
Loading…
Cancel
Save