Advent of Code 2021 https://adventofcode.com/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

53 lines
2.3 KiB

#lang racket
(define data (map string->list (file->lines "day10.txt")))
(define pairs (list (list #\{ #\}) (list #\( #\)) (list #\[ #\]) (list #\< #\>)))
(define opening (map first pairs))
(define closing (map second pairs))
(define (go input stack) ; returns the incomplete list OR the first broken bracket if corrupted
(if (= 0 (length input)) ; if we've run out of input..
stack ; we've got an incomplete chunk. return the stack
(let ([x (first input)] [xs (rest input)]) ; grab the first element of the input
(if (member x opening) ; if it is an opening bracket
(go xs (cons x stack)) ; push it on the stack and recurse
(let* ([y (first stack)] ; otherwise, it's a closing bracket. grab the top of the stack..
[matching (second (assoc y pairs))]) ; and find its matching closing bracket
(if (equal? matching x) ; if they match..
(go xs (rest stack)) ; remove it and recurse
x)))))) ; if they don't match, return the offending bracket
(define part1
(let* ([res (map (λ (x) (go x '())) data)]
[bads (filter (λ (x) (not (list? x))) res)] ; filter out the lists - they're the incomplete chunks
[costs (list (list #\) 3) (list #\] 57) (list #\} 1197) (list #\> 25137))]
[points (map (λ (x) (second (assoc x costs))) bads)]
[total (apply + points)])
total))
part1
; PART 2
(define (complete input stack) ; find the necessary closing brackets to complete the chunk
(if (= 0 (length input))
stack
(let* ([x (first input)]
[matching (second (assoc x pairs))])
(complete (rest input) (cons matching stack)))))
(define (score chunk)
(let ([costs (list (list #\) 1) (list #\] 2) (list #\} 3) (list #\> 4))])
(foldl (λ (x acc) (+ (second (assoc x costs)) (* 5 acc))) 0 chunk)))
(define part2
(let* ([res (map (λ (x) (go x '())) data)]
[rev (reverse res)] ; reverse so we can use `first` & `cons`
[incompletes (filter (λ (x) (list? x)) res)] ; filter out the lists - they're the incomplete chunks
[completing (map reverse (map (λ (x) (complete x '())) incompletes))] ; un-reverse it
[scores (map score completing)]
[sorted (sort scores <)])
(list-ref sorted (/ (- (length sorted) 1) 2)))) ; find the median scoring chunk
part2