You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
aoc-racket/2020/14.rkt

46 lines
1.8 KiB
Racket

4 years ago
#lang br
(require racket/file rackunit racket/dict math)
(define insts
(for/list ([ln (file->lines "14.rktd")])
(cond
[(string-prefix? ln "mask = ") (string-trim ln "mask = ")]
[else (apply cons (map string->number (cdr (regexp-match #px"^mem\\[(\\d+)\\] = (\\d+)$" ln))))])))
(define (cs2int cs) (string->number (list->string cs) 2))
(define (int2str int) (~r #:base 2 int #:min-width 36 #:pad-string "0"))
(define (solve [decoder-version 1])
(define memory (make-hasheq))
(for/fold ([bitmask #f]
#:result (apply + (hash-values memory)))
([inst (in-list insts)])
(match inst
[(? string? new-bitmask) new-bitmask]
[(cons loc val)
(define value-to-store
(cond
[(eq? decoder-version 1)
(cs2int (for/list ([val-char (in-string (int2str val))]
[mask-char (in-string bitmask)])
(if (char=? mask-char #\X) val-char mask-char)))]
[else val]))
(define expanded-locs
(cond
[(eq? decoder-version 2)
(for/fold ([locs '(())]
#:result (map (λ (loc) (cs2int (reverse loc))) locs))
([loc-char (in-string (int2str loc))]
[mask-char (in-string bitmask)])
(append* (for/list ([loc (in-list locs)])
(match mask-char
[#\0 (list (cons loc-char loc))]
[#\1 (list (cons #\1 loc))]
[_ (list (cons #\1 loc) (cons #\0 loc))]))))]
[else (list loc)]))
(for ([loc expanded-locs])
(hash-set! memory loc value-to-store))
bitmask])))
(check-equal? (solve) 13727901897109)
(check-equal? (solve 2) 5579916171823)