1

I had a question about a program I've been trying to get running. Encrypt takes a message, public-key, and private-key, and returns the message with the letters from the message in the public-key changed to the letters from the private-key.

For ex, (encrypt "abcd" "abcd" "efgh") should return "efgh" and (encrypt "abcl" "abcd" "efgh") should return "efgl" (the letter from message that was not in the public-key will stay the same).

I've written a few helper programs to solve this but I keep getting the error "exception in car, __ is not a pair" when I try to run it.. but I'm not sure what's amiss. If anyone has any pointers, let me know. Thanks!

(define encrypt
  (lambda (message public-key private-key)
    (cond
      [(list->string (encrypt-helper (string->list message)
      (string->list public-key) (string->list private-key)))])))

(define encrypt-helper
  (lambda (msg-ls public-ls private-ls)
    (cond
      [(null? public-ls) '()]
      [(null? private-ls) '()]
      [(and (null? public-ls) (null? private-ls)) msg-ls]
      [else (cons (encrypt-key (car msg-ls) (car public-ls) (car private-ls))
        (encrypt-helper (cdr msg-ls) (cdr public-ls) (cdr private-ls)))])))

;should encrypt all letters in msg-ls. not working correctly

(define encrypt-key
  (lambda (char pub-key priv-key)
    (cond
      [(null? pub-key) char]
      [(equal? char (car pub-key)) (car priv-key)]
      [else (encrypt-key char (cdr pub-key) (cdr priv-key))])))

;encrypts just one letter, ex: (encrypt-key 'a '(a) '(b)) => b
;works correctly
kristianp
  • 5,496
  • 37
  • 56
mdegges
  • 963
  • 3
  • 18
  • 39

1 Answers1

2

The problem is that inside encrypt-helper, you're calling

[else (cons (encrypt-key (car msg-ls) (car public-ls) (car private-ls)...

but (car public-ls) (and (car private-ls)) is an atom, while inside encrypt-key you also perform

[(equal? char (car pub-key) ...

and you can't car pub-key here because car only works on a list, while pub-key is an atom.

In the example you give that works, i.e.

(encrypt-key 'a '(a) '(b)) => b

you'll notice that '(a) and '(b) are specified as lists, for exactly this reason. Hint:

>(cons 'a ())
(a)
> 

I'll leave it there :)

Caleb Hattingh
  • 9,005
  • 2
  • 31
  • 44
  • Thanks, that really helped me a lot :). The other problem someone pointed out to me was that I was cdring down the public and private lists in the recursive call of my helper! While this returned the encrypted list, it did not return the rest of the list that was not in the public list. – mdegges Apr 01 '11 at 01:02
  • @Michele: in the DrScheme (which has now become Racket) editor, your original error produced program-flow lines all over the code to indicate where the error occurred, and the preceding calls to that point. It made it very easy to debug. What environment are you using to work with Scheme? – Caleb Hattingh Apr 01 '11 at 09:46