0

How do I write a function that takes both a scoring function (which I've written already) and a list of pairs of strings as input (which I'm confused on how to write), and returns a modified list of pairs of strings, where the returned list should contain all the optimal string pairs from the input, scored according to the input function.

Example input:

'( ("hello" "b_low") ("hello_" "b_l_ow") ("hello" "_blow") ("hello" "blow") ("h_e_llo" "bl_o__w") )

Example output:

( ("hello" "b_low") ("hello_" "b_l_ow") ("hello" "_blow") )

the function takes a list of pairs of strings as shown above. It also takes in a function. It uses this function that it takes in as a means to evaluate the list of pairs of strings. It then returns a list of pairs of strings containing all of the pairs of strings that had the highest match-score based on the function it was given to evaluate them with. In other words, (("hello" "b_low") ("hello_" "b_l_ow") ("hello" “_blow")) all had the same score of -3, but ("h_e_llo" “bl_o__w”)) has a score of -12, thus it is dropped from the list.

The functions to compute alignemt:

(define (char-scorer char1 char2)
  (cond 
    ((char=? char1 char2) 2)
    ((or (char=? char1 #\_ ) (char=? #\_ char2)) -2)
    (else -1)))

(define (alignment-score s1 s2)
  (define min-length (min (string-length s1) (string-length s2)))
  (let loop ((score 0) (index 0))
    (if (= index min-length)
      score
      (loop (+ score (char-scorer (string-ref s1 index) (string-ref s2 index)))(+ index 1))))) 
Definer
  • 1
  • 3
  • This seems very related (possible duplicate) of [Scheme - Help Writing A Function](http://stackoverflow.com/q/23154180/1281433). The example inputs and outputs are pretty much the same, if not identical. – Joshua Taylor Apr 21 '14 at 21:12

1 Answers1

0

I would divide the operation into two steps.

  1. Compute the maximum score. Here's a function that can do that.

    (define (get-maximum-score lst scoring-func)
     (apply max (map (lambda (x) (scoring-func (car x) (cadr x))) lst)))
    
  2. Filter the list by selecting the items that match the maximum score and drop the rest.

    (define (get-maximum-score-items lst scoring-func)
    
      (define max-score (get-maximum-score lst scoring-func))
    
      (define (helper in out)
        (if (null? in)
          out
          (if (eq? max-score (scoring-func (caar in) (cadar in)))
            (helper (cdr in) (append out (list (car in))))
            (helper (cdr in) out))))
    
      (helper lst '())
      )
    

Now get the result.

(print
 (get-maximum-score-items
  '(("hello" "b_low") ("hello_" "b_l_ow") ("hello" "_blow") ("hello" "blow") ("h_e_llo" "bl_o__w"))
     alignment-score))
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • I tried that, and the say there's a wrong number of arguments passed to procedure? Am i suppose to add something else? – Definer Apr 21 '14 at 20:30
  • @Definer I had some typos in my answer. Try the functions again. – R Sahu Apr 21 '14 at 20:35
  • I still get an error kind Sir, it says Error in Map -- Wrong number of arguments passed to procedure (score-function '("hello" "b_low")) – Definer Apr 21 '14 at 20:40
  • @Definer Can you post your scoring function? – R Sahu Apr 21 '14 at 20:48
  • (define (scoring-function char1 char2) (cond ((char=? char1 char2) 2) ((or (char=? char1 #\_ ) (char=? #\_ char2)) -2) (else -1))) **and also** (define (alignment-score s1 s2) (define min-length (min (string-length s1) (string-length s2))) (let loop ((score 0) (index 0)) (if (= index min-length) score(loop (+ score (scoring-function (string-ref s1 index) (string-ref s2 index)))(+ index 1))))) – Definer Apr 21 '14 at 20:50
  • @Definer I updated your post with the functions you provided and my answer to match those functions. It should work now. – R Sahu Apr 21 '14 at 21:04
  • thank you, I tried that, but when I execute it, nothing happens, the function just ends – Definer Apr 21 '14 at 21:10
  • @Definer sorry for the sloppy answers. It's fixed now. Give it another try. – R Sahu Apr 21 '14 at 21:20
  • no problem sir. It gives me output of hello_b_l_o_w6> now, prompting me to input again – Definer Apr 21 '14 at 21:26
  • @Definer Don't know how I can help any more. With your functions and my functions, I get the correct output - `(("hello" "b_low") ("hello_" "b_l_ow") ("hello" "_blow"))` – R Sahu Apr 21 '14 at 21:32
  • I renamed a few of my things, so maybe there's a bit confusion in that? Did you use my updated example? – Definer Apr 21 '14 at 21:37
  • Also, is your "scoring-func" refer to my "alignment-score" – Definer Apr 21 '14 at 21:45
  • Yes. The `print` function uses `alignment-score` to call `get-maximum-score-items`. – R Sahu Apr 21 '14 at 21:58
  • @ R Sahu , any idea why else it won't work? Maybe you could post or email me please? – Definer Apr 21 '14 at 22:04
  • I'm very confused on how to fix it, please help @R Sahu – Definer Apr 21 '14 at 22:16
  • Or maybe even post your and my version as one post please – Definer Apr 21 '14 at 22:18
  • @Definer I think it will be a disservice to you if I help you any more than I already have. You should be able to take it from here. – R Sahu Apr 22 '14 at 02:23