Tuesday, 27 September 2011

Exercise 148: Design a program that encodes text files numerically.

Exercise 148: Design a program that encodes text files numerically.
Each letter in a word should be encoded as a numeric three-letter string with a value between 0 and 256. Here is our encoding function for letters:



; 1String -> String
; auxiliary for stating tests
;(define (code1 c)
;  (number->string (string->int c)))

;(check-expect (encode-letter "\t") 
;              (string-append "00" (code1 "\t")))
;(check-expect (encode-letter "a") 
;              (string-append "0" (code1 "a")))
;(check-expect (encode-letter "z") (code1 "z"))

;(define (encode-letter s)
;  (cond
;    [(< (string->int s) 10) (string-append "00" (code1 s))]
;    [(< (string->int s) 100) (string-append "0" (code1 s))]
;    [else (code1 s)]))


; Before you start, explain this function. Also recall how
; a string can be converted into a list of 1Strings.
; Again, use read-words/line to preserve the organization of
; the file into lines and words.  




They don't specify in the question what they want you to do with the  output, so I'm going to return it as a plain string with no padding between the groups.


(require racket/base)
; 1String -> String
; convert the given 1string into a three-letter numeric string

; 1String -> String
; auxiliary for stating tests
(define (code1 c)
  (number->string (string->int c)))

(check-expect (encode-letter "\t") 
              (string-append "00" (code1 "\t")))
(check-expect (encode-letter "a")
              (string-append "0" (code1 "a")))
(check-expect (encode-letter "z") 
              (code1 "z"))

(define (encode-letter s)
  (cond
    [(< (string->int s) 10) (string-append "00" (code1 s))]
    [(< (string->int s) 100) (string-append "0" (code1 s))]
    [else (code1 s)]))




Explaining how it works is straight forward. code1 calls string->int, which will convert the char passed in into an int.  (Presumably it's ascii code decimal equivilant). This is then converted to  a string and returned. 
As this will be a straight int (eg, no leading zero's) the function encode-letter will prepend "00" if the number is less than 10, or prepend "0" if the number is greater than 10 but less than 100.


; encode a list of numbers - returns a list of strings of 
; encoded chars
; 1String -> String
(define (process-word loc)
  (cond ((empty? loc) "")
        ((cons? loc) (string-append (encode-letter (first loc))
                                    (process-word (rest loc))))))


(check-expect (process-word (list "t" "h" "e")) "116104101")


; Process the entire line of words into integer codes. Note the
; use of the 'explode' function here. I was originally trying
; to use string->list which will not work!
; List-of-Strings->String
(define (process-line los)
  (cond ((empty? los) 
         "")
        ((cons? los) 
         (string-append (process-word (explode (first los)))
                        (process-line (rest los))))))


(check-expect (process-line (list "the" "cat" "in" "the" "hat"))
              "116104101099097116105110116104101104097116")



No comments:

Post a Comment