1
+ #lang racket
2
+
3
+ (require rackunit)
4
+
5
+ (struct mask (ones zeros xs) #:transparent )
6
+
7
+ (define (mask-value m val)
8
+ (bitwise-and (bitwise-ior val (mask-ones m))
9
+ (bitwise-not (mask-zeros m))))
10
+
11
+ (define (mask-permute-xs m xs)
12
+ (bitwise-and (mask-xs m)
13
+ (+ 1 xs (bitwise-ior (mask-ones m) (mask-zeros m)))))
14
+
15
+ (define (mask-list-xs m)
16
+ (let loop ([list-xs '(0 )])
17
+ (if (= (car list-xs) (mask-xs m))
18
+ list-xs
19
+ (loop (cons (mask-permute-xs m (car list-xs)) list-xs)))))
20
+
21
+ (define (mask-addresses m addr)
22
+ (for/list ([xs (in-list (mask-list-xs m))])
23
+ (bitwise-ior xs
24
+ (mask-ones m)
25
+ (bitwise-and addr (mask-zeros m)))))
26
+
27
+ (define (string->mask str)
28
+ (for/fold ([ones 0 ]
29
+ [zeros 0 ]
30
+ [xs 0 ]
31
+ #:result (mask ones zeros xs))
32
+ ([ch (in-list (string->list str))])
33
+ (case ch
34
+ [(#\X ) (values (* 2 ones) (* 2 zeros) (add1 (* 2 xs)))]
35
+ [(#\0 ) (values (* 2 ones) (add1 (* 2 zeros)) (* 2 xs))]
36
+ [(#\1 ) (values (add1 (* 2 ones)) (* 2 zeros) (* 2 xs))])))
37
+
38
+ (define (parse-line line)
39
+ (match line
40
+ [(regexp #rx"mask = ([X01]+) " (list _ m)) (string->mask m)]
41
+ [(regexp #rx"mem\\[([0-9]+)\\] = ([0-9]+) " (list _ addr val))
42
+ (list (string->number addr) (string->number val))]))
43
+
44
+ (define (transform1 memory msk addr val)
45
+ (hash-set memory addr (mask-value msk val)))
46
+
47
+ (define (transform2 memory msk addr val)
48
+ (for/fold ([memory memory])
49
+ ([addr (in-list (mask-addresses msk addr))])
50
+ (hash-set memory addr val)))
51
+
52
+ (define (run-program lines transform)
53
+ (for/fold ([memory (hash)]
54
+ [msk (mask 0 0 0 )]
55
+ #:result memory)
56
+ ([line (in-list lines)])
57
+ (match (parse-line line)
58
+ [(list addr val) (values (transform memory msk addr val) msk)]
59
+ [m (values memory m)])))
60
+
61
+ (let ([lines (file->lines "day14.txt " )])
62
+ (values (apply + (hash-values (run-program lines transform1)))
63
+ (apply + (hash-values (run-program lines transform2)))))
0 commit comments