AoC '21, Day 16, second problem, rvc


Each packet represents an arithmetic operation or a number. The second half of the problem involves evaluating the packet to find the value computed.

 $cat 16b.rkt 
 #lang racket 
  
 (require "16a.rkt") 
  
  
 (define aoc16b (lambda args 
  
  ; Return the summed packet versions for the second half of the 
  ; sixteenth AoC '21 problem. 
  
  (let-values (((packets bl) (parse-input (apply read-input args)))) 
  
    (unless (= (length packets) 1) 
      (raise-user-error 'evaluate-packets 
        "expected to evaluate 1 packet, ~a given" (length packets))) 
  
    (evaluate-packet (car packets))))) 
  
  
 (define (evaluate-packet p) 
  
   ; Return the value associated with the given packet. 
  
  
   (define (logically-evaluate-packet lop p) 
  
     ; Return the result of applying the given logical operator to the 
     ; two argument subpackets in the given packet. 
  
     (let ((operands (packet-operator-subpackets p))) 
  
       (unless (= (length operands) 2) 
         (raise-user-error 'logically-evaluate-packets 
           "two operands expectd, ~a given") (length operands)) 
  
       (if (apply lop (map evaluate-packet operands)) 1 0))) 
  
  
   (cond 
  
    ((packet-literal? p) 
     (packet-literal-value p)) 
  
    ((packet-operator? p) 
     (case (packet-operator-type p) 
       ((0) 
        (foldr + 0 (map evaluate-packet (packet-operator-subpackets p)))) 
  
       ((1) 
        (foldr * 1 (map evaluate-packet (packet-operator-subpackets p)))) 
  
       ((2) 
        (apply min (map evaluate-packet (packet-operator-subpackets p)))) 
  
       ((3) 
        (apply max (map evaluate-packet (packet-operator-subpackets p)))) 
  
       ((5) 
        (logically-evaluate-packet > p)) 
  
       ((6) 
        (logically-evaluate-packet < p)) 
  
       ((7) 
        (logically-evaluate-packet = p)) 
  
       (else 
        (raise-user-error 'evaluate-packet 
                          "unrecognized operator type: ~a" (packet-operator-type p))))) 
  
    (#t 
     (raise-user-error 'evaluate-packet "unrecognized packet type")))) 
  
  
 (module+ main 
  
   (aoc16b)) 
  
    
 (module+ test 
  
   (require rackunit) 
  
   (for-each 
    (lambda (p) (check-equal? (aoc16b (car p)) (cdr p))) 
    '(("C200B40A82" . 3) 
      ("04005AC33890" . 54) 
      ("880086C3E88112" . 7) 
      ("CE00C43D881120" . 9) 
      ("D8005AC2A8F0" . 1) 
      ("F600BC2D8F" . 0) 
      ("9C005AC2F8F0" . 0) 
      ("9C0141080250320F1802104A08" . 1))) 
  
   (check-equal? (aoc16b) 144595909277) 
   ) 
  
 $ raco test 16b.rkt  
 raco test: (submod "16b.rkt" test) 
 9 tests passed 
  
 $