summaryrefslogtreecommitdiff
path: root/day3/1/guile/main.scm
blob: 5d27e919e80773f503251cb6addad361093e3d49 (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
#!/usr/bin/env guile
!#

(use-modules (ice-9 rdelim)
             (srfi srfi-1)
             (srfi srfi-60))

(define (bit-frequency acc)
  (let* ((num-string (read-line))
         (num-length (string-length num-string))
         (num (string->number num-string 2)))
    (if (integer? num)
      (let* ((num-freq-list (map (lambda (b) (if b '(1 0) '(0 1)))    ;; 101 -> 5 -> '(#t #f #t) -> '((1 0) (0 1) (1 0))
                                 (integer->list num num-length)))
             (next-acc (if (null? acc)  ;; If we have not yet accumulated anything
                         num-freq-list  ;; Return the current value as the new accumulator.
                         ;; Otherwise add each pair to the previous accumulator.
                         (map (lambda (xs ys) (map + xs ys))
                              acc num-freq-list))))
        (bit-frequency next-acc))
      acc))) ;; If the input was not an integer (ie EOF) return what we have accumulated.

;; Capture the result of bit-frequency in a closure.
(define bit-frequency-to-num
  (let ((bf (bit-frequency '())))
    ;; The closure applies a predicate to the frequency of 1s and 0s seen for the current bit.
    ;; If the predicate returns true, the current bit is 1, and vice versa.
    (lambda (predicate)
      (list->integer
        (map (lambda (freq) (apply predicate freq))
             bf)))))

(define gamma-rate        (bit-frequency-to-num >))     ;; Gamma rate is the number with the most common bits.
(define epsilon-rate      (bit-frequency-to-num <))     ;; Epsilon rate is the number with the least common bits.
(define power-consumption (* gamma-rate epsilon-rate))  ;; Power consumption is the gamma rate * the epsilon rate.

(display power-consumption)
(newline)