aboutsummaryrefslogtreecommitdiff
path: root/aoc/2021/day03/part2.neb
blob: 1ff258ca3456085426d01251a61ca24961759535 (plain)
1
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
;; https://adventofcode.com/2021/day/3

(func bit-counts (inp)
    (list
        (length (filter (lambda (x) (eq? "0" x)) inp))
        (length (filter (lambda (x) (eq? "1" x)) inp))))

; treating bits as a string of 1s and 0s
; note: for this problem, even if neb had byte things,
; strings would probably still be the way to go
(func bit-flip (bitstr)
    (join
        (map
            (lambda (x) (if (eq? "0" x) "1" "0"))
            (split bitstr))
        ""))

; 'exp' or something should be in the stdlib
(func two-n (n)
    (branch
        ((eq? 0 n) 1)
        ((eq? 1 n) 2)
        (#true
            (* 2 (two-n (- n 1))))))

(func parse-binary (bitstr)
    (parse-binary bitstr 0 0))

(func parse-binary (bitstr pos acc)
    (if (eq? 0 (length bitstr))
        acc
        (block
            (def next-int (string->int (last bitstr)))
            (if (eq? 0 next-int)
                (parse-binary
                    (most bitstr)
                    (+ 1 pos)
                    acc)
                (parse-binary
                    (most bitstr)
                    (+ 1 pos)
                    (+ acc
                        (two-n pos)))))))
                        ;(* 2 pos)))))))

(func vertical-slice (inp idx)
    (map
        (lambda (x)
            (first (slice x idx 1)))
        inp))

; since ox-gen and co2-scrub only differ in which
; bit is considered the "winner" when comparing
; bit counts, use a generic function
(func generic-calc (inp idx bit-order)
    (if (eq? 1 (length inp))
        (parse-binary (first inp))
        (block
            (def val
                (if (apply <= (bit-counts (vertical-slice inp idx)))
                    (first bit-order)
                    (last bit-order)))

            (generic-calc
                (filter
                    (lambda (x)
                        (eq? val (first (slice x idx 1))))
                    inp)
                (+ 1 idx)
                bit-order))))

(func ox-gen-calc (inp idx)
    (generic-calc inp idx (list "1" "0")))

(func co2-scrub-calc (inp idx)
    (generic-calc inp idx (list "0" "1")))

(func do-the-thing (inp)
    (def ox (ox-gen-calc inp 1))
    (def co2 (co2-scrub-calc inp 1))
    (print (concat "ox: " (->string ox)))
    (print (concat "co2: " (->string co2)))
    (print (concat "life support: " (->string (* ox co2)))))

(def lines 
    (map split  ; get all numbers as list of chars
        (map strip
            (read-lines "input.txt"))))

(do-the-thing lines)