morpheus1977
morpheus1977

Reputation: 43

Using racket to recursively sum nested lists within a list of permutations

I have a list of numbers and a list of operators in racket.

(define numList (list 5 25))
(define ops '(+ *))

I am using the cartesian-product to join the operators to each possible permutation of the list of numbers.

(cartesian-product ops (permutations numList))

which gives the following result;

'((+ (5 25))
  (+ (25 5))
  (* (5 25))
  (* (25 5)))

I want to sum each nested list, ie (+ (5 25)) and then add them to a list. I have managed to do the following so far using the eval keyword;

(define ns (make-base-namespace))

(list (eval
   (flatten
    (cadr
     (cartesian-product ops (permutations numList))))ns ))

Which removes the nesting of each list and performs the sum on the first 3 elements and returns a value of 50 (+ (5 25)). I want to perform this recursively on each nested section before the flatten is performed. I know that I'll be able to use remove-duplicates too. I'm new to Racket, but here's what i have so far;

(define (evalCart l)
(if (null? l)
  0
  (list
   (eval
    (flatten
     (cadr
      (cartesian-product ops (permutations numList)))) ns ) (evalCart (car 
l)))))

Upvotes: 2

Views: 426

Answers (1)

law-of-fives
law-of-fives

Reputation: 643

eval is a bit overkill. You can instead determine which procedure you want by comparing for symbol equality. Since racket has first class procedures, you can just return the procedure itself. For instance:

(define (get-procedure term)
  (case term
    [(+) +]
    [(-) -]
    [(*) *]
    [(/) /]))

If you don't know case you can use a cond form

(cond [(eq? term '+) +] ...

Then you can use this with apply as in

(define (evaluate term)
  (define procedure (get-procedure (first term)))
  (define arguments (second term))
  (apply procedure arguments))

Then you can map the procedure evaluate as in

(map evaluate (cartesian-product ops (permutations numList)))

This will give you a list of numbers. In the case of the list of four elements you gave, you would get '(30 30 125 125), which I believe is what you're looking for.

Upvotes: 3

Related Questions