diff --git a/2016/day13/lang.rkt b/2016/day13/lang.rkt index 238291a..3d3b420 100644 --- a/2016/day13/lang.rkt +++ b/2016/day13/lang.rkt @@ -11,54 +11,48 @@ (define-macro (mb NUM) #'(#%module-begin - (solve 50 NUM) + (solve 50 NUM) ; 50 is arbitrarily large space to search (solve2 NUM))) +(define starting-pt 1+1i) + (define (solve dim num) (define open? (make-open-pred num)) - (define g (undirected-graph '((0 0)))) - (for* ([y (in-range dim)] - [x (in-range dim)] - #:when (open? (cons x y))) - (when (open? (cons (add1 x) y)) - (add-edge! g (cons x y) (cons (add1 x) y))) - (when (open? (cons x (add1 y))) - (add-edge! g (cons x y) (cons x (add1 y))))) - (define path (fewest-vertices-path g '(1 . 1) '(31 . 39))) + (define g (undirected-graph (list starting-pt))) + (for* ([row (in-range dim)] + [col (in-range dim)] + [p (in-value (+ col (* +i row)))] + #:when (open? p)) + (when (open? (+ p 1)) (add-edge! g p (+ p 1))) + (when (open? (+ p +i)) (add-edge! g p (+ p +i)))) + (define path (fewest-vertices-path g 1+1i 31+39i)) (displayln (and path (sub1 (length path))))) (define (solve2 num) (define open? (make-open-pred num)) - (define (nonnegative? pt) (and (not (negative? (car pt))) - (not (negative? (cdr pt))) + (define (nonnegative? pt) (and (not (negative? (real-part pt))) + (not (negative? (imag-part pt))) pt)) - (let loop ([all-visited-pts empty] - [last-visited-pts '((1 . 1))] - [step 0]) - (cond - [(= step 50) - (length (remove-duplicates (append all-visited-pts last-visited-pts)))] - [else - (loop (append last-visited-pts all-visited-pts) - (append* - (for/list ([lvp (in-list last-visited-pts)]) - (match-define (cons x y) lvp) - (for/list ([pt (in-list (list (cons (add1 x) y) - (cons x (add1 y)) - (cons (sub1 x) y) - (cons x (sub1 y))))] - #:when (and (nonnegative? pt) - (open? pt) - (not (member pt all-visited-pts)))) - pt))) - (add1 step))]))) + (let take-step ([all-visited-pts empty] + [last-visited-pts (list starting-pt)] + [count 0]) + (if (= count 50) + (length (remove-duplicates (append all-visited-pts last-visited-pts))) + (take-step + (append last-visited-pts all-visited-pts) + (flatten + (for*/list ([p (in-list last-visited-pts)] + [next-p (in-list (map (curry + p) '(1 -1 +i -i)))] + #:when (and (nonnegative? next-p) + (open? next-p) + (not (member next-p all-visited-pts)))) + next-p)) + (add1 count))))) (define (make-open-pred num) (λ(pt) - (match-define (cons x y) pt) + (define col (real-part pt)) + (define row (imag-part pt)) (define sum - (+ (* x x) (* 3 x) (* 2 x y) y (* y y) num)) - (even? - (for/sum ([c (in-string (format "~b" sum))] - #:when (char=? #\1 c)) - 1)))) \ No newline at end of file + (+ (* col col) (* 3 col) (* 2 col row) row (* row row) num)) + (even? (length (regexp-match* "1" (format "~b" sum)))))) \ No newline at end of file