#lang racket ;; test for pr11445 (require 2htdp/batch-io) (define batch-io3 #< Exact-nonnegative-integer ;; coercion with error message for parse-file (define (enni x) (if (exact-nonnegative-integer? x) x (error 'parse-file pem x))) (define pem "exact-nonnegative-integer expected for relative file position; given: ~e")) (module+ test ;; String -> Void ;; read input, process queries, write output (define (solution file-name) ;; S-expression [Dataset -> String] -> String (define (input->output i) (let loop ((ds# (first (first i))) (file (rest i))) (cond [(zero? ds#) ""] [else (parse-file file ([(sales-record# queries#) 1] [sales-records sales-record#] [queries queries#]) (string-append (process-dataset sales-records queries) "\n" (loop (sub1 ds#) file)))]))) ;; Dataset -> String ;; process one dataset (define (process-dataset sales-records queries) (foldr (λ (query r) (string-append (total-message sales-records (first query)) r)) "" queries)) ;; [Listof [List Number String Number]] String -> String ;; compute query result and turn into string (define (total-message sales-records query) (define good* (filter (λ (sales-record) (string=? (second sales-record) query)) sales-records)) (define count (apply + (map first good*))) (define value (apply + (map third good*))) (format "You sold ~a ~a for a total of $~a.\n" count (add-s query (length good*)) (real->decimal-string value 2))) ;; String Natural -> String ;; add s to string if plurality calls for it (define (add-s str n) (if (and (> n 1) (not (string=? (substring str (- (string-length str) 1)) "s"))) (string-append str "s") str)) ;; -- in -- ;; should be write-file from batch io (with-output-to-string (λ () (printf (input->output batch-io3.sexpr))))) (check-equal? (solution "don't care") batch-io3-expected))