0
votes

I'm trying to do a recursive function that gets a list of string-int pairs + a string named prefix, and using function named "starts-with" it sums up all the ints whose begininng match the prefix. Problem is, I can never get the list to go forward, it gets stuck at the beginning and then program crashes.

(define (sum-of-pairs-start-with prefix ls)
    ( let*(  (prefix2 (string->list prefix))
          (str2 (string->list (car (car ls)))))
(cond((null? str2) 0)   
     ( (starts-with prefix (car(car ls))) 
       (+  cdr(car ls) (sum-of-pairs-start-with prefix (cdr ls))) ) 
     (else sum-of-pairs-start-with prefix (cdr ls))) ) )     

I work with input:

(sum-of-pairs-start-with "a" (list (cons "a" 1) (cons "b" 2) (cons "aa" 33) (cons "ca" 4))) ;; =34

but once i get to the second pair in the list ("b" 2) it goes to the else condition as expected, but then ls gets back up one line to origin (with the previous value) instead of going forward to next value ("aa" 33). I 'm new to scheme and I dont get why that happens, it's frustrating

2
First, get rid of all the syntax errors.Michael Vehrs
which syntax errors? racket's compiler didnt mention any..mooly
Well, there are syntax errors, and there are syntax errors. Compare these two expressions: (list (+ 1 2)) and (list + 1 2). The compiler or interpreter will not complain about the second one because it is a perfectly legal expression. It is also almost certainly not what you want.Michael Vehrs
How are you seeing it "back up"? I get "+: constract violation ..." in Racket. (As expected, by the way; you're trying to add cdr, (car ls), and the recursive result.)molbdnilo
I see it on Debug mode, it's in the "else" line and then gets right back to the line above itmooly

2 Answers

2
votes

You just have to call the starts-with procedure that we previously defined (let it take care of converting the strings to char lists), and fix all of the syntax problems:

(define (sum-of-pairs-start-with prefix ls)
  (cond ((null? ls) 0)   
        ((starts-with prefix (car (car ls)))
         (+ (cdr (car ls)) (sum-of-pairs-start-with prefix (cdr ls))))
        (else (sum-of-pairs-start-with prefix (cdr ls)))))

Once again, you're having trouble invoking the procedures. For example, these snippets are wrong:

cdr(car ls)
(else sum-of-pairs-start-with prefix (cdr ls))

Please, grab a book on Scheme and practice the basic syntax, remember that procedures are not called like this: f(x), the correct way is (f x). Also, pay attention to the correct way to indent the code, it'll be easier to find the errors if you follow the conventions.

0
votes

Following is a solution using higher functions:

(define (sum-of-pairs-start-with prefix ls)
  (apply +
         (map cdr
              (filter (λ (x) (starts-with prefix (car x)))
                      ls))))

It filters out those sublists which have prefix in first item, then gets second item (cdr) from each of those sublists and finally applies add function to all of them.