nland
nland

Reputation: 669

Computing a series in racket

Ok, I'll start out by saying that this is a hw question. That being said, I'm not looking for the answer, just some direction to the answer.

I've got to compute a series up to n. My initial thoughts were to use recursion, and do something like the following

(define (series-b n)
  (if (= n -1) 0 ; Not sure how to handle this
    (+ (/ (expt -1 n) (factorial n)) (series-b (sub1 n)))
  )
)

That seems to be the way to do this. However, I'm not really sure how to handle the -1 case, and that is throwing my expected answers off. Thanks in advance.

Edit

I do have some test cases, and they are as follows

n = 0: 1
n = 1: 1/2
n = 2: 2/3
n = 3: 5/8
n = 4: 19/30
n = 5: 91/144

I'm not entirely sure which series that is either.

Edit 2

I've selected soegaard's answer, however, I did make a small change to the final solution, which is:

(define (series-b n)
  (for/sum ([i (+ n 1)])
      (/ (expt -1 i)
         (factorial (+ i 1))))
)

The accepted answer uses (factorial i) rather than (factorial (+ i 1)). I was not yet familiar with for/sum, but that is a really nice way to handle this problem, so thanks!

Upvotes: 2

Views: 224

Answers (3)

soegaard
soegaard

Reputation: 31145

Your definitions seems right to me. The value of the empty sum is 0, so you are returning the correct value.

Your solution is the canonical one using recursion. An alternative using for/sum looks like this:

(define (series-c n)
  (for/sum ([i (+ n 1)])
    (/ (expt -1 i)
       (factorial (+ i 1))))

Upvotes: 3

C. K. Young
C. K. Young

Reputation: 223133

You can implement this series as a SRFI 41 stream!

(require srfi/41)
(define negatives (stream-cons -1 (stream-map sub1 negatives)))
(define terms (stream-cons 1 (stream-map / terms (stream-cdr negatives))))
(define series (stream-cons 1 (stream-map + series (stream-cdr terms))))

Example usage:

> (stream->list 10 series)
(1 1/2 2/3 5/8 19/30 91/144 177/280 3641/5760 28673/45360 28319/44800)

Don't like streams? I like soegaard's answer, except that it has to recompute the factorial each time! I wish for/sum has the ability to hold "state" values the way for/fold does. Here's an implementation using for/fold:

(define (factorial-series n)
  (define-values (sum _)
    (for/fold ((sum 0) (value 1))
              ((i (in-range -2 (- -3 n) -1)))
      (values (+ sum value)
              (/ value i))))
  sum)

Example usage:

> (map factorial-series (range 10))
(1 1/2 2/3 5/8 19/30 91/144 177/280 3641/5760 28673/45360 28319/44800)

Upvotes: 1

John Clements
John Clements

Reputation: 17223

You're doing well, and I think you're very close.

Start by writing a few test cases. Make sure to include test cases for the base case.

It's hard to answer the math part of the question, because I can't tell what series it is that you're computing!

Upvotes: 1

Related Questions