Here is some simple code to memoize a recursive function in Scheme. I originally got this from a Stackoverflow question, but the link is now dead, so I thought I will post it up here.
Memoize function:
(define (memoize op)
(letrec ((get (lambda (key) (list #f)))
(set (lambda (key item)
(let ((old-get get))
(set! get (lambda (new-key)
(if (equal? key new-key) (cons #t item)
(old-get new-key))))))))
(lambda args
(let ((ans (get args)))
(if (car ans) (cdr ans)
(let ((new-ans (apply op args)))
(set args new-ans)
new-ans))))))
After we have memoized this, we can use this within our recursive function. For example, Challenge 121 (Intermediate)
This problem uses the same money-changing device from Monday’s Easy challenge.
Bytelandian Currency is made of coins with integers on them. There is a coin for each non-negative integer (including 0). You have access to a peculiar money changing machine. If you insert a N-valued coin, it pays back 3 coins of the value N/2,N/3 and N/4, rounded down. For example, if you insert a 19-valued coin, you get three coins worth 9, 6, and 4. If you insert a 2-valued coin, you get three coins worth 1, 0, and 0.
This machine can potentially be used to make a profit. For instance, a 20-valued coin can be changed into three coins worth 10, 6, and 5, and 10+6+5 = 21. Through a series of exchanges, you’re able to turn a 1000-valued coin into a set of coins with a total value of 1370.Starting with a single N-valued coin, what’s the maximum value you could get using this machine? Be able to handle very large N.
Author: Thomas1122
Can be solved through memoization with the following code:
(define (memoize op)
(letrec ((get (lambda (key) (list #f)))
(set (lambda (key item)
(let ((old-get get))
(set! get (lambda (new-key)
(if (equal? key new-key) (cons #t item)
(old-get new-key))))))))
(lambda args
(let ((ans (get args)))
(if (car ans) (cdr ans)
(let ((new-ans (apply op args)))
(set args new-ans)
new-ans))))))
(define coin-value (memoize (lambda (coin)
(if (insert? coin)
(+ (coin-value (floor (/ coin 2)))
(coin-value (floor (/ coin 3)))
(coin-value (floor (/ coin 4))))
coin))))
(define (insert? coin)
(< coin
(+ (floor (/ coin 2))
(floor (/ coin 3))
(floor (/ coin 4)))))