1

I have an assignment to make a tail-recursive function that takes 3 integers(possibly very large), p q and r, and calculates the modulo of the division (p^q)/r. I figured out how to do make a function that achieves the goal, but it is not tail recursive.

(define (mod-exp p q r)
  (if (= 0 p)
      0
      (if (= 0 q)
          1
          (if (= 0 (remainder r 2))
              (remainder (* (mod-exp p (quotient q 2) r)
                            (mod-exp p (quotient q 2) r))
                         r)
              (remainder (* (remainder p r)
                            (remainder (mod-exp p (- q 1) r) r))
                         r)))))

I'm having a hard time wrapping my head around making this tail-recursive, I don't see how I can "accumulate" the remainder. I'm pretty much restricted to using the basic math operators and quotient and remainder for this task.

Sylwester
  • 47,942
  • 4
  • 47
  • 79
gunnnnii
  • 9
  • 2
  • 2
  • 2
    Start with a tail-recursive "regular" exponentiation, then add `remainder` as appropriate. (You need to add an accumulation parameter.) – molbdnilo Oct 04 '18 at 10:12

1 Answers1

0

I see that you're implementing binary exponentiation, with the extra feature that it's reduced mod r.

What you may want to do is take a normal (tail recursive) binary exponentiation algorithm and simply change the 2-ary functions + and * to your own user defined 3-ary functions +/mod and */mode which also take r and reduce the result mod r before returning it.

Now how do you do binary exponentiation in a tail recursive way? You need the main function to call into a helper function that takes an extra accumulator parameter - initial value 1. This is kind of similar to tail recursive REVERSE using a helper function REVAPPEND - if you're familiar with that.

Hope that helps and feel free to ask if you need more information.

river
  • 1,028
  • 6
  • 16