AoC '21, day 10, first problem rvc


Given a set of strings, where each string is a sequence of nested groups delimited by one of four bracketing characters ('(', '[', '{', '<' and associated closing characters), find the left-most mismatched group (which may not exist). Assign the mismatched closing bracket a score, and return the sum of the scores of all mismatched brackets.

 $ cat 10a.rkt  
 #lang racket 
  
  
 (provide 
   example-input 
   read-input 
   ) 
  
  
 (require "./aoc.rkt") 
  
  
 (define (aoc10a . args) 
  
   ; Return the nav-sys error score for the first half of the 
   ; tenth AoC '21 problem.  If no argument is given, use the 
   ; contest problem input; otherwise assume the argument is 
   ; the string representation of a problem input. 
  
   (total-error-score (apply read-input args))) 
  
  
 (define line-error-score 
  
   ; Return the error score for the given nav-system line. 
  
   (let* 
  
     ((error-scores (make-hash  
        '((#\) . 3) (#\] . 57) (#\} . 1197) (#\> . 25137)))) 
      (group-close (make-hash  
        '((#\( . #\)) (#\[ . #\]) (#\{ . #\}) (#\< . #\>)))) 
         
      (push (lambda (s e) (cons e s))) 
      (pop cdr) 
      (top car) 
         
      (is-group-open? (lambda (c) (member c '(#\( #\[ #\{ #\<)))) 
      (closes-group? (lambda (g c) 
        (and (not (null? g)) 
             (char=? (hash-ref group-close (top g)) c))))) 
  
     (lambda (nav-sys-line) 
       (call-with-current-continuation 
         (lambda (k) 
           (foldl 
             (lambda (e open-groups) 
               (cond 
                 ((is-group-open? e)             
                    (push open-groups e)) 
                 ((closes-group? open-groups e)  
                    (pop open-groups)) 
                 (#t                             
                    (k (hash-ref error-scores e))))) 
             '() nav-sys-line) 
           0))))) 
  
  
 (define  (read-input . inp) 
  
   ; Return the navigation subsystem described by the given 
   ; input.  If no input is given, use the contest problem 
   ; input; otherwise the argument is taken to be the string 
   ; representation of input. 
  
   (map 
     string->list 
     (flatten (car  
       (aoc-read-input (if (null? inp) 10 (car inp))))))) 
  
  
 (define (total-error-score nav-sys) 
  
   ; Return the total error score for the given nav system. 
  
   (apply + (map line-error-score nav-sys))) 
  
  
 (module+ main 
  
   (aoc10a) 
   ) 
  
  
 (define example-input 
   (string-join 
     '("[({(<(())[]>[[{[]{<()<>>" 
       "[(()[<>])]({[<{<<[]>>(" 
       "{([(<{}[<>[]}>{[]{[(<()>" 
       "(((({<>}<{<{<>}{[]{[]{}" 
       "[[<[([]))<([[{}[[()]]]" 
       "[{[{({}]{}}([{[{{{}}([]" 
       "{<[[]]>}<{[{[{[]{()[[[]" 
       "[<(<(<(<{}))><([]([]()" 
       "<{([([[(<>()){}]>(<<{{" 
       "<{([{{}}[<[[[<>{}]]]>[]]" 
       ) 
     "\n")) 
  
 (define example-output 26397) 
  
  
 (module+ test 
  
   (require rackunit) 
  
   (check-equal? (line-error-score (read-input "")) 0) 
    
   (for-each 
  
    (lambda (p) 
      (check-equal? 
        (line-error-score (car (read-input (car p)))) (cadr p))) 
  
    '(("(" 0) ("()" 0) (")" 3) 
      ("[" 0) ("[]" 0) ("]" 57) 
      ("{" 0) ("{}" 0) ("}" 1197) 
      ("<" 0) ("<>" 0) (">" 25137) 
      ("{([(<{}[<>[]}>{[]{[(<()>" 1197) 
      ("[[<[([]))<([[{}[[()]]]" 3) 
      ("[{[{({}]{}}([{[{{{}}([]" 57) 
      ("[<(<(<(<{}))><([]([]()" 3) 
      ("<{([([[(<>()){}]>(<<{{" 25137))) 
  
   (check-equal? 
     (total-error-score (read-input example-input)) example-output) 
   (check-equal? (aoc10a example-input) example-output) 
   ) 
  
 $ raco test 10a.rkt 
 raco test: (submod "10a.rkt" test) 
 20 tests passed 
  
 $