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.
46 lines
1.8 KiB
Racket
46 lines
1.8 KiB
Racket
#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) |