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
|
(import (chicken io)
(chicken string)
(srfi-151))
(define txtlines (call-with-input-file "input" read-lines))
(define lines (map string->list txtlines))
(define (transpose matrix)
(apply map list matrix))
(define (chars->nums l)
(map (lambda (x) (- x 48)) (map char->integer l)))
(define ints (map chars->nums lines))
; return #t or #f so it works with srfi-151's list->bits
(define (mode-0-1-ind l i)
(let ((sum (apply + (map (lambda (xl) (list-ref xl i)) l)))
(n (length l)))
(if (<= 0.5 (/ sum n))
#t
#f)))
(define (construct-modes nums)
(let loop ((i 0) (lst '()))
(if (>= i (length (car nums)))
(reverse lst)
(loop (+ i 1) (cons (mode-0-1-ind nums i) lst)))))
(define gamma-bitlist (construct-modes ints))
(define epsilon-bitlist (map not gamma-bitlist))
; reverse because the list is interpreted as least sig bit last
(define gamma (list->bits (reverse gamma-bitlist)))
(define epsilon (list->bits (reverse epsilon-bitlist)))
; part 1
(print (* gamma epsilon))
; part 2
; remove-elem returns lst without elements satisfying condit
(define (remove-elem lst condit)
(cond
((null? lst) '())
((condit (car lst)) (remove-elem (cdr lst) condit))
(else (cons (car lst) (remove-elem (cdr lst) condit)))))
(define (bool->int b)
(unless (boolean? b) (error "not a boolean" b))
(if b 1 0))
(define (int->bool i)
(unless (integer? i) (error "not an integer" i))
(cond ((= 0 i) #f)
(else #t)))
; most-or least is a boolean: #t to keep values which are the most common
(define (remove-not-matching lst index most-or-least)
(remove-elem lst
(lambda (x)
(= (list-ref x index)
(bool->int
(if most-or-least
(not (mode-0-1-ind lst index))
(mode-0-1-ind lst index)))))))
; most-or least is a boolean: #t to keep values which are the most common
(define (find-last-matching lst most-or-least)
(let loop ((i 0) (l lst))
(cond ((= (length l) 1) (car l))
(else (loop (+ i 1) (remove-not-matching l i most-or-least))))))
; reverse because the list is interpreted as least sig bit last
(define co2 (list->bits (reverse (map int->bool (find-last-matching ints #f)))))
(define oxy (list->bits (reverse (map int->bool (find-last-matching ints #t)))))
(print (* oxy co2))
|