Searching for perfect numbers

Your objectives in today's project lab are to read and understand a Scheme program and then to modify it so that it solves a different, but related, problem.

Step 1

The program that you are to examine and modify is stored in a file called /home/stone/courses/scheme/examples/perfect-search.ss. Make a copy of this file in your home directory by starting a terminal-emulator window and typing in the command

cp /home/stone/courses/scheme/examples/perfect-search.ss perfect-search.ss

The cp command makes a copy of an existing file under a new name. After the cp, you supply the name of the existing file and the name of the file that will contain the copy. Notice that there is a space after cp and another space between the name of the existing file and the name of the new file.

Step 2

Start DrScheme, asking it to load your copy of the program initially:

drscheme perfect-search.ss &

DrScheme will set up a definitions window and display the program in it.

Step 3

Read through the program and figure out what each procedure does and how it does it. If you like, you can experiment with each procedure as you come to it. When you click on the Execute button, DrScheme will learn the definitions and set up an interactions window in which you can invoke them however you like.

Step 4

Use the perfect-search procedure to find all the perfect numbers less than or equal to 500.

Step 5

As you see, few numbers are perfect. Usually the sum of a number's proper divisors is less than the number itself (in which case the number is said to be ``deficient''); occasionally, the sum of the proper divisors is greater than the number (in which case the number is said to be ``abundant'').

Using any of the procedures defined in the program, define and test a Scheme predicate named abundant? that determines whether or not a given positive integer is abundant.

Step 6

Abundant numbers are not uncommon, but almost all of them are even. Using your abundant? predicate, rewrite the entire program originally stored in perfect-search.ss so that it searches for odd abundant numbers instead of perfect ones. Store your revised program in a file called odd-abundant-search.ss. Use it to find the first odd abundant number. (Hint: it's less than 1000).


Suggestions for further inquiry (optional)

Range searching

Every time perfect-search is invoked, it starts over again from 1. Modify it so that it searches a specified range of values, so that we can extend a previous search without having to repeat all the earlier work.

Greater efficiency

Perfect numbers are rare; there is only one other one less than one million. We could find it by writing (perfect-search 1000000), but it would take several years for the program as currently written to evaluate this procedure call. Fortunately, there are much faster methods of computing proper-divisors for large arguments. Currently, proper-divisors spends most of its time testing possible divisors unsuccessfully. Figure out a way to reduce the number of unsuccessful divisions without losing any divisors.

(Hint: Most divisors come in pairs. If you're looking for divisors of, say, 192, and you discover that 2 is a divisor, you've also learned that 192/2 is a divisor; similarly, when you find that 3 is a divisor, you've also learned that 192/3 is a divisor.)

Amicable numbers

Two positive integers are amicable if each is the sum of the other's proper divisors. (For instance, the proper divisors of 1184 are 1, 2, 4, 8, 16, 32, 37, 74, 148, 296, and 592, which add up to 1210; the proper divisors of 1210 are 1, 2, 5, 10, 11, 22, 55, 110, 121, 242, and 605, which add up to 1184. So 1184 and 1210 are amicable.)

Write a Scheme program to find the smallest pair of amicable numbers.


This document is available on the World Wide Web as

http://www.cs.grinnell.edu/~stone/courses/scheme/perfect-search-project.xhtml

created February 9, 2000
last revised March 17, 2000

John David Stone (stone@cs.grinnell.edu)