AoC'21, day 3, second problem rvc


An elimination tournament with one set of candidates having the majority bit in each round and the other set of candidates having the minority bit.

 $ cat 03b.rkt  
 #lang racket 
  
  
 (require 
   (prefix-in aoc03: "03a.rkt")) 
  
  
 (define (aoc03b . input) 
  
   ; Return the life-support rating from the given diagnostic 
   ; report.  If no report is given, use the contest problem 
   ; input; otherwise assume the argument is the string 
   ; representation of a problem input. 
  
   (life-support-rating (apply aoc03:read-input input))) 
  
  
 (define (life-support-rating readings) 
  
   ; Return the life-support ratings indicated by the given 
   ; readings. 
    
  
   (define (partition readings) 
  
     ; Return (zeros ones), where zeros is a list of readings from 
     ; the given list that start with 0, and ones is a list of 
     ; readings from the given list that start with 1. 
      
     (let ((p (foldl 
                (lambda (r p) 
                  (let ((bit (caar r)) 
                        (r (cons (cdar r) (cdr r)))) 
                    (vector-set! p bit (cons r (vector-ref p bit))) 
                    p)) 
  
                (vector null null) 
  
                readings))) 
  
       (list (vector-ref p 0) (vector-ref p 1)))) 
  
  
   (define (winnow readings selector) 
  
     ; Reduce the given readings down to a single reading using 
     ; the given selector, and return the reading's associated 
     ; numeric representation. 
  
     (let loop ((readings readings)) 
  
       (if (= (length readings) 1) 
  
           (foldl (lambda (b n) (+ (* n 2) b)) 0 (cdar readings)) 
  
           (loop (apply selector (partition readings)))))) 
  
  
   (let* 
  
     ((min (lambda (z o) (if (> (length z) (length o)) o z))) 
      (max (lambda (z o) (if (> (length z) (length o)) z o))) 
  
      ; Each reading is represented as bit-list pair.  The car is 
      ; used to select the proper reading, and is reduced by one 
      ; bit on each pass.  The cdr is maintained as the complete 
      ; bit list so the associated number can be recovered. 
  
      (readings (map (lambda (r) (cons r r)) readings)) 
  
      (oxy (winnow readings max)) 
      (co2 (winnow readings min))) 
  
     (* co2 oxy))) 
  
  
 (module+ main 
  
   (aoc03b)) 
  
  
 (define example-result 230) 
  
  
 (module+ test 
  
   (require rackunit) 
  
   (check-equal? (aoc03b aoc03:example-data) example-result) 
   (check-equal? (aoc03b) 4550283)) 
  
  
 $ raco test 03b.rkt  
 raco test: (submod "03b.rkt" test) 
 2 tests passed 
  
 $