├── 2016 ├── README.md ├── day01 │ ├── lang.rkt │ └── test.rkt ├── day02 │ ├── lang-b.rkt │ ├── lang.rkt │ ├── test-b.rkt │ └── test.rkt ├── day03 │ ├── lang-b.rkt │ ├── lang.rkt │ ├── test-b.rkt │ └── test.rkt ├── day04 │ ├── input.rkt │ ├── lang.rkt │ └── test.rkt ├── day05 │ ├── input.rkt │ └── lang.rkt ├── day06 │ ├── input.rkt │ ├── lang.rkt │ └── test.rkt ├── day07 │ ├── input.rkt │ ├── lang.rkt │ └── test.rkt ├── day08 │ ├── input.rkt │ ├── lang.rkt │ └── test.rkt ├── day09 │ ├── input.rkt │ ├── lang.rkt │ └── test.rkt ├── day10 │ ├── input.rkt │ ├── lang.rkt │ └── test.rkt ├── day12 │ ├── input.rkt │ ├── lang.rkt │ └── test.rkt ├── day13 │ ├── input.rkt │ ├── lang.rkt │ └── test.rkt ├── day14 │ ├── input.rkt │ ├── lang.rkt │ └── test.rkt ├── day15 │ ├── input-b.rkt │ ├── input.rkt │ ├── lang.rkt │ └── test.rkt ├── day16 │ ├── input-b.rkt │ ├── input.rkt │ ├── lang.rkt │ ├── test-b.rkt │ └── test.rkt ├── day17 │ ├── input.rkt │ ├── lang.rkt │ └── test.rkt ├── day18 │ ├── input.rkt │ ├── lang.rkt │ └── test.rkt ├── day19 │ ├── input.rkt │ ├── lang.rkt │ └── test.rkt ├── day20 │ ├── input.rkt │ ├── lang.rkt │ └── test.rkt ├── day21 │ ├── input.rkt │ ├── lang.rkt │ └── test.rkt ├── day22 │ ├── input.rkt │ ├── lang.rkt │ └── test.rkt ├── day23 │ ├── info.rkt │ ├── input.rkt │ ├── lang.rkt │ └── test.rkt ├── day24 │ ├── input.rkt │ ├── lang.rkt │ └── test.rkt └── day25 │ ├── input.rkt │ └── lang.rkt ├── 2017 ├── README.md ├── aoc-lang.rkt ├── d01 │ ├── main.rkt │ ├── star1.rkt │ ├── star2.rkt │ ├── test1.rkt │ └── test2.rkt ├── d02 │ ├── main.rkt │ ├── star1.rkt │ ├── star2.rkt │ ├── test1.rkt │ └── test2.rkt ├── d03 │ ├── main.rkt │ ├── star1.rkt │ ├── star2.rkt │ ├── test1.rkt │ └── test2.rkt ├── d04 │ ├── main.rkt │ ├── star1.rkt │ ├── star2.rkt │ ├── test1.rkt │ └── test2.rkt ├── d05 │ ├── main.rkt │ ├── star1.rkt │ ├── star2.rkt │ ├── test1.rkt │ └── test2.rkt ├── d06 │ ├── main.rkt │ ├── star1.rkt │ ├── star2.rkt │ ├── test1.rkt │ └── test2.rkt ├── d07 │ ├── main.rkt │ ├── star1.rkt │ ├── star2.rkt │ ├── test1.rkt │ └── test2.rkt ├── d08 │ ├── main.rkt │ ├── star1.rkt │ ├── star2.rkt │ ├── test1.rkt │ └── test2.rkt ├── d09 │ ├── main.rkt │ ├── star1.rkt │ ├── star2.rkt │ ├── test1.rkt │ └── test2.rkt ├── d10 │ ├── main.rkt │ ├── star1.rkt │ ├── star2.rkt │ ├── test1.rkt │ └── test2.rkt ├── d11 │ ├── main.rkt │ ├── star1.rkt │ ├── star2.rkt │ ├── test1.rkt │ └── test2.rkt ├── d12 │ ├── main.rkt │ ├── star1.rkt │ ├── star2.rkt │ ├── test1.rkt │ └── test2.rkt ├── d13 │ ├── main.rkt │ ├── star1.rkt │ ├── star2.rkt │ ├── test1.rkt │ └── test2.rkt ├── d14 │ ├── main.rkt │ ├── star1.rkt │ ├── star2.rkt │ ├── test1.rkt │ └── test2.rkt ├── d15 │ ├── main.rkt │ ├── star1.rkt │ ├── star2.rkt │ ├── test1.rkt │ └── test2.rkt ├── d16 │ ├── main.rkt │ ├── star1.rkt │ ├── star2.rkt │ ├── test1.rkt │ └── test2.rkt ├── d17 │ ├── main.rkt │ ├── star1.rkt │ ├── star2.rkt │ └── test1.rkt ├── d18 │ ├── main.rkt │ ├── main2.rkt │ ├── star1.rkt │ ├── star2.rkt │ ├── test1.rkt │ └── test2.rkt ├── d19 │ ├── main.rkt │ ├── star1.rkt │ ├── star2.rkt │ ├── test1.rkt │ └── test2.rkt ├── d20 │ ├── main.rkt │ ├── star1.rkt │ ├── star2.rkt │ ├── test1.rkt │ └── test2.rkt ├── d21 │ ├── main.rkt │ ├── star1.rkt │ ├── star2.rkt │ └── test1.rkt ├── d22 │ ├── main.rkt │ ├── star1.rkt │ ├── star2.rkt │ ├── test1.rkt │ └── test2.rkt ├── d23 │ ├── main.rkt │ ├── star1.rkt │ └── star2.rkt ├── d24 │ ├── main.rkt │ ├── star1.rkt │ ├── star2.rkt │ ├── test1.rkt │ └── test2.rkt ├── d25 │ ├── main.rkt │ ├── star1.rkt │ └── test1.rkt └── helper.rkt ├── 2018 ├── 01-test.txt ├── 01.rkt ├── 01.txt ├── 02-test.txt ├── 02.rkt ├── 02.txt ├── 03-test.txt ├── 03.rkt ├── 03.txt ├── 04-test.txt ├── 04.rkt ├── 04.txt ├── 05-test.txt ├── 05.rkt ├── 05.txt ├── 06-test.txt ├── 06.rkt ├── 06.txt ├── 07-test.txt ├── 07.rkt ├── 07.txt ├── 08-test.txt ├── 08.rkt ├── 08.txt ├── 09-test.txt ├── 09.rkt ├── 09.txt ├── 10-test.txt ├── 10.rkt ├── 10.txt ├── 11.rkt ├── README.md └── stub.rkt ├── 2019 ├── 01.rkt ├── 01.rktd ├── 02.rkt ├── 02.rktd ├── 03.rkt ├── 03.rktd ├── 04.rkt ├── 04.rktd ├── 05.rkt ├── 05.rktd ├── 06.rkt ├── 06.rktd ├── 07-gen.rkt ├── 07.rkt ├── 07.rktd ├── 08.rkt ├── 08.rktd ├── 09.rkt ├── 09.rktd ├── 10.rkt ├── 10.rktd ├── 11.rkt ├── 11.rktd ├── 12.rkt ├── 12.rktd ├── 13.rkt ├── 13.rktd ├── 14.rkt ├── 14input.rkt ├── 14test.rkt ├── 15.rkt ├── 15.rktd ├── 16.rkt ├── 16.rktd ├── 17.rkt ├── 17.rktd ├── 19.rkt ├── 19.rktd ├── 20.rkt ├── 20.rktd ├── 22.rkt ├── 22.rktd ├── 23.rkt ├── 23.rktd ├── 24.rkt ├── 24.rktd ├── 25.rkt ├── 25.rktd └── README.md ├── 2020 ├── 01.rkt ├── 01.rktd ├── 02.rkt ├── 02.rktd ├── 03.rkt ├── 03.rktd ├── 04.rkt ├── 04.rktd ├── 05.rkt ├── 05.rktd ├── 06.rkt ├── 06.rktd ├── 07.rkt ├── 07.rktd ├── 08.rkt ├── 08.rktd ├── 09.rkt ├── 09.rktd ├── 10.rkt ├── 10.rktd ├── 11.rkt ├── 11.rktd ├── 12.rkt ├── 12.rktd ├── 13.rkt ├── 13.rktd ├── 14.rkt ├── 14.rktd ├── 15.rkt ├── 16.rkt ├── 16.rktd ├── 17.rkt ├── 17.rktd ├── 18.rkt ├── 18.rktd ├── 19.rkt ├── 19.rktd ├── 20.rkt ├── 20.rktd ├── 21.rkt ├── 21.rktd ├── 22.rkt ├── 22.rktd ├── 23.rkt ├── 24.rkt ├── 24.rktd └── 25.rkt ├── 2021 ├── 01.rkt ├── 01.rktd ├── 02.rkt ├── 02.rktd ├── 03.rkt ├── 03.rktd ├── 04.rkt ├── 04.rktd ├── 05.rkt ├── 05.rktd ├── 06.rkt ├── 06.rktd ├── 07.rkt ├── 07.rktd ├── 08.rkt ├── 08.rktd ├── 09.rkt ├── 09.rktd ├── 10.rkt ├── 10.rktd ├── 11.rkt ├── 11.rktd ├── 12.rkt ├── 12.rktd ├── 13.rkt ├── 13.rktd ├── 14.rkt ├── 14.rktd ├── 15.rkt └── 15.rktd ├── .gitignore ├── LICENSE.md ├── README.md ├── aoc-racket.scrbl ├── day01-input.txt ├── day01.rkt ├── day02-input.txt ├── day02.rkt ├── day03-input.txt ├── day03.rkt ├── day04-input.txt ├── day04.rkt ├── day05-input.txt ├── day05.rkt ├── day06-input.txt ├── day06.rkt ├── day07-input.txt ├── day07.rkt ├── day08-input.txt ├── day08.rkt ├── day09-input.txt ├── day09.rkt ├── day10-input.txt ├── day10.rkt ├── day11-input.txt ├── day11.rkt ├── day12-input.txt ├── day12.rkt ├── day13-input.txt ├── day13.rkt ├── day14-input.txt ├── day14.rkt ├── day15-input.txt ├── day15.rkt ├── day16-input-master-attrs.txt ├── day16-input.txt ├── day16.rkt ├── day17-input.txt ├── day17.rkt ├── day18-input.txt ├── day18.rkt ├── day19-input.txt ├── day19.rkt ├── day20-input.txt ├── day20.rkt ├── day21-input.txt ├── day21.rkt ├── day22-input.txt ├── day22.rkt ├── day23-input.txt ├── day23.rkt ├── day24-input.txt ├── day24.rkt ├── day25-input.txt ├── day25.rkt ├── helper.rkt ├── info.rkt └── main.rkt /.gitignore: -------------------------------------------------------------------------------- 1 | # for Racket 2 | compiled/ 3 | *~ 4 | 5 | # for Mac OS X 6 | .DS_Store 7 | .AppleDouble 8 | .LSOverride 9 | Icon 10 | 11 | # Thumbnails 12 | ._* 13 | 14 | # Files that might appear on external disk 15 | .Spotlight-V100 16 | .Trashes 17 | 18 | # generated documentation 19 | doc/* 20 | *.js 21 | *.css 22 | *.html -------------------------------------------------------------------------------- /2016/README.md: -------------------------------------------------------------------------------- 1 | In 2016 I wrote all my solutions as DSLs. 2 | -------------------------------------------------------------------------------- /2016/day01/lang.rkt: -------------------------------------------------------------------------------- 1 | #lang br/quicklang 2 | 3 | (define (read-syntax path port) 4 | (define turn-strings (string-split (port->string port) ",")) 5 | (define turn-pattern #px"^([LR])(\\d+)$") 6 | (define turn-datums 7 | (for*/list ([tstr (in-list turn-strings)]) 8 | (define match-result (regexp-match turn-pattern (string-trim tstr))) 9 | `(turn ,@(cdr (or match-result empty))))) 10 | (strip-bindings 11 | #`(module day01-mod "lang.rkt" 12 | #,@turn-datums))) 13 | (provide read-syntax) 14 | 15 | (define-macro (mb . TURNS) 16 | #'(#%module-begin 17 | (solve . TURNS))) 18 | (provide (rename-out [mb #%module-begin])) 19 | 20 | (define (loc-dist loc) 21 | (+ (abs (imag-part loc)) (abs (real-part loc)))) 22 | 23 | (struct $turn (rot dist) #:transparent) 24 | (define rotate-left +i) 25 | (define rotate-right -i) 26 | (define same-dir 1) 27 | 28 | (define (solve . turns) 29 | (define found-twice-visited-loc #f) 30 | (define north 0+1i) 31 | (define starting-loc 0+0i) 32 | (let loop ([locs (list starting-loc)] [dir north] [turns turns]) 33 | (cond 34 | [(empty? turns) 35 | (displayln (format "part 1 (dist of final location): ~a" (loc-dist (car locs))))] 36 | [(zero? ($turn-dist (car turns))) (loop locs dir (cdr turns))] 37 | [else 38 | (define new-dir (* dir ($turn-rot (car turns)))) 39 | (define one-step 1) 40 | (define new-loc (+ (car locs) (* new-dir one-step))) 41 | (when (and (not found-twice-visited-loc) (member new-loc locs)) 42 | (set! found-twice-visited-loc new-loc) 43 | (displayln (format "part 2 (dist of first twice-visited location): ~a" 44 | (loc-dist new-loc)))) 45 | (define decremented-turn ($turn same-dir (sub1 ($turn-dist (car turns))))) 46 | (loop (cons new-loc locs) new-dir (cons decremented-turn (cdr turns)))]))) 47 | 48 | (define-macro-cases turn 49 | [(_ DIR DIST) 50 | (with-pattern ([ENCODED-DIR (syntax-case #'DIR () 51 | ["L" #'rotate-left] 52 | ["R" #'rotate-right])]) 53 | #'($turn ENCODED-DIR (string->number DIST)))] 54 | [else #'(void)]) 55 | (provide turn) -------------------------------------------------------------------------------- /2016/day01/test.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "lang.rkt" 2 | R4, R5, L5, L5, L3, R2, R1, R1, L5, R5, R2, L1, L3, L4, R3, L1, L1, R2, R3, R3, R1, L3, L5, R3, R1, L1, R1, R2, L1, L4, L5, R4, R2, L192, R5, L2, R53, R1, L5, R73, R5, L5, R186, L3, L2, R1, R3, L3, L3, R1, L4, L2, R3, L5, R4, R3, R1, L1, R5, R2, R1, R1, R1, R3, R2, L1, R5, R1, L5, R2, L2, L4, R3, L1, R4, L5, R4, R3, L5, L3, R4, R2, L5, L5, R2, R3, R5, R4, R2, R1, L1, L5, L2, L3, L4, L5, L4, L5, L1, R3, R4, R5, R3, L5, L4, L3, L1, L4, R2, R5, R5, R4, L2, L4, R3, R1, L2, R5, L5, R1, R1, L1, L5, L5, L2, L1, R5, R2, L4, L1, R4, R3, L3, R1, R5, L1, L4, R2, L3, R5, R3, R1, L3 -------------------------------------------------------------------------------- /2016/day02/lang-b.rkt: -------------------------------------------------------------------------------- 1 | #lang br/quicklang 2 | 3 | (define (read-syntax path port) 4 | (define moveset-strs (string-split (port->string port))) 5 | (define moveset-datums 6 | (for*/list ([msstr (in-list moveset-strs)]) 7 | `(moveset ,@(regexp-match* #rx"." msstr)))) 8 | (strip-bindings 9 | #`(module day01-mod "lang-b.rkt" 10 | #,@moveset-datums))) 11 | (provide read-syntax) 12 | 13 | (define-macro moveset #'list) 14 | (provide moveset) 15 | 16 | (define-macro (mb . MOVESETS) 17 | #'(#%module-begin 18 | (void (solve (list . MOVESETS))))) 19 | (provide (rename-out [mb #%module-begin])) 20 | 21 | (define (do-moveset button moveset) 22 | (for/fold ([button button]) 23 | ([move (in-list moveset)]) 24 | (vector-ref 25 | (case move 26 | [("U") '#(1 2 1 4 5 2 3 4 9 6 7 8 #xb)] 27 | [("L") '#(1 2 2 3 5 5 6 7 8 #xa #xa #xb #xd)] 28 | [("R") '#(1 3 4 4 6 7 8 9 9 #xb #xc #xc #xd)] 29 | [("D") '#(3 6 7 8 5 #xa #xb #xc 9 #xa #xd #xc #xd)]) 30 | (sub1 button)))) 31 | 32 | (define starting-button 5) 33 | (define (solve mss) 34 | (for/fold ([button starting-button]) 35 | ([ms (in-list mss)]) 36 | (define result (do-moveset button ms)) 37 | (display (string-upcase (number->string result 16))) 38 | result)) -------------------------------------------------------------------------------- /2016/day02/lang.rkt: -------------------------------------------------------------------------------- 1 | #lang br/quicklang 2 | 3 | (define (read-syntax path port) 4 | (define moveset-strs (string-split (port->string port))) 5 | (define moveset-datums 6 | (for*/list ([msstr (in-list moveset-strs)]) 7 | `(moveset ,@(regexp-match* #rx"." msstr)))) 8 | (strip-bindings 9 | #`(module day01-mod "lang.rkt" 10 | #,@moveset-datums))) 11 | (provide read-syntax) 12 | 13 | (define-macro moveset #'list) 14 | (provide moveset) 15 | 16 | (define-macro (mb . MOVESETS) 17 | #'(#%module-begin 18 | (void (solve (list . MOVESETS))))) 19 | (provide (rename-out [mb #%module-begin])) 20 | 21 | (define (do-moveset button moveset) 22 | (for/fold ([button button]) 23 | ([move (in-list moveset)]) 24 | (vector-ref 25 | (case move 26 | [("U") '#(1 2 3 1 2 3 4 5 6)] 27 | [("L") '#(1 1 2 4 4 5 7 7 8)] 28 | [("R") '#(2 3 3 5 6 6 8 9 9)] 29 | [("D") '#(4 5 6 7 8 9 7 8 9)]) 30 | (sub1 button)))) 31 | 32 | (define starting-button 5) 33 | (define (solve mss) 34 | (for/fold ([button starting-button]) 35 | ([ms (in-list mss)]) 36 | (define result (do-moveset button ms)) 37 | (display (string-upcase (number->string result 16))) 38 | result)) -------------------------------------------------------------------------------- /2016/day03/lang-b.rkt: -------------------------------------------------------------------------------- 1 | #lang br/quicklang 2 | (require sugar/list) 3 | 4 | (define (read-syntax path port) 5 | (define triads (slice-at (map string-split (string-split (port->string port) "\n")) 3)) 6 | (define new-triples 7 | (slice-at (flatten (for/list ([triad (in-list triads)]) 8 | (apply map list triad))) 3)) 9 | (strip-bindings 10 | #`(module mod "lang-b.rkt" 11 | #,@(for*/list ([triple (in-list new-triples)]) 12 | `(triangle ,@triple))))) 13 | (provide read-syntax) 14 | 15 | (define-macro (mb . TRIANGLES) 16 | #'(#%module-begin 17 | (length (filter valid-triangle? (list . TRIANGLES))))) 18 | (provide (rename-out [mb #%module-begin])) 19 | 20 | (define-macro (triangle A B C) 21 | #'(map string->number (list A B C))) 22 | (provide triangle) 23 | 24 | (define (valid-triangle? triangle) 25 | (match-define (list a b c) triangle) 26 | (and (> (+ a b) c) 27 | (> (+ b c) a) 28 | (> (+ a c) b))) -------------------------------------------------------------------------------- /2016/day03/lang.rkt: -------------------------------------------------------------------------------- 1 | #lang br/quicklang 2 | 3 | (define (read-syntax path port) 4 | (strip-bindings 5 | #`(module mod "lang.rkt" 6 | #,@(for*/list ([triangle-str (in-list (string-split (port->string port) "\n"))]) 7 | `(triangle ,@(string-split triangle-str)))))) 8 | (provide read-syntax) 9 | 10 | (define-macro (mb . TRIANGLES) 11 | #'(#%module-begin 12 | (length (filter valid-triangle? (list . TRIANGLES))))) 13 | (provide (rename-out [mb #%module-begin])) 14 | 15 | (define-macro (triangle A B C) 16 | #'(map string->number (list A B C))) 17 | (provide triangle) 18 | 19 | (define (valid-triangle? triangle) 20 | (match-define (list a b c) triangle) 21 | (and (> (+ a b) c) 22 | (> (+ b c) a) 23 | (> (+ a c) b))) -------------------------------------------------------------------------------- /2016/day04/lang.rkt: -------------------------------------------------------------------------------- 1 | #lang br/quicklang 2 | 3 | (define (read-syntax path port) 4 | (strip-bindings 5 | #`(module mod "lang.rkt" 6 | #,@(for*/list ([room-str (in-lines port)] 7 | #:when (not (equal? "" room-str))) 8 | `(room ,@(cdr (regexp-match #px"^(.*)-(\\d+)\\[(\\w+)\\]$" room-str))))))) 9 | (provide read-syntax) 10 | 11 | #| 12 | Each room consists of an encrypted name (lowercase letters separated by dashes) 13 | followed by a dash, a sector ID, and a checksum in square brackets. 14 | |# 15 | (struct $room (name sector checksum) #:transparent) 16 | (define-macro (room NAME SECTOR CHECKSUM) 17 | #'($room NAME (string->number SECTOR) CHECKSUM)) 18 | (provide room) 19 | 20 | (define-macro (mb . ROOMS) 21 | #'(#%module-begin 22 | (define rooms (list . ROOMS)) 23 | (display "part a: ") 24 | (displayln (for/sum ([room (in-list rooms)] 25 | #:when (real-room? room)) 26 | ($room-sector room))) 27 | (display "part b: ") 28 | (displayln 29 | (for/first ([room (in-list rooms)] 30 | #:when (equal? (shift-string ($room-name room) ($room-sector room)) 31 | "northpole object storage")) 32 | ($room-sector room))))) 33 | (provide (rename-out [mb #%module-begin])) 34 | 35 | #| 36 | A room is real (not a decoy) if the checksum is 37 | the five most common letters in the encrypted name, in order, 38 | with ties broken by alphabetization. 39 | |# 40 | 41 | (require sugar/list) 42 | (define (real-room? room) 43 | (define room-chars (string->list (string-replace ($room-name room) "-" ""))) 44 | (define freqs (hash->list (frequency-hash room-chars))) 45 | (define sorted-freqs (sort (sort freqs char #:key cdr)) 46 | (equal? ($room-checksum room) (list->string (map car (take sorted-freqs 5))))) 47 | 48 | (define (shift-string str shift) 49 | (list->string 50 | (for/list ([c (in-string str)]) 51 | (cond 52 | [(char=? c #\-) #\space] 53 | [else 54 | (define a-val (char->integer #\a)) 55 | (integer->char (+ (modulo (+ (char->integer c) (- a-val) shift) 26) a-val))])))) -------------------------------------------------------------------------------- /2016/day04/test.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "lang.rkt" 2 | aaaaa-bbb-z-y-x-123[abxyz] 3 | a-b-c-d-e-f-g-h-987[abcde] 4 | not-a-real-room-404[oarel] 5 | totally-real-room-200[decoy] -------------------------------------------------------------------------------- /2016/day05/input.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "lang.rkt" 2 | ojvtpuvg -------------------------------------------------------------------------------- /2016/day05/lang.rkt: -------------------------------------------------------------------------------- 1 | #lang br/quicklang 2 | (require openssl/md5) 3 | (provide read-syntax) 4 | (define (read-syntax path port) 5 | (strip-bindings 6 | #`(module mod "lang.rkt" 7 | (solve #,(string-trim (port->string port)))))) 8 | 9 | (provide #%module-begin) 10 | 11 | (define (solve key) 12 | (define-values 13 | (part-a-solution part-b-solution) 14 | (for*/fold ([part-a empty] 15 | [part-b (make-vector 8 #f)]) 16 | ([idx (in-naturals 1000000)] 17 | [this-key (in-value (format "~a~a" key idx))] 18 | #:break (and (= 8 (length part-a)) 19 | (andmap string? (vector->list part-b)))) 20 | (define this-hash (md5 (open-input-string this-key))) 21 | (define next-part-a 22 | (if (and (not (= 8 (length part-a))) 23 | (string-prefix? this-hash "00000")) 24 | (let ([next-str (substring this-hash 5 6)]) 25 | (displayln (format "part a progress: ~a" next-str)) 26 | (cons next-str part-a)) 27 | part-a)) 28 | (define next-part-b 29 | (let () 30 | (when (and (string-prefix? this-hash "00000") 31 | (string->number (substring this-hash 5 6)) 32 | (<= 0 (string->number (substring this-hash 5 6)) 7) 33 | (not (vector-ref part-b (string->number (substring this-hash 5 6))))) 34 | (displayln (format "part b progress: idx ~a, hash ~a, ~a at ~a" idx this-hash (substring this-hash 6 7) (substring this-hash 5 6))) 35 | (vector-set! part-b (string->number (substring this-hash 5 6)) (substring this-hash 6 7))) 36 | part-b)) 37 | (values next-part-a next-part-b))) 38 | (displayln (format "part a: ~a" (apply string-append (reverse part-a-solution)))) 39 | (displayln (format "part b: ~a" (apply string-append (vector->list part-b-solution))))) 40 | (provide solve) 41 | -------------------------------------------------------------------------------- /2016/day06/lang.rkt: -------------------------------------------------------------------------------- 1 | #lang br/quicklang 2 | (provide read-syntax) 3 | (define (read-syntax path port) 4 | (strip-bindings 5 | #`(module mod "lang.rkt" 6 | (solve #,@(string-split (port->string port)))))) 7 | (module+ reader (provide read-syntax)) 8 | 9 | (require sugar/list) 10 | (define (solve . ws) 11 | (define-values (s1 s2) 12 | (for/lists (acc acc2) ([vert-cs (in-list (apply map list (map string->list ws)))]) 13 | (define freqs (hash->list (frequency-hash vert-cs))) 14 | (values (car (argmax cdr freqs)) (car (argmin cdr freqs))))) 15 | (displayln (list->string s1)) 16 | (displayln (list->string s2))) 17 | (provide solve) 18 | 19 | (provide #%module-begin) -------------------------------------------------------------------------------- /2016/day06/test.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "lang.rkt" 2 | eedadn 3 | drvtee 4 | eandsr 5 | raavrd 6 | atevrs 7 | tsrnev 8 | sdttsa 9 | rasrtv 10 | nssdts 11 | ntnada 12 | svetve 13 | tesnvt 14 | vntsnd 15 | vrdear 16 | dvrsen 17 | enarar -------------------------------------------------------------------------------- /2016/day07/lang.rkt: -------------------------------------------------------------------------------- 1 | #lang br/quicklang 2 | 3 | (provide read-syntax) 4 | (define (read-syntax path port) 5 | (strip-bindings 6 | #`(module mod "lang.rkt" 7 | #,@(for/list ([ip (in-lines port)] 8 | #:when (not (equal? ip ""))) 9 | ip)))) 10 | 11 | (provide (rename-out [mb #%module-begin])) 12 | (define-macro (mb . IPS) 13 | #'(#%module-begin 14 | (define ips (list . IPS)) 15 | (displayln (format "part a: ~a" (length (filter supports-tls? ips)))) 16 | (displayln (format "part b: ~a" (length (filter supports-ssl? ips)))))) 17 | 18 | (define bracketed-pattern #rx"\\[.*?\\]") 19 | 20 | (define (bracketed-parts str) 21 | (regexp-match* bracketed-pattern str)) 22 | 23 | (define (unbracketed-parts str) 24 | (string-split str bracketed-pattern)) 25 | 26 | (define (has-abba? str) 27 | (for*/or ([idx (in-range (string-length str))] 28 | [substr (in-list (regexp-match* #px"^\\w\\w\\w\\w" str idx))] 29 | #:when substr) 30 | (define cs (string->list substr)) 31 | (and 32 | (char=? (first cs) (fourth cs)) 33 | (char=? (second cs) (third cs)) 34 | (not (char=? (first cs) (second cs)))))) 35 | 36 | (define (supports-tls? str) 37 | (and 38 | (ormap has-abba? (unbracketed-parts str)) 39 | (andmap (negate has-abba?) (bracketed-parts str)))) 40 | 41 | (define (find-abas str) 42 | (for*/list ([idx (in-range (string-length str))] 43 | [substr (in-list (regexp-match* #px"^\\w\\w\\w" str idx))] 44 | [cs (in-value (string->list substr))] 45 | #:when (and 46 | substr 47 | (char=? (first cs) (third cs)) 48 | (not (char=? (first cs) (second cs))))) 49 | substr)) 50 | 51 | (define (aba->bab aba) (format "~a~a~a" (substring aba 1 2) 52 | (substring aba 0 1) 53 | (substring aba 1 2))) 54 | 55 | (define (supports-ssl? str) 56 | (define abas (append-map find-abas (unbracketed-parts str))) 57 | (for*/or ([bab (in-list (map aba->bab abas))] 58 | [str (in-list (bracketed-parts str))]) 59 | (regexp-match bab str))) 60 | -------------------------------------------------------------------------------- /2016/day07/test.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "lang.rkt" 2 | abba[mnop]qrst 3 | abcd[bddb]xyyx 4 | aaaa[qwer]tyui 5 | ioxxoj[asdfgh]zxcvbn -------------------------------------------------------------------------------- /2016/day08/lang.rkt: -------------------------------------------------------------------------------- 1 | #lang br/quicklang 2 | (provide read-syntax) 3 | (define (read-syntax path port) 4 | (strip-bindings 5 | #`(module mod "lang.rkt" 6 | #,@(for/list ([inst (in-lines port)] 7 | #:when (not (equal? inst ""))) 8 | (format-datum '(~a) inst))))) 9 | 10 | (provide (rename-out [mb #%module-begin])) 11 | (define-macro (mb INST ...) 12 | #'(#%module-begin 13 | (define g (for/fold ([g (grid 50 6)]) 14 | ([inst (in-list (list INST ...))]) 15 | (inst g))) 16 | (for-each displayln (map (λ (gr) (map (λ (gri) (if (= gri 1) "X" " ")) gr)) g)) 17 | (apply + (flatten g)))) 18 | 19 | (require (for-syntax racket/string)) 20 | (define-macro (rect ARG) 21 | (with-pattern ([(COLS ROWS) (map string->number (string-split (symbol->string (syntax->datum #'ARG)) "x"))]) 22 | #'(curryr fill COLS ROWS))) 23 | (provide rect) 24 | 25 | (define-macro (rotate DIR WHICH-RAW by DIST) 26 | (with-pattern ([PROC (prefix-id "shift-" #'DIR)] 27 | [WHICH (string->number (car (string-split (symbol->string (syntax->datum #'WHICH-RAW)) #rx"[xy]=")))]) 28 | #'(curryr PROC WHICH DIST))) 29 | (provide rotate) 30 | 31 | (define (grid x y) 32 | (make-list y (make-list x 0))) 33 | 34 | (define (fill g cols rows) 35 | (for/list ([(row ridx) (in-indexed g)]) 36 | (for/list ([(col cidx) (in-indexed (list-ref g ridx))]) 37 | (if (and (< ridx rows) (< cidx cols)) 38 | 1 39 | col)))) 40 | 41 | (require sugar/list) 42 | (define (shift-row g which dist) 43 | (for/list ([(row ridx) (in-indexed g)]) 44 | (if (= which ridx) 45 | (shift row dist #f #t) 46 | row))) 47 | (provide shift-row) 48 | 49 | (define (shift-column g which dist) 50 | (apply map list (shift-row (apply map list g) which dist))) 51 | (provide shift-column) -------------------------------------------------------------------------------- /2016/day08/test.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "lang.rkt" 2 | rect 3x2 3 | rotate column x=1 by 1 4 | rotate row y=0 by 4 5 | rotate column x=1 by 1 -------------------------------------------------------------------------------- /2016/day09/test.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "lang.rkt" 2 | (27x12)(20x12)(13x14)(7x10)(1x12)A -------------------------------------------------------------------------------- /2016/day10/lang.rkt: -------------------------------------------------------------------------------- 1 | #lang br/quicklang 2 | ;; http://adventofcode.com/2016/day/10 3 | (provide read-syntax) 4 | (define (read-syntax path port) 5 | (strip-bindings 6 | #`(module mod "lang.rkt" 7 | #,@(for/list ([str (in-lines port)] 8 | #:when (not (equal? str ""))) 9 | `(handle ,@(string-split str)))))) 10 | 11 | (define chip-comparison-key '(17 61)) 12 | (define-macro (mb . ARGS) 13 | #'(#%module-begin 14 | (begin . ARGS) 15 | (displayln 16 | (for/first ([(k v) (in-hash gates)] 17 | #:when (equal? (sort (apply eval-gate k) <) 18 | (sort chip-comparison-key <))) 19 | k)) 20 | (displayln (for/product ([i (in-range 3)]) 21 | (gate-low "output" (~a i)))))) 22 | (provide (rename-out [mb #%module-begin])) 23 | 24 | (define gates (make-hash)) 25 | 26 | (define-macro-cases handle 27 | [(_ "value" VAL "goes" "to" TYPE NUM) 28 | #'(hash-update! gates (list TYPE NUM) (λ (val) (cons (λ () (let ([v VAL]) 29 | (if (string? v) 30 | (string->number v) 31 | v))) val)) empty)] 32 | [(_ "bot" BOT "gives" "low" "to" LOW-TYPE LOW-NUM "and" "high" "to" HIGH-TYPE HIGH-NUM) 33 | #'(begin 34 | (handle "value" (gate-low "bot" BOT) "goes" "to" LOW-TYPE LOW-NUM) 35 | (handle "value" (gate-high "bot" BOT) "goes" "to" HIGH-TYPE HIGH-NUM))]) 36 | (provide handle) 37 | 38 | (require sugar/cache) 39 | (define/caching (eval-gate type num) 40 | (for/list ([proc (in-list (hash-ref gates (list type num)))]) 41 | (proc))) 42 | 43 | (define (gate-low type num) (car (sort (eval-gate type num) <))) 44 | (define (gate-high type num) (car (sort (eval-gate type num) >))) 45 | -------------------------------------------------------------------------------- /2016/day10/test.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "lang.rkt" 2 | value 5 goes to bot 2 3 | bot 2 gives low to bot 1 and high to bot 0 4 | value 3 goes to bot 1 5 | bot 1 gives low to output 1 and high to bot 0 6 | bot 0 gives low to output 2 and high to output 0 7 | value 2 goes to bot 2 -------------------------------------------------------------------------------- /2016/day12/input.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "lang.rkt" 2 | cpy 1 a 3 | cpy 1 b 4 | cpy 26 d 5 | jnz c 2 6 | jnz 1 5 7 | cpy 7 c 8 | inc d 9 | dec c 10 | jnz c -2 11 | cpy a c 12 | inc a 13 | dec b 14 | jnz b -2 15 | cpy c b 16 | dec d 17 | jnz d -6 18 | cpy 16 c 19 | cpy 17 d 20 | inc a 21 | dec d 22 | jnz d -2 23 | dec c 24 | jnz c -5 -------------------------------------------------------------------------------- /2016/day12/lang.rkt: -------------------------------------------------------------------------------- 1 | #lang br/quicklang 2 | ;; http://adventofcode.com/2016/day/12 3 | (provide read-syntax 4 | (rename-out [mb #%module-begin]) 5 | cpy inc dec jnz) 6 | 7 | (define (read-syntax path port) 8 | (strip-bindings 9 | #`(module mod "lang.rkt" 10 | #,@(for/list ([str (in-lines port)] 11 | #:when (not (zero? (string-length str)))) 12 | (format-datum '(~a) str))))) 13 | 14 | (define-macro (mb . INSTS) 15 | #'(#%module-begin 16 | (define insts (vector . INSTS)) 17 | (define regs (make-hash '((a . 0)(b . 0)(c . 0)(d . 0)))) 18 | (println (solve insts regs)) 19 | (hash-set! regs 'c 1) 20 | (println (solve insts regs)))) 21 | 22 | (define (solve insts regs) 23 | (let loop ([ptr 0]) 24 | (if (>= ptr (vector-length insts)) 25 | regs 26 | (loop (+ ptr (let ([move ((vector-ref insts ptr) regs)]) 27 | (if (void? move) 1 move))))))) 28 | 29 | (define-macro (cpy X Y) 30 | #'(λ (regs) 31 | (define val (if (number? 'X) 'X (hash-ref regs 'X))) 32 | (hash-set! regs 'Y val))) 33 | 34 | (define-macro (inc X) #'(λ (regs) (hash-update! regs 'X add1))) 35 | 36 | (define-macro (dec X) #'(λ (regs) (hash-update! regs 'X sub1))) 37 | 38 | (define-macro (jnz X Y) 39 | #'(λ (regs) 40 | (when (not (zero? (if (number? 'X) 'X (hash-ref regs 'X)))) 41 | Y))) 42 | -------------------------------------------------------------------------------- /2016/day12/test.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "lang.rkt" 2 | cpy 41 a 3 | inc a 4 | inc a 5 | dec a 6 | jnz a 2 7 | dec a -------------------------------------------------------------------------------- /2016/day13/input.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "lang.rkt" 2 | 1358 -------------------------------------------------------------------------------- /2016/day13/lang.rkt: -------------------------------------------------------------------------------- 1 | #lang br/quicklang 2 | ;; http://adventofcode.com/2016/day/13 3 | (require graph) 4 | (provide read-syntax 5 | (rename-out [mb #%module-begin])) 6 | 7 | (define (read-syntax path port) 8 | (strip-bindings 9 | #`(module mod "lang.rkt" 10 | #,(string->number (string-trim (port->string port)))))) 11 | 12 | (define-macro (mb NUM) 13 | #'(#%module-begin 14 | (solve 50 NUM) ; 50 is arbitrarily large space to search 15 | (solve2 NUM))) 16 | 17 | (define starting-pt 1+1i) 18 | 19 | (define (solve dim num) 20 | (define open? (make-open-pred num)) 21 | (define g (undirected-graph (list starting-pt))) 22 | (for* ([row (in-range dim)] 23 | [col (in-range dim)] 24 | [p (in-value (+ col (* +i row)))] 25 | #:when (open? p)) 26 | (when (open? (+ p 1)) (add-edge! g p (+ p 1))) 27 | (when (open? (+ p +i)) (add-edge! g p (+ p +i)))) 28 | (define path (fewest-vertices-path g 1+1i 31+39i)) 29 | (displayln (and path (sub1 (length path))))) 30 | 31 | (define (solve2 num) 32 | (define open? (make-open-pred num)) 33 | (define (nonnegative? pt) (and (not (negative? (real-part pt))) 34 | (not (negative? (imag-part pt))) 35 | pt)) 36 | (let take-step ([all-visited-pts empty] 37 | [last-visited-pts (list starting-pt)] 38 | [count 0]) 39 | (if (= count 50) 40 | (length (remove-duplicates (append all-visited-pts last-visited-pts))) 41 | (take-step 42 | (append last-visited-pts all-visited-pts) 43 | (flatten 44 | (for*/list ([p (in-list last-visited-pts)] 45 | [next-p (in-list (map (curry + p) '(1 -1 +i -i)))] 46 | #:when (and (nonnegative? next-p) 47 | (open? next-p) 48 | (not (member next-p all-visited-pts)))) 49 | next-p)) 50 | (add1 count))))) 51 | 52 | (define (make-open-pred num) 53 | (λ (pt) 54 | (define col (real-part pt)) 55 | (define row (imag-part pt)) 56 | (define sum 57 | (+ (* col col) (* 3 col) (* 2 col row) row (* row row) num)) 58 | (even? (length (regexp-match* "1" (format "~b" sum)))))) -------------------------------------------------------------------------------- /2016/day13/test.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "lang.rkt" 2 | 10 -------------------------------------------------------------------------------- /2016/day14/input.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "lang.rkt" 2 | ahsbgdzn -------------------------------------------------------------------------------- /2016/day14/lang.rkt: -------------------------------------------------------------------------------- 1 | #lang br/quicklang ;; http://adventofcode.com/2016/day/14 2 | (require openssl/md5) 3 | (provide read-syntax 4 | (rename-out [mb #%module-begin])) 5 | 6 | (define (read-syntax path port) 7 | (strip-bindings 8 | #`(module mod "lang.rkt" 9 | #,(string-trim (port->string port))))) 10 | 11 | (define-macro (mb SALT) 12 | #'(#%module-begin 13 | (solve SALT) 14 | (parameterize ([key-stretch 2017]) 15 | (solve SALT)))) 16 | 17 | (define key-stretch (make-parameter 0)) 18 | (require sugar/cache) 19 | (define/caching (get-hash salt i) 20 | (for/fold ([str (string-downcase (format "~a~a" salt i))]) 21 | ([i (in-range (key-stretch))]) 22 | (md5 (open-input-string str)))) 23 | 24 | (define (valid? hash salt i) 25 | (let* ([triple-char-pat (pregexp "(.)\\1\\1")] 26 | [result (regexp-match triple-char-pat hash)]) 27 | (and result 28 | (let* ([repeated-char (cadr result)] 29 | [penta-char-pat (pregexp (format "(~a)\\1\\1\\1\\1" repeated-char))]) 30 | (for/or ([idx (in-range (add1 i) (+ 1001 i))]) 31 | (regexp-match penta-char-pat (get-hash salt idx))))))) 32 | 33 | (define (solve salt) 34 | (caar 35 | (for/fold ([keys empty]) 36 | ([i (in-naturals)] 37 | #:break (= (length keys) 64)) 38 | (define hash (get-hash salt i)) 39 | (if (valid? hash salt i) 40 | (report* i hash (cons (cons i hash) keys)) 41 | keys)))) 42 | -------------------------------------------------------------------------------- /2016/day14/test.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "lang.rkt" 2 | abc -------------------------------------------------------------------------------- /2016/day15/input-b.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "lang.rkt" 2 | Disc #1 has 5 positions; at time=0, it is at position 2. 3 | Disc #2 has 13 positions; at time=0, it is at position 7. 4 | Disc #3 has 17 positions; at time=0, it is at position 10. 5 | Disc #4 has 3 positions; at time=0, it is at position 2. 6 | Disc #5 has 19 positions; at time=0, it is at position 9. 7 | Disc #6 has 7 positions; at time=0, it is at position 0. 8 | Disc #7 has 11 positions; at time=0, it is at position 0. -------------------------------------------------------------------------------- /2016/day15/input.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "lang.rkt" 2 | Disc #1 has 5 positions; at time=0, it is at position 2. 3 | Disc #2 has 13 positions; at time=0, it is at position 7. 4 | Disc #3 has 17 positions; at time=0, it is at position 10. 5 | Disc #4 has 3 positions; at time=0, it is at position 2. 6 | Disc #5 has 19 positions; at time=0, it is at position 9. 7 | Disc #6 has 7 positions; at time=0, it is at position 0. -------------------------------------------------------------------------------- /2016/day15/lang.rkt: -------------------------------------------------------------------------------- 1 | #lang br/quicklang ;; http://adventofcode.com/2016/day/15 2 | (provide read-syntax 3 | (rename-out [mb #%module-begin])) 4 | 5 | (define (read-syntax path port) 6 | (strip-bindings 7 | #`(module mod "lang.rkt" 8 | #,@(for/list ([line (in-list (string-split (port->string port) "\n"))]) 9 | `(disc ,@(map string->number (regexp-match* #px"\\d+" line))))))) 10 | 11 | (define-macro (mb . DISCS) 12 | #'(#%module-begin 13 | (solve . DISCS))) 14 | 15 | (define-macro (solve . DISCS) 16 | (with-pattern ([(DISC-ID ...) (generate-temporaries #'DISCS)] 17 | [(DISC-SLOTS ...) #'DISCS]) 18 | #'(for/first ([DISC-ID (in-cycle DISC-SLOTS)] ... 19 | [i (in-naturals)] 20 | #:when (= 0 DISC-ID ...)) 21 | i))) 22 | 23 | (require sugar/list) 24 | (define-macro (disc TIME-OFFSET SIZE _ START) 25 | #'(shift-left-cycle (range SIZE) (+ START TIME-OFFSET))) 26 | (provide disc) -------------------------------------------------------------------------------- /2016/day15/test.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "lang.rkt" 2 | Disc #1 has 5 positions; at time=0, it is at position 4. 3 | Disc #2 has 2 positions; at time=0, it is at position 1. -------------------------------------------------------------------------------- /2016/day16/input-b.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "lang.rkt" 2 | 35651584, 10010000000110000 -------------------------------------------------------------------------------- /2016/day16/input.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "lang.rkt" 2 | 272, 10010000000110000 -------------------------------------------------------------------------------- /2016/day16/lang.rkt: -------------------------------------------------------------------------------- 1 | #lang br/quicklang ;; http://adventofcode.com/2016/day/16 2 | (require openssl/md5) 3 | (provide read-syntax 4 | (rename-out [mb #%module-begin])) 5 | 6 | (define (read-syntax path port) 7 | (strip-bindings 8 | #`(module mod "lang.rkt" 9 | #,@(string-split (string-trim (port->string port)) ", ")))) 10 | 11 | (define-macro (mb SIZE INIT) 12 | #'(#%module-begin 13 | (time (display (list->string (checksum (fill-disk (string->list INIT) (string->number SIZE)))))))) 14 | 15 | (define (dragonize cs) 16 | (append cs '(#\0) 17 | (for/list ([c (in-list (reverse cs))]) 18 | (if (eqv? c #\1) 19 | #\0 20 | #\1)))) 21 | 22 | (define (fill-disk init size) 23 | (let loop ([cs init]) 24 | (if (>= (length cs) size) 25 | (take cs size) 26 | (loop (dragonize cs))))) 27 | 28 | (define (checksum cs) 29 | (define cvec (list->vector cs)) 30 | (let loop ([cvec cvec]) 31 | (match (vector-length cvec) 32 | [(? odd?) (vector->list cvec)] 33 | [len 34 | (define newvec (make-vector (/ len 2) #\0)) 35 | (for ([idx (in-range 0 (vector-length cvec) 2)] 36 | #:when (char=? (vector-ref cvec idx) (vector-ref cvec (add1 idx)))) 37 | (vector-set! newvec (/ idx 2) #\1)) 38 | (loop newvec)]))) 39 | 40 | -------------------------------------------------------------------------------- /2016/day16/test-b.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "lang.rkt" 2 | 20, 10000 -------------------------------------------------------------------------------- /2016/day16/test.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "lang.rkt" 2 | 12, 110010110100 -------------------------------------------------------------------------------- /2016/day17/input.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "lang.rkt" 2 | hhhxzeay -------------------------------------------------------------------------------- /2016/day17/test.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "lang.rkt" 2 | hijkl -------------------------------------------------------------------------------- /2016/day18/input.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "lang.rkt" 2 | .^^^.^.^^^.^.......^^.^^^^.^^^^..^^^^^.^.^^^..^^.^.^^..^.^..^^...^.^^.^^^...^^.^.^^^..^^^^.....^.... -------------------------------------------------------------------------------- /2016/day18/lang.rkt: -------------------------------------------------------------------------------- 1 | #lang br/quicklang ;; http://adventofcode.com/2016/day/18 2 | (provide read-syntax 3 | (rename-out [mb #%module-begin])) 4 | 5 | (define (read-syntax path port) 6 | (strip-bindings 7 | #`(module mod "lang.rkt" 8 | #,(string-trim (port->string port))))) 9 | 10 | (define-macro (mb STR) 11 | #'(#%module-begin 12 | (define (traps cs) 13 | (length (filter (λ (c) (char=? #\. c)) cs))) 14 | (let loop ([cs (string->list STR)] 15 | [count (traps (string->list STR))] 16 | [i 0]) 17 | (if (= i 399999) ; number of rows 18 | count 19 | (let* ([result (next-cs cs)] 20 | [this-count (traps result)]) 21 | (loop result (+ this-count count) (add1 i))))))) 22 | 23 | (define (next-cs cs) 24 | (define adj-cs (append (list #\.) cs (list #\.))) 25 | (for/list ([c1 (in-list adj-cs)] 26 | [c2 (in-list (cdr adj-cs))] 27 | [c3 (in-list (cddr adj-cs))]) 28 | (case (list c1 c2 c3) 29 | [((#\^ #\^ #\.) (#\. #\^ #\^) (#\^ #\. #\.) (#\. #\. #\^)) #\^] 30 | [else #\.]))) 31 | -------------------------------------------------------------------------------- /2016/day18/test.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "lang.rkt" 2 | .^^.^.^^^^ -------------------------------------------------------------------------------- /2016/day19/input.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "lang.rkt" 2 | 3017957 -------------------------------------------------------------------------------- /2016/day19/lang.rkt: -------------------------------------------------------------------------------- 1 | #lang br/quicklang ;; http://adventofcode.com/2016/day/19 2 | (provide read-syntax 3 | (rename-out [mb #%module-begin])) 4 | 5 | (define (read-syntax path port) 6 | (strip-bindings 7 | #`(module mod "lang.rkt" 8 | #,(string-trim (port->string port))))) 9 | 10 | (define-macro (mb NUM-STR) 11 | #'(#%module-begin 12 | #;(displayln (solve (string->number NUM-STR) #f)) 13 | (displayln (solve (string->number NUM-STR) #t)))) 14 | 15 | (define (idx-after vec x) 16 | (or 17 | (for/first ([idx (in-range (modulo (add1 x) (vector-length vec)) (vector-length vec))] 18 | #:when (vector-ref vec idx)) 19 | idx) 20 | (idx-after vec -1))) 21 | 22 | (define (solve num [circle? #f]) 23 | (define elves (make-vector num #t)) 24 | (let loop ([taker 0][elves-left num]) 25 | (cond 26 | [(= elves-left 2) (add1 taker)] 27 | [else 28 | (define giver (for/fold ([elf taker]) 29 | ([i (in-range (if circle? (floor (/ elves-left 2)) 1))]) 30 | (idx-after elves elf))) 31 | (vector-set! elves giver #f) 32 | (loop (idx-after elves taker) (sub1 elves-left))]))) 33 | 34 | -------------------------------------------------------------------------------- /2016/day19/test.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "lang.rkt" 2 | 5 -------------------------------------------------------------------------------- /2016/day20/lang.rkt: -------------------------------------------------------------------------------- 1 | #lang br/quicklang ;; http://adventofcode.com/2016/day/20 2 | (provide read-syntax 3 | cons 4 | (rename-out [mb #%module-begin])) 5 | 6 | (define (read-syntax path port) 7 | (strip-bindings 8 | #`(module mod "lang.rkt" 9 | #,@(for/list ([line (in-list (string-split (port->string port) "\n"))]) 10 | `(cons ,@(map string->number (string-split line "-"))))))) 11 | 12 | (define-macro (mb . RANGE-PAIRS) 13 | #'(#%module-begin 14 | (define range-pairs (sort (list . RANGE-PAIRS) < #:key car)) 15 | (solve-a range-pairs) 16 | (solve-b range-pairs))) 17 | 18 | (define (solve-a range-pairs) 19 | (for/first ([left (in-list range-pairs)] 20 | [right (in-list (cdr range-pairs))] 21 | #:when (> (- (car right) (cdr left)) 1)) 22 | (add1 (cdr left)))) 23 | 24 | (define (find-overlap n ranges) 25 | (and (pair? ranges) 26 | (for/first ([r (in-list ranges)] 27 | #:when (<= (car r) n (cdr r))) 28 | r))) 29 | 30 | (define (solve-b range-pairs) 31 | (define rps (for/fold ([rps empty]) 32 | ([rp (in-list (append range-pairs '((4294967295 . 4294967295))))]) 33 | (define next-rps rps) 34 | (define left (or 35 | (let ([result (find-overlap (car rp) rps)]) 36 | (and result (set! next-rps (remove result next-rps)) (car result))) 37 | (car rp))) 38 | (define right (or 39 | (let ([result (find-overlap (cdr rp) rps)]) 40 | (and result (set! next-rps (remove result next-rps)) (cdr result))) 41 | (cdr rp))) 42 | (cons (cons left right) next-rps))) 43 | (define sorted-rps (sort rps < #:key car)) 44 | (for/sum ([left (in-list sorted-rps)] 45 | [right (in-list (cdr sorted-rps))] 46 | #:when (> (- (car right) (cdr left)) 1)) 47 | (- (car right) (cdr left) 1))) -------------------------------------------------------------------------------- /2016/day20/test.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "lang.rkt" 2 | 5-8 3 | 0-2 4 | 4-7 5 | -------------------------------------------------------------------------------- /2016/day21/test.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "lang.rkt" 2 | abcde 3 | swap position 4 with position 0 4 | swap letter d with letter b 5 | reverse positions 0 through 4 6 | rotate left 1 step 7 | move position 1 to position 4 8 | move position 3 to position 0 9 | rotate based on position of letter b 10 | rotate based on position of letter d -------------------------------------------------------------------------------- /2016/day22/lang.rkt: -------------------------------------------------------------------------------- 1 | #lang br/quicklang ;; http://adventofcode.com/2016/day/22 2 | (provide read-syntax 3 | (rename-out [mb #%module-begin])) 4 | 5 | (define (read-syntax path port) 6 | (strip-bindings 7 | (let ([lines (string-split (port->string port) "\n")]) 8 | #`(module mod "lang.rkt" 9 | #,@(for/list ([args (in-list (map string-split (cddr lines)))]) 10 | `(node ,@args)))))) 11 | 12 | (define-macro (mb . NODES) 13 | #'(#%module-begin 14 | (define nodes (list . NODES)) 15 | (count-viable-pairs nodes))) 16 | 17 | (struct $node (pos used avail) #:transparent) 18 | 19 | (define-macro (node NAME _ USED AVAIL _) 20 | #'($node 21 | (apply (λ (r i) (+ (string->number r) 22 | (* (string->number i) +i))) (regexp-match* #px"\\d+" NAME)) 23 | (string->number (string-trim USED "T")) 24 | (string->number (string-trim AVAIL "T")))) 25 | (provide node) 26 | 27 | (define (count-viable-pairs nodes) 28 | (for*/sum ([a (in-list nodes)] 29 | [b (in-list nodes)] 30 | #:when (and (not (zero? ($node-used a))) 31 | (not (equal? ($node-pos a) ($node-pos b))) 32 | (<= ($node-used a) ($node-avail b)))) 33 | 1)) -------------------------------------------------------------------------------- /2016/day22/test.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "lang.rkt" 2 | root@ebhq-gridcenter# df -h 3 | Filesystem Size Used Avail Use% -------------------------------------------------------------------------------- /2016/day23/info.rkt: -------------------------------------------------------------------------------- 1 | #lang info 2 | (define compile-omit-paths 'all) -------------------------------------------------------------------------------- /2016/day23/input.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "lang.rkt" 2 | cpy a b 3 | dec b 4 | cpy a d 5 | cpy 0 a 6 | cpy b c 7 | inc a 8 | dec c 9 | jnz c -2 10 | dec d 11 | jnz d -5 12 | dec b 13 | cpy b c 14 | cpy c d 15 | dec d 16 | inc c 17 | jnz d -2 18 | tgl c 19 | cpy -16 c 20 | jnz 1 c 21 | cpy 70 c 22 | jnz 87 d 23 | inc a 24 | inc d 25 | jnz d -2 26 | inc c 27 | jnz c -5 -------------------------------------------------------------------------------- /2016/day23/test.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "lang.rkt" 2 | cpy 2 a -------------------------------------------------------------------------------- /2016/day24/test.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "lang.rkt" 2 | ########### 3 | #0.1.....2# 4 | #.#######.# 5 | #4.......3# 6 | ########### -------------------------------------------------------------------------------- /2016/day25/input.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "lang.rkt" 2 | cpy a d 3 | cpy 14 c 4 | cpy 182 b 5 | inc d 6 | dec b 7 | jnz b -2 8 | dec c 9 | jnz c -5 10 | cpy d a 11 | jnz 0 0 12 | cpy a b 13 | cpy 0 a 14 | cpy 2 c 15 | jnz b 2 16 | jnz 1 6 17 | dec b 18 | dec c 19 | jnz c -4 20 | inc a 21 | jnz 1 -7 22 | cpy 2 b 23 | jnz c 2 24 | jnz 1 4 25 | dec b 26 | dec c 27 | jnz 1 -4 28 | jnz 0 0 29 | out b 30 | jnz a -19 31 | jnz 1 -21 -------------------------------------------------------------------------------- /2016/day25/lang.rkt: -------------------------------------------------------------------------------- 1 | #lang br/quicklang ;; http://adventofcode.com/2016/day/25 2 | (provide read-syntax 3 | (rename-out [mb #%module-begin]) 4 | cpy inc dec jnz out) 5 | 6 | (define (read-syntax path port) 7 | (strip-bindings 8 | #`(module mod "lang.rkt" 9 | #,@(for/list ([str (in-lines port)] 10 | #:when (not (zero? (string-length str)))) 11 | (format-datum '(~a) str))))) 12 | 13 | (define-macro (mb . INSTS) 14 | #'(#%module-begin 15 | (define insts (vector . INSTS)) 16 | (define regs (make-hash '((a . 0)(b . 0)(c . 0)(d . 0)))) 17 | (for*/first ([i (in-naturals)] 18 | #:when 19 | (begin 20 | (hash-set! regs 'a i) 21 | (regexp-match "010101010101" (with-output-to-string (λ () (solve insts regs 50000)))))) 22 | i))) 23 | 24 | (define (solve insts regs max-count) 25 | (let loop ([ptr 0][count 0]) 26 | (if (or (>= ptr (vector-length insts)) (> count max-count)) 27 | regs 28 | (loop (+ ptr (let ([move ((vector-ref insts ptr) regs)]) 29 | (if (void? move) 1 move))) 30 | (add1 count))))) 31 | 32 | (define-macro (cpy X Y) 33 | #'(λ (regs) 34 | (define val (if (number? 'X) 'X (hash-ref regs 'X))) 35 | (hash-set! regs 'Y val))) 36 | 37 | (define-macro (inc X) #'(λ (regs) (hash-update! regs 'X add1))) 38 | 39 | (define-macro (dec X) #'(λ (regs) (hash-update! regs 'X sub1))) 40 | 41 | (define-macro (jnz X Y) 42 | #'(λ (regs) 43 | (when (not (zero? (if (number? 'X) 'X (hash-ref regs 'X)))) 44 | Y))) 45 | 46 | (define-macro (out X) 47 | #'(λ (regs) 48 | (print (hash-ref regs 'X)))) 49 | -------------------------------------------------------------------------------- /2017/README.md: -------------------------------------------------------------------------------- 1 | In 2017 I wrote all the solutions as DSLs. 2 | -------------------------------------------------------------------------------- /2017/aoc-lang.rkt: -------------------------------------------------------------------------------- 1 | #| 2 | #lang s-exp syntax/module-reader 3 | #:read read 4 | #:read-syntax read-syntax 5 | #:language `(submod ,aoc-lang expander) 6 | (require racket/runtime-path) 7 | (define-runtime-path aoc-lang "aoc-lang.rkt") 8 | |# 9 | 10 | #lang br/quicklang 11 | (require "helper.rkt") 12 | (provide (except-out (all-from-out br/quicklang "helper.rkt") read-syntax #%module-begin) 13 | (rename-out [my-rs read-syntax] [my-mb #%module-begin])) 14 | 15 | (define (my-rs path port) 16 | (define datums (for/list ([datum (in-port (curry read-syntax path) port)]) 17 | datum)) 18 | (strip-context (with-pattern ([THIS-FILE (syntax-source #'here)] 19 | [DATUMS datums]) 20 | (syntax/loc (car datums) (module puzzle-lang THIS-FILE 21 | . DATUMS))))) 22 | 23 | (define (blank? line) (regexp-match #px"^\\s*$" line)) 24 | 25 | (define-macro (my-mb . ARGS) 26 | (with-pattern ([MOD-PATH (syntax-source caller-stx)]) 27 | #'(#%module-begin 28 | (provide read-syntax) 29 | (define (read-syntax path port) 30 | (strip-context #`(module mod MOD-PATH 31 | #,@(for/list ([line (in-lines port)] 32 | #:unless (blank? line)) 33 | (for/list ([datums (in-port read (open-input-string (string-replace line "," " ")))]) 34 | 35 | datums))))) 36 | . ARGS))) 37 | -------------------------------------------------------------------------------- /2017/d01/main.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "../aoc-lang.rkt" 2 | 3 | (provide (rename-out [#%mb #%module-begin])) 4 | (define-macro (#%mb (STARS) (NUMBER) ...) 5 | #'(#%module-begin (time (captcha-sum 'STARS NUMBER) ...))) 6 | 7 | (define (captcha-sum stars num) 8 | (define digits (number->digits num)) 9 | (define offset (if (eq? stars '★) -1 (quotient (length digits) 2))) 10 | (for/sum ([digit (in-list digits)] 11 | [other-digit (in-list (shift-cycle digits offset))] 12 | #:when (= digit other-digit)) 13 | digit)) -------------------------------------------------------------------------------- /2017/d01/star1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ ; 1343 2 | 9513446799636685297929646689682997114316733445451534532351778534251427172168183621874641711534917291674333857423799375512628489423332297538215855176592633692631974822259161766238385922277893623911332569448978771948316155868781496698895492971356383996932885518732997624253678694279666572149831616312497994856288871586777793459926952491318336997159553714584541897294117487641872629796825583725975692264125865827534677223541484795877371955124463989228886498682421539667224963783616245646832154384756663251487668681425754536722827563651327524674183443696227523828832466473538347472991998913211857749878157579176457395375632995576569388455888156465451723693767887681392547189273391948632726499868313747261828186732986628365773728583387184112323696592536446536231376615949825166773536471531487969852535699774113163667286537193767515119362865141925612849443983484245268194842563154567638354645735331855896155142741664246715666899824364722914296492444672653852387389477634257768229772399416521198625393426443499223611843766134883441223328256883497423324753229392393974622181429913535973327323952241674979677481518733692544535323219895684629719868384266425386835539719237716339198485163916562434854579365958111931354576991558771236977242668756782139961638347251644828724786827751748399123668854393894787851872256667336215726674348886747128237416273154988619267824361227888751562445622387695218161341884756795223464751862965655559143779425283154533252573949165492138175581615176611845489857169132936848668646319955661492488428427435269169173654812114842568381636982389224236455633316898178163297452453296667661849622174541778669494388167451186352488555379581934999276412919598411422973399319799937518713422398874326665375216437246445791623283898584648278989674418242112957668397484671119761553847275799873495363759266296477844157237423239163559391553961176475377151369399646747881452252547741718734949967752564774161341784833521492494243662658471121369649641815562327698395293573991648351369767162642763475561544795982183714447737149239846151871434656618825566387329765118727515699213962477996399781652131918996434125559698427945714572488376342126989157872118279163127742349 -------------------------------------------------------------------------------- /2017/d01/star2.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★★ ; 1274 2 | 9513446799636685297929646689682997114316733445451534532351778534251427172168183621874641711534917291674333857423799375512628489423332297538215855176592633692631974822259161766238385922277893623911332569448978771948316155868781496698895492971356383996932885518732997624253678694279666572149831616312497994856288871586777793459926952491318336997159553714584541897294117487641872629796825583725975692264125865827534677223541484795877371955124463989228886498682421539667224963783616245646832154384756663251487668681425754536722827563651327524674183443696227523828832466473538347472991998913211857749878157579176457395375632995576569388455888156465451723693767887681392547189273391948632726499868313747261828186732986628365773728583387184112323696592536446536231376615949825166773536471531487969852535699774113163667286537193767515119362865141925612849443983484245268194842563154567638354645735331855896155142741664246715666899824364722914296492444672653852387389477634257768229772399416521198625393426443499223611843766134883441223328256883497423324753229392393974622181429913535973327323952241674979677481518733692544535323219895684629719868384266425386835539719237716339198485163916562434854579365958111931354576991558771236977242668756782139961638347251644828724786827751748399123668854393894787851872256667336215726674348886747128237416273154988619267824361227888751562445622387695218161341884756795223464751862965655559143779425283154533252573949165492138175581615176611845489857169132936848668646319955661492488428427435269169173654812114842568381636982389224236455633316898178163297452453296667661849622174541778669494388167451186352488555379581934999276412919598411422973399319799937518713422398874326665375216437246445791623283898584648278989674418242112957668397484671119761553847275799873495363759266296477844157237423239163559391553961176475377151369399646747881452252547741718734949967752564774161341784833521492494243662658471121369649641815562327698395293573991648351369767162642763475561544795982183714447737149239846151871434656618825566387329765118727515699213962477996399781652131918996434125559698427945714572488376342126989157872118279163127742349 -------------------------------------------------------------------------------- /2017/d01/test1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ 2 | 1122 3 | 1111 4 | 1234 5 | 91212129 -------------------------------------------------------------------------------- /2017/d01/test2.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★★ 2 | 1212 3 | 1221 4 | 123425 5 | 123123 6 | 12131415 -------------------------------------------------------------------------------- /2017/d02/main.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "../aoc-lang.rkt" 2 | 3 | (provide (rename-out [#%mb #%module-begin])) 4 | (define-macro (#%mb (STARS) (NUMBER ...) ...) 5 | #'(#%module-begin (time (checksum 'STARS '((NUMBER ...) ...))))) 6 | 7 | (define (checksum stars intss) 8 | (define (max-min-diff ints) (- (apply max ints) (apply min ints))) 9 | (define (no-remainder ints) 10 | (for*/first ([duo (in-combinations ints 2)] 11 | [result (in-value (apply / (sort duo >)))] 12 | #:when (integer? result)) 13 | result)) 14 | (define row-proc (if (eq? stars '★) max-min-diff no-remainder)) 15 | (apply + (map row-proc intss))) 16 | -------------------------------------------------------------------------------- /2017/d02/star1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ ; 53978 2 | 1919 2959 82 507 3219 239 3494 1440 3107 259 3544 683 207 562 276 2963 3 | 587 878 229 2465 2575 1367 2017 154 152 157 2420 2480 138 2512 2605 876 4 | 744 6916 1853 1044 2831 4797 213 4874 187 6051 6086 7768 5571 6203 247 285 5 | 1210 1207 1130 116 1141 563 1056 155 227 1085 697 735 192 1236 1065 156 6 | 682 883 187 307 269 673 290 693 199 132 505 206 231 200 760 612 7 | 1520 95 1664 1256 685 1446 253 88 92 313 754 1402 734 716 342 107 8 | 146 1169 159 3045 163 3192 1543 312 161 3504 3346 3231 771 3430 3355 3537 9 | 177 2129 3507 3635 2588 3735 3130 980 324 266 1130 3753 175 229 517 3893 10 | 4532 164 191 5169 4960 3349 3784 3130 5348 5036 2110 151 5356 193 1380 3580 11 | 2544 3199 3284 3009 3400 953 3344 3513 102 1532 161 143 2172 2845 136 2092 12 | 194 5189 3610 4019 210 256 5178 4485 5815 5329 5457 248 5204 4863 5880 3754 13 | 3140 4431 4534 4782 3043 209 216 5209 174 161 3313 5046 1160 160 4036 111 14 | 2533 140 4383 1581 139 141 2151 2104 2753 4524 4712 866 3338 2189 116 4677 15 | 1240 45 254 1008 1186 306 633 1232 1457 808 248 1166 775 1418 1175 287 16 | 851 132 939 1563 539 1351 1147 117 1484 100 123 490 152 798 1476 543 17 | 1158 2832 697 113 121 397 1508 118 2181 2122 809 2917 134 2824 3154 2791 -------------------------------------------------------------------------------- /2017/d02/star2.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★★ ; 314 2 | 1919 2959 82 507 3219 239 3494 1440 3107 259 3544 683 207 562 276 2963 3 | 587 878 229 2465 2575 1367 2017 154 152 157 2420 2480 138 2512 2605 876 4 | 744 6916 1853 1044 2831 4797 213 4874 187 6051 6086 7768 5571 6203 247 285 5 | 1210 1207 1130 116 1141 563 1056 155 227 1085 697 735 192 1236 1065 156 6 | 682 883 187 307 269 673 290 693 199 132 505 206 231 200 760 612 7 | 1520 95 1664 1256 685 1446 253 88 92 313 754 1402 734 716 342 107 8 | 146 1169 159 3045 163 3192 1543 312 161 3504 3346 3231 771 3430 3355 3537 9 | 177 2129 3507 3635 2588 3735 3130 980 324 266 1130 3753 175 229 517 3893 10 | 4532 164 191 5169 4960 3349 3784 3130 5348 5036 2110 151 5356 193 1380 3580 11 | 2544 3199 3284 3009 3400 953 3344 3513 102 1532 161 143 2172 2845 136 2092 12 | 194 5189 3610 4019 210 256 5178 4485 5815 5329 5457 248 5204 4863 5880 3754 13 | 3140 4431 4534 4782 3043 209 216 5209 174 161 3313 5046 1160 160 4036 111 14 | 2533 140 4383 1581 139 141 2151 2104 2753 4524 4712 866 3338 2189 116 4677 15 | 1240 45 254 1008 1186 306 633 1232 1457 808 248 1166 775 1418 1175 287 16 | 851 132 939 1563 539 1351 1147 117 1484 100 123 490 152 798 1476 543 17 | 1158 2832 697 113 121 397 1508 118 2181 2122 809 2917 134 2824 3154 2791 -------------------------------------------------------------------------------- /2017/d02/test1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ 2 | 5 1 9 5 3 | 7 5 3 4 | 2 4 6 8 -------------------------------------------------------------------------------- /2017/d02/test2.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★★ 2 | 5 9 2 8 3 | 9 4 7 3 4 | 3 8 6 5 -------------------------------------------------------------------------------- /2017/d03/main.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "../aoc-lang.rkt" 2 | 3 | (provide (rename-out [#%mb #%module-begin])) 4 | (define-macro (#%mb (STARS) (NUMBER) ...) 5 | #'(#%module-begin (time ((if (eq? 'STARS '★) dist larger-sum) NUMBER) ...))) 6 | 7 | (define (ring-side r) (* 2 r)) 8 | (define (ring-last r) (expt (add1 (ring-side r)) 2)) 9 | (define (ring-first r) (if (zero? r) 1 (add1 (ring-last (sub1 r))))) 10 | 11 | (define (ring int) 12 | (for/first ([i (in-naturals)] 13 | #:when (<= int (ring-last i))) 14 | i)) 15 | 16 | (define (nth-coordinate n) 17 | (cond 18 | [(= n 1) 0] 19 | [else 20 | (define ring-idx (ring n)) 21 | (define offset (- n (ring-first ring-idx))) 22 | (define-values (quadrant pos) 23 | (quotient/remainder offset (ring-side ring-idx))) 24 | (* (+ ring-idx (* +i (- pos (sub1 ring-idx)))) (expt +i quadrant))])) 25 | 26 | (define (dist n) 27 | (define c (nth-coordinate n)) 28 | (+ (abs (real-part c)) (abs (imag-part c)))) 29 | 30 | (define vals (make-hash)) 31 | (define (neighbor-sum n) 32 | (define c (nth-coordinate n)) 33 | (hash-ref! vals c (λ () (if (= c 0) 34 | 1 35 | (for*/sum ([h (in-list '(-1 0 1))] 36 | [v (in-list '(-1 0 1))]) 37 | (define neighbor (+ h (* +i v))) 38 | (hash-ref vals (+ c neighbor) 0)))))) 39 | 40 | (define (larger-sum x) 41 | (for*/first ([n (in-naturals 1)] 42 | #:when (> (neighbor-sum n) x)) 43 | (neighbor-sum n))) -------------------------------------------------------------------------------- /2017/d03/star1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ ; 480 2 | 347991 -------------------------------------------------------------------------------- /2017/d03/star2.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★★ ; 349975 2 | 347991 -------------------------------------------------------------------------------- /2017/d03/test1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ 2 | 1 3 | 12 4 | 23 5 | 1024 -------------------------------------------------------------------------------- /2017/d03/test2.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★★ 2 | 1 3 | 12 4 | 23 5 | 1024 -------------------------------------------------------------------------------- /2017/d04/main.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "../aoc-lang.rkt" 2 | 3 | (provide (rename-out [#%mb #%module-begin])) 4 | (define-macro (#%mb (STARS) (WORD ...) ...) 5 | #'(#%module-begin 6 | (time (for/sum ([ws (in-list '((WORD ...) ...))] 7 | #:when (no-duplicates? ws #:anagrams? (eq? 'STARS '★★))) 8 | 1)))) 9 | 10 | (define (sort-chars word) 11 | (sort (string->list (symbol->string word)) charvector '(JMP ...)) 'STARS)))) 7 | 8 | (define (escape vec stars) 9 | (let/ec exit 10 | (for/fold ([pos 0]) 11 | ([i (in-naturals)]) 12 | (unless (<= 0 pos (sub1 (vector-length vec))) 13 | (exit i)) 14 | (define jmp (vector-ref vec pos)) 15 | (vector-set! vec pos ((if (and (eq? stars '★★) (>= jmp 3)) 16 | sub1 17 | add1) jmp)) 18 | (+ pos jmp)))) 19 | 20 | -------------------------------------------------------------------------------- /2017/d05/test1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ 2 | 0 3 | 3 4 | 0 5 | 1 6 | -3 -------------------------------------------------------------------------------- /2017/d05/test2.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★★ 2 | 0 3 | 3 4 | 0 5 | 1 6 | -3 -------------------------------------------------------------------------------- /2017/d06/main.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "../aoc-lang.rkt" 2 | 3 | (provide (rename-out [#%mb #%module-begin])) 4 | (define-macro (#%mb (STARS) (BANK ...)) 5 | #`(#%module-begin 6 | (time (count-redists (list->vector '(BANK ...)) 'STARS)))) 7 | 8 | (define (redist starting-vec) 9 | (define vec (vector-copy starting-vec)) 10 | (define max-blocks (vector-argmax values vec)) 11 | (define start-at (vector-member max-blocks vec)) 12 | (vector-set! vec start-at 0) 13 | (for ([block (in-range max-blocks)] 14 | [idx (in-cycle (shift-left-cycle (range (vector-length vec)) (add1 start-at)))]) 15 | (vector-set! vec idx (+ (vector-ref vec idx) 1))) 16 | vec) 17 | 18 | (define (count-redists bankvec stars) 19 | (let/ec exit 20 | (for/fold ([bankvecs-seen (list bankvec)]) 21 | ([i (in-naturals)]) 22 | (cond 23 | [(member (car bankvecs-seen) (cdr bankvecs-seen)) 24 | => (λ (tail) (exit (if (eq? stars '★) 25 | i 26 | (- (length bankvecs-seen) (length tail)))))]) 27 | (cons (redist (car bankvecs-seen)) bankvecs-seen)))) 28 | 29 | -------------------------------------------------------------------------------- /2017/d06/star1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ ; 14029 2 | 10 3 15 10 5 15 5 15 9 2 5 8 5 2 3 6 -------------------------------------------------------------------------------- /2017/d06/star2.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★★ ; 2765 2 | 10 3 15 10 5 15 5 15 9 2 5 8 5 2 3 6 -------------------------------------------------------------------------------- /2017/d06/test1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ 2 | 0 2 7 0 -------------------------------------------------------------------------------- /2017/d06/test2.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★★ 2 | 0 2 7 0 -------------------------------------------------------------------------------- /2017/d07/main.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "../aoc-lang.rkt" 2 | (provide (rename-out [#%mb #%module-begin])) 3 | 4 | (define current-stars (make-parameter #f)) 5 | (define current-target-len (make-parameter #f)) 6 | 7 | (define-macro (#%mb (STARS) (NAME . TOKS) ...) 8 | #`(#%module-begin 9 | (current-stars 'STARS) 10 | (current-target-len (length '(NAME ...))) 11 | (handle NAME . TOKS) ...)) 12 | 13 | (define (weights= . xs) (apply =* (map wt xs))) 14 | 15 | (define (unique-weight x xs) 16 | (= 1 (length (filter values (map (curry weights= x) xs))))) 17 | 18 | (define (unbalanced-subsym subsyms) 19 | (findf (curryr unique-weight subsyms) subsyms)) 20 | 21 | (define (balanced-subsym subsyms) 22 | (findf (negate (curryr unique-weight subsyms)) subsyms)) 23 | 24 | (struct prog (sym wt) #:transparent) 25 | 26 | (define/caching (wt sym) 27 | (apply + (map prog-wt (flatten (sym))))) 28 | 29 | (define-macro-cases handle 30 | [(M SYM (NUM) -> . SUBSYMS) 31 | #'(begin (define/caching (SYM [target-weight #f]) 32 | (define subsyms (list . SUBSYMS)) 33 | (if target-weight 34 | (if (apply weights= subsyms) 35 | (displayln (format "~a is bad: needs to be ~a" 'SYM (- NUM (- (wt SYM) target-weight)))) 36 | ((unbalanced-subsym subsyms) (wt (balanced-subsym subsyms)))) 37 | (cons (prog 'SYM NUM) (map app subsyms)))) 38 | (module+ main 39 | (when (= (current-target-len) (length (flatten (SYM)))) 40 | (if (eq? (current-stars) '★) 'SYM (SYM 'find-bad-weight)))))] 41 | [(M SYM (NUM)) #'(M SYM (NUM) ->)]) -------------------------------------------------------------------------------- /2017/d07/test1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ 2 | pbga (66) 3 | xhth (57) 4 | ebii (61) 5 | havc (66) 6 | ktlj (57) 7 | fwft (72) -> ktlj, cntj, xhth 8 | qoyq (66) 9 | padx (45) -> pbga, havc, qoyq 10 | tknk (41) -> ugml, padx, fwft 11 | jptl (61) 12 | ugml (68) -> gyxo, ebii, jptl 13 | gyxo (61) 14 | cntj (57) -------------------------------------------------------------------------------- /2017/d07/test2.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★★ 2 | pbga (66) 3 | xhth (57) 4 | ebii (61) 5 | havc (66) 6 | ktlj (57) 7 | fwft (72) -> ktlj, cntj, xhth 8 | qoyq (66) 9 | padx (45) -> pbga, havc, qoyq 10 | tknk (41) -> ugml, padx, fwft 11 | jptl (61) 12 | ugml (68) -> gyxo, ebii, jptl 13 | gyxo (61) 14 | cntj (57) -------------------------------------------------------------------------------- /2017/d08/main.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "../aoc-lang.rkt" 2 | (provide (rename-out [#%mb #%module-begin])) 3 | 4 | (define-macro (#%mb (STARS) (TOK ...) ...) 5 | #`(#%module-begin 6 | (time 7 | (inst TOK ...) ... 8 | (if (eq? 'STARS '★) (max-arg vals) max-seen)))) 9 | 10 | (define vals (make-hasheq)) 11 | (define (get-val key) (hash-ref! vals key 0)) 12 | (define (max-arg vals) (argmax cdr (hash->list vals))) 13 | (define max-seen 0) 14 | (define (set-val! key updater) 15 | (hash-update! vals key (λ (val) 16 | (define new-val (updater val)) 17 | (set! max-seen (max max-seen new-val)) 18 | new-val) 0)) 19 | 20 | (provide >= <= < > ==) 21 | (define-macro-cases cmp 22 | [(_ ==) #'=] 23 | [(_ !=) #'(negate =)] 24 | [(_ OTHER) #'OTHER]) 25 | 26 | (define-macro-cases updater 27 | [(_ dec) #'-] 28 | [(_ inc) #'+]) 29 | 30 | (provide if) 31 | (define-macro (inst TARGET UPDATE-OP UPDATE-VAL if SRC CMP VAL) 32 | #'(when ((cmp CMP) (get-val 'SRC) VAL) 33 | (set-val! 'TARGET (λ (val) ((updater UPDATE-OP) val UPDATE-VAL))))) 34 | -------------------------------------------------------------------------------- /2017/d08/test1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ 2 | b inc 5 if a > 1 3 | a inc 1 if b < 5 4 | c dec -10 if a >= 1 5 | c inc -20 if c == 10 -------------------------------------------------------------------------------- /2017/d08/test2.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★★ 2 | b inc 5 if a > 1 3 | a inc 1 if b < 5 4 | c dec -10 if a >= 1 5 | c inc -20 if c == 10 -------------------------------------------------------------------------------- /2017/d09/main.rkt: -------------------------------------------------------------------------------- 1 | #lang br/quicklang 2 | (require "../helper.rkt") 3 | (provide read-syntax (rename-out [#%mb #%module-begin])) 4 | 5 | (define (read-syntax path port) 6 | (strip-context #`(module mod "main.rkt" 7 | #,@(port->lines port)))) 8 | 9 | (define-macro (#%mb STARS-LINE SEXP-LINE ...) 10 | #`(#%module-begin 11 | (time (if (eq? (process-line STARS-LINE) '★) 12 | (score (process-line SEXP-LINE)) 13 | (process-line SEXP-LINE #t)) 14 | ...))) 15 | 16 | (define (process-line line [garbage #f]) 17 | (define gchars 0) 18 | (let* ([line (string-trim line)] 19 | [line (regexp-replace* #rx"!." line "")] 20 | [line (regexp-replace* #rx"<.*?>" line 21 | (λ (m) (set! gchars (+ gchars (string-length m) -2)) ""))] 22 | [line (regexp-replace* #rx"," line "")]) 23 | (if garbage gchars (read (open-input-string line))))) 24 | 25 | (define (score tree [start 0]) 26 | (+ (add1 start) (for/sum ([x (in-list tree)]) 27 | (score x (add1 start))))) 28 | -------------------------------------------------------------------------------- /2017/d09/test1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ 2 | {} 3 | {{{}}} 4 | {{},{}} 5 | {{{},{},{{}}}} 6 | {,,,} 7 | {{},{},{},{}} 8 | {{},{},{},{}} 9 | {{},{},{},{}} -------------------------------------------------------------------------------- /2017/d09/test2.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★★ 2 | <> 3 | 4 | <<<<> 5 | <{!>}> 6 | 7 | > 8 | <{o"i!a,<{i -------------------------------------------------------------------------------- /2017/d10/main.rkt: -------------------------------------------------------------------------------- 1 | #lang br/quicklang 2 | (require "../helper.rkt" racket/sequence) 3 | (provide read-syntax (rename-out [#%mb #%module-begin])) 4 | 5 | (define (read-syntax path port) 6 | (define lines (port->lines port)) 7 | (strip-context #`(module mod "main.rkt" 8 | #,@(for/list ([datum (in-port read (open-input-string (car lines)))]) 9 | datum) 10 | #,@(cdr lines)))) 11 | 12 | (define-macro (#%mb STARS RANGE-IN STR) 13 | #`(#%module-begin 14 | (time ((if (eq? 'STARS '★) one-star two-star) RANGE-IN STR)))) 15 | 16 | (define (one-star range-in str) 17 | (define lens (with-input-from-string (string-replace str "," " ") 18 | (λ () (for/list ([len (in-port)]) 19 | len)))) 20 | (define nums (reverse-segments range-in lens)) 21 | (* (first nums) (second nums))) 22 | 23 | (define (two-star range-in str) 24 | (define ascii-chars (map char->integer (string->list str))) 25 | (define nums (reverse-segments range-in (append ascii-chars '(17 31 73 47 23)) #:reps 64)) 26 | (define dense-hash (for/list ([vals (in-slice 16 nums)]) 27 | (apply bitwise-xor vals))) 28 | (string-append* (for/list ([num (in-list dense-hash)]) 29 | (~r num #:base 16 #:min-width 2 #:pad-string "0")))) 30 | 31 | (define (reverse-segments range-in lens #:reps [reps 1]) 32 | (define vec (list->vector (range range-in))) 33 | (for*/fold ([current-position 0] 34 | [skip-size 0]) 35 | ([rep (in-range reps)] 36 | [len (in-list lens)]) 37 | (define posns (for/list ([i (in-range len)]) 38 | (modulo (+ current-position i) range-in))) 39 | (for ([val (in-list (map (λ (posn) (vector-ref vec posn)) posns))] 40 | [posn (in-list (reverse posns))]) 41 | (vector-set! vec posn val)) 42 | (values (+ current-position len skip-size) (add1 skip-size))) 43 | (vector->list vec)) -------------------------------------------------------------------------------- /2017/d10/star1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ 256 ; 4144 2 | 165,1,255,31,87,52,24,113,0,91,148,254,158,2,73,153 -------------------------------------------------------------------------------- /2017/d10/star2.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★★ 256 ; "2f8c3d2100fdd57cec130d928b0fd2dd" 2 | 165,1,255,31,87,52,24,113,0,91,148,254,158,2,73,153 -------------------------------------------------------------------------------- /2017/d10/test1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ 5 2 | 3, 4, 1, 5 -------------------------------------------------------------------------------- /2017/d10/test2.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★★ 256 2 | 1,2,3 -------------------------------------------------------------------------------- /2017/d11/main.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "../aoc-lang.rkt" 2 | (provide (rename-out [#%mb #%module-begin])) 3 | 4 | (define-macro (#%mb (STARS) (HEX ...) ...) 5 | #'(#%module-begin 6 | (time ((if (eq? 'STARS '★) one-star two-star) (list HEX ...)) ...))) 7 | 8 | (define origin '(0 0 0)) 9 | (define ne '(1 0 -1)) (define sw '(-1 0 1)) 10 | (define n '(0 1 -1)) (define s '(0 -1 1)) 11 | (define nw '(-1 1 0)) (define se '(1 -1 0)) 12 | (provide ne sw n s nw se) 13 | 14 | (define (dist h1 h2) (/ (apply + (map abs (map - h1 h2))) 2)) 15 | 16 | (define (one-star hexes) (dist origin (apply map + hexes))) 17 | 18 | (define (two-star hexes) 19 | (for/fold ([sum origin] 20 | [max-dist 0] 21 | #:result max-dist) 22 | ([h (in-list hexes)]) 23 | (define this-sum (map + h sum)) 24 | (values this-sum (max max-dist (dist origin this-sum))))) -------------------------------------------------------------------------------- /2017/d11/test1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ 2 | ne,ne,ne ; is 3 steps away. 3 | ne,ne,sw,sw ; is 0 steps away (back where you started). 4 | ne,ne,s,s ; is 2 steps away (se,se). 5 | se,sw,se,sw,sw ; is 3 steps away (s,s,sw). -------------------------------------------------------------------------------- /2017/d11/test2.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★★ 2 | ne,ne,ne ; is 3 steps away. 3 | ne,ne,sw,sw ; is 0 steps away (back where you started). 4 | ne,ne,s,s ; is 2 steps away (se,se). 5 | se,sw,se,sw,sw ; is 3 steps away (s,s,sw). -------------------------------------------------------------------------------- /2017/d12/main.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "../aoc-lang.rkt" 2 | (require graph) 3 | (provide (rename-out [#%mb #%module-begin])) 4 | 5 | (define-macro (#%mb (STARS) (NUM <-> . NUMS) ...) 6 | #'(#%module-begin 7 | (time 8 | (define g (unweighted-graph/undirected null)) 9 | (for-each (curry add-edge! g NUM) (list . NUMS)) ... 10 | (if (eq? 'STARS '★) 11 | (programs-in-group g 0) 12 | (number-of-groups g (list NUM ...)))))) 13 | 14 | (define (programs-in-group g x) (length (group-of g x))) 15 | 16 | (define (group-of g x) 17 | (define-values (connects _) (dijkstra g x)) 18 | (for/list ([(k v) (in-mutable-hash connects)] 19 | #:when (integer? v)) 20 | k)) 21 | 22 | (define (number-of-groups g nums) 23 | (for/fold ([nums-seen null] 24 | [group-count 0] 25 | #:result group-count) 26 | ([num (in-list nums)] 27 | #:unless (memv num nums-seen)) 28 | (values (append (group-of g num) nums-seen) (add1 group-count)))) 29 | 30 | -------------------------------------------------------------------------------- /2017/d12/test1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ ; 6 2 | 0 <-> 2 3 | 1 <-> 1 4 | 2 <-> 0, 3, 4 5 | 3 <-> 2, 4 6 | 4 <-> 2, 3, 6 7 | 5 <-> 6 8 | 6 <-> 4, 5 -------------------------------------------------------------------------------- /2017/d12/test2.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★★ ; 2 2 | 0 <-> 2 3 | 1 <-> 1 4 | 2 <-> 0, 3, 4 5 | 3 <-> 2, 4 6 | 4 <-> 2, 3, 6 7 | 5 <-> 6 8 | 6 <-> 4, 5 -------------------------------------------------------------------------------- /2017/d13/main.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "../aoc-lang.rkt" 2 | (require (for-syntax racket/string racket/sequence) racket/dict) 3 | (provide (rename-out [#%mb #%module-begin]) ★ ★★) 4 | 5 | (define-macro (#%mb (STARS) (DEPTH: RANGE) ...) 6 | (with-pattern ([(DEPTH ...) 7 | (for/list ([id (in-syntax #'(DEPTH: ...))]) 8 | (string->number (string-trim (symbol->string (syntax->datum id)) ":")))]) 9 | #'(#%module-begin (time (STARS '(DEPTH ...) '(RANGE ...)))))) 10 | 11 | (define (caught? depth range [delay 0]) 12 | (zero? (modulo (+ depth delay) (* 2 (sub1 range))))) 13 | 14 | (define (★ ds rs) 15 | (for/sum ([d (in-list ds)] 16 | [r (in-list rs)] 17 | #:when (caught? d r)) 18 | (* d r))) 19 | 20 | (define (★★ ds rs) 21 | (for/first ([delay (in-naturals)] 22 | #:unless (for/or ([d (in-list ds)] 23 | [r (in-list rs)]) 24 | (caught? d r delay))) 25 | delay)) 26 | -------------------------------------------------------------------------------- /2017/d13/star1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ ; 1612 2 | 0: 3 3 | 1: 2 4 | 2: 4 5 | 4: 6 6 | 6: 4 7 | 8: 6 8 | 10: 5 9 | 12: 6 10 | 14: 8 11 | 16: 8 12 | 18: 8 13 | 20: 6 14 | 22: 12 15 | 24: 8 16 | 26: 8 17 | 28: 10 18 | 30: 9 19 | 32: 12 20 | 34: 8 21 | 36: 12 22 | 38: 12 23 | 40: 12 24 | 42: 14 25 | 44: 14 26 | 46: 12 27 | 48: 12 28 | 50: 12 29 | 52: 12 30 | 54: 14 31 | 56: 12 32 | 58: 14 33 | 60: 14 34 | 62: 14 35 | 64: 14 36 | 70: 10 37 | 72: 14 38 | 74: 14 39 | 76: 14 40 | 78: 14 41 | 82: 14 42 | 86: 17 43 | 88: 18 44 | 96: 26 -------------------------------------------------------------------------------- /2017/d13/star2.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★★ ; 3907994 2 | 0: 3 3 | 1: 2 4 | 2: 4 5 | 4: 6 6 | 6: 4 7 | 8: 6 8 | 10: 5 9 | 12: 6 10 | 14: 8 11 | 16: 8 12 | 18: 8 13 | 20: 6 14 | 22: 12 15 | 24: 8 16 | 26: 8 17 | 28: 10 18 | 30: 9 19 | 32: 12 20 | 34: 8 21 | 36: 12 22 | 38: 12 23 | 40: 12 24 | 42: 14 25 | 44: 14 26 | 46: 12 27 | 48: 12 28 | 50: 12 29 | 52: 12 30 | 54: 14 31 | 56: 12 32 | 58: 14 33 | 60: 14 34 | 62: 14 35 | 64: 14 36 | 70: 10 37 | 72: 14 38 | 74: 14 39 | 76: 14 40 | 78: 14 41 | 82: 14 42 | 86: 17 43 | 88: 18 44 | 96: 26 -------------------------------------------------------------------------------- /2017/d13/test1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ ; 24 2 | 0: 3 3 | 1: 2 4 | 4: 4 5 | 6: 4 -------------------------------------------------------------------------------- /2017/d13/test2.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★★ 2 | 0: 3 3 | 1: 2 4 | 4: 4 5 | 6: 4 -------------------------------------------------------------------------------- /2017/d14/star1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ ; 8214 2 | hxtvlmkl -------------------------------------------------------------------------------- /2017/d14/star2.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★★ ; 1093 2 | hxtvlmkl -------------------------------------------------------------------------------- /2017/d14/test1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ ; 8108 2 | flqrgnkx -------------------------------------------------------------------------------- /2017/d14/test2.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★★ ; 1242 2 | flqrgnkx -------------------------------------------------------------------------------- /2017/d15/main.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "../aoc-lang.rkt" 2 | (provide (rename-out [#%mb #%module-begin]) ★ ★★) 3 | 4 | (define-macro (#%mb (STARS) (Generator X starts with NUM) ...) 5 | #`(#%module-begin 6 | (time (STARS 'NUM ...)))) 7 | 8 | (define (lower-16-bits x) (bitwise-bit-field x 0 16)) 9 | 10 | (define (generator-fold start factor mod) 11 | (for/fold ([val start]) 12 | ([i (in-naturals)] 13 | #:break (and (positive? i) (zero? (modulo val mod)))) 14 | (remainder (* factor val) 2147483647))) 15 | 16 | (define (generator-base a-start b-start rounds [modulo-a 1] [modulo-b 1]) 17 | (for/fold ([a-start a-start] 18 | [b-start b-start] 19 | [sum 0] 20 | #:result sum) 21 | ([i (in-range rounds)]) 22 | (define a (generator-fold a-start 16807 modulo-a)) 23 | (define b (generator-fold b-start 48271 modulo-b)) 24 | (values a b (+ sum (if (= (lower-16-bits a) (lower-16-bits b)) 1 0))))) 25 | 26 | (define (★ a-start b-start) (generator-base a-start b-start (* 40 1000000))) 27 | 28 | (define (★★ a-start b-start) (generator-base a-start b-start (* 5 1000000) 4 8)) -------------------------------------------------------------------------------- /2017/d15/star1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ ; 650 2 | Generator A starts with 783 3 | Generator B starts with 325 -------------------------------------------------------------------------------- /2017/d15/star2.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★★ ; 336 2 | Generator A starts with 783 3 | Generator B starts with 325 -------------------------------------------------------------------------------- /2017/d15/test1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ ; 588 2 | Generator A starts with 65 3 | Generator B starts with 8921 -------------------------------------------------------------------------------- /2017/d15/test2.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★★ ; 309 2 | Generator A starts with 65 3 | Generator B starts with 8921 -------------------------------------------------------------------------------- /2017/d16/test1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ 5 ; "baedc" 2 | s1,x3/4,pe/b -------------------------------------------------------------------------------- /2017/d16/test2.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★★ 5 ; "ceadb" 2 | s1,x3/4,pe/b -------------------------------------------------------------------------------- /2017/d17/main.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "../aoc-lang.rkt" 2 | (provide (rename-out [#%mb #%module-begin]) ★ ★★) 3 | 4 | (define-macro (#%mb (STARS) (STEP-SIZE)) 5 | #`(#%module-begin 6 | (time (STARS STEP-SIZE)))) 7 | 8 | (define (★ step-size) 9 | (define iterations 2017) 10 | (for/fold ([buf '(0)] 11 | [current-pos 0] 12 | #:result (second (member iterations buf))) 13 | ([i (in-range iterations)]) 14 | (define pos (add1 (modulo (+ current-pos step-size) (add1 i)))) 15 | (define-values (head tail) (split-at buf pos)) 16 | (values (append head (list (add1 i)) tail) pos))) 17 | 18 | (define (★★ step-size) 19 | (for/fold ([in-first-pos #f] 20 | [current-pos 0] 21 | #:result in-first-pos) 22 | ([i (in-range (* 50 1e6))]) 23 | (define pos (add1 (modulo (+ current-pos step-size) (add1 i)))) 24 | (values (if (= 1 pos) (add1 i) in-first-pos) pos))) 25 | -------------------------------------------------------------------------------- /2017/d17/star1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ ; 417 2 | 348 -------------------------------------------------------------------------------- /2017/d17/star2.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★★ ; 34334221 2 | 348 -------------------------------------------------------------------------------- /2017/d17/test1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ ; 638 2 | 3 -------------------------------------------------------------------------------- /2017/d18/main.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "../aoc-lang.rkt" 2 | (provide (rename-out [#%mb #%module-begin]) ★ ★★) 3 | 4 | (define-macro (#%mb (STARS) TOKS ...) 5 | #`(#%module-begin 6 | (time (STARS (vector (λ () TOKS) ...))))) 7 | 8 | (define regs (make-hasheq)) 9 | (define last-sound-played (make-parameter #f)) 10 | (struct offset-signal (val)) 11 | (struct end-signal (val)) 12 | 13 | (provide snd set add mul mod rcv jgz) 14 | (define-macro (value VAL) #'(let ([val 'VAL]) (if (number? val) val (hash-ref regs val)))) 15 | (define-macro (snd REG) #'(last-sound-played (hash-ref regs 'REG))) 16 | (define-macro (set REG VAL) #'(hash-set! regs 'REG (value VAL))) 17 | (define-macro (add REG VAL) #'(hash-update! regs 'REG (λ (val) (+ val (value VAL))) 0)) 18 | (define-macro (mul REG VAL) #'(hash-update! regs 'REG (λ (val) (* val (value VAL))) 0)) 19 | (define-macro (mod REG VAL) #'(hash-update! regs 'REG (λ (val) (modulo val (value VAL))) 0)) 20 | (define-macro (rcv REG) #'(unless (zero? (hash-ref regs 'REG)) (raise (last-sound-played)))) 21 | (define-macro (jgz REG VAL) #'(when (positive? (hash-ref regs 'REG)) (raise (offset-signal (value VAL))))) 22 | 23 | (define (★ insts) 24 | (with-handlers ([number? values]) 25 | (for/fold ([offset 0]) 26 | ([i (in-naturals)]) 27 | (with-handlers ([offset-signal? (λ (os) (+ (offset-signal-val os) offset))]) 28 | (define proc (vector-ref insts offset)) 29 | (proc) 30 | (add1 offset))))) 31 | -------------------------------------------------------------------------------- /2017/d18/star1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ 2 | set i 31 3 | set a 1 4 | mul p 17 5 | jgz p p 6 | mul a 2 7 | add i -1 8 | jgz i -2 9 | add a -1 10 | set i 127 11 | set p 464 12 | mul p 8505 13 | mod p a 14 | mul p 129749 15 | add p 12345 16 | mod p a 17 | set b p 18 | mod b 10000 19 | snd b 20 | add i -1 21 | jgz i -9 22 | jgz a 3 23 | rcv b 24 | jgz b -1 25 | set f 0 26 | set i 126 27 | rcv a 28 | rcv b 29 | set p a 30 | mul p -1 31 | add p b 32 | jgz p 4 33 | snd a 34 | set a b 35 | jgz 1 3 36 | snd b 37 | set f 1 38 | add i -1 39 | jgz i -11 40 | snd a 41 | jgz f -16 42 | jgz a -19 -------------------------------------------------------------------------------- /2017/d18/star2.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main2.rkt" ★★ ; 5969 2 | set i 31 3 | set a 1 4 | mul p 17 5 | jgz p p 6 | mul a 2 7 | add i -1 8 | jgz i -2 9 | add a -1 10 | set i 127 11 | set p 464 12 | mul p 8505 13 | mod p a 14 | mul p 129749 15 | add p 12345 16 | mod p a 17 | set b p 18 | mod b 10000 19 | snd b 20 | add i -1 21 | jgz i -9 22 | jgz a 3 23 | rcv b 24 | jgz b -1 25 | set f 0 26 | set i 126 27 | rcv a 28 | rcv b 29 | set p a 30 | mul p -1 31 | add p b 32 | jgz p 4 33 | snd a 34 | set a b 35 | jgz 1 3 36 | snd b 37 | set f 1 38 | add i -1 39 | jgz i -11 40 | snd a 41 | jgz f -16 42 | jgz a -19 -------------------------------------------------------------------------------- /2017/d18/test1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ ; 4 2 | set a 1 3 | add a 2 4 | mul a a 5 | mod a 5 6 | snd a 7 | set a 0 8 | rcv a 9 | jgz a -1 10 | set a 1 11 | jgz a -2 -------------------------------------------------------------------------------- /2017/d18/test2.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main2.rkt" ★★ ; 3 2 | snd 1 3 | snd 2 4 | snd p 5 | rcv a 6 | rcv b 7 | rcv c 8 | rcv d -------------------------------------------------------------------------------- /2017/d19/main.rkt: -------------------------------------------------------------------------------- 1 | #lang br/quicklang 2 | (require "../helper.rkt") 3 | (provide read-syntax (rename-out [#%mb #%module-begin]) ★ ★★) 4 | 5 | (define (read-syntax path port) 6 | (define lines (port->lines port)) 7 | (strip-context #`(module mod "main.rkt" 8 | #,@(for/list ([datum (in-port read (open-input-string (car lines)))]) 9 | datum) 10 | #,@(cdr lines)))) 11 | 12 | (define-macro (#%mb STARS LINE ...) 13 | #'(#%module-begin 14 | (time (STARS (list LINE ...))))) 15 | 16 | (define (traverse lines #:count-steps [count-steps? #f]) 17 | (define chars (for*/hasheqv ([(line lidx) (in-indexed lines)] 18 | [(c cidx) (in-indexed (string->list line))] 19 | #:unless (char=? c #\space)) 20 | (values (+ lidx (* +i cidx)) c))) 21 | (define start (for/first ([k (in-hash-keys chars)] 22 | #:when (zero? (real-part k))) 23 | k)) 24 | (define down 1) (define up -1) (define left -i) (define right +i) 25 | (let loop ([here start][dir down][path null]) 26 | (define here-char (hash-ref chars here #f)) 27 | (cond 28 | [here-char 29 | (define next-dir (if (char=? here-char #\+) 30 | (if (hash-has-key? chars (+ here (* dir right))) (* dir right) (* dir left)) 31 | dir)) 32 | (loop (+ here next-dir) next-dir (cons here-char path))] 33 | [count-steps? (length path)] 34 | [else (list->string (filter char-alphabetic? (reverse path)))]))) 35 | 36 | (define (★ lines) (traverse lines)) 37 | 38 | (define (★★ lines) (traverse lines #:count-steps #t)) 39 | 40 | -------------------------------------------------------------------------------- /2017/d19/test1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ ; "ABCDEF" 2 | | 3 | | +--+ 4 | A | C 5 | F---|----E|--+ 6 | | | | D 7 | +B-+ +--+ 8 | -------------------------------------------------------------------------------- /2017/d19/test2.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★★ ; 38 2 | | 3 | | +--+ 4 | A | C 5 | F---|----E|--+ 6 | | | | D 7 | +B-+ +--+ 8 | -------------------------------------------------------------------------------- /2017/d20/main.rkt: -------------------------------------------------------------------------------- 1 | #lang br/quicklang 2 | (require "../helper.rkt") 3 | (provide read-syntax (rename-out [#%mb #%module-begin]) ★ ★★) 4 | 5 | (define (read-syntax path port) 6 | (define str (let* ([str (port->string port)] 7 | [str (string-replace str "," " ")] 8 | [str (string-replace str "<" "(")] 9 | [str (string-replace str ">" ")")]) 10 | str)) 11 | (strip-context #`(module mod "main.rkt" 12 | #,@(for/list ([line (in-lines (open-input-string str))]) 13 | (for/list ([datum (in-port read (open-input-string line))]) 14 | datum))))) 15 | 16 | (define-macro (#%mb (STARS) (p= PNUMS v= VNUMS a= ANUMS) ...) 17 | #`(#%module-begin 18 | (time (STARS (particle 'PNUMS 'VNUMS 'ANUMS) ...)))) 19 | 20 | (struct particle (pos vel acc) #:transparent) 21 | 22 | (define (do-tick p) 23 | (define next-vel (map + (particle-vel p) (particle-acc p))) 24 | (define next-pos (map + (particle-pos p) next-vel)) 25 | (particle next-pos next-vel (particle-acc p))) 26 | 27 | (define (dist p) (apply + (map abs (particle-pos p)))) 28 | 29 | (define (remove-collisions particles) 30 | (define (find-duplicate-particle ps) (check-duplicates ps #:key particle-pos)) 31 | (for/fold ([ps particles] 32 | [dup (find-duplicate-particle particles)] 33 | #:result ps) 34 | ([i (in-naturals)] 35 | #:break (not dup)) 36 | (values (filter-not (λ (p) (andmap = (particle-pos dup) (particle-pos p))) ps) 37 | (find-duplicate-particle ps)))) 38 | 39 | (define (closest particles #:collisions [collisions? #f]) 40 | (for/fold ([particles particles] 41 | #:result (if collisions? 42 | (length particles) 43 | (argmin cdr (for/list ([(p pidx) (in-indexed particles)]) 44 | (cons pidx (dist p)))))) 45 | ([i (in-range 1000)]) 46 | ((if collisions? remove-collisions values) (map do-tick particles)))) 47 | 48 | (define (★ . particles) (closest particles)) 49 | 50 | (define (★★ . particles) (closest particles #:collisions #t)) 51 | -------------------------------------------------------------------------------- /2017/d20/test1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ ; 0 2 | p=< 3,0,0>, v=< 2,0,0>, a=<-1,0,0> 3 | p=< 4,0,0>, v=< 0,0,0>, a=<-2,0,0> -------------------------------------------------------------------------------- /2017/d20/test2.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★★ 2 | p=<-6,0,0>, v=< 3,0,0>, a=< 0,0,0> 3 | p=<-4,0,0>, v=< 2,0,0>, a=< 0,0,0> ; -6 -5 -4 -3 -2 -1 0 1 2 3 4 | p=<-2,0,0>, v=< 1,0,0>, a=< 0,0,0> ; (0) (1) (2) (3) 5 | p=< 3,0,0>, v=<-1,0,0>, a=< 0,0,0> -------------------------------------------------------------------------------- /2017/d21/main.rkt: -------------------------------------------------------------------------------- 1 | #lang br/quicklang 2 | (require "../helper.rkt" racket/sequence) 3 | (provide read-syntax (rename-out [#%mb #%module-begin]) ★ ★★) 4 | 5 | (define (read-syntax path port) 6 | (define lines (port->lines port)) 7 | (strip-context #`(module mod "main.rkt" 8 | #,(for/list ([datum (in-port read (open-input-string (car lines)))]) 9 | datum) 10 | #,@(for/list ([line (in-list (cdr lines))]) 11 | (for/list ([datum (string-split line)]) 12 | datum))))) 13 | 14 | (define-macro (#%mb (STARS ITERATIONS) (LH "=>" RH) ...) 15 | #`(#%module-begin 16 | (time (STARS ITERATIONS '(LH . RH) ...)))) 17 | 18 | (define (charify str) (map string->list (string-split str "/"))) 19 | 20 | (define (grid-size grid) (length (car grid))) 21 | 22 | (define (grid-split grid size) 23 | (append* 24 | (for/list ([rowset (in-slice size grid)]) 25 | (apply map list (map (λ (row) (slice-at row size)) rowset))))) 26 | 27 | (define (enhance-grid grid rules) 28 | (let/ec exit 29 | (for*/fold ([rotations (list grid)]) 30 | ([i (in-range 4)]) 31 | (define rot (apply map list (reverse (car rotations)))) 32 | (cond 33 | [(hash-ref rules rot (λ () (hash-ref rules (map reverse rot) #f))) => exit] 34 | [else (cons rot rotations)])))) 35 | 36 | (define (join-grids grids) 37 | (define side (sqrt (length grids))) 38 | (append* 39 | (for/list ([gridset (in-slice side grids)]) 40 | (apply map append gridset)))) 41 | 42 | (define (★ iterations . rulepairs) 43 | (define rules (for/hash ([rp (in-list rulepairs)]) 44 | (values (charify (car rp)) (charify (cdr rp))))) 45 | (for/fold ([grid (charify ".#./..#/###")] 46 | #:result (count (λ (c) (char=? c #\#)) (flatten grid))) 47 | ([i (in-range iterations)]) 48 | (define grid-pieces (grid-split grid (if (even? (grid-size grid)) 2 3))) 49 | (join-grids (map (λ (gp) (enhance-grid gp rules)) grid-pieces)))) 50 | 51 | (define ★★ ★) -------------------------------------------------------------------------------- /2017/d21/test1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ 2 ; 12 2 | ../.# => ##./#../... 3 | .#./..#/### => #..#/..../..../#..# -------------------------------------------------------------------------------- /2017/d22/star1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ ; 5411 2 | #.#.#.##.#.##.###.#.###.# 3 | .#..#.....#..#######.##.# 4 | ......###..##..###..#...# 5 | ##....#.#.#....#..#..#..# 6 | #..#....#.##.#.#..#..#.#. 7 | ..##..##.##..##...#...### 8 | ..#.#....#..####.##.##... 9 | ###...#.#...#.######...#. 10 | ..#####...###..#####.#.## 11 | ...#..#......####.##..#.# 12 | #...##..#.#####...#.##... 13 | ..#.#.###.##.##....##.### 14 | ##.##...###....#######.#. 15 | #.#...#.#..#.##..##..##.# 16 | .#...###...#..#..####.... 17 | ####...#...##.####..#.#.. 18 | ......#.....##.#.##....## 19 | ###.......####..##.#.##.. 20 | ....###.....##.##..###.#. 21 | .##..##.#.###.###..#.###. 22 | ..#..##.######.##........ 23 | #..#.#..#.###....##.##..# 24 | .##.#.#...######...##.##. 25 | ##..#..#..##.#.#..#..#### 26 | #######.#.######.#.....## -------------------------------------------------------------------------------- /2017/d22/star2.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★★ ; 2511416 2 | #.#.#.##.#.##.###.#.###.# 3 | .#..#.....#..#######.##.# 4 | ......###..##..###..#...# 5 | ##....#.#.#....#..#..#..# 6 | #..#....#.##.#.#..#..#.#. 7 | ..##..##.##..##...#...### 8 | ..#.#....#..####.##.##... 9 | ###...#.#...#.######...#. 10 | ..#####...###..#####.#.## 11 | ...#..#......####.##..#.# 12 | #...##..#.#####...#.##... 13 | ..#.#.###.##.##....##.### 14 | ##.##...###....#######.#. 15 | #.#...#.#..#.##..##..##.# 16 | .#...###...#..#..####.... 17 | ####...#...##.####..#.#.. 18 | ......#.....##.#.##....## 19 | ###.......####..##.#.##.. 20 | ....###.....##.##..###.#. 21 | .##..##.#.###.###..#.###. 22 | ..#..##.######.##........ 23 | #..#.#..#.###....##.##..# 24 | .##.#.#...######...##.##. 25 | ##..#..#..##.#.#..#..#### 26 | #######.#.######.#.....## -------------------------------------------------------------------------------- /2017/d22/test1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ ; 5587 2 | ..# 3 | #.. 4 | ... 5 | -------------------------------------------------------------------------------- /2017/d22/test2.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★★ ; 2511944 2 | ..# 3 | #.. 4 | ... 5 | -------------------------------------------------------------------------------- /2017/d23/main.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "../aoc-lang.rkt" 2 | (provide (rename-out [#%mb #%module-begin]) ★ ★★) 3 | 4 | (define-macro (#%mb (STARS) TOKS ...) 5 | #`(#%module-begin 6 | (time (STARS (vector (λ () TOKS) ...))))) 7 | 8 | (define regs (make-hasheq)) 9 | 10 | (provide set mul sub jnz) 11 | (define-macro (value VAL) #'(let ([val 'VAL]) (if (number? val) val (hash-ref! regs val 0)))) 12 | (define-macro (set REG VAL) #'(hash-set! regs 'REG (value VAL))) 13 | (define-macro (sub REG VAL) #'(hash-update! regs 'REG (λ (val) (- val (value VAL))) 0)) 14 | (define-macro (mul REG VAL) #'(begin (hash-update! regs 'mul-count add1 0) 15 | (hash-update! regs 'REG (λ (val) (* val (value VAL))) 0))) 16 | (define-macro (jnz REG VAL) #'(when (not (zero? (value REG))) (raise (value VAL)))) 17 | 18 | (define (★ insts [final-key 'mul-count]) 19 | (for/fold ([offset 0] 20 | #:result (hash-ref regs final-key)) 21 | ([i (in-naturals)] 22 | #:break (not (<= 0 offset (sub1 (vector-length insts))))) 23 | (with-handlers ([integer? (λ (num) (+ num offset))]) 24 | (define inst (vector-ref insts offset)) 25 | (inst) 26 | (add1 offset)))) 27 | 28 | (define (★★ insts) 29 | (hash-set! regs 'a 1) 30 | (★ insts 'h)) -------------------------------------------------------------------------------- /2017/d23/star1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ ; 8281 2 | set b 93 3 | set c b 4 | jnz a 2 5 | jnz 1 5 6 | mul b 100 7 | sub b -100000 8 | set c b 9 | sub c -17000 10 | set f 1 11 | set d 2 12 | set e 2 13 | set g d 14 | mul g e 15 | sub g b 16 | jnz g 2 17 | set f 0 18 | sub e -1 19 | set g e 20 | sub g b 21 | jnz g -8 22 | sub d -1 23 | set g d 24 | sub g b 25 | jnz g -13 26 | jnz f 2 27 | sub h -1 28 | set g b 29 | sub g c 30 | jnz g 2 31 | jnz 1 3 32 | sub b -17 33 | jnz 1 -23 -------------------------------------------------------------------------------- /2017/d23/star2.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★★ ; to be fair, this question had nothing to do with Racket 2 | set h 911 -------------------------------------------------------------------------------- /2017/d24/main.rkt: -------------------------------------------------------------------------------- 1 | #lang br/quicklang 2 | (require "../helper.rkt") 3 | (provide read-syntax (rename-out [#%mb #%module-begin]) ★ ★★) 4 | 5 | (define (read-syntax path port) 6 | (define lines (port->lines port)) 7 | (strip-context #`(module mod "main.rkt" 8 | #,@(for/list ([datum (in-port read (open-input-string (car lines)))]) 9 | datum) 10 | #,@(map (λ (ln) (apply cons (map string->number (string-split ln "/")))) (cdr lines))))) 11 | 12 | (define-macro (#%mb STARS DOMS ...) 13 | #'(#%module-begin 14 | (time (STARS '(DOMS ...))))) 15 | 16 | (define (find-dominoes-with-val dominoes val) 17 | (filter (λ (d) (or (= (car d) val) (= (cdr d) val))) dominoes)) 18 | 19 | (define (other-val-on-domino dom val) 20 | ((if (= (car dom) val) cdr car) dom)) 21 | 22 | (define (remove-dom doms dom) 23 | (filter-not (λ (d) (equal? d dom)) doms)) 24 | 25 | (define (bridges dominoes [current-val 0] [current-bridge null]) 26 | (define doms (find-dominoes-with-val dominoes current-val)) 27 | (if (null? doms) 28 | (list (flatten current-bridge)) 29 | (append-map (λ (dom) (bridges (remove-dom dominoes dom) 30 | (other-val-on-domino dom current-val) 31 | (cons dom current-bridge))) doms))) 32 | 33 | (define (strongest bridges) 34 | (apply max (map (λ (br) (apply + br)) bridges))) 35 | 36 | (define (★ dominoes) 37 | (strongest (bridges dominoes))) 38 | 39 | (define (★★ dominoes) 40 | (define brs (bridges dominoes)) 41 | (define maxlen (apply max (map length brs))) 42 | (strongest (filter (λ (b) (= maxlen (length b))) brs))) 43 | 44 | -------------------------------------------------------------------------------- /2017/d24/star1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ ; 1868 2 | 25/13 3 | 4/43 4 | 42/42 5 | 39/40 6 | 17/18 7 | 30/7 8 | 12/12 9 | 32/28 10 | 9/28 11 | 1/1 12 | 16/7 13 | 47/43 14 | 34/16 15 | 39/36 16 | 6/4 17 | 3/2 18 | 10/49 19 | 46/50 20 | 18/25 21 | 2/23 22 | 3/21 23 | 5/24 24 | 46/26 25 | 50/19 26 | 26/41 27 | 1/50 28 | 47/41 29 | 39/50 30 | 12/14 31 | 11/19 32 | 28/2 33 | 38/47 34 | 5/5 35 | 38/34 36 | 39/39 37 | 17/34 38 | 42/16 39 | 32/23 40 | 13/21 41 | 28/6 42 | 6/20 43 | 1/30 44 | 44/21 45 | 11/28 46 | 14/17 47 | 33/33 48 | 17/43 49 | 31/13 50 | 11/21 51 | 31/39 52 | 0/9 53 | 13/50 54 | 10/14 55 | 16/10 56 | 3/24 57 | 7/0 58 | 50/50 -------------------------------------------------------------------------------- /2017/d24/star2.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★★ ; 1841 2 | 25/13 3 | 4/43 4 | 42/42 5 | 39/40 6 | 17/18 7 | 30/7 8 | 12/12 9 | 32/28 10 | 9/28 11 | 1/1 12 | 16/7 13 | 47/43 14 | 34/16 15 | 39/36 16 | 6/4 17 | 3/2 18 | 10/49 19 | 46/50 20 | 18/25 21 | 2/23 22 | 3/21 23 | 5/24 24 | 46/26 25 | 50/19 26 | 26/41 27 | 1/50 28 | 47/41 29 | 39/50 30 | 12/14 31 | 11/19 32 | 28/2 33 | 38/47 34 | 5/5 35 | 38/34 36 | 39/39 37 | 17/34 38 | 42/16 39 | 32/23 40 | 13/21 41 | 28/6 42 | 6/20 43 | 1/30 44 | 44/21 45 | 11/28 46 | 14/17 47 | 33/33 48 | 17/43 49 | 31/13 50 | 11/21 51 | 31/39 52 | 0/9 53 | 13/50 54 | 10/14 55 | 16/10 56 | 3/24 57 | 7/0 58 | 50/50 -------------------------------------------------------------------------------- /2017/d24/test1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ ; 31 2 | 0/2 3 | 2/2 4 | 2/3 5 | 3/4 6 | 3/5 7 | 0/1 8 | 10/1 9 | 9/10 10 | -------------------------------------------------------------------------------- /2017/d24/test2.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★★ ; 19 2 | 0/2 3 | 2/2 4 | 2/3 5 | 3/4 6 | 3/5 7 | 0/1 8 | 10/1 9 | 9/10 10 | -------------------------------------------------------------------------------- /2017/d25/main.rkt: -------------------------------------------------------------------------------- 1 | #lang br/quicklang 2 | (require "../helper.rkt") 3 | (provide read-syntax (rename-out [#%mb #%module-begin]) ★ ★★) 4 | 5 | (define (read-syntax path port) 6 | (define lines (for/list ([ln (in-lines port)]) 7 | (string-trim ln #px"\\W"))) 8 | (strip-context #`(module mod "main.rkt" 9 | #,(for/list ([datum (in-port read (open-input-string (car lines)))]) 10 | datum) 11 | #,(list 12 | (string->symbol (last (string-split (second lines)))) 13 | (string->number (car (take-right (string-split (third lines)) 2)))) 14 | #,@(for/list ([state-line-group (in-list (filter-split (cdddr lines) (λ (ln) (equal? ln ""))))]) 15 | (for/list ([state-line (in-list state-line-group)]) 16 | (read (open-input-string (last (string-split state-line))))))))) 17 | 18 | (define-macro (#%mb (STARS) (STATE STEPS) (TOK ...) ...) 19 | #`(#%module-begin 20 | (time (STARS STATE STEPS (TOK ...) ...)))) 21 | 22 | (define-macro (★ STATE STEPS (TOK ...) ...) 23 | #'(begin 24 | (define-state TOK ...) ... 25 | (run STATE STEPS))) 26 | 27 | (define tape (make-hasheqv)) 28 | 29 | (define (read-tape pos) (hash-ref! tape pos 0)) 30 | (define (write-tape pos val) (hash-set! tape pos val)) 31 | (define (change-pos pos dir) (+ pos (if (eq? dir 'left) -1 1))) 32 | 33 | (define-macro (define-state STATE 0 VAL0 DIR0 THEN0 1 VAL1 DIR1 THEN1) 34 | #'(define (STATE pos) 35 | (case (read-tape pos) 36 | [(0) 37 | (write-tape pos VAL0) 38 | (values (change-pos pos 'DIR0) THEN0)] 39 | [(1) 40 | (write-tape pos VAL1) 41 | (values (change-pos pos 'DIR1) THEN1)]))) 42 | 43 | (define (run state steps) 44 | (for/fold ([pos 0] 45 | [state state] 46 | #:result (apply + (hash-values tape))) 47 | ([step (in-range steps)]) 48 | (state pos))) 49 | -------------------------------------------------------------------------------- /2017/d25/star1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ ; 5744 2 | Begin in state A. 3 | Perform a diagnostic checksum after 12261543 steps. 4 | 5 | In state A: 6 | If the current value is 0: 7 | - Write the value 1. 8 | - Move one slot to the right. 9 | - Continue with state B. 10 | If the current value is 1: 11 | - Write the value 0. 12 | - Move one slot to the left. 13 | - Continue with state C. 14 | 15 | In state B: 16 | If the current value is 0: 17 | - Write the value 1. 18 | - Move one slot to the left. 19 | - Continue with state A. 20 | If the current value is 1: 21 | - Write the value 1. 22 | - Move one slot to the right. 23 | - Continue with state C. 24 | 25 | In state C: 26 | If the current value is 0: 27 | - Write the value 1. 28 | - Move one slot to the right. 29 | - Continue with state A. 30 | If the current value is 1: 31 | - Write the value 0. 32 | - Move one slot to the left. 33 | - Continue with state D. 34 | 35 | In state D: 36 | If the current value is 0: 37 | - Write the value 1. 38 | - Move one slot to the left. 39 | - Continue with state E. 40 | If the current value is 1: 41 | - Write the value 1. 42 | - Move one slot to the left. 43 | - Continue with state C. 44 | 45 | In state E: 46 | If the current value is 0: 47 | - Write the value 1. 48 | - Move one slot to the right. 49 | - Continue with state F. 50 | If the current value is 1: 51 | - Write the value 1. 52 | - Move one slot to the right. 53 | - Continue with state A. 54 | 55 | In state F: 56 | If the current value is 0: 57 | - Write the value 1. 58 | - Move one slot to the right. 59 | - Continue with state A. 60 | If the current value is 1: 61 | - Write the value 1. 62 | - Move one slot to the right. 63 | - Continue with state E. -------------------------------------------------------------------------------- /2017/d25/test1.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "main.rkt" ★ ; 3 2 | Begin in state A. 3 | Perform a diagnostic checksum after 6 steps. 4 | 5 | In state A: 6 | If the current value is 0: 7 | - Write the value 1. 8 | - Move one slot to the right. 9 | - Continue with state B. 10 | If the current value is 1: 11 | - Write the value 0. 12 | - Move one slot to the left. 13 | - Continue with state B. 14 | 15 | In state B: 16 | If the current value is 0: 17 | - Write the value 1. 18 | - Move one slot to the left. 19 | - Continue with state A. 20 | If the current value is 1: 21 | - Write the value 1. 22 | - Move one slot to the right. 23 | - Continue with state A. -------------------------------------------------------------------------------- /2017/helper.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require syntax/strip-context sugar) 3 | (provide (all-defined-out) (all-from-out syntax/strip-context sugar)) 4 | 5 | (define ★ '★) (define ★★ '★★) 6 | 7 | (define (port->datums port) 8 | (for/list ([datum (in-port read port)]) 9 | datum)) 10 | 11 | (define (number->digits num) 12 | (for/list ([c (in-string (number->string num))]) 13 | (string->number (string c)))) 14 | 15 | (define (dirname path) 16 | (define-values (dir name _) (split-path path)) 17 | dir) 18 | 19 | (define (=* . xs) 20 | (or (< (length xs) 2) (apply = xs))) 21 | 22 | (define (app x . args) (apply x args)) -------------------------------------------------------------------------------- /2018/01-test.txt: -------------------------------------------------------------------------------- 1 | +1 2 | -2 3 | +3 4 | +1 -------------------------------------------------------------------------------- /2018/01.rkt: -------------------------------------------------------------------------------- 1 | #lang debug br 2 | (require racket/set) 3 | 4 | (define fp (open-input-file "01.txt")) 5 | 6 | (define frequencies 7 | (map string->number (port->lines fp))) 8 | 9 | (define (★) 10 | (apply + frequencies)) 11 | 12 | (define (★★) 13 | (for/fold ([last-sum 0] 14 | [sums (set)] 15 | #:result last-sum) 16 | ([freq (in-cycle frequencies)] 17 | #:break (set-member? sums last-sum)) 18 | (values (+ freq last-sum) (set-add sums last-sum)))) 19 | 20 | (module+ test 21 | (require rackunit) 22 | (check-equal? (time (★)) 454) 23 | (check-equal? (time (★★)) 566)) -------------------------------------------------------------------------------- /2018/02-test.txt: -------------------------------------------------------------------------------- 1 | abcde 2 | fghij 3 | klmno 4 | pqrst 5 | fguij 6 | axcye 7 | wvxyz -------------------------------------------------------------------------------- /2018/02.rkt: -------------------------------------------------------------------------------- 1 | #lang debug br 2 | 3 | (define fp (open-input-file "02.txt")) 4 | 5 | (define ids 6 | (map string-trim (port->lines fp))) 7 | 8 | (define ((cluster len) chars) 9 | (for/or ([group (in-list (group-by values chars char=?))]) 10 | (= len (length group)))) 11 | 12 | (define (★) 13 | (define charss (map string->list ids)) 14 | (define twos (length (filter (cluster 2) charss))) 15 | (define threes (length (filter (cluster 3) charss))) 16 | (* twos threes)) 17 | 18 | (define (differ-by-one? id id2) 19 | (= (length (common-chars id id2)) (sub1 (string-length id)))) 20 | 21 | (define (common-chars id id2) 22 | (for/list ([c (in-string id)] 23 | [c2 (in-string id2)] 24 | #:when (char=? c c2)) 25 | c)) 26 | 27 | (define (★★) 28 | (list->string 29 | (for*/first ([id (in-list ids)] 30 | [id2 (in-list (cdr ids))] 31 | #:when (differ-by-one? id id2)) 32 | (common-chars id id2)))) 33 | 34 | (module+ test 35 | (require rackunit) 36 | (check-equal? (time (★)) 6696) 37 | (check-equal? (time (★★)) "bvnfawcnyoeyudzrpgslimtkj")) -------------------------------------------------------------------------------- /2018/03-test.txt: -------------------------------------------------------------------------------- 1 | #1 @ 1,3: 4x4 2 | #2 @ 3,1: 4x4 3 | #3 @ 5,5: 2x2 -------------------------------------------------------------------------------- /2018/03.rkt: -------------------------------------------------------------------------------- 1 | #lang debug br 2 | 3 | (define fp (open-input-file "03.txt")) 4 | 5 | (struct pt (x y) #:transparent) 6 | (struct rect (ul lr) #:transparent) 7 | 8 | (define (parse-claim ln) 9 | (match-define (list left top width height) 10 | (map string->number (cdr (regexp-match #px"(\\d+),(\\d+): (\\d+)x(\\d+)" ln)))) 11 | (rect (pt left top) (pt (+ left width) (+ top height)))) 12 | 13 | (define claims 14 | (map parse-claim (port->lines fp))) 15 | 16 | (define coverage (make-hash)) 17 | (for ([(claim idx) (in-indexed claims)]) 18 | (define cidx (add1 idx)) 19 | (match-define (rect (pt left top) (pt right bottom)) claim) 20 | (for* ([x (in-range left right)] 21 | [y (in-range top bottom)]) 22 | (hash-update! coverage (pt x y) (λ (cidxs) (cons cidx cidxs)) empty))) 23 | 24 | (define (★) 25 | (for/sum ([cidxs (in-list (hash-values coverage))] 26 | #:when (<= 2 (length cidxs))) 27 | 1)) 28 | 29 | (define (★★) 30 | (define cidxss (hash-values coverage)) 31 | (for/first ([cidx (in-range 1 (add1 (length claims)))] 32 | #:when (for/and ([cidxs (in-list cidxss)] 33 | #:when (memv cidx cidxs)) 34 | (= (length cidxs) 1))) 35 | cidx)) 36 | 37 | (module+ test 38 | (require rackunit) 39 | (check-equal? (time (★)) 110827) 40 | (check-equal? (time (★★)) 116)) -------------------------------------------------------------------------------- /2018/04-test.txt: -------------------------------------------------------------------------------- 1 | [1518-11-01 00:00] Guard #10 begins shift 2 | [1518-11-01 00:05] falls asleep 3 | [1518-11-01 00:25] wakes up 4 | [1518-11-01 00:30] falls asleep 5 | [1518-11-01 00:55] wakes up 6 | [1518-11-01 23:58] Guard #99 begins shift 7 | [1518-11-02 00:40] falls asleep 8 | [1518-11-02 00:50] wakes up 9 | [1518-11-03 00:05] Guard #10 begins shift 10 | [1518-11-03 00:24] falls asleep 11 | [1518-11-03 00:29] wakes up 12 | [1518-11-04 00:02] Guard #99 begins shift 13 | [1518-11-04 00:36] falls asleep 14 | [1518-11-04 00:46] wakes up 15 | [1518-11-05 00:03] Guard #99 begins shift 16 | [1518-11-05 00:45] falls asleep 17 | [1518-11-05 00:55] wakes up -------------------------------------------------------------------------------- /2018/04.rkt: -------------------------------------------------------------------------------- 1 | #lang debug br 2 | (require sugar/list gregor) 3 | 4 | (define fp (open-input-file "04.txt")) 5 | 6 | (define (parse-rec ln) 7 | (match (regexp-match #px"^(\\[.*?\\]) (.*)$" ln) 8 | [(list _ datestr desc) (cons 9 | (parse-datetime datestr "[yyyy-MM-dd HH:mm]") 10 | desc)])) 11 | 12 | (define recs 13 | (map parse-rec (port->lines fp))) 14 | 15 | (define (make-interval-hash recs) 16 | (define intervals (make-hasheqv)) 17 | (for/fold ([guard #f] 18 | [recs (sort recs datetimeminutes dt) (->minutes other-dt))) 26 | (hash-update! intervals guard (λ (val) (append mins val)) null) 27 | (values guard (drop recs 2))] 28 | [(cons _ (regexp #px"\\d+" m)) (values (string->number (car m)) (cdr recs))]))) 29 | 30 | (define (sleepiest h) 31 | (argmax (compose1 length cdr) (hash->list h))) 32 | 33 | (define (most-common-minute gms) 34 | (argmax cdr (hash->list (frequency-hash gms)))) 35 | 36 | (define h (make-interval-hash recs)) 37 | (define (★) 38 | (match (sleepiest h) 39 | [(cons guard minutes) 40 | (match (most-common-minute minutes) 41 | [(cons min _) (* guard min)])])) 42 | 43 | (define (★★) 44 | (define guard-min-freqs 45 | (for/list ([(k v) (in-hash h)]) 46 | (match-define (cons min freq) (most-common-minute v)) 47 | (list k min freq))) 48 | (apply * (take (argmax third guard-min-freqs) 2))) 49 | 50 | (module+ test 51 | (require rackunit) 52 | (check-equal? (time (★)) 99759) 53 | (check-equal? (time (★★)) 97884)) -------------------------------------------------------------------------------- /2018/05-test.txt: -------------------------------------------------------------------------------- 1 | dabAcCaCBAcCcaDA -------------------------------------------------------------------------------- /2018/05.rkt: -------------------------------------------------------------------------------- 1 | #lang debug br 2 | (require racket/file racket/set) 3 | 4 | (define fp (open-input-file "05.txt")) 5 | 6 | (define fpbs (port->bytes fp)) 7 | 8 | (define-macro (for/mutable-list (SEQ ...) . BODY) 9 | #'(let loop ([mprs null][xs (reverse (for/list (SEQ ...) . BODY))]) 10 | (if (empty? xs) 11 | mprs 12 | (loop (mcons (car xs) mprs) (cdr xs))))) 13 | 14 | (define (reactive-pair? mprs) 15 | (= 32 (abs (- (mcar (mcdr mprs)) (mcar (mcdr (mcdr mprs))))))) 16 | 17 | (define (react [fpbs fpbs]) 18 | (define mprs0 (mcons #f (for/mutable-list ([b (in-bytes fpbs)]) 19 | b))) 20 | (let loop ([mprs mprs0][found? #false]) 21 | (cond 22 | [(or (empty? mprs) 23 | (empty? (mcdr mprs)) 24 | (empty? (mcdr (mcdr mprs)))) 25 | (if found? (loop mprs0 #false) mprs0)] 26 | [(reactive-pair? mprs) 27 | (set-mcdr! mprs (mcdr (mcdr (mcdr mprs)))) 28 | (loop (mcdr mprs) #true)] 29 | [else (loop (mcdr mprs) found?)])) 30 | (for/sum ([val (in-mlist (mcdr mprs0))]) 31 | 1)) 32 | 33 | (define (★) 34 | (react fpbs)) 35 | 36 | (define possible-units 37 | (map char->integer (remove-duplicates (map char-upcase (map integer->char (bytes->list fpbs))) char=?))) 38 | 39 | (define (remove-unit fbps unit) 40 | (regexp-replace* (regexp (format "[~a~a]" (integer->char unit) (integer->char (+ unit 32)))) fbps "")) 41 | 42 | (define (★★) 43 | (apply min (for/list ([unit (in-list possible-units)]) 44 | (react (remove-unit fpbs unit))))) 45 | 46 | (module+ test 47 | (require rackunit) 48 | (check-equal? (time (★)) 10564) 49 | (check-equal? (time (★★)) 6336)) -------------------------------------------------------------------------------- /2018/06-test.txt: -------------------------------------------------------------------------------- 1 | 1, 1 2 | 1, 6 3 | 8, 3 4 | 3, 4 5 | 5, 5 6 | 8, 9 -------------------------------------------------------------------------------- /2018/06.txt: -------------------------------------------------------------------------------- 1 | 165, 169 2 | 334, 217 3 | 330, 227 4 | 317, 72 5 | 304, 232 6 | 115, 225 7 | 323, 344 8 | 161, 204 9 | 316, 259 10 | 63, 250 11 | 280, 205 12 | 84, 282 13 | 271, 158 14 | 190, 296 15 | 106, 349 16 | 171, 178 17 | 203, 108 18 | 89, 271 19 | 193, 254 20 | 111, 210 21 | 341, 343 22 | 349, 311 23 | 143, 172 24 | 170, 307 25 | 128, 157 26 | 183, 315 27 | 211, 297 28 | 74, 281 29 | 119, 164 30 | 266, 345 31 | 184, 62 32 | 96, 142 33 | 134, 61 34 | 117, 52 35 | 318, 72 36 | 338, 287 37 | 61, 215 38 | 323, 255 39 | 93, 171 40 | 325, 249 41 | 183, 171 42 | 71, 235 43 | 329, 306 44 | 322, 219 45 | 151, 298 46 | 180, 255 47 | 336, 291 48 | 72, 300 49 | 223, 286 50 | 179, 257 -------------------------------------------------------------------------------- /2018/07-test.txt: -------------------------------------------------------------------------------- 1 | Step C must be finished before step A can begin. 2 | Step C must be finished before step F can begin. 3 | Step A must be finished before step B can begin. 4 | Step A must be finished before step D can begin. 5 | Step B must be finished before step E can begin. 6 | Step D must be finished before step E can begin. 7 | Step F must be finished before step E can begin. -------------------------------------------------------------------------------- /2018/08-test.txt: -------------------------------------------------------------------------------- 1 | 2 3 0 3 10 11 12 1 1 0 1 99 2 1 1 2 -------------------------------------------------------------------------------- /2018/08.rkt: -------------------------------------------------------------------------------- 1 | #lang debug br 2 | 3 | (define ps "08.txt") 4 | 5 | (define (★) 6 | (define (node-value) 7 | (define child-count (read)) 8 | (define metadata-count (read)) 9 | (+ (for/sum ([c (in-range child-count)]) 10 | (node-value)) 11 | (for/sum ([c (in-range metadata-count)]) 12 | (read)))) 13 | (with-input-from-file ps node-value)) 14 | 15 | (define (★★) 16 | (define (node-value) 17 | (define child-count (read)) 18 | (define metadata-count (read)) 19 | (define child-values (for/list ([c (in-range child-count)]) 20 | (node-value))) 21 | (define metadatas (for/list ([c (in-range metadata-count)]) 22 | (read))) 23 | (if (zero? child-count) 24 | (apply + metadatas) 25 | (for/sum ([md (in-list metadatas)] 26 | #:when (<= 1 md child-count)) 27 | (list-ref child-values (sub1 md))))) 28 | (with-input-from-file ps node-value)) 29 | 30 | (module+ test 31 | (require rackunit) 32 | (check-equal? (time (★)) 44838) 33 | (check-equal? (time (★★)) 22198)) -------------------------------------------------------------------------------- /2018/09-test.txt: -------------------------------------------------------------------------------- 1 | 9 players; last marble is worth 25 points -------------------------------------------------------------------------------- /2018/09.rkt: -------------------------------------------------------------------------------- 1 | #lang debug br 2 | (require racket/file) 3 | 4 | #| 5 | This puzzle seemed annoying at first but turned out to be educational. 6 | An epic difference between the naive solution (= make a list and iterate from the start) 7 | and using a double-linked list, which minimizes traversal. 8 | |# 9 | 10 | (struct dll (val prev next) #:mutable) 11 | 12 | (define (move-by dll n) 13 | (define iterator 14 | (match n 15 | [(? positive?) dll-next] 16 | [(? negative?) dll-prev] 17 | [_ values])) 18 | (for/fold ([dll dll]) 19 | ([i (in-range (abs n))]) 20 | (iterator dll))) 21 | 22 | (define (remove-marble! marble) 23 | (set-dll-next! (dll-prev marble) (dll-next marble)) 24 | (set-dll-prev! (dll-next marble) (dll-prev marble))) 25 | 26 | (define (find-winner player-count max-marbles) 27 | (define scores (make-hasheqv)) 28 | (define first-marble (dll 0 #f #f)) 29 | (set-dll-prev! first-marble first-marble) 30 | (set-dll-next! first-marble first-marble) 31 | (for/fold ([current-marble first-marble] 32 | #:result (cdr (argmax cdr (hash->list scores)))) 33 | ([marble (in-range 1 max-marbles)]) 34 | (cond 35 | [(zero? (modulo marble 23)) 36 | (define marble-to-remove (move-by current-marble -7)) 37 | (remove-marble! marble-to-remove) 38 | (define player (modulo marble player-count)) 39 | (hash-update! scores player (λ (sc) (+ (dll-val marble-to-remove) marble sc)) 0) 40 | (dll-next marble-to-remove)] 41 | [else 42 | (define left-marble (move-by current-marble 1)) 43 | (define right-marble (dll-next left-marble)) 44 | (define new-marble (dll marble left-marble right-marble)) 45 | (set-dll-next! left-marble new-marble) 46 | (set-dll-prev! right-marble new-marble) 47 | new-marble]))) 48 | 49 | (match-define (list player-count max-marbles) 50 | (map string->number (regexp-match* #px"\\d+" (file->string "09.txt")))) 51 | 52 | (define (★) (find-winner player-count max-marbles)) 53 | 54 | (define (★★) (find-winner player-count (* 100 max-marbles))) 55 | 56 | (module+ test 57 | (require rackunit) 58 | (check-equal? (time (★)) 437654) 59 | (check-equal? (time (★★)) 3689913905)) -------------------------------------------------------------------------------- /2018/09.txt: -------------------------------------------------------------------------------- 1 | 400 players; last marble is worth 71864 points -------------------------------------------------------------------------------- /2018/10-test.txt: -------------------------------------------------------------------------------- 1 | position=< 9, 1> velocity=< 0, 2> 2 | position=< 7, 0> velocity=<-1, 0> 3 | position=< 3, -2> velocity=<-1, 1> 4 | position=< 6, 10> velocity=<-2, -1> 5 | position=< 2, -4> velocity=< 2, 2> 6 | position=<-6, 10> velocity=< 2, -2> 7 | position=< 1, 8> velocity=< 1, -1> 8 | position=< 1, 7> velocity=< 1, 0> 9 | position=<-3, 11> velocity=< 1, -2> 10 | position=< 7, 6> velocity=<-1, -1> 11 | position=<-2, 3> velocity=< 1, 0> 12 | position=<-4, 3> velocity=< 2, 0> 13 | position=<10, -3> velocity=<-1, 1> 14 | position=< 5, 11> velocity=< 1, -2> 15 | position=< 4, 7> velocity=< 0, -1> 16 | position=< 8, -2> velocity=< 0, 1> 17 | position=<15, 0> velocity=<-2, 0> 18 | position=< 1, 6> velocity=< 1, 0> 19 | position=< 8, 9> velocity=< 0, -1> 20 | position=< 3, 3> velocity=<-1, 1> 21 | position=< 0, 5> velocity=< 0, -1> 22 | position=<-2, 2> velocity=< 2, 0> 23 | position=< 5, -2> velocity=< 1, 2> 24 | position=< 1, 4> velocity=< 2, 1> 25 | position=<-2, 7> velocity=< 2, -2> 26 | position=< 3, 6> velocity=<-1, -1> 27 | position=< 5, 0> velocity=< 1, 0> 28 | position=<-6, 0> velocity=< 2, 0> 29 | position=< 5, 9> velocity=< 1, -2> 30 | position=<14, 7> velocity=<-2, 0> 31 | position=<-3, 6> velocity=< 2, -1> -------------------------------------------------------------------------------- /2018/10.rkt: -------------------------------------------------------------------------------- 1 | #lang debug br 2 | 3 | (struct pt (x y xv yv) #:transparent #:mutable) 4 | 5 | (define pts 6 | (for/list ([ln (in-lines (open-input-file "10.txt"))]) 7 | (apply pt 8 | (map string->number (regexp-match* #px"-?\\d+" ln))))) 9 | 10 | (define (inc pt) 11 | (set-pt-x! pt (+ (pt-x pt) (pt-xv pt))) 12 | (set-pt-y! pt (+ (pt-y pt) (pt-yv pt))) 13 | pt) 14 | 15 | (define (normalize pts) 16 | (define xmin (apply min (map pt-x pts))) 17 | (define ymin (apply min (map pt-y pts))) 18 | (for ([pt (in-list pts)]) 19 | (set-pt-x! pt (- (pt-x pt) xmin)) 20 | (set-pt-y! pt (- (pt-y pt) ymin)))) 21 | 22 | (define (fonted? pts) 23 | (define ys (map pt-y pts)) 24 | (for/and ([y (in-list ys)]) 25 | (<= 4 y 11))) 26 | 27 | (require racket/draw racket/gui) 28 | 29 | 30 | (define (print-pts pts) 31 | (define xmax (apply max (map pt-x pts))) 32 | (define ymax (apply max (map pt-y pts))) 33 | (define prs (map cons (map pt-x pts) (map pt-y pts))) 34 | (when (= #R (- xmax (apply min (map pt-x pts))) 61) 35 | #R xmax #R ymax 36 | (define target (make-bitmap (+ 3 xmax) (+ 3 ymax))) 37 | (define dc (new bitmap-dc% [bitmap target])) 38 | (for* ([y (in-range (+ 3 ymax))] 39 | [x (in-range (+ 3 xmax))] 40 | #:when (member (cons x y) prs)) 41 | (send dc set-pixel x y (make-object color% "DarkSlateGray"))) 42 | (make-object image-snip% target))) 43 | 44 | 45 | (let loop ([idx 0][pts pts]) 46 | (normalize pts) 47 | (display idx) 48 | (display (print-pts pts)) 49 | (if (fonted? pts) 50 | (display (print-pts pts)) 51 | (loop (add1 idx) (map inc pts)))) 52 | 53 | 54 | #;(define (★) 55 | ) 56 | #;(★) 57 | 58 | #;(define (★★) 59 | ) 60 | #;(★★) 61 | 62 | #;(module+ test 63 | (require rackunit) 64 | (check-equal? (time (★)) 454) 65 | (check-equal? (time (★★)) 566)) -------------------------------------------------------------------------------- /2018/11.rkt: -------------------------------------------------------------------------------- 1 | #lang debug br 2 | (require sugar/cache) 3 | 4 | (define (hundreds-digit x) 5 | (quotient (modulo x 1000) 100)) 6 | 7 | (define current-serial (make-parameter 0)) 8 | 9 | (define/caching (power-at x y) 10 | (define rack-id (+ x 10)) 11 | (- (hundreds-digit (* (+ (* rack-id y) (current-serial)) rack-id)) 5)) 12 | 13 | (define (grid-scores size-min [size-max size-min]) 14 | (for*/list ([side (in-range size-min (add1 size-max))] 15 | [x (in-range 1 (- 301 side))] 16 | [y (in-range 1 (- 301 side))]) 17 | (list x y 18 | (for*/sum ([x (in-range x (+ side x))] 19 | [y (in-range y (+ side y))]) 20 | (power-at x y))))) 21 | 22 | (define (★) 23 | (parameterize ([current-serial 7803]) 24 | (take (argmax third (grid-scores 3)) 2))) 25 | 26 | #;(grid-scores 1 300) 27 | 28 | #;(define (★★) 29 | ) 30 | #;(★★) 31 | 32 | (module+ test 33 | (require rackunit) 34 | #;(check-equal? (time (★)) '(20 51)) 35 | #;(check-equal? (time (★★)) _)) -------------------------------------------------------------------------------- /2018/README.md: -------------------------------------------------------------------------------- 1 | This year, I plan to practice writing Racket solutions that are as fast as possible. 2 | -------------------------------------------------------------------------------- /2018/stub.rkt: -------------------------------------------------------------------------------- 1 | #lang debug br 2 | 3 | #;(define (★) 4 | ) 5 | #;(★) 6 | 7 | #;(define (★★) 8 | ) 9 | #;(★★) 10 | 11 | #;(module+ test 12 | (require rackunit) 13 | (check-equal? (time (★)) 454) 14 | (check-equal? (time (★★)) 566)) -------------------------------------------------------------------------------- /2019/01.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file rackunit) 3 | 4 | (define (fuel-required mass) (- (floor (/ mass 3)) 2)) 5 | 6 | (define masses 7 | (for/list ([ln (in-port read (open-input-file "01.rktd"))]) 8 | ln)) 9 | 10 | ;; 1 11 | (check-eq? (apply + (map fuel-required masses)) 3167282) 12 | 13 | (define (recursive-fuel mass [acc 0]) 14 | (match (fuel-required mass) 15 | [(? positive? fuel) 16 | (recursive-fuel fuel (+ acc fuel))] 17 | [else acc])) 18 | 19 | ;; 2 20 | (check-eq? (apply + (map recursive-fuel masses)) 4748063) -------------------------------------------------------------------------------- /2019/01.rktd: -------------------------------------------------------------------------------- 1 | 143754 2 | 83242 3 | 124730 4 | 62796 5 | 128187 6 | 68925 7 | 60687 8 | 68800 9 | 112450 10 | 70696 11 | 94653 12 | 62124 13 | 82251 14 | 91514 15 | 79895 16 | 82973 17 | 71678 18 | 141671 19 | 88243 20 | 109553 21 | 135097 22 | 78026 23 | 100048 24 | 52113 25 | 109934 26 | 92274 27 | 62821 28 | 138384 29 | 90112 30 | 114684 31 | 137383 32 | 71727 33 | 143236 34 | 79842 35 | 101187 36 | 71202 37 | 131156 38 | 128805 39 | 105102 40 | 71319 41 | 88615 42 | 62024 43 | 126027 44 | 55321 45 | 91226 46 | 75020 47 | 136689 48 | 70265 49 | 97850 50 | 96536 51 | 135311 52 | 64962 53 | 87137 54 | 50402 55 | 70604 56 | 56879 57 | 60016 58 | 98231 59 | 136635 60 | 64590 61 | 143522 62 | 112152 63 | 142511 64 | 95350 65 | 83483 66 | 123681 67 | 123792 68 | 99044 69 | 139282 70 | 96610 71 | 116844 72 | 50416 73 | 110682 74 | 55137 75 | 69795 76 | 100411 77 | 110119 78 | 141558 79 | 90780 80 | 108063 81 | 102247 82 | 85487 83 | 107174 84 | 79009 85 | 131908 86 | 95164 87 | 120588 88 | 62031 89 | 51070 90 | 63773 91 | 128565 92 | 96458 93 | 91388 94 | 54345 95 | 52840 96 | 130519 97 | 51357 98 | 146851 99 | 68455 100 | 102463 -------------------------------------------------------------------------------- /2019/02.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file rackunit) 3 | 4 | (define (string->regs str) 5 | (list->vector (map string->number (string-split str ",")))) 6 | 7 | (define (solve regs) 8 | (define (deref ptr) (vector-ref regs ptr)) 9 | (let loop ([ptr 0]) 10 | (match (vector-ref regs ptr) 11 | [(and (or 1 2) opcode) 12 | (vector-set! regs (deref (+ ptr 3)) 13 | ((match opcode [1 +][_ *]) 14 | (deref (deref (+ ptr 1))) 15 | (deref (deref (+ ptr 2))))) 16 | (loop (+ ptr 4))] 17 | [99 regs]))) 18 | 19 | (define test "1,1,1,4,99,5,6,0,99") 20 | (check-equal? (solve (string->regs test)) '#(30 1 1 4 2 5 6 0 99)) 21 | 22 | (define (nv-result noun verb) 23 | (define regs (string->regs (file->string "02.rktd"))) 24 | (vector-set*! regs 1 noun 2 verb) 25 | (vector-ref (solve regs) 0)) 26 | 27 | ;; 1 28 | (check-eq? (nv-result 12 2) 6730673) 29 | 30 | ;; 2 31 | (check-eq? 32 | (for*/first ([noun (in-range 91)] 33 | [verb (in-range 91)] 34 | #:when (eq? (nv-result noun verb) 19690720)) 35 | (+ (* 100 noun) verb)) 36 | 3749) -------------------------------------------------------------------------------- /2019/02.rktd: -------------------------------------------------------------------------------- 1 | 1,0,0,3,1,1,2,3,1,3,4,3,1,5,0,3,2,9,1,19,1,19,6,23,2,6,23,27,2,27,9,31,1,5,31,35,1,35,10,39,2,39,9,43,1,5,43,47,2,47,10,51,1,51,6,55,1,5,55,59,2,6,59,63,2,63,6,67,1,5,67,71,1,71,9,75,2,75,10,79,1,79,5,83,1,10,83,87,1,5,87,91,2,13,91,95,1,95,10,99,2,99,13,103,1,103,5,107,1,107,13,111,2,111,9,115,1,6,115,119,2,119,6,123,1,123,6,127,1,127,9,131,1,6,131,135,1,135,2,139,1,139,10,0,99,2,0,14,0 -------------------------------------------------------------------------------- /2019/04.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file rackunit) 3 | 4 | (match-define (list low high) 5 | (map string->number (string-split (file->string "04.rktd") "-"))) 6 | 7 | (define (find-doubles digits) 8 | (match (for/list ([d0 (in-list digits)] 9 | [d1 (in-list (cdr digits))] 10 | #:when (= d0 d1)) 11 | d0) 12 | [(? null?) #false] 13 | [dds (remove-duplicates dds)])) 14 | 15 | (define (num->digits num) 16 | (for/list ([c (in-string (number->string num))]) 17 | (string->number (string c)))) 18 | 19 | (define (increasing? digits) (apply <= digits)) 20 | 21 | ;; 1 22 | (check-eq? 23 | (for/sum ([digits (in-list (map num->digits (range low (add1 high))))]) 24 | (match digits 25 | [(and (? find-doubles) (? increasing?)) 1] 26 | [_ 0])) 27 | 1079) 28 | 29 | (define (triple-digit? ds d) 30 | (and (pair? ds) 31 | (or (list-prefix? (list d d d) ds) 32 | (triple-digit? (cdr ds) d)))) 33 | 34 | ;; 2 35 | (check-eq? 36 | (for/sum ([digits (in-list (map num->digits (range low (add1 high))))]) 37 | (match digits 38 | [(and (app find-doubles (? list? doubled-digits)) (? increasing?)) 39 | #:when (for/or ([dd (in-list doubled-digits)]) 40 | (not (triple-digit? digits dd))) 1] 41 | [_ 0])) 42 | 699) 43 | 44 | -------------------------------------------------------------------------------- /2019/04.rktd: -------------------------------------------------------------------------------- 1 | 245318-765747 -------------------------------------------------------------------------------- /2019/06.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file rackunit graph racket/dict) 3 | 4 | (define (string->orbits str) 5 | (for/list ([ln (in-list (string-split str))]) 6 | (map string->symbol (string-split ln ")")))) 7 | 8 | (define orbit-recs (string->orbits (file->string "06.rktd"))) 9 | 10 | (define (count-orbits orbit-recs) 11 | (match/values (bfs (undirected-graph orbit-recs) 'COM) 12 | [(dists _) (apply + (hash-values dists))])) 13 | 14 | ;; 1 15 | (check-eq? (count-orbits orbit-recs) 261306) 16 | 17 | (define (count-transfers orbit-recs) 18 | (match/values (bellman-ford (undirected-graph orbit-recs) 'YOU) 19 | [(dists _) (- (hash-ref dists 'SAN) 2)])) 20 | 21 | ;; 2 22 | (check-eq? (count-transfers orbit-recs) 382) 23 | 24 | 25 | ;; alternate solution, using only lists 26 | 27 | (define orbit-dict (for/list ([rec (in-list orbit-recs)]) 28 | (cons (second rec) (first rec)))) 29 | 30 | (define orbit-chains 31 | ;; path from each object back to 'COM 32 | (for/list ([orbiter (in-dict-keys orbit-dict)]) 33 | (let loop ([chain (list orbiter)]) 34 | (match (assq (car chain) orbit-dict) 35 | [#false (reverse chain)] 36 | [(app cdr dest) (loop (cons dest chain))])))) 37 | 38 | ;; 1 39 | ;; orbit count is one less than the length of each chain 40 | (check-eq? (apply + (map sub1 (map length orbit-chains))) 261306) 41 | 42 | (define you-chain (assq 'YOU orbit-chains)) 43 | (define san-chain (assq 'SAN orbit-chains)) 44 | (define common-tail (take-common-prefix (reverse you-chain) (reverse san-chain))) 45 | 46 | ;; 2 47 | ;; answer path is two less than the length of path between YOU and SAN 48 | (check-eq? 49 | (- (+ (- (length you-chain) (length common-tail)) 50 | (- (length san-chain) (length common-tail))) 51 | 2) 52 | 382) -------------------------------------------------------------------------------- /2019/07.rktd: -------------------------------------------------------------------------------- 1 | 3,8,1001,8,10,8,105,1,0,0,21,46,67,76,101,118,199,280,361,442,99999,3,9,1002,9,4,9,1001,9,2,9,102,3,9,9,101,3,9,9,102,2,9,9,4,9,99,3,9,1001,9,3,9,102,2,9,9,1001,9,2,9,1002,9,3,9,4,9,99,3,9,101,3,9,9,4,9,99,3,9,1001,9,2,9,1002,9,5,9,101,5,9,9,1002,9,4,9,101,5,9,9,4,9,99,3,9,102,2,9,9,1001,9,5,9,102,2,9,9,4,9,99,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,2,9,9,4,9,99,3,9,101,1,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,101,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,2,9,9,4,9,99,3,9,1001,9,1,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,1,9,9,4,9,3,9,101,2,9,9,4,9,99,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,1001,9,2,9,4,9,99,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,2,9,9,4,9,99 -------------------------------------------------------------------------------- /2019/08.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file rackunit racket/sequence) 3 | 4 | (define pixel-data (for/list ([c (in-string (file->string "08.rktd"))]) 5 | (string->number (string c)))) 6 | (define img-width 25) 7 | (define img-height 6) 8 | 9 | (define layers (for/list ([layer (in-slice (* img-width img-height) pixel-data)]) 10 | layer)) 11 | 12 | (define ((digit-count digit) layer) 13 | (for/sum ([x (in-list layer)] 14 | #:when (= x digit)) 15 | 1)) 16 | 17 | (define least-zero-layer (argmin (digit-count 0) layers)) 18 | 19 | ;; 1 20 | (check-eq? 21 | (* ((digit-count 1) least-zero-layer) ((digit-count 2) least-zero-layer)) 22 | 2286) 23 | 24 | (define (sum-pixels . ps) 25 | (for/first ([p (in-list ps)] 26 | #:when (< p 2)) 27 | p)) 28 | 29 | (define (layer->string layer) 30 | (string-join (for/list ([row (in-slice img-width layer)]) 31 | (string-join (for/list ([digit (in-list row)]) 32 | (if (zero? digit) " " "X")) "")) "\n")) 33 | 34 | ;; 2 35 | (check-equal? (layer->string (apply map sum-pixels layers)) 36 | " XX XX XXXX X XXX \nX X X X X X X \nX X X X X X \nX X X X XXX \nX X X X X X X \n XX XX XXXX XXXX X ") -------------------------------------------------------------------------------- /2019/10.rktd: -------------------------------------------------------------------------------- 1 | .###.###.###.#####.# 2 | #####.##.###..###..# 3 | .#...####.###.###### 4 | ######.###.####.#### 5 | #####..###..######## 6 | #.##.###########.#.# 7 | ##.###.######..#.#.# 8 | .#.##.###.#.####.### 9 | ##..#.#.##.######### 10 | ###.#######.###..##. 11 | ###.###.##.##..####. 12 | .##.####.##########. 13 | #######.##.###.##### 14 | #####.##..####.##### 15 | ##.#.#####.##.#.#..# 16 | ###########.#######. 17 | #.##..#####.#####..# 18 | #####..#####.###.### 19 | ####.#.############. 20 | ####.#.#.##########. -------------------------------------------------------------------------------- /2019/11.rktd: -------------------------------------------------------------------------------- 1 | 3,8,1005,8,324,1106,0,11,0,0,0,104,1,104,0,3,8,1002,8,-1,10,1001,10,1,10,4,10,1008,8,0,10,4,10,1001,8,0,29,3,8,1002,8,-1,10,101,1,10,10,4,10,108,0,8,10,4,10,101,0,8,50,1,1106,9,10,1,102,15,10,2,1003,3,10,1,3,19,10,3,8,102,-1,8,10,101,1,10,10,4,10,1008,8,0,10,4,10,1001,8,0,89,1,1105,9,10,2,1103,1,10,3,8,102,-1,8,10,101,1,10,10,4,10,1008,8,1,10,4,10,1001,8,0,119,1006,0,26,1,109,7,10,3,8,1002,8,-1,10,1001,10,1,10,4,10,108,1,8,10,4,10,1002,8,1,147,1006,0,75,1,1005,17,10,3,8,102,-1,8,10,101,1,10,10,4,10,108,0,8,10,4,10,102,1,8,176,3,8,102,-1,8,10,1001,10,1,10,4,10,1008,8,1,10,4,10,102,1,8,199,3,8,102,-1,8,10,1001,10,1,10,4,10,108,1,8,10,4,10,102,1,8,220,2,103,10,10,1,1,0,10,1,102,17,10,3,8,1002,8,-1,10,101,1,10,10,4,10,108,1,8,10,4,10,101,0,8,254,2,1001,10,10,1006,0,12,1,3,6,10,3,8,102,-1,8,10,101,1,10,10,4,10,1008,8,0,10,4,10,102,1,8,288,2,1106,9,10,2,1009,6,10,2,1101,18,10,2,103,8,10,101,1,9,9,1007,9,1045,10,1005,10,15,99,109,646,104,0,104,1,21101,838211318676,0,1,21102,341,1,0,1106,0,445,21101,0,838211051932,1,21101,0,352,0,1106,0,445,3,10,104,0,104,1,3,10,104,0,104,0,3,10,104,0,104,1,3,10,104,0,104,1,3,10,104,0,104,0,3,10,104,0,104,1,21101,0,21704576195,1,21101,0,399,0,1106,0,445,21101,0,179356830951,1,21101,410,0,0,1105,1,445,3,10,104,0,104,0,3,10,104,0,104,0,21102,837897052948,1,1,21102,1,433,0,1106,0,445,21102,709052085092,1,1,21102,1,444,0,1105,1,445,99,109,2,21201,-1,0,1,21101,0,40,2,21102,476,1,3,21102,466,1,0,1105,1,509,109,-2,2105,1,0,0,1,0,0,1,109,2,3,10,204,-1,1001,471,472,487,4,0,1001,471,1,471,108,4,471,10,1006,10,503,1102,1,0,471,109,-2,2106,0,0,0,109,4,2102,1,-1,508,1207,-3,0,10,1006,10,526,21101,0,0,-3,21201,-3,0,1,21201,-2,0,2,21101,0,1,3,21101,545,0,0,1105,1,550,109,-4,2105,1,0,109,5,1207,-3,1,10,1006,10,573,2207,-4,-2,10,1006,10,573,21201,-4,0,-4,1105,1,641,22102,1,-4,1,21201,-3,-1,2,21202,-2,2,3,21101,592,0,0,1105,1,550,21201,1,0,-4,21102,1,1,-1,2207,-4,-2,10,1006,10,611,21101,0,0,-1,22202,-2,-1,-2,2107,0,-3,10,1006,10,633,21202,-1,1,1,21101,633,0,0,106,0,508,21202,-2,-1,-2,22201,-4,-2,-4,109,-5,2105,1,0 -------------------------------------------------------------------------------- /2019/12.rktd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /2019/14input.rkt: -------------------------------------------------------------------------------- 1 | #lang reader (submod "14.rkt" reader) 2 | 1 FVBHS, 29 HWPND => 4 CPXDX 3 | 5 TNWDG, 69 VZMS, 1 GXSD, 48 NCLZ, 3 RSRZ, 15 HWPND, 25 SGPK, 2 SVCQ => 1 FUEL 4 | 1 PQRLB, 1 TWPMQ => 4 QBXC 5 | 9 QBXC => 7 RNHQ 6 | 12 VZMS => 6 MGQRZ 7 | 6 QBVG, 10 XJWX => 6 BWLZ 8 | 4 MVGN => 6 BHZH 9 | 2 LKTWD => 7 FVBHS 10 | 2 BWFK => 7 TFPQ 11 | 15 VZBJ, 9 TSVN, 2 BWLZ => 2 TNWDG 12 | 10 KVFL, 2 BWLZ, 1 VGSBF => 4 KBFJV 13 | 12 TXCR, 2 JMBG => 4 DCFD 14 | 5 VMDT, 6 JKPFT, 3 RJKJD => 7 LGWM 15 | 1 LDFGW => 2 DHRBP 16 | 129 ORE => 8 LDFGW 17 | 9 DNVRJ => 8 BMNGX 18 | 7 NLPB => 6 NCLZ 19 | 1 VMDT, 6 DCFD => 9 SGRXC 20 | 1 LDFGW, 2 VRHFB => 8 QHGQC 21 | 10 VGSBF, 5 WVMG, 6 BWLZ => 3 BWFK 22 | 4 KVFL, 1 TSVN => 6 SVCQ 23 | 2 VZBJ, 3 SWJZ => 3 QZLC 24 | 5 JMBG, 1 PQRLB => 3 CJLH 25 | 13 LKTWD, 6 TFPQ => 3 WVRXR 26 | 20 QHGQC, 10 NSPVD => 5 VGSBF 27 | 5 TFPQ, 1 DHRBP, 2 KVFL => 8 NLPB 28 | 2 KBFJV, 1 CJLH, 20 RNHQ, 1 BWLZ, 13 MNBK, 1 BHZH, 1 PKRJF => 8 RSRZ 29 | 154 ORE => 2 VRHFB 30 | 2 NHRCK => 7 DNVRJ 31 | 2 VRHFB, 4 XJWX => 4 NHRCK 32 | 1 TFPQ, 12 JMBG => 5 MNBK 33 | 8 TMFS => 2 VZMS 34 | 175 ORE => 2 TMFS 35 | 1 LBZN, 2 SWJZ, 3 VGSBF => 8 BLDN 36 | 7 KFJD, 5 WVRXR, 5 RJKJD => 6 MVGN 37 | 3 RJKJD, 1 TXCR => 8 KVFL 38 | 3 QHGQC, 1 MGQRZ, 10 VGSBF => 8 LKTWD 39 | 178 ORE => 1 XJWX 40 | 1 QBXC, 1 BWFK => 6 TSVN 41 | 1 NHRCK, 2 DHRBP => 4 VZBJ 42 | 1 LDFGW, 2 NHRCK, 10 BWLZ => 8 TWPMQ 43 | 28 TWPMQ => 4 RJKJD 44 | 10 SVCQ, 1 KVFL => 6 CZNMG 45 | 3 VZMS, 3 MGQRZ => 3 WVMG 46 | 19 MGQRZ => 8 KFJD 47 | 3 WVMG => 6 PQRLB 48 | 31 SVCQ, 1 TXCR => 8 VMDT 49 | 20 KFJD, 5 CPXDX, 2 BLDN, 2 PQWJX, 12 TFPQ, 2 BHZH, 2 MVGN => 9 SGPK 50 | 7 QZLC => 8 JMBG 51 | 1 PQRLB => 1 HWPND 52 | 9 VMDT, 5 CZNMG, 3 CPXDX, 1 MVGN, 8 VSMTK, 2 SGRXC, 1 MNBK, 8 LGWM => 7 GXSD 53 | 2 NSPVD => 8 QBVG 54 | 20 CZNMG => 4 PQWJX 55 | 1 LDFGW => 4 NSPVD 56 | 16 KBFJV, 22 BLDN => 2 VSMTK 57 | 10 BWLZ => 9 LBZN 58 | 1 BWLZ => 3 SWJZ 59 | 1 HWPND => 9 TXCR 60 | 12 CJLH, 9 LGWM, 3 BHZH => 6 PKRJF 61 | 5 BMNGX => 7 JKPFT -------------------------------------------------------------------------------- /2019/14test.rkt: -------------------------------------------------------------------------------- 1 | #lang reader (submod "14.rkt" reader) 2 | 10 ORE => 10 A 3 | 1 ORE => 1 B 4 | 7 A, 1 B => 1 C 5 | 7 A, 1 C => 1 D 6 | 7 A, 1 D => 1 E 7 | 7 A, 1 E => 1 FUEL -------------------------------------------------------------------------------- /2019/16.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file rackunit) 3 | 4 | (define (make-patintss ints) 5 | (for/list ([i (in-range (length ints))]) 6 | (apply append (map (curry make-list (add1 i)) '(0 1 0 -1))))) 7 | 8 | (define (fft str [phase-count 1]) 9 | (define ints (for/list ([c (in-string str)]) 10 | (string->number (string c)))) 11 | (define patintss (make-patintss ints)) 12 | (time 13 | (for/fold ([ints ints] 14 | #:result (take ints 8)) 15 | ([pidx (in-range phase-count)]) 16 | (for/list ([patints (in-list patintss)]) 17 | (modulo (abs (for/sum ([int (in-list (cons 0 ints))] ; cons 0 to burn off first patint 18 | [patint (in-cycle patints)]) 19 | (* int patint))) 10))))) 20 | 21 | 22 | (check-equal? (fft "80871224585914546619083218645595" 100) '(2 4 1 7 6 1 7 6)) 23 | (check-equal? (fft "19617804207202209144916044189917" 100) '(7 3 7 4 5 4 1 8)) 24 | (check-equal? (fft "69317163492948606335995924319873" 100) '(5 2 4 3 2 1 3 3)) 25 | 26 | ;; 1 27 | (check-equal? (fft (file->string "16.rktd") 100) '(8 5 7 2 6 5 0 2)) -------------------------------------------------------------------------------- /2019/16.rktd: -------------------------------------------------------------------------------- 1 | 59773775883217736423759431065821647306353420453506194937477909478357279250527959717515453593953697526882172199401149893789300695782513381578519607082690498042922082853622468730359031443128253024761190886248093463388723595869794965934425375464188783095560858698959059899665146868388800302242666479679987279787144346712262803568907779621609528347260035619258134850854741360515089631116920328622677237196915348865412336221562817250057035898092525020837239100456855355496177944747496249192354750965666437121797601987523473707071258599440525572142300549600825381432815592726865051526418740875442413571535945830954724825314675166862626566783107780527347044 -------------------------------------------------------------------------------- /2019/19.rktd: -------------------------------------------------------------------------------- 1 | 109,424,203,1,21101,0,11,0,1105,1,282,21101,18,0,0,1105,1,259,2101,0,1,221,203,1,21102,1,31,0,1105,1,282,21101,0,38,0,1106,0,259,21002,23,1,2,22101,0,1,3,21101,0,1,1,21102,1,57,0,1106,0,303,2102,1,1,222,21001,221,0,3,20102,1,221,2,21101,0,259,1,21101,80,0,0,1106,0,225,21101,0,23,2,21102,91,1,0,1106,0,303,1201,1,0,223,20101,0,222,4,21101,0,259,3,21102,1,225,2,21102,1,225,1,21102,1,118,0,1105,1,225,20102,1,222,3,21101,0,87,2,21101,133,0,0,1106,0,303,21202,1,-1,1,22001,223,1,1,21101,0,148,0,1105,1,259,2101,0,1,223,20102,1,221,4,21002,222,1,3,21101,0,9,2,1001,132,-2,224,1002,224,2,224,1001,224,3,224,1002,132,-1,132,1,224,132,224,21001,224,1,1,21102,1,195,0,106,0,109,20207,1,223,2,21001,23,0,1,21102,1,-1,3,21101,0,214,0,1106,0,303,22101,1,1,1,204,1,99,0,0,0,0,109,5,2102,1,-4,249,21201,-3,0,1,22101,0,-2,2,21202,-1,1,3,21102,250,1,0,1106,0,225,21202,1,1,-4,109,-5,2106,0,0,109,3,22107,0,-2,-1,21202,-1,2,-1,21201,-1,-1,-1,22202,-1,-2,-2,109,-3,2105,1,0,109,3,21207,-2,0,-1,1206,-1,294,104,0,99,21202,-2,1,-2,109,-3,2105,1,0,109,5,22207,-3,-4,-1,1206,-1,346,22201,-4,-3,-4,21202,-3,-1,-1,22201,-4,-1,2,21202,2,-1,-1,22201,-4,-1,1,22102,1,-2,3,21102,1,343,0,1106,0,303,1106,0,415,22207,-2,-3,-1,1206,-1,387,22201,-3,-2,-3,21202,-2,-1,-1,22201,-3,-1,3,21202,3,-1,-1,22201,-3,-1,2,21201,-4,0,1,21102,384,1,0,1105,1,303,1106,0,415,21202,-4,-1,-4,22201,-4,-3,-4,22202,-3,-2,-2,22202,-2,-4,-4,22202,-3,-2,-3,21202,-4,-1,-2,22201,-3,-2,1,21202,1,1,-4,109,-5,2106,0,0 -------------------------------------------------------------------------------- /2019/20.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file rackunit racket/set graph) 3 | 4 | (define str (file->string "20.rktd")) 5 | 6 | (define (find-cells pred) 7 | (for*/hasheqv ([(row ridx) (in-indexed (string-split str "\n"))] 8 | [(c cidx) (in-indexed row)] 9 | #:when (pred c)) 10 | (values (make-rectangular cidx ridx) c))) 11 | 12 | (define passage-locs (find-cells (λ (c) (char=? c #\.)))) 13 | (define letter-locs (find-cells char-alphabetic?)) 14 | 15 | (define g (unweighted-graph/undirected null)) 16 | 17 | (for* ([loc (in-hash-keys passage-locs)] 18 | [delta (list 1 -1 +i -i)]) 19 | (when (hash-has-key? passage-locs (+ loc delta)) 20 | (add-edge! g loc (+ loc delta))) 21 | (when (hash-has-key? letter-locs (+ loc delta)) 22 | (add-edge! g loc (string->symbol 23 | (apply string ((if (member delta (list -1 -i)) 24 | reverse 25 | values) (for/list ([d (list delta (* 2 delta))]) 26 | (hash-ref letter-locs (+ loc d))))))))) 27 | 28 | (for ([v (in-vertices g)] 29 | #:when (and (symbol? v) (not (memq v '(AA ZZ))))) 30 | (apply add-edge! g (get-neighbors g v))) 31 | 32 | 33 | ;; 1 34 | (check-eq? (- (length (fewest-vertices-path g 'AA 'ZZ)) 3) 638) -------------------------------------------------------------------------------- /2019/24.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file racket/dict rackunit) 3 | 4 | (define (bug? x) (char=? x #\#)) 5 | 6 | (define (parse-grid lns) 7 | (for*/list ([(ln row) (in-indexed lns)] 8 | [(c col) (in-indexed ln)]) 9 | (cons (make-rectangular col row) c))) 10 | 11 | (define (adjacent-bugs g tile) 12 | (for/sum ([delta '(+i -i 1 -1)] 13 | #:when (bug? (dict-ref g (+ tile delta) #\.))) 14 | 1)) 15 | 16 | (define (step g) 17 | (for*/list ([row (in-range 5)] 18 | [col (in-range 5)]) 19 | (define tile (make-rectangular col row)) 20 | (cons tile 21 | (match (cons (dict-ref g tile) (adjacent-bugs g tile)) 22 | [(cons #\# 1) #\#] 23 | [(cons #\# _) #\.] 24 | [(cons #\. (or 1 2)) #\#] 25 | [(cons other _) other])))) 26 | 27 | (define (biodiversity-rating g) 28 | (for/sum ([(rec idx) (in-indexed g)] 29 | #:when (bug? (cdr rec))) 30 | (expt 2 idx))) 31 | 32 | (define (solve lns) 33 | (let loop ([gs (list (parse-grid lns))]) 34 | (define next-g (step (car gs))) 35 | (cond 36 | [(member next-g gs) (biodiversity-rating next-g)] 37 | [else (loop (cons next-g gs))]))) 38 | 39 | (check-eq? 40 | (solve (string-split "....# 41 | #..#. 42 | #..## 43 | ..#.. 44 | #....")) 2129920) 45 | 46 | ;; 1 47 | (check-eq? (solve (file->lines "24.rktd")) 18407158) -------------------------------------------------------------------------------- /2019/24.rktd: -------------------------------------------------------------------------------- 1 | ..#.# 2 | ##### 3 | .#... 4 | ...#. 5 | ##... -------------------------------------------------------------------------------- /2019/README.md: -------------------------------------------------------------------------------- 1 | ## MB’s Advent of Code tips 2 | 3 | * The problems are often designed around a particular computer-y abstraction. If you notice what the abstraction is, and then find the closest analog in Racket, the solution tends to come together quickly. Otherwise, you can spend a lot of time reinventing the wheel. 4 | 5 | * Complex numbers are a nice way of modeling two-dimensional positions. 6 | 7 | * Use lists whenever feasible, because there are many useful list functions in the Racket library that don’t have vector equivalents. In particular, [these list functions](https://docs.racket-lang.org/reference/pairs.html?q=racket%2Flist#%28part._.Additional_.List_.Functions_and_.Synonyms%29) are very useful, especially `argmin` and `argmax`. 8 | 9 | * Vectors are better than lists in situations where you need random access to members. 10 | 11 | * `eq?` is the fastest equality check, but it only works for symbols and fixnums (therefore, use more symbols and fixnums so you can use `eq?`!) 12 | 13 | * `match` is fantastic. 14 | 15 | * Association lists (= lists of pairs) are underrated. They’re compatible with all the usual list functions, of course, but also dictionary forms (like `dict-ref` and `in-dict`). 16 | 17 | * The `graph` library can be helpful for graph-based problems. 18 | 19 | * It’s good to know about sets and mutable pairs. 20 | 21 | * Also the fancier `for` iterators, like `for/first` and `for/or`. 22 | 23 | * `let/ec` is a way of jumping out of a deeply nested computation, akin to how `return` works in other languages. 24 | 25 | 26 | 27 | ## My solutions 28 | 29 | * I try to write solutions that are succinct but not cryptic. 30 | 31 | * I don’t optimize for speed. 32 | 33 | * I like doing the Advent of Code problems because it forces me to use parts of Racket that I don’t ordinarily use. So I treat it as a chance to expand my awareness of the Racketverse. 34 | 35 | * I’m unlikely to finish every problem. Judging by past years, there is a point where the problems get sufficiently complex that I’d rather put that time into improving my other Racket projects :metal: 36 | -------------------------------------------------------------------------------- /2020/01.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file rackunit) 3 | 4 | (define (solve combo-length) 5 | (for/first ([c (in-combinations (map string->number (file->lines "01.rktd")) combo-length)] 6 | #:when (eq? 2020 (apply + c))) 7 | (apply * c))) 8 | 9 | (check-equal? (solve 2) 1007331) 10 | (check-equal? (solve 3) 48914340) -------------------------------------------------------------------------------- /2020/01.rktd: -------------------------------------------------------------------------------- 1 | 1834 2 | 1546 3 | 1119 4 | 1870 5 | 1193 6 | 1198 7 | 1542 8 | 1944 9 | 1817 10 | 1249 11 | 1361 12 | 1856 13 | 1258 14 | 1425 15 | 1835 16 | 1520 17 | 1792 18 | 1130 19 | 2004 20 | 1366 21 | 1549 22 | 1347 23 | 1507 24 | 1699 25 | 1491 26 | 1557 27 | 1865 28 | 1948 29 | 1199 30 | 1229 31 | 1598 32 | 1756 33 | 1643 34 | 1306 35 | 1838 36 | 1157 37 | 1745 38 | 1603 39 | 1972 40 | 1123 41 | 1963 42 | 1759 43 | 1118 44 | 1526 45 | 1695 46 | 1661 47 | 1262 48 | 1117 49 | 1844 50 | 1922 51 | 1997 52 | 1630 53 | 1337 54 | 1721 55 | 1147 56 | 1848 57 | 1476 58 | 1975 59 | 1942 60 | 1569 61 | 1126 62 | 1313 63 | 1449 64 | 1206 65 | 1722 66 | 1534 67 | 1706 68 | 1596 69 | 1700 70 | 1811 71 | 906 72 | 1666 73 | 1945 74 | 1271 75 | 1629 76 | 1456 77 | 1316 78 | 1636 79 | 1884 80 | 1556 81 | 1317 82 | 1393 83 | 1953 84 | 1658 85 | 2005 86 | 1252 87 | 1878 88 | 1691 89 | 60 90 | 1872 91 | 386 92 | 1369 93 | 1739 94 | 1460 95 | 1267 96 | 1935 97 | 1992 98 | 1310 99 | 1818 100 | 1320 101 | 1437 102 | 1486 103 | 1205 104 | 1286 105 | 1670 106 | 1577 107 | 1237 108 | 1558 109 | 1937 110 | 1938 111 | 1656 112 | 1220 113 | 1732 114 | 1647 115 | 1857 116 | 1446 117 | 1516 118 | 1450 119 | 1860 120 | 1625 121 | 1377 122 | 1312 123 | 1588 124 | 1895 125 | 1967 126 | 1567 127 | 1582 128 | 1428 129 | 1415 130 | 1731 131 | 1919 132 | 1651 133 | 1597 134 | 1982 135 | 1576 136 | 1172 137 | 1568 138 | 1867 139 | 1660 140 | 1754 141 | 1227 142 | 1121 143 | 1733 144 | 537 145 | 1809 146 | 1322 147 | 1876 148 | 1665 149 | 1124 150 | 1461 151 | 1888 152 | 1368 153 | 1235 154 | 1479 155 | 1529 156 | 1148 157 | 1996 158 | 1939 159 | 1340 160 | 1531 161 | 1438 162 | 1897 163 | 1152 164 | 1321 165 | 1770 166 | 897 167 | 1750 168 | 1111 169 | 1772 170 | 1615 171 | 1798 172 | 1359 173 | 1470 174 | 1610 175 | 1362 176 | 1973 177 | 1892 178 | 1830 179 | 599 180 | 1341 181 | 1681 182 | 1572 183 | 1873 184 | 42 185 | 1246 186 | 1447 187 | 1800 188 | 1524 189 | 1214 190 | 1784 191 | 1664 192 | 1882 193 | 1989 194 | 1797 195 | 1211 196 | 1170 197 | 1854 198 | 1287 199 | 1641 200 | 1760 201 | -------------------------------------------------------------------------------- /2020/02.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file rackunit) 3 | 4 | (struct rec (password target low high)) 5 | (define recs (for/list ([ln (file->lines "02.rktd")]) 6 | (match-define (list range target password) (string-split ln)) 7 | (match-define (list low high) (map string->number (string-split range "-"))) 8 | (rec password (string-ref (string-trim target ":") 0) low high))) 9 | 10 | (check-equal? 11 | (for/sum ([rec recs]) 12 | (define howmany (count (λ (c) (char=? c (rec-target rec))) (string->list (rec-password rec)))) 13 | (if (<= (rec-low rec) howmany (rec-high rec)) 1 0)) 14 | 422) 15 | 16 | (check-equal? 17 | (for/sum ([rec recs]) 18 | (define low? (char=? (rec-target rec) (string-ref (rec-password rec) (sub1 (rec-low rec))))) 19 | (define high? (char=? (rec-target rec) (string-ref (rec-password rec) (sub1 (rec-high rec))))) 20 | (if (or (and low? (not high?)) (and high? (not low?))) 1 0)) 21 | 451) -------------------------------------------------------------------------------- /2020/03.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file rackunit) 3 | 4 | (define (trees-in-slope horiz vert) 5 | (for/fold ([mod 0] 6 | [sum 0] 7 | #:result sum) 8 | ([(ln lidx) (in-indexed (file->lines "03.rktd"))] 9 | #:when (zero? (modulo lidx vert))) 10 | (values (+ mod horiz) 11 | (if (char=? #\# (string-ref ln (modulo mod (string-length ln)))) (add1 sum) sum)))) 12 | 13 | (check-equal? (trees-in-slope 3 1) 151) 14 | 15 | (check-equal? (apply * (list 16 | (trees-in-slope 1 1) 17 | (trees-in-slope 3 1) 18 | (trees-in-slope 5 1) 19 | (trees-in-slope 7 1) 20 | (trees-in-slope 1 2))) 7540141059) -------------------------------------------------------------------------------- /2020/04.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file rackunit) 3 | 4 | (define passports (for/list ([pstr (string-split (file->string "04.rktd") #rx"\n\n+")]) 5 | (for/hash ([kvstr (string-split pstr)]) 6 | (apply values (string-split kvstr ":"))))) 7 | 8 | (define required-fields '("byr" "iyr" "eyr" "hgt" "hcl" "ecl" "pid")) ; "cid" is not required 9 | 10 | (define (passport-keys-valid? p) 11 | (for*/and ([passport-keys (in-value (hash-keys p))] 12 | [field required-fields]) 13 | (member field passport-keys))) 14 | 15 | (check-equal? (count passport-keys-valid? passports) 202) 16 | 17 | (define (stringval-in-range str low high) 18 | (<= low (string->number str) high)) 19 | 20 | (define (passport-values-valid? p) 21 | (and 22 | (stringval-in-range (hash-ref p "byr") 1920 2002) 23 | (stringval-in-range (hash-ref p "iyr") 2010 2020) 24 | (stringval-in-range (hash-ref p "eyr") 2020 2030) 25 | (let ([hgt (hash-ref p "hgt")]) 26 | (cond 27 | [(string-suffix? hgt "cm") (stringval-in-range (string-trim hgt "cm") 150 193)] 28 | [(string-suffix? hgt "in") (stringval-in-range (string-trim hgt "in") 59 76)] 29 | [else #false])) 30 | (let ([hcl (hash-ref p "hcl")]) 31 | (and (regexp-match #rx"#......" hcl) (string->number (string-trim hcl "#") 16))) 32 | (member (hash-ref p "ecl") '("amb" "blu" "brn" "gry" "grn" "hzl" "oth")) 33 | (let ([pid (hash-ref p "pid")]) (and (= 9 (string-length pid)) (string->number pid))))) 34 | 35 | (check-equal? (count (λ (p) (and (passport-keys-valid? p) (passport-values-valid? p))) passports) 137) -------------------------------------------------------------------------------- /2020/05.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file srfi/13 rackunit) 3 | 4 | (define (seat-id seat) 5 | (for/sum ([(c i) (in-indexed (string-reverse seat))] 6 | #:when (memv c '(#\R #\B))) 7 | (arithmetic-shift 1 i))) 8 | 9 | (define seat-ids (map seat-id (file->lines "05.rktd"))) 10 | 11 | (check-equal? (apply max seat-ids) 915) 12 | 13 | (check-equal? 14 | (for/first ([first (sort seat-ids <)] 15 | [second (cdr (sort seat-ids <))] 16 | #:when (= 2 (- second first))) 17 | (sub1 second)) 18 | 699) -------------------------------------------------------------------------------- /2020/06.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file racket/set rackunit) 3 | 4 | (define (solve set-proc) 5 | (for/sum ([group (string-split (file->string "06.rktd") #px"\n\n+")]) 6 | (set-count (apply set-proc (for/list ([person (string-split group "\n")]) 7 | (for/seteqv ([c person]) 8 | c)))))) 9 | 10 | (check-equal? (solve set-union) 6549) 11 | 12 | (check-equal? (solve set-intersect) 3466) 13 | 14 | -------------------------------------------------------------------------------- /2020/07.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file graph rackunit) 3 | 4 | (struct $bag (weight name)) 5 | 6 | (define parsed-baglists 7 | (for/list ([ln (file->lines "07.rktd")]) 8 | (for/list ([str (string-split ln #px" bags?[,.]?")]) 9 | (define pcs (string-split str)) 10 | ($bag 11 | (and (>= (length pcs) 3) (string->number (car (take-right pcs 3)))) 12 | (string-join (take-right pcs 2)))))) 13 | 14 | (define g1 (unweighted-graph/directed 15 | (for*/list ([baglist parsed-baglists] 16 | [bag (cdr baglist)]) 17 | (list ($bag-name bag) ($bag-name (car baglist)))))) 18 | 19 | (define-values (distances _) (dijkstra g1 "shiny gold")) 20 | 21 | (check-equal? (count exact-positive-integer? (hash-values distances)) 222) 22 | 23 | (define g2 (weighted-graph/directed 24 | (for*/list ([baglist parsed-baglists] 25 | [bag (cdr baglist)]) 26 | (match-define ($bag weight name) bag) 27 | (list weight ($bag-name (car baglist)) name)))) 28 | 29 | (define (bag-count name) 30 | (+ 1 (for*/sum ([name2 (get-neighbors g2 name)] 31 | [weight (in-value (edge-weight g2 name name2))] 32 | #:when (exact-positive-integer? weight)) 33 | (* weight (bag-count name2))))) 34 | 35 | (check-equal? (sub1 (bag-count "shiny gold")) 13264) 36 | 37 | 38 | -------------------------------------------------------------------------------- /2020/08.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file rackunit racket/sequence racket/set) 3 | 4 | (define toks (for/list ([tok (in-port read (open-input-file "08.rktd"))]) 5 | tok)) 6 | 7 | (struct $inst (name val)) 8 | (define instructions (for/vector ([slice (in-slice 2 toks)]) 9 | (apply $inst slice))) 10 | 11 | (define (run insts) 12 | (let loop ([acc 0][ptr 0][visited null]) 13 | (cond 14 | [(eq? ptr (vector-length insts)) (cons 'terminated acc)] 15 | [(memq ptr visited) acc] 16 | [else 17 | (define next-visited (cons ptr visited)) 18 | (match (vector-ref insts ptr) 19 | [($inst 'acc val) (loop (+ acc val) (add1 ptr) next-visited)] 20 | [($inst 'jmp val) (loop acc (+ ptr val) next-visited)] 21 | [($inst 'nop val) (loop acc (add1 ptr) next-visited)])]))) 22 | 23 | (check-equal? (run instructions) 1818) 24 | 25 | (define (fix-bug insts) 26 | (for/or ([(inst idx) (in-indexed insts)] 27 | #:when (memq ($inst-name inst) '(jmp nop))) 28 | (define new-insts (vector-copy insts)) 29 | (vector-set! insts idx ($inst (if (eq? ($inst-name inst) 'jmp) 'nop 'jmp) ($inst-val inst))) 30 | (match (run new-insts) 31 | [(cons 'terminated acc) acc] 32 | [_ #false]))) 33 | 34 | (check-equal? (fix-bug instructions) 187) -------------------------------------------------------------------------------- /2020/09.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file rackunit) 3 | 4 | (define vec (list->vector (map string->number (file->lines "09.rktd")))) 5 | 6 | (define preamble-length 25) 7 | 8 | (define (idx-valid? idx) 9 | (define predecessors (for/list ([val (in-vector vec (- idx preamble-length) idx)]) 10 | val)) 11 | (define target (vector-ref vec idx)) 12 | (for/or ([ints (in-combinations predecessors 2)]) 13 | (eq? (apply + ints) target))) 14 | 15 | (define invalid-number 16 | (for/first ([idx (in-range (add1 preamble-length) (vector-length vec))] 17 | #:unless (idx-valid? idx)) 18 | (vector-ref vec idx))) 19 | 20 | (check-equal? invalid-number 14144619) 21 | 22 | (check-equal? 23 | (for/or ([lidx (in-range 0 (vector-length vec))]) 24 | (let/ec skip-to-next-lidx 25 | (for/or ([ridx (in-range (add1 lidx) (vector-length vec))]) 26 | (define ints (for/list ([val (in-vector vec lidx (add1 ridx))]) 27 | val)) 28 | (define sum (apply + ints)) 29 | (cond 30 | [(> sum invalid-number) (skip-to-next-lidx #false)] 31 | [(eq? sum invalid-number) (+ (apply min ints) (apply max ints))] 32 | [else #false])))) 33 | 1766397) 34 | -------------------------------------------------------------------------------- /2020/10.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file rackunit) 3 | 4 | (define adapters (map string->number (file->lines "10.rktd"))) 5 | (define sources (sort `(0 ,@adapters ,(+ (apply max adapters) 3)) <)) 6 | 7 | (define diffs (for/list ([left sources] 8 | [right (cdr sources)]) 9 | (- right left))) 10 | 11 | (check-equal? (* (count (curry = 1) diffs) (count (curry = 3) diffs)) 2590) 12 | 13 | (define (sequential-subsequences sources [seqs null]) 14 | (match sources 15 | [(? null?) seqs] 16 | [(list head tail ...) 17 | (let loop ([head (list head)][tail tail]) 18 | (match tail 19 | [(list first rest ...) #:when (eq? (car head) (sub1 first)) 20 | (loop (cons first head) rest)] 21 | [_ (sequential-subsequences tail (cons head seqs))]))])) 22 | 23 | (define (subseq->multiplier subseq) 24 | (match (length subseq) 25 | [3 2] ; abc | ac 26 | [4 4] ; abcd | acd | abd | ad 27 | [5 7] ; abcde | acde | abde | abce | abe | ace | ade 28 | [_ 1])) 29 | 30 | (check-equal? (for/product ([subseq (sequential-subsequences sources)]) 31 | (subseq->multiplier subseq)) 226775649501184) 32 | -------------------------------------------------------------------------------- /2020/10.rktd: -------------------------------------------------------------------------------- 1 | 105 2 | 78 3 | 37 4 | 153 5 | 10 6 | 175 7 | 62 8 | 163 9 | 87 10 | 22 11 | 24 12 | 92 13 | 46 14 | 5 15 | 115 16 | 61 17 | 124 18 | 128 19 | 8 20 | 60 21 | 17 22 | 93 23 | 166 24 | 29 25 | 90 26 | 148 27 | 113 28 | 55 29 | 141 30 | 134 31 | 79 32 | 101 33 | 49 34 | 133 35 | 38 36 | 53 37 | 33 38 | 30 39 | 66 40 | 159 41 | 23 42 | 132 43 | 145 44 | 147 45 | 121 46 | 94 47 | 146 48 | 21 49 | 135 50 | 56 51 | 176 52 | 118 53 | 44 54 | 138 55 | 85 56 | 169 57 | 111 58 | 9 59 | 1 60 | 83 61 | 36 62 | 59 63 | 140 64 | 149 65 | 160 66 | 43 67 | 131 68 | 69 69 | 2 70 | 25 71 | 84 72 | 39 73 | 28 74 | 171 75 | 172 76 | 100 77 | 18 78 | 15 79 | 114 80 | 70 81 | 86 82 | 97 83 | 155 84 | 152 85 | 40 86 | 122 87 | 77 88 | 16 89 | 11 90 | 170 91 | 52 92 | 45 93 | 139 94 | 76 95 | 102 96 | 63 97 | 54 98 | 142 99 | 14 100 | 158 101 | 80 102 | 154 103 | 112 104 | 91 105 | 108 106 | 73 107 | 127 108 | 123 -------------------------------------------------------------------------------- /2020/11.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file rackunit) 3 | 4 | (define grid 5 | (for*/hasheqv ([(row ridx) (in-indexed (file->lines "11.rktd"))] 6 | [(col cidx) (in-indexed row)]) 7 | (values (make-rectangular cidx ridx) col))) 8 | 9 | (define (seat-count grid) 10 | (count (λ (val) (char=? val #\#)) (hash-values grid))) 11 | 12 | (define offsets '(-1-1i -1 -1+i +i 1+i 1 1-i -i)) 13 | 14 | (define (visible-occupied-seats grid k [adjacent-only? #false]) 15 | (for/sum ([offset (in-list offsets)]) 16 | (let loop ([k (+ k offset)] [sum 0]) 17 | (match (hash-ref grid k #false) 18 | [#false sum] 19 | [#\# 1] 20 | [#\L 0] 21 | [_ (if adjacent-only? 22 | sum 23 | (loop (+ k offset) sum))])))) 24 | 25 | (define (adjacent-occupied-seats grid k) (visible-occupied-seats grid k #true)) 26 | 27 | (define (iterate grid seat-counter threshold) 28 | (for/hasheqv ([(k v) (in-hash grid)]) 29 | (match v 30 | [#\L #:when (zero? (seat-counter grid k)) (values k #\#)] 31 | [#\# #:when (<= threshold (seat-counter grid k)) (values k #\L)] 32 | [_ (values k v)]))) 33 | 34 | (define (solve grid iteration-proc) 35 | (let loop ([grid grid]) 36 | (define next-grid (iteration-proc grid)) 37 | (if (eqv? (seat-count grid) (seat-count next-grid)) 38 | (seat-count grid) 39 | (solve next-grid iteration-proc)))) 40 | 41 | (check-equal? (solve grid (λ (grid) (iterate grid adjacent-occupied-seats 4))) 2489) 42 | 43 | (check-equal? (solve grid (λ (grid) (iterate grid visible-occupied-seats 5))) 2180) -------------------------------------------------------------------------------- /2020/12.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file rackunit racket/dict) 3 | 4 | (define insts 5 | (for/list ([ln (file->lines "12.rktd")]) 6 | (match-define (list _ name dist) (regexp-match #px"(\\D+)(\\d+)" ln)) 7 | (cons (string->symbol name) (string->number dist)))) 8 | 9 | (define left-turn +i) 10 | (define right-turn -i) 11 | (define north +i) 12 | (define east (* north right-turn)) 13 | (define south (* east right-turn)) 14 | (define west (* south right-turn)) 15 | 16 | (define (manhattan-dist pos) (+ (abs (real-part pos)) (abs (imag-part pos)))) 17 | 18 | (define (solve insts [use-waypoint? #false]) 19 | (for/fold ([pos 0] 20 | [facing 1] 21 | [waypoint 10+i] 22 | #:result (manhattan-dist pos)) 23 | ([(name dist) (in-dict insts)]) 24 | (case name 25 | [(F) 26 | (define ref-point (if use-waypoint? waypoint facing)) 27 | (values (+ pos (* ref-point dist)) facing waypoint)] 28 | [(N E S W) 29 | (define direction (match name 30 | ['S south] 31 | ['N north] 32 | ['E east] 33 | ['W west])) 34 | (define next-pos (if use-waypoint? pos (+ pos (* direction dist)))) 35 | (values next-pos facing (+ waypoint (* direction dist)))] 36 | [(L R) 37 | (define rotation 38 | (expt (if (eq? name 'L) left-turn right-turn) (/ dist 90))) 39 | (values pos (* facing rotation) (* waypoint rotation))]))) 40 | 41 | (check-equal? (solve insts) 1496) 42 | (check-equal? (solve insts #t) 63843) -------------------------------------------------------------------------------- /2020/13.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file rackunit racket/dict) 3 | 4 | (match-define (cons target buses-all) 5 | (for/list ([tok 6 | (in-port read 7 | (open-input-string 8 | (string-replace (file->string "13.rktd") "," " ")))]) 9 | tok)) 10 | 11 | (define (overshoot bus) 12 | (for/last ([i (in-naturals)] 13 | #:final (> (* i bus) target)) 14 | (- (* i bus) target))) 15 | 16 | (define (solve-1) 17 | (define winner (argmin overshoot (filter integer? buses-all))) 18 | (* winner (overshoot winner))) 19 | 20 | (check-equal? (solve-1) 246) 21 | 22 | (define (solve-2) 23 | (define pairs (for/list ([(b i) (in-indexed buses-all)] 24 | #:when (integer? b)) 25 | (cons b i))) 26 | (for/fold ([t 0] 27 | [increment 1] 28 | #:result t) 29 | ([(bus overshoot) (in-dict pairs)]) 30 | (define mod-target (let loop ([overshoot overshoot]) 31 | (cond 32 | [(zero? overshoot) 0] 33 | [(< overshoot bus) (- bus overshoot)] 34 | [else (loop (- overshoot bus))]))) 35 | (define multiplier 36 | (for/first ([multiplier (in-naturals)] 37 | #:when (= (modulo (+ t (* increment multiplier)) bus) mod-target)) 38 | multiplier)) 39 | (values (+ t (* increment multiplier)) (* increment bus)))) 40 | 41 | (check-equal? (solve-2) 939490236001473) -------------------------------------------------------------------------------- /2020/13.rktd: -------------------------------------------------------------------------------- 1 | 1000066 2 | 13,x,x,41,x,x,x,37,x,x,x,x,x,659,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,19,x,x,x,23,x,x,x,x,x,29,x,409,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,17 -------------------------------------------------------------------------------- /2020/14.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file rackunit racket/dict math) 3 | 4 | (define insts 5 | (for/list ([ln (file->lines "14.rktd")]) 6 | (cond 7 | [(string-prefix? ln "mask = ") (string-trim ln "mask = ")] 8 | [else (apply cons (map string->number (cdr (regexp-match #px"^mem\\[(\\d+)\\] = (\\d+)$" ln))))]))) 9 | 10 | (define (cs2int cs) (string->number (list->string cs) 2)) 11 | (define (int2str int) (~r #:base 2 int #:min-width 36 #:pad-string "0")) 12 | 13 | (define (solve [decoder-version 1]) 14 | (define memory (make-hasheq)) 15 | (for/fold ([bitmask #f] 16 | #:result (apply + (hash-values memory))) 17 | ([inst (in-list insts)]) 18 | (match inst 19 | [(? string? new-bitmask) new-bitmask] 20 | [(cons loc val) 21 | (define value-to-store 22 | (cond 23 | [(eq? decoder-version 1) 24 | (cs2int (for/list ([val-char (in-string (int2str val))] 25 | [mask-char (in-string bitmask)]) 26 | (if (char=? mask-char #\X) val-char mask-char)))] 27 | [else val])) 28 | (define expanded-locs 29 | (cond 30 | [(eq? decoder-version 2) 31 | (for/fold ([locs '(())] 32 | #:result (map (λ (loc) (cs2int (reverse loc))) locs)) 33 | ([loc-char (in-string (int2str loc))] 34 | [mask-char (in-string bitmask)]) 35 | (append* (for/list ([loc (in-list locs)]) 36 | (match mask-char 37 | [#\0 (list (cons loc-char loc))] 38 | [#\1 (list (cons #\1 loc))] 39 | [_ (list (cons #\1 loc) (cons #\0 loc))]))))] 40 | [else (list loc)])) 41 | (for ([loc expanded-locs]) 42 | (hash-set! memory loc value-to-store)) 43 | bitmask]))) 44 | 45 | (check-equal? (solve) 13727901897109) 46 | (check-equal? (solve 2) 5579916171823) -------------------------------------------------------------------------------- /2020/15.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file rackunit) 3 | 4 | (define (solve str max-turns) 5 | (define nums (map string->number (string-split str ","))) 6 | (define previously-seen (make-hasheq)) 7 | (for ([(num turn) (in-indexed (drop-right nums 1))]) 8 | (hash-set! previously-seen num (add1 turn))) 9 | (for/fold ([last-seen (last nums)]) 10 | ([turn (in-range (add1 (length nums)) (add1 max-turns))]) 11 | (begin0 12 | (match (hash-ref previously-seen last-seen #false) 13 | [#false 0] 14 | [where-previously-seen (- (sub1 turn) where-previously-seen)]) 15 | (hash-set! previously-seen last-seen (sub1 turn))))) 16 | 17 | (check-equal? (solve "11,0,1,10,5,19" 2020) 870) 18 | (check-equal? (solve "11,0,1,10,5,19" 30000000) 9136) -------------------------------------------------------------------------------- /2020/17.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file rackunit) 3 | 4 | (define grid 5 | (for*/hash ([(row ridx) (in-indexed (file->lines "17.rktd"))] 6 | [(col cidx) (in-indexed row)]) 7 | (values (list 0 (make-rectangular cidx ridx)) col))) 8 | 9 | (define (seat-count grid) 10 | (count (λ (val) (char=? val #\#)) (hash-values grid))) 11 | 12 | (define offsets-3d (for*/list ([z '(1 0 -1)] 13 | [xy '(-1-1i -1 -1+i +i 1+i 1 1-i -i 0)] 14 | #:unless (and (zero? z) (zero? xy))) 15 | (list z xy))) 16 | 17 | (define offsets-4d 18 | (for*/list ([offset (cons '(0 0) offsets-3d)] 19 | [zadj '(+i 0 -i)] 20 | [nextval (in-value 21 | (list (+ zadj (first offset)) (second offset)))] 22 | #:unless (equal? nextval '(0 0))) 23 | nextval)) 24 | 25 | (define (adjacent-occupied-seats grid offsets k) 26 | (for/sum ([offset (in-list offsets)]) 27 | (let loop ([k (map + k offset)] [sum 0]) 28 | (match (hash-ref grid k #false) 29 | [#\# 1] 30 | [_ 0])))) 31 | 32 | (define (grow grid offsets) 33 | (define newgrid (make-hash)) 34 | (for* ([k (in-hash-keys grid)] 35 | [offset (cons '(0 0) offsets)]) 36 | (define newk (map + k offset)) 37 | (hash-ref! newgrid newk (hash-ref grid newk #\.))) 38 | newgrid) 39 | 40 | (define (iterate grid offsets) 41 | (for/hash ([(k v) (in-hash (grow grid offsets))]) 42 | (match v 43 | [#\# (values k (if (<= 2 (adjacent-occupied-seats grid offsets k) 3) #\# #\.))] 44 | [_ (values k (if (= (adjacent-occupied-seats grid offsets k) 3) #\# #\.))]))) 45 | 46 | (define (count-active grid) 47 | (count (λ (val) (char=? val #\#)) (hash-values grid))) 48 | 49 | (define (solve offsets) 50 | (for/fold ([grid grid] 51 | #:result (count-active grid)) 52 | ([i 6]) 53 | (iterate grid offsets))) 54 | 55 | (check-equal? (solve offsets-3d) 395) 56 | 57 | ;; warning: slow 58 | #;(check-equal? (solve offsets-4d) 2296) -------------------------------------------------------------------------------- /2020/17.rktd: -------------------------------------------------------------------------------- 1 | .####### 2 | #######. 3 | ###.###. 4 | #....### 5 | .#..##.. 6 | #.#.###. 7 | ###..### 8 | .#.#.##. -------------------------------------------------------------------------------- /2020/18.rkt: -------------------------------------------------------------------------------- 1 | #lang at-exp br 2 | (require racket/file rackunit br/module) 3 | 4 | @module/lang[parser1]{ 5 | #lang brag 6 | op : [op ("+" | "*")] term 7 | @"@"term : /"(" op /")" | digit 8 | @"@"digit : "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" 9 | } 10 | 11 | (require (prefix-in parser1: 'parser1)) 12 | 13 | (define (op . xs) 14 | (match xs 15 | [(list left opstr right) ((if (equal? opstr "*") * +) left (op right))] 16 | [(list (? number? num)) num] 17 | [(list (app string->number num)) num])) 18 | 19 | (define-namespace-anchor ns) 20 | 21 | (define ((solve parser) str) 22 | (eval (parser (regexp-match* #px"\\S" str)) (namespace-anchor->namespace ns))) 23 | 24 | (check-equal? (apply + (map (solve parser1:parse) (file->lines "18.rktd"))) 9535936849815) 25 | 26 | @module/lang[parser2]{ 27 | #lang brag 28 | prod : [prod "*"] sum 29 | sum : [sum "+"] term 30 | @"@"term : /"(" prod /")" | digit 31 | @"@"digit : "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" 32 | } 33 | 34 | (define prod op) 35 | (define sum op) 36 | 37 | (require (prefix-in parser2: 'parser2)) 38 | (check-equal? 39 | (apply + (map (solve parser2:parse) (file->lines "18.rktd"))) 472171581333710) -------------------------------------------------------------------------------- /2020/19.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file rackunit br/module) 3 | 4 | (begin-for-syntax 5 | (require racket/match racket/string racket/file) 6 | (define rules 7 | (let* ([str (file->string "19.rktd")] 8 | [str (car (string-split str "\n\n"))] 9 | [strs (string-split str "\n")]) 10 | (sort strs stringstring "19.rktd") "\n\n")) "\n")) 25 | 26 | (define (solve parser) 27 | (for/sum ([sample samples]) 28 | (with-handlers ([exn:fail? (λ (exn) 0)]) 29 | (parser sample) 30 | 1))) 31 | 32 | (check-equal? (solve parser1:parse) 129) 33 | 34 | (begin-for-syntax 35 | (set! rules 36 | (for/list ([rule rules]) 37 | (match rule 38 | ["8: 42" "8: 42 | 42 8"] 39 | ["11: 42 31" "11: 42 31 | 42 11 31"] 40 | [_ rule])))) 41 | 42 | (make-parser-submodule parser2) 43 | (require (prefix-in parser2: 'parser2)) 44 | (check-equal? (solve parser2:parse) 243) -------------------------------------------------------------------------------- /2020/21.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file rackunit racket/set) 3 | 4 | (struct rec (ingredients allergens) #:transparent) 5 | 6 | (define (parse-recs str) 7 | (for/list ([r (in-list (string-split str "\n"))]) 8 | (match-define (list head tail) (string-split r "(contains ")) 9 | (rec 10 | (apply set (string-split head)) 11 | (apply set (string-split (string-trim tail ")") ", "))))) 12 | 13 | (define recs (parse-recs (file->string "21.rktd"))) 14 | 15 | (define all-allergens (apply set-union (map rec-allergens recs))) 16 | 17 | (define filtered-recs 18 | (for/list ([allergen (in-set all-allergens)]) 19 | (define recs-with-allergen 20 | (filter (λ (r) (set-member? (rec-allergens r) allergen)) recs)) 21 | (rec (apply set-intersect (map rec-ingredients recs-with-allergen)) 22 | (set allergen)))) 23 | 24 | (define allergenic-records 25 | (let loop ([acc null][filtered-recs filtered-recs]) 26 | (cond 27 | [(null? filtered-recs) acc] 28 | [else 29 | (define-values (singletons others) 30 | (partition (λ (r) (= 1 (set-count (rec-ingredients r)))) filtered-recs)) 31 | (loop (append singletons acc) 32 | (for/list ([other (in-list others)]) 33 | (rec (apply set-subtract (rec-ingredients other) 34 | (map rec-ingredients singletons)) 35 | (rec-allergens other))))]))) 36 | 37 | (define allergenic-ingredients 38 | (apply set-union (map rec-ingredients allergenic-records))) 39 | 40 | (define (hypoallergenic-ingredient-count recs) 41 | (for/sum ([r (in-list recs)]) 42 | (set-count (set-subtract (rec-ingredients r) allergenic-ingredients)))) 43 | 44 | (check-equal? (hypoallergenic-ingredient-count recs) 1958) 45 | 46 | (define ingredient-list 47 | (let* ([pairs (for/list ([r (in-list allergenic-records)]) 48 | (car (map cons (set->list (rec-ingredients r)) 49 | (set->list (rec-allergens r)))))] 50 | [pairs (sort pairs #:key cdr stringstring "22.rktd")] 8 | [strs (string-split str "\n\n")]) 9 | (map (λ (str) (cdr (map string->number (string-split str "\n")))) strs))) 10 | 11 | (define (play-game p1s p2s [recursive #false]) 12 | (define game-states (mutable-set)) 13 | (let/ec exit 14 | (for/fold ([p1s p1s] [p2s p2s] 15 | #:result (if (empty? p1s) (result 'p2 p2s) (result 'p1 p1s))) 16 | ([i (in-naturals)] 17 | #:break (or (empty? p1s) (empty? p2s))) 18 | (match-define (list (cons p1 p1s-rest) (cons p2 p2s-rest)) (list p1s p2s)) 19 | (define (p1-wins) (values (append p1s-rest (list p1 p2)) p2s-rest)) 20 | (define (p2-wins) (values p1s-rest (append p2s-rest (list p2 p1)))) 21 | (cond 22 | [(and recursive 23 | (let ([game-state (cons p1s p2s)]) 24 | (when (set-member? game-states game-state) 25 | (exit (result 'p1 p1s))) 26 | (set-add! game-states game-state)) 27 | (<= p1 (length p1s-rest)) (<= p2 (length p2s-rest))) 28 | (match (play-game (take p1s-rest p1) (take p2s-rest p2) #true) 29 | [(result 'p1 _) (p1-wins)] 30 | [_ (p2-wins)])] 31 | [(> p1 p2) (p1-wins)] 32 | [else (p2-wins)])))) 33 | 34 | (define (winner->score winner) 35 | (for/sum ([(val i) (in-indexed (reverse (result-cards winner)))]) 36 | (* val (add1 i)))) 37 | 38 | (check-equal? (winner->score (play-game p1s p2s)) 30138) 39 | 40 | (check-equal? (winner->score (play-game p1s p2s #true)) 31587) -------------------------------------------------------------------------------- /2020/22.rktd: -------------------------------------------------------------------------------- 1 | Player 1: 2 | 29 3 | 30 4 | 44 5 | 35 6 | 27 7 | 2 8 | 4 9 | 38 10 | 45 11 | 33 12 | 50 13 | 21 14 | 17 15 | 11 16 | 25 17 | 40 18 | 5 19 | 43 20 | 41 21 | 24 22 | 12 23 | 19 24 | 23 25 | 8 26 | 42 27 | 28 | Player 2: 29 | 32 30 | 13 31 | 22 32 | 7 33 | 31 34 | 16 35 | 37 36 | 6 37 | 10 38 | 20 39 | 47 40 | 46 41 | 34 42 | 39 43 | 1 44 | 26 45 | 49 46 | 9 47 | 48 48 | 36 49 | 14 50 | 15 51 | 3 52 | 18 53 | 28 54 | -------------------------------------------------------------------------------- /2020/23.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file rackunit racket/set) 3 | 4 | (define ints (map string->number (regexp-match* #rx"." "389547612"))) 5 | 6 | (define (solve ints [max-int 9] [turns 100] [string-result? #true]) 7 | 8 | (define cups (let* ([ints (if (= max-int (apply max ints)) 9 | ints 10 | (append ints (for/list ([i (in-range 1 (add1 max-int))] 11 | #:unless (memq i ints)) 12 | i)))] 13 | [cups (make-vector (length ints))]) 14 | (for ([int (in-list ints)] 15 | [next (in-list (append (cdr ints) (list (car ints))))]) 16 | (vector-set! cups (sub1 int) next)) 17 | cups)) 18 | 19 | (define (cup-next val) 20 | (vector-ref cups (sub1 val))) 21 | 22 | (define (link-cups! this next) 23 | (vector-set! cups (sub1 this) next)) 24 | 25 | (define (next-cups start count) 26 | (cdr (reverse (foldl (λ (val acc) (cons (cup-next (car acc)) acc)) 27 | (list start) 28 | (range count))))) 29 | 30 | (define min-cup-val (apply min ints)) 31 | (define max-cup-val max-int) 32 | 33 | (for/fold ([current (first ints)] 34 | #:result (void)) 35 | ([turn (in-range turns)]) 36 | (match-define (list cup1 cup2 cup3 cup4) (next-cups current 4)) 37 | (link-cups! current cup4) 38 | (define dest (let ([pickup-vals (list cup1 cup2 cup3)]) 39 | (let loop ([dest (sub1 current)]) 40 | (cond 41 | [(< dest min-cup-val) (loop max-cup-val)] 42 | [(memq dest pickup-vals) (loop (sub1 dest))] 43 | [else dest])))) 44 | (link-cups! cup3 (cup-next dest)) 45 | (link-cups! dest cup1) 46 | (cup-next current)) 47 | 48 | (if string-result? 49 | (string-append* (map ~a (next-cups 1 (sub1 (vector-length cups))))) 50 | (apply * (next-cups 1 2)))) 51 | 52 | (check-equal? (solve ints 9 100) "45286397") 53 | (check-equal? (solve ints 1000000 10000000 #f) 836763710) 54 | -------------------------------------------------------------------------------- /2020/24.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file rackunit) 3 | 4 | (define (lex-1 port) 5 | (match (regexp-match #rx"^se|nw|sw|ne|w|e" port) 6 | [#false eof] 7 | [(list str) str])) 8 | 9 | (define tokss (for/list ([ln (in-list (file->lines "24.rktd"))]) 10 | (for/list ([tok (in-port lex-1 (open-input-string ln))]) 11 | tok))) 12 | 13 | (define (tok->delta tok) 14 | (match tok 15 | [#"w" -1] 16 | [#"e" 1] 17 | [#"nw" -i] 18 | [#"ne" 1-i] 19 | [#"sw" -1+i] 20 | [#"se" +i])) 21 | 22 | (define white -1) 23 | (define black 1) 24 | (define black? positive?) 25 | 26 | (define (make-initial-floor tokss) 27 | (define floor (make-hasheqv)) 28 | (for ([toks (in-list tokss)]) 29 | (hash-update! floor (apply + (map tok->delta toks)) - white)) 30 | floor) 31 | 32 | (define deltas '(1 -1 -i 1-i -1+i +i)) 33 | 34 | (define (grow! floor) 35 | (for* ([k (in-list (hash-keys floor))] 36 | [delta (in-list deltas)]) 37 | (hash-ref! floor (+ k delta) white))) 38 | 39 | (define (adjacent-black-tiles floor k) 40 | (for/sum ([delta (in-list deltas)] 41 | #:when (black? (hash-ref floor (+ k delta) white))) 42 | 1)) 43 | 44 | (define (iterate floor num) 45 | (for ([i (in-range num)]) 46 | (grow! floor) 47 | (define fliplist 48 | (for/list ([(k v) (in-hash floor)] 49 | #:when (let ([abt (adjacent-black-tiles floor k)]) 50 | (cond 51 | [(and (black? v) (or (zero? abt) (< 2 abt)))] 52 | [(and (not (black? v)) (= 2 abt))] 53 | [else #false]))) 54 | k)) 55 | (for ([k (in-list fliplist)]) 56 | (hash-update! floor k -))) 57 | floor) 58 | 59 | (define floor (make-initial-floor tokss)) 60 | (check-equal? (count black? (hash-values floor)) 436) 61 | (check-equal? (count black? (hash-values (iterate floor 100))) 4133) -------------------------------------------------------------------------------- /2020/25.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file rackunit) 3 | 4 | (match-define (list card-pubkey door-pubkey) '(18356117 5909654)) 5 | 6 | (define (transform subject-number [break-proc void]) 7 | (for/fold ([val 1] 8 | [count 0] 9 | #:result (cons val count)) 10 | ([i (in-naturals)] 11 | #:break (break-proc val i)) 12 | (values (remainder (* val subject-number) 20201227) (add1 count)))) 13 | 14 | (define card-loop-size (cdr (transform 7 (λ (val i) (eq? val card-pubkey))))) 15 | (define door-loop-size (cdr (transform 7 (λ (val i) (eq? val door-pubkey))))) 16 | 17 | (check-equal? (car (transform card-pubkey (λ (val i) (eq? i door-loop-size)))) 16902792) -------------------------------------------------------------------------------- /2021/01.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file rackunit) 3 | 4 | (define depths (map string->number (file->lines "01.rktd"))) 5 | 6 | (define (positive-deltas depths) 7 | (filter positive? 8 | (for/list ([d1 (in-list depths)] 9 | [d2 (in-list (cdr depths))]) 10 | (- d2 d1)))) 11 | 12 | (check-equal? (length (positive-deltas depths)) 1167) 13 | 14 | (define (trios depths) 15 | (for/list ([d1 (in-list depths)] 16 | [d2 (in-list (cdr depths))] 17 | [d3 (in-list (cddr depths))]) 18 | (+ d1 d2 d3))) 19 | 20 | (check-equal? (length (positive-deltas (trios depths))) 1130) -------------------------------------------------------------------------------- /2021/02.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file sugar/list rackunit) 3 | 4 | (define instructions 5 | (slice-at (for/list ([datum (in-port read (open-input-file "02.rktd"))]) 6 | datum) 2)) 7 | 8 | (define (solve matcher) 9 | (for/fold ([pos 0] 10 | [depth 0] 11 | [aim 0] 12 | #:result (* pos depth)) 13 | ([i (in-list instructions)]) 14 | (matcher pos depth aim i))) 15 | 16 | (define (solve-1) 17 | (solve (λ (pos depth aim i) 18 | (match i 19 | [(list 'forward amt) (values (+ pos amt) depth aim)] 20 | [(list 'down amt) (values pos (+ depth amt) aim)] 21 | [(list 'up amt) (values pos (- depth amt) aim)])))) 22 | 23 | (check-equal? (solve-1) 1488669) 24 | 25 | (define (solve-2) 26 | (solve (λ (pos depth aim i) 27 | (match i 28 | [(list 'forward amt) (values (+ pos amt) (+ depth (* aim amt)) aim)] 29 | [(list 'down amt) (values pos depth (+ aim amt))] 30 | [(list 'up amt) (values pos depth (- aim amt))])))) 31 | 32 | (check-equal? (solve-2) 1176514794) -------------------------------------------------------------------------------- /2021/03.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file rackunit) 3 | 4 | (define lines (map string->list (file->lines "03.rktd"))) 5 | (define (digit-columns lines) (apply map list lines)) 6 | 7 | (define (most-common-digit chars) 8 | (define zeroes (count (λ (c) (char=? c #\0)) chars)) 9 | (define most-threshold (/ (length chars) 2)) 10 | (cond 11 | [(= zeroes most-threshold) #f] 12 | [(> zeroes most-threshold) #\0] 13 | [else #\1])) 14 | 15 | (define (least-common-digit chars) 16 | (match (most-common-digit chars) 17 | [#false #false] 18 | [#\0 #\1] 19 | [_ #\0])) 20 | 21 | (define (chars->binary-number chars) 22 | (string->number (list->string chars) 2)) 23 | 24 | (define gamma-rate (chars->binary-number (map most-common-digit (digit-columns lines)))) 25 | (define epsilon-rate (chars->binary-number (map least-common-digit (digit-columns lines)))) 26 | 27 | (check-equal? (* gamma-rate epsilon-rate) 4174964) 28 | 29 | (define (find-digit proc default) 30 | (for/fold ([lines lines] 31 | #:result (chars->binary-number (car lines))) 32 | ([i (in-range (length (car lines)))] 33 | #:break (= (length lines) 1)) 34 | (define target (or (proc (list-ref (digit-columns lines) i)) default)) 35 | (filter (λ (line) (char=? (list-ref line i) target)) lines))) 36 | 37 | (define oxygen-rate (find-digit most-common-digit #\1)) 38 | (define co2-rate (find-digit least-common-digit #\0)) 39 | 40 | (check-equal? (* oxygen-rate co2-rate) 4474944) -------------------------------------------------------------------------------- /2021/04.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file sugar rackunit) 3 | 4 | (define lines (file->lines "04.rktd")) 5 | 6 | (define numbers-to-draw (map string->number (string-split (string-replace (car lines) "," " ")))) 7 | 8 | (define boards 9 | (map list->vector (slice-at (map string->number (string-split (string-join (cdr lines)))) 25))) 10 | 11 | (define winning-lines 12 | (let () 13 | (define rows '((0 1 2 3 4) (5 6 7 8 9) (10 11 12 13 14) (15 16 17 18 19) (20 21 22 23 24))) 14 | (define cols (apply map list rows)) 15 | (append rows cols))) 16 | 17 | (define (board-wins board) 18 | (for/or ([winning-line winning-lines]) 19 | (for/and ([idx winning-line]) 20 | (eq? (vector-ref board idx) #true)))) 21 | 22 | (define (run-game boards) 23 | (for*/fold ([boards boards] 24 | [winners null] 25 | #:result (reverse winners)) 26 | ([number numbers-to-draw] 27 | #:break (empty? boards)) 28 | (for ([board boards]) 29 | (define pos-of-number (vector-member number board)) 30 | (when pos-of-number 31 | (vector-set! board pos-of-number #true))) 32 | (define-values (new-winners losers) (partition board-wins boards)) 33 | (values losers (append (for/list ([winner new-winners]) 34 | (cons number winner)) winners)))) 35 | 36 | (define (calc-score res) 37 | (match res 38 | [(cons last-number board) (* last-number (apply + (filter number? (vector->list board))))])) 39 | 40 | (define results (run-game boards)) 41 | (check-equal? (calc-score (first results)) 64084) 42 | (check-equal? (calc-score (last results)) 12833) 43 | 44 | -------------------------------------------------------------------------------- /2021/05.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file sugar rackunit racket/set) 3 | 4 | (define lines (map (λ (s) (map (λ (s2) (define ints (map string->number (string-split s2 ","))) 5 | (+ (first ints) (* +i (second ints)))) (string-split s " -> "))) (file->lines "05.rktd"))) 6 | 7 | (define (Line-not-diagonal line) 8 | (match line 9 | [(list left right) (or (= (real-part left) (real-part right)) (= (imag-part left) (imag-part right)))])) 10 | 11 | ;; why does make-polar cause the solution to run faster? 12 | ;; both functions create an imaginary number 13 | ;; make-polar is slower to create the numbers (because it has to call trig functions) 14 | ;; but storing the polar numbers with frequency-hash is much faster 15 | ;; using inexact coefficients makes make-rectangular go faster 16 | ;; but still not as fast as make-polar 17 | (define go-fast? #true) 18 | (define imag-func (if go-fast? make-polar make-rectangular)) 19 | 20 | (define (expand line) 21 | (match-define (list x1 x2) (map real-part line)) 22 | (match-define (list y1 y2) (map imag-part line)) 23 | (cond 24 | [(= x1 x2) 25 | (for/list ([i (in-range (apply min (list y1 y2)) (add1 (apply max (list y1 y2))))]) 26 | (imag-func x1 i))] 27 | [(= y1 y2) 28 | (for/list ([i (in-range (apply min (list x1 x2)) (add1 (apply max (list x1 x2))))]) 29 | (imag-func i y1))] 30 | [else (for/list ([x (in-range x1 ((if (> x1 x2) sub1 add1) x2) (if (> x1 x2) -1 1))] 31 | [y (in-range y1 ((if (> y1 y2) sub1 add1) y2) (if (> y1 y2) -1 1))]) 32 | (imag-func x y))])) 33 | 34 | (define (calc-result points) 35 | (length (filter (λ (x) (>= x 2)) (hash-values (time (frequency-hash points)))))) 36 | 37 | (check-equal? (calc-result (append-map expand (filter Line-not-diagonal lines))) 6113) 38 | (check-equal? (calc-result (append-map expand lines)) 20373) -------------------------------------------------------------------------------- /2021/06.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file sugar rackunit) 3 | 4 | (define fish (map string->number (string-split (file->string "06.rktd") ","))) 5 | 6 | (define (simulate fish days) 7 | (for/fold ([freqs (frequency-hash fish)] 8 | #:result (apply + (hash-values freqs))) 9 | ([d (in-range days)]) 10 | (hash-set* 11 | (for/hasheq ([(k v) (in-hash freqs)] 12 | #:unless (zero? k)) 13 | (values (sub1 k) v)) 14 | 6 (+ (hash-ref freqs 7 0) (hash-ref freqs 0 0)) 15 | 8 (hash-ref freqs 0 0)))) 16 | 17 | (check-equal? (simulate fish 80) 361169) 18 | (check-equal? (simulate fish 256) 1634946868992) -------------------------------------------------------------------------------- /2021/06.rktd: -------------------------------------------------------------------------------- 1 | 1,1,3,5,3,1,1,4,1,1,5,2,4,3,1,1,3,1,1,5,5,1,3,2,5,4,1,1,5,1,4,2,1,4,2,1,4,4,1,5,1,4,4,1,1,5,1,5,1,5,1,1,1,5,1,2,5,1,1,3,2,2,2,1,4,1,1,2,4,1,3,1,2,1,3,5,2,3,5,1,1,4,3,3,5,1,5,3,1,2,3,4,1,1,5,4,1,3,4,4,1,2,4,4,1,1,3,5,3,1,2,2,5,1,4,1,3,3,3,3,1,1,2,1,5,3,4,5,1,5,2,5,3,2,1,4,2,1,1,1,4,1,2,1,2,2,4,5,5,5,4,1,4,1,4,2,3,2,3,1,1,2,3,1,1,1,5,2,2,5,3,1,4,1,2,1,1,5,3,1,4,5,1,4,2,1,1,5,1,5,4,1,5,5,2,3,1,3,5,1,1,1,1,3,1,1,4,1,5,2,1,1,3,5,1,1,4,2,1,2,5,2,5,1,1,1,2,3,5,5,1,4,3,2,2,3,2,1,1,4,1,3,5,2,3,1,1,5,1,3,5,1,1,5,5,3,1,3,3,1,2,3,1,5,1,3,2,1,3,1,1,2,3,5,3,5,5,4,3,1,5,1,1,2,3,2,2,1,1,2,1,4,1,2,3,3,3,1,3,5 -------------------------------------------------------------------------------- /2021/07.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file sugar rackunit) 3 | 4 | (define posns (map string->number (string-split (file->string "07.rktd") ","))) 5 | 6 | (define/caching (gauss-summation x) (* (/ x 2) (+ x 1))) 7 | 8 | (define (fuel-cost alignment [post-proc values]) 9 | (foldl (λ (posn res) (+ res (post-proc (abs (- alignment posn))))) 0 posns)) 10 | 11 | (define possible-alignments (remove-duplicates posns)) 12 | (check-equal? (apply min (map fuel-cost possible-alignments)) 349357) 13 | (check-equal? (apply min (map (λ (pa) (fuel-cost pa gauss-summation)) possible-alignments)) 96708205) -------------------------------------------------------------------------------- /2021/09.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file rackunit) 3 | 4 | (define depths 5 | (for*/hasheqv ([(line lidx) (in-indexed (file->lines "09.rktd"))] 6 | [(depth cidx) (in-indexed line)]) 7 | (values (make-rectangular cidx lidx) (string->number (string depth))))) 8 | 9 | (define (neighbors loc) 10 | (for*/list ([delta '(1 -1)] 11 | [ifactor '(1 +i)]) 12 | (+ loc (* delta ifactor)))) 13 | 14 | (define (low? loc) 15 | (< (hash-ref depths loc) 16 | (apply min (filter-map (λ (li) (hash-ref depths li #f)) (neighbors loc))))) 17 | 18 | (define low-locs (for/list ([(loc depth) (in-hash depths)] 19 | #:when (low? loc)) 20 | loc)) 21 | 22 | (check-equal? (apply + (map (λ (lp) (add1 (hash-ref depths lp))) low-locs)) 539) 23 | 24 | (define (higher-adjacent loc) 25 | (for/list ([neighbor (neighbors loc)] 26 | #:when (and 27 | (hash-has-key? depths neighbor) 28 | (not (= (hash-ref depths neighbor) 9)) 29 | (< (hash-ref depths loc) (hash-ref depths neighbor)))) 30 | neighbor)) 31 | 32 | (define (basin-at loc) 33 | (remove-duplicates (cons loc (append-map basin-at (higher-adjacent loc))))) 34 | 35 | (define basin-sizes (map length (map basin-at low-locs))) 36 | (check-equal? (apply * (take (sort basin-sizes >) 3)) 736920) -------------------------------------------------------------------------------- /2021/10.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file rackunit) 3 | 4 | (define lines (map string->list (file->lines "10.rktd"))) 5 | (define left-toks (list #\[ #\( #\{ #\<)) 6 | (define right-toks (list #\] #\) #\} #\>)) 7 | (define duos (map list left-toks right-toks)) 8 | (define (matched-pair? left right) (member (list left right) duos)) 9 | 10 | (define (parse tokens) 11 | (with-handlers ([char? values]) 12 | (let loop ([tokens tokens][lefts null]) 13 | (cond 14 | [(empty? tokens) lefts] 15 | [(memv (car tokens) left-toks) 16 | (loop (cdr tokens) (cons (car tokens) lefts))] 17 | [(and (pair? lefts) (matched-pair? (car lefts) (car tokens))) 18 | (loop (cdr tokens) (cdr lefts))] 19 | [else (raise (car tokens))])))) 20 | 21 | (define (corrupt? parsed-line) 22 | (case parsed-line 23 | [(#\)) 3] 24 | [(#\]) 57] 25 | [(#\}) 1197] 26 | [(#\>) 25137] 27 | [else #f])) 28 | 29 | (check-equal? (apply + (filter-map corrupt? (map parse lines))) 366027) 30 | 31 | (define (autocomplete-score parsed-line) 32 | (for/fold ([total 0]) 33 | ([c parsed-line]) 34 | (+ (* total 5) (case c 35 | [(#\() 1] 36 | [(#\[) 2] 37 | [(#\{) 3] 38 | [(#\<) 4])))) 39 | 40 | (define autocomplete-scores 41 | (map autocomplete-score (filter-not corrupt? (map parse lines)))) 42 | 43 | (check-equal? (list-ref (sort autocomplete-scores >) (floor (/ (length autocomplete-scores) 2))) 1118645287) -------------------------------------------------------------------------------- /2021/11.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file rackunit) 3 | 4 | (define (make-octopodes) 5 | (define octopodes (make-hasheqv)) 6 | (for* ([(line lidx) (in-indexed (file->lines "11.rktd"))] 7 | [(depth cidx) (in-indexed line)]) 8 | (hash-set! octopodes (make-rectangular cidx lidx) (string->number (string depth)))) 9 | octopodes) 10 | 11 | (define octopodes (make-octopodes)) 12 | 13 | (define (neighbors loc) 14 | (remove loc 15 | (for*/list ([rd '(-1 0 1)] 16 | [id '(-1 0 1)]) 17 | (+ loc (make-rectangular rd id))))) 18 | 19 | (define (increment! loc) 20 | (cond 21 | [(number? (hash-ref octopodes loc #false)) 22 | (define next-val 23 | (match (modulo (add1 (hash-ref octopodes loc)) 10) 24 | [0 'flashed] 25 | [val val])) 26 | (hash-set! octopodes loc next-val) 27 | (when (eq? next-val 'flashed) 28 | (for-each increment! (neighbors loc)))])) 29 | 30 | (define (find-flashes-and-reset) 31 | (for/list ([(loc val) (in-hash octopodes)] 32 | #:when (eq? val 'flashed)) 33 | (hash-set! octopodes loc 0) 34 | loc)) 35 | 36 | (define (part-1) 37 | (for/fold ([flashes null] 38 | #:result (length flashes)) 39 | ([step (in-range 100)]) 40 | (for-each increment! (hash-keys octopodes)) 41 | (append (find-flashes-and-reset) flashes))) 42 | 43 | (check-equal? (part-1) 1705) 44 | 45 | (set! octopodes (make-octopodes)) 46 | 47 | (define (part-2) 48 | (for/or ([step (in-naturals)]) 49 | (for-each increment! (hash-keys octopodes)) 50 | (and (= (length (find-flashes-and-reset)) (length (hash-keys octopodes))) (add1 step)))) 51 | 52 | (check-equal? (part-2) 265) 53 | -------------------------------------------------------------------------------- /2021/11.rktd: -------------------------------------------------------------------------------- 1 | 3113284886 2 | 2851876144 3 | 2774664484 4 | 6715112578 5 | 7146272153 6 | 6256656367 7 | 3148666245 8 | 3857446528 9 | 7322422833 10 | 8152175168 -------------------------------------------------------------------------------- /2021/12.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file sugar rackunit racket/set racket/bool) 3 | 4 | (define links (for/set ([line (file->lines "12.rktd")]) 5 | (list->set (string-split line "-")))) 6 | 7 | (define (is-downcase? loc) (equal? (string-downcase loc) loc)) 8 | 9 | (define (paths-from last-loc links [small-caves (set)]) 10 | (match last-loc 11 | ["end" '(("end"))] 12 | [loc #:when (and small-caves (set-member? small-caves loc)) 13 | (define pruned-links 14 | (for*/set ([previous-locs (in-value (set-remove small-caves loc))] 15 | [link links] 16 | #:when (set-empty? (set-intersect link previous-locs))) 17 | link)) 18 | (paths-from last-loc pruned-links #false)] 19 | [loc 20 | (define next-lc-visited (cond 21 | [(false? small-caves) #false] 22 | [(and (is-downcase? loc) (not (equal? loc "start"))) 23 | (set-add small-caves loc)] 24 | [else small-caves])) 25 | (define links-with-loc (for/set ([link links] 26 | #:when (set-member? link loc)) 27 | link)) 28 | (define remaining-links (if (or (equal? loc "start") 29 | (and (is-downcase? loc) (not small-caves))) 30 | (set-subtract links links-with-loc) 31 | links)) 32 | (for*/list ([link links-with-loc] 33 | [next-loc (in-value (set-first (set-remove link loc)))] 34 | [path (paths-from next-loc remaining-links next-lc-visited)]) 35 | (cons loc path))])) 36 | 37 | (check-equal? (length (paths-from "start" links #f)) 5576) 38 | (check-equal? (length (paths-from "start" links)) 152837) -------------------------------------------------------------------------------- /2021/12.rktd: -------------------------------------------------------------------------------- 1 | QR-da 2 | QR-end 3 | QR-al 4 | start-op 5 | zh-iw 6 | zh-start 7 | da-PF 8 | op-bj 9 | iw-QR 10 | end-HR 11 | bj-PF 12 | da-LY 13 | op-PF 14 | bj-iw 15 | end-da 16 | bj-zh 17 | HR-iw 18 | zh-op 19 | zh-PF 20 | HR-bj 21 | start-PF 22 | HR-da 23 | QR-bj 24 | -------------------------------------------------------------------------------- /2021/13.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file sugar rackunit racket/set) 3 | 4 | (define-values (point-strs fold-strs) (splitf-at (file->lines "13.rktd") non-empty-string?)) 5 | 6 | (define points 7 | (for/seteqv ([str point-strs]) 8 | (apply make-rectangular (map string->number (string-split (string-replace str "," " ")))))) 9 | 10 | (define creases 11 | (for/list ([str fold-strs] 12 | #:when (non-empty-string? str)) 13 | (match (string-split str "=") 14 | [(list "fold along y" numstr) (* +i (string->number numstr))] 15 | [(list "fold along x" numstr) (string->number numstr)]))) 16 | 17 | (define (do-crease points [stop-at +inf.0]) 18 | (for/fold ([points points]) 19 | ([crease creases] 20 | [i (in-range stop-at)]) 21 | (for/seteqv ([pt points]) 22 | (define imag-diff (- (imag-part pt) (imag-part crease))) 23 | (define real-diff (- (real-part pt) (real-part crease))) 24 | (cond 25 | [(and (zero? (real-part crease)) (positive? imag-diff)) 26 | (+ (real-part pt) (* +i (- (imag-part crease) imag-diff)))] 27 | [(and (zero? (imag-part crease)) (positive? real-diff)) 28 | (+ (- (real-part crease) real-diff) (* +i (imag-part pt)))] 29 | [else pt])))) 30 | 31 | (check-equal? (set-count (do-crease points 1)) 706) 32 | 33 | (define matrix (do-crease points)) 34 | (for-each displayln 35 | (map string-join 36 | (for/list ([row (add1 (apply max (map imag-part (set->list matrix))))]) 37 | (for/list ([col (add1 (apply max (map real-part (set->list matrix))))]) 38 | (if (set-member? matrix (make-rectangular col row)) "X" " "))))) 39 | ;; draws word LRFJBJEH 40 | 41 | -------------------------------------------------------------------------------- /2021/14.rktd: -------------------------------------------------------------------------------- 1 | BVBNBVPOKVFHBVCSHCFO 2 | 3 | SO -> V 4 | PB -> P 5 | HV -> N 6 | VF -> O 7 | KS -> F 8 | BB -> C 9 | SH -> H 10 | SB -> C 11 | FS -> F 12 | PV -> F 13 | BC -> K 14 | SF -> S 15 | NO -> O 16 | SK -> C 17 | PO -> N 18 | VK -> F 19 | FC -> C 20 | VV -> S 21 | SV -> S 22 | HH -> K 23 | FH -> K 24 | HN -> O 25 | NP -> F 26 | PK -> N 27 | VO -> K 28 | NC -> C 29 | KP -> B 30 | CS -> C 31 | KO -> F 32 | BK -> N 33 | OO -> N 34 | CF -> H 35 | KN -> C 36 | BV -> S 37 | OK -> O 38 | CN -> F 39 | OP -> O 40 | VP -> N 41 | OC -> P 42 | NH -> C 43 | VN -> S 44 | VC -> B 45 | NF -> H 46 | FO -> H 47 | CC -> B 48 | KB -> N 49 | CP -> N 50 | HK -> N 51 | FB -> H 52 | BH -> V 53 | BN -> N 54 | KC -> F 55 | CV -> K 56 | SP -> V 57 | VS -> P 58 | KF -> S 59 | CH -> V 60 | NS -> N 61 | HS -> O 62 | CK -> K 63 | NB -> O 64 | OF -> K 65 | VB -> N 66 | PS -> B 67 | KH -> P 68 | BS -> C 69 | VH -> C 70 | KK -> F 71 | FN -> F 72 | BP -> B 73 | HF -> O 74 | HB -> V 75 | OV -> H 76 | NV -> N 77 | HO -> S 78 | OS -> H 79 | SS -> K 80 | BO -> V 81 | OB -> K 82 | HP -> P 83 | CO -> B 84 | PP -> K 85 | HC -> N 86 | BF -> S 87 | NK -> S 88 | ON -> P 89 | PH -> C 90 | FV -> H 91 | CB -> H 92 | PC -> K 93 | FF -> P 94 | PN -> P 95 | NN -> O 96 | PF -> F 97 | SC -> C 98 | FK -> K 99 | SN -> K 100 | KV -> P 101 | FP -> B 102 | OH -> F 103 | -------------------------------------------------------------------------------- /2021/15.rkt: -------------------------------------------------------------------------------- 1 | #lang br 2 | (require racket/file graph rackunit) 3 | 4 | (define lines (file->lines "15.rktd")) 5 | 6 | (define grid (for*/list ([(line ridx) (in-indexed lines)] 7 | [(num cidx) (in-indexed (map string->number (regexp-match* #rx"." line)))]) 8 | (cons (make-rectangular cidx ridx) num))) 9 | 10 | (define data (make-hash grid)) 11 | 12 | (define (row-length data) (add1 (apply max (map imag-part (hash-keys data))))) 13 | (define (col-length data) (add1 (apply max (map real-part (hash-keys data))))) 14 | 15 | (define (make-grid-graph data) 16 | (define rows (row-length data)) 17 | (define cols (col-length data)) 18 | (define g (weighted-graph/directed null)) 19 | (for ([k (in-hash-keys data)]) 20 | (add-vertex! g k)) 21 | (define (edges-between pt0 pt1) 22 | (add-directed-edge! g pt0 pt1 (hash-ref data pt1)) 23 | (add-directed-edge! g pt1 pt0 (hash-ref data pt0))) 24 | (for ([v (in-vertices g)]) 25 | (unless (= (real-part v) (sub1 cols)) 26 | (edges-between v (add1 v))) 27 | (unless (= (imag-part v) (sub1 rows)) 28 | (edges-between v (+ +i v)))) 29 | g) 30 | 31 | (define (preds->path preds dest) 32 | (for/fold ([path (list dest)]) 33 | ([i (in-naturals)] 34 | #:break (zero? (car path))) 35 | (cons (hash-ref preds (car path)) path))) 36 | 37 | (define (solve data) 38 | (define g (make-grid-graph data)) 39 | (define-values (paths preds) (dijkstra g 0)) 40 | (define dest (make-rectangular (sub1 (col-length data)) (sub1 (row-length data)))) 41 | (hash-ref paths dest)) 42 | (check-equal? (solve data) 487) 43 | 44 | (define big-data (make-hash)) 45 | (define rows (row-length data)) 46 | (define cols (col-length data)) 47 | 48 | (for* ([(k v) (in-hash data)] 49 | [rowrepeat 5] 50 | [colrepeat 5]) 51 | (define next-val (+ v colrepeat rowrepeat)) 52 | (hash-set! big-data (+ k (make-rectangular (+ (* colrepeat cols)) (+ (* rowrepeat rows)))) 53 | (cond 54 | [(> next-val 9) (- next-val 9)] 55 | [else next-val]))) 56 | 57 | ;; graph library is too slow to solve big grid 58 | ;; needs dynamic programming 59 | #;(solve big-data) -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License for `aoc-racket` 2 | 3 | © 2015-2019 Matthew Butterick 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /aoc-racket.scrbl: -------------------------------------------------------------------------------- 1 | #lang scribble/manual 2 | @(require (for-label racket rackunit sugar/list) aoc-racket/helper) 3 | 4 | @title{Advent of Code: solutions & explanations} 5 | 6 | @author[(author+email "Matthew Butterick" "mb@mbtype.com")] 7 | 8 | @defmodule[aoc-racket] 9 | 10 | @italic{Dedicated to curious characters everywhere, especially those learning Racket.} 11 | 12 | @link["http://adventofcode.com"]{Advent of Code} is a series of programming puzzles designed by @link["http://was.tl"]{Eric Wastl}. 13 | 14 | I find that programming puzzles are a good way of learning something new about a programming language, or learning how to do certain things better. Documenting these solutions helped me nail down some discoveries. 15 | 16 | Thank you to Eric Wastl. If you like Advent of Code, please @link["http://adventofcode.com/about"]{pay him for it}. 17 | 18 | You can install this package (if you haven't already) with 19 | 20 | @tt{raco pkg install aoc-racket} 21 | 22 | @local-table-of-contents[] 23 | 24 | @include-section[(submod "day01.rkt" doc)] 25 | @include-section[(submod "day02.rkt" doc)] 26 | @include-section[(submod "day03.rkt" doc)] 27 | @include-section[(submod "day04.rkt" doc)] 28 | @include-section[(submod "day05.rkt" doc)] 29 | @include-section[(submod "day06.rkt" doc)] 30 | @include-section[(submod "day07.rkt" doc)] 31 | @include-section[(submod "day08.rkt" doc)] 32 | @include-section[(submod "day09.rkt" doc)] 33 | @include-section[(submod "day10.rkt" doc)] 34 | @include-section[(submod "day11.rkt" doc)] 35 | @include-section[(submod "day12.rkt" doc)] 36 | @include-section[(submod "day13.rkt" doc)] 37 | @include-section[(submod "day14.rkt" doc)] 38 | @include-section[(submod "day15.rkt" doc)] 39 | @include-section[(submod "day16.rkt" doc)] 40 | @include-section[(submod "day17.rkt" doc)] 41 | @include-section[(submod "day18.rkt" doc)] 42 | @include-section[(submod "day19.rkt" doc)] 43 | @include-section[(submod "day20.rkt" doc)] 44 | @include-section[(submod "day21.rkt" doc)] 45 | @include-section[(submod "day22.rkt" doc)] 46 | @include-section[(submod "day23.rkt" doc)] 47 | @include-section[(submod "day24.rkt" doc)] 48 | @include-section[(submod "day25.rkt" doc)] 49 | 50 | 51 | @index-section[] -------------------------------------------------------------------------------- /day04-input.txt: -------------------------------------------------------------------------------- 1 | iwrupvqb -------------------------------------------------------------------------------- /day08.rkt: -------------------------------------------------------------------------------- 1 | #lang scribble/lp2 2 | @(require scribble/manual aoc-racket/helper) 3 | 4 | @aoc-title[8] 5 | 6 | @defmodule[aoc-racket/day08] 7 | 8 | @link["http://adventofcode.com/day/8"]{The puzzle}. Our @link-rp["day08-input.txt"]{input} consists of a list of seemingly random strings within quotation marks. 9 | 10 | @chunk[ 11 | 12 | 13 | 14 | ] 15 | 16 | @isection{What's the difference between the literal length of the strings, and their length in memory?} 17 | 18 | The puzzle relies the fact that within strings, certain single characters — like the backslash @litchar{\} and double-quote mark @litchar{"} — are described with more than one character. Thus, the question asks us to compare the two lengths. 19 | 20 | The literal length of the string is trivial — use @iracket[string-length]. The memory length requires interpreting a string as a Racket value, which (as seen in @secref{Day_7}) simply means using @iracket[read]. 21 | 22 | @chunk[ 23 | (require racket rackunit) 24 | (provide (all-defined-out)) 25 | ] 26 | 27 | @chunk[ 28 | (define (memory-length str) (string-length (read (open-input-string str)))) 29 | 30 | (define (q1 strs) 31 | (- (apply + (map string-length strs)) (apply + (map memory-length strs))))] 32 | 33 | 34 | 35 | @isection{What's the difference between the re-encoded length of the literal string, and the original length?} 36 | 37 | This question simply comes down to — do you know how to use the string-formatting functions in your programming language? 38 | 39 | In Racket, a string can be re-encoded with @iracket[~v]. Not a very puzzling puzzle overall. 40 | 41 | 42 | @chunk[ 43 | (define (encoded-length str) (string-length (~v str))) 44 | 45 | (define (q2 strs) 46 | (- (apply + (map encoded-length strs)) (apply + (map string-length strs)))) ] 47 | 48 | 49 | @section{Testing Day 8} 50 | 51 | @chunk[ 52 | (module+ test 53 | (define input-strs (file->lines "day08-input.txt")) 54 | (check-equal? (q1 input-strs) 1333) 55 | (check-equal? (q2 input-strs) 2046))] 56 | 57 | 58 | -------------------------------------------------------------------------------- /day09-input.txt: -------------------------------------------------------------------------------- 1 | Tristram to AlphaCentauri = 34 2 | Tristram to Snowdin = 100 3 | Tristram to Tambi = 63 4 | Tristram to Faerun = 108 5 | Tristram to Norrath = 111 6 | Tristram to Straylight = 89 7 | Tristram to Arbre = 132 8 | AlphaCentauri to Snowdin = 4 9 | AlphaCentauri to Tambi = 79 10 | AlphaCentauri to Faerun = 44 11 | AlphaCentauri to Norrath = 147 12 | AlphaCentauri to Straylight = 133 13 | AlphaCentauri to Arbre = 74 14 | Snowdin to Tambi = 105 15 | Snowdin to Faerun = 95 16 | Snowdin to Norrath = 48 17 | Snowdin to Straylight = 88 18 | Snowdin to Arbre = 7 19 | Tambi to Faerun = 68 20 | Tambi to Norrath = 134 21 | Tambi to Straylight = 107 22 | Tambi to Arbre = 40 23 | Faerun to Norrath = 11 24 | Faerun to Straylight = 66 25 | Faerun to Arbre = 144 26 | Norrath to Straylight = 115 27 | Norrath to Arbre = 135 28 | Straylight to Arbre = 127 -------------------------------------------------------------------------------- /day10-input.txt: -------------------------------------------------------------------------------- 1 | 1321131112 -------------------------------------------------------------------------------- /day11-input.txt: -------------------------------------------------------------------------------- 1 | hxbxwxba -------------------------------------------------------------------------------- /day14-input.txt: -------------------------------------------------------------------------------- 1 | Dancer can fly 27 km/s for 5 seconds, but then must rest for 132 seconds. 2 | Cupid can fly 22 km/s for 2 seconds, but then must rest for 41 seconds. 3 | Rudolph can fly 11 km/s for 5 seconds, but then must rest for 48 seconds. 4 | Donner can fly 28 km/s for 5 seconds, but then must rest for 134 seconds. 5 | Dasher can fly 4 km/s for 16 seconds, but then must rest for 55 seconds. 6 | Blitzen can fly 14 km/s for 3 seconds, but then must rest for 38 seconds. 7 | Prancer can fly 3 km/s for 21 seconds, but then must rest for 40 seconds. 8 | Comet can fly 18 km/s for 6 seconds, but then must rest for 103 seconds. 9 | Vixen can fly 18 km/s for 5 seconds, but then must rest for 84 seconds. -------------------------------------------------------------------------------- /day15-input.txt: -------------------------------------------------------------------------------- 1 | Frosting: capacity 4, durability -2, flavor 0, texture 0, calories 5 2 | Candy: capacity 0, durability 5, flavor -1, texture 0, calories 8 3 | Butterscotch: capacity -1, durability 0, flavor 5, texture 0, calories 6 4 | Sugar: capacity 0, durability 0, flavor -2, texture 2, calories 1 -------------------------------------------------------------------------------- /day16-input-master-attrs.txt: -------------------------------------------------------------------------------- 1 | children: 3 2 | cats: 7 3 | samoyeds: 2 4 | pomeranians: 3 5 | akitas: 0 6 | vizslas: 0 7 | goldfish: 5 8 | trees: 3 9 | cars: 2 10 | perfumes: 1 -------------------------------------------------------------------------------- /day17-input.txt: -------------------------------------------------------------------------------- 1 | 43 2 | 3 3 | 4 4 | 10 5 | 21 6 | 44 7 | 4 8 | 6 9 | 47 10 | 41 11 | 34 12 | 17 13 | 17 14 | 44 15 | 36 16 | 31 17 | 46 18 | 9 19 | 27 20 | 38 -------------------------------------------------------------------------------- /day19-input.txt: -------------------------------------------------------------------------------- 1 | Al => ThF 2 | Al => ThRnFAr 3 | B => BCa 4 | B => TiB 5 | B => TiRnFAr 6 | Ca => CaCa 7 | Ca => PB 8 | Ca => PRnFAr 9 | Ca => SiRnFYFAr 10 | Ca => SiRnMgAr 11 | Ca => SiTh 12 | F => CaF 13 | F => PMg 14 | F => SiAl 15 | H => CRnAlAr 16 | H => CRnFYFYFAr 17 | H => CRnFYMgAr 18 | H => CRnMgYFAr 19 | H => HCa 20 | H => NRnFYFAr 21 | H => NRnMgAr 22 | H => NTh 23 | H => OB 24 | H => ORnFAr 25 | Mg => BF 26 | Mg => TiMg 27 | N => CRnFAr 28 | N => HSi 29 | O => CRnFYFAr 30 | O => CRnMgAr 31 | O => HP 32 | O => NRnFAr 33 | O => OTi 34 | P => CaP 35 | P => PTi 36 | P => SiRnFAr 37 | Si => CaSi 38 | Th => ThCa 39 | Ti => BP 40 | Ti => TiTi 41 | e => HF 42 | e => NAl 43 | e => OMg 44 | 45 | ORnPBPMgArCaCaCaSiThCaCaSiThCaCaPBSiRnFArRnFArCaCaSiThCaCaSiThCaCaCaCaCaCaSiRnFYFArSiRnMgArCaSiRnPTiTiBFYPBFArSiRnCaSiRnTiRnFArSiAlArPTiBPTiRnCaSiAlArCaPTiTiBPMgYFArPTiRnFArSiRnCaCaFArRnCaFArCaSiRnSiRnMgArFYCaSiRnMgArCaCaSiThPRnFArPBCaSiRnMgArCaCaSiThCaSiRnTiMgArFArSiThSiThCaCaSiRnMgArCaCaSiRnFArTiBPTiRnCaSiAlArCaPTiRnFArPBPBCaCaSiThCaPBSiThPRnFArSiThCaSiThCaSiThCaPTiBSiRnFYFArCaCaPRnFArPBCaCaPBSiRnTiRnFArCaPRnFArSiRnCaCaCaSiThCaRnCaFArYCaSiRnFArBCaCaCaSiThFArPBFArCaSiRnFArRnCaCaCaFArSiRnFArTiRnPMgArF -------------------------------------------------------------------------------- /day20-input.txt: -------------------------------------------------------------------------------- 1 | 36000000 -------------------------------------------------------------------------------- /day21-input.txt: -------------------------------------------------------------------------------- 1 | Hit Points: 109 2 | Damage: 8 3 | Armor: 2 -------------------------------------------------------------------------------- /day22-input.txt: -------------------------------------------------------------------------------- 1 | Hit Points: 58 2 | Damage: 9 3 | -------------------------------------------------------------------------------- /day23-input.txt: -------------------------------------------------------------------------------- 1 | jio a, +19 2 | inc a 3 | tpl a 4 | inc a 5 | tpl a 6 | inc a 7 | tpl a 8 | tpl a 9 | inc a 10 | inc a 11 | tpl a 12 | tpl a 13 | inc a 14 | inc a 15 | tpl a 16 | inc a 17 | inc a 18 | tpl a 19 | jmp +23 20 | tpl a 21 | tpl a 22 | inc a 23 | inc a 24 | tpl a 25 | inc a 26 | inc a 27 | tpl a 28 | inc a 29 | tpl a 30 | inc a 31 | tpl a 32 | inc a 33 | tpl a 34 | inc a 35 | inc a 36 | tpl a 37 | inc a 38 | inc a 39 | tpl a 40 | tpl a 41 | inc a 42 | jio a, +8 43 | inc b 44 | jie a, +4 45 | tpl a 46 | inc a 47 | jmp +2 48 | hlf a 49 | jmp -7 -------------------------------------------------------------------------------- /day24-input.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 3 3 | 5 4 | 11 5 | 13 6 | 17 7 | 19 8 | 23 9 | 29 10 | 31 11 | 37 12 | 41 13 | 43 14 | 47 15 | 53 16 | 59 17 | 67 18 | 71 19 | 73 20 | 79 21 | 83 22 | 89 23 | 97 24 | 101 25 | 103 26 | 107 27 | 109 28 | 113 -------------------------------------------------------------------------------- /day25-input.txt: -------------------------------------------------------------------------------- 1 | To continue, please consult the code grid in the manual. Enter the code at row 2947, column 3029. -------------------------------------------------------------------------------- /helper.rkt: -------------------------------------------------------------------------------- 1 | #lang at-exp racket/base 2 | (require scribble/manual scribble/html-properties 3 | scribble/core scribble/decode) 4 | (require (for-syntax racket/base racket/syntax)) 5 | (provide (all-defined-out)) 6 | 7 | (define current-day (make-parameter #f)) 8 | (define current-section (make-parameter #f)) 9 | 10 | (define-syntax-rule (iracket term) 11 | (list 12 | (part-index-decl 13 | (list (symbol->string 'term)) 14 | (list (tt (symbol->string 'term)) 15 | (if (current-section) 16 | (decode-content (cons (format "in Day ~a / " (current-day)) (current-section))) 17 | ""))) 18 | (racket term))) 19 | 20 | (define-syntax (define-isec stx) 21 | (syntax-case stx () 22 | [(_ secid) 23 | (with-syntax ([isecid (format-id stx "i~a" #'secid)]) 24 | #'(define isecid 25 | (make-keyword-procedure 26 | (λ (kws kwargs . args) 27 | (begin 28 | (current-section args) 29 | (keyword-apply secid kws kwargs args))))))])) 30 | 31 | (define-isec section) 32 | (define-isec subsection) 33 | 34 | 35 | (define (aoc-title which) 36 | (define which-str (number->string which)) 37 | (current-day which-str) 38 | (define day-x (format "day-~a" which-str)) 39 | (define day-prefix (format "~a-" day-x)) 40 | @title[#:style manual-doc-style]{Day @which-str}) 41 | 42 | (define (link-rp path . text-args) 43 | (element (style #f (list (link-resource path))) 44 | text-args)) -------------------------------------------------------------------------------- /info.rkt: -------------------------------------------------------------------------------- 1 | #lang info 2 | (define collection "aoc-racket") 3 | (define scribblings '(("aoc-racket.scrbl" (multi-page)))) 4 | (define deps '("brag-lib" 5 | "csp" 6 | "srfi-lite-lib" 7 | "graph" 8 | "base" 9 | "scribble-lib" 10 | ("sugar" #:version "0.3") 11 | "rackunit-lib" 12 | "math-lib" 13 | "beautiful-racket-lib" 14 | "gregor" 15 | "debug" 16 | "draw-lib" 17 | "gui-lib")) 18 | (define test-omit-paths (list #rx"rkt$")) 19 | (define build-deps '("rackunit-lib" 20 | "racket-doc" 21 | "scribble-doc" 22 | "rackunit-doc" 23 | "at-exp-lib" 24 | "math-doc")) -------------------------------------------------------------------------------- /main.rkt: -------------------------------------------------------------------------------- 1 | #lang racket/base 2 | 3 | ;; nothing at the top level --------------------------------------------------------------------------------