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)
|