Wednesday, July 4, 2012

How many angels can dance on the head of a pin?

While working furiously in my "Fundamentals of Java" textbook, I came across this interesting design problem. The task was to write a simple Java program that could answer the question, "How many angels can dance on the head of a pin?" Obviously there is a mathematical solution to this problem! 

First, the programmer will need to know certain parameters:
  • An angel can share at most 30 percent of its space with other angels
  • 70 percent of its space cannot be shared
  • Within any shared region, only two angels can overlap
These factors tell us what the inputs for the program will be (i.e. data the user will provide):
  • The radius of the pinhead
  • The space occupied by an angel
  • The overlap factor
The program will then calculate:
  • The area (A) of the pinhead = Π * radius^2
  • Nonoverlapping space required by an angel = space required by an angel * (1 - overlap factor)
  • Number (N) of angels on a pinhead = area (A) of the pinhead / nonoverlapping space required by an angel
So, the proposed Java program (as run from the terminal) would proceed as follows:
  1. Enter the radius [of the pinhead] in millimeters: 10
  2. Enter the space occupied by an angel in square micrometers: 0.0001
  3. Enter the overlap factor: 0.75
  4. The number of angels = 1.256E7 (or 1.256 x 10^7 or 12,560,000)
For the purposes of this exercise, the book stated that we would use the "rather crude estimate for Pi" of 3.14. Any mathematicians reading this are almost certainly apoplectic with rage over that estimate, assuming, of course, they haven't already fainted from shock at the glaring holes in the logic of our equations (more on that in a minute). 

At any rate, the book then provides what it refers to as pseudo code, or a loosely code-based textual representation of how the program should work:
  1. read radius
  2. read angelSpace
  3. read overlapFactor
  4. area = 3.14 * radius * radius
  5. nonOverlapSpace = angelSpace * (1.0 - overlapFactor)
  6. numberAngels = area / nonOverlapSpace
  7. print numberAngels
So that's how the program is supposed to proceed. I won't lie, the book provides the code in its entirety and I copied it line for line. I'm (sorta) new at this and I learn as I go, so I just copied the code and made sure that I understood what it was doing as I went along. Here is the entire program:

import java.util.Scanner;

public class CountAngels {
   public static void main(String [] args) {

       Scanner reader = new Scanner(System.in);

       double radius;              
       double angelSpace;
       double overlapFactor;     
       double area;             
       double nonOverlapSpace;  
       double numberAngels; 

       //Get user inputs
       System.out.print("Enter the radius in millimeters: ");
       radius = reader.nextDouble();
       
       System.out.print("Enter the space occupied by an angel in square micrometers: ");
       angelSpace = reader.nextDouble();

       System.out.print("Enter the overlap factor: ");
       overlapFactor = reader.nextDouble();

       //Perform calculations
       area = 3.14 * radius * radius;
       nonOverlapSpace = angelSpace * (1.0 - overlapFactor);
       numberAngels = area / nonOverlapSpace;

       //Print results
       System.out.print ("The number of angels = " + numberAngels);
    }
}

Once you compile that, it should run. Enter the inputs and press enter and then the nice little program spits out the answer right there in the terminal. However, there are some HUGE problems in our calculations. (Mathematicians, your time has come.) 

First, although the program works as is and doesn't return any errors, our math is WAY off. We completely failed to account for the shape of the region occupied by an angel. Is it round? Is it square? Is it triangular? I'll quote the book on this one:

"To appreciate the significance of our oversight, consider the problem of placing as many pennies as possible on a plate without overlap. Because there are gaps between the pennies, the answer is not obtained by dividing the area of the plate by the area of a penny. Even if two pennies are allowed to overlap by some amount, there are still gaps. Thus, our solution is only correct if angels can mold their shapes to eliminate all empty spaces."

Well, as it turns out, for the purposes of this exercise we get to ignore this oversight and proceed under the assumption that angels can occupy the pinhead in such a way that no empty space is left. But our calculations are still off. We need to assume that "the space occupied by two overlapping angels equals the space each would occupy alone minus the amount by which they overlap." If you've ever worked with Venn Diagrams, the concept is similar. 

So to continue stealing from the book:

space for two overlapping angels 
  • = 2 * space occupied by angel - space occupied by angel * overlap factor 
  • = 2 * space occupied by angel * (1.0 - overlap factor / 2)

Thus,

space for one angel with overlap = space occupied by angel * (1.0 - overlap factor / 2)

and,

number of angels on pinhead = area of pinhead / space for one angel with overlap

The book graciously gives the reader the opportunity to go back and fix the calculations in the program, but I will graciously decline. I think we all get the point. Not to mention the fact that the original question was about dancing angels, not stationary ones. If they fit, that's one thing. But we have no clear notion of the maths involved with dancing angels.  

Source: Fundamentals of Java: AP* Computer Science Essentials for the A and AB Exams, Third Edition by Lambert/Osborne. http://www.amazon.com/Fundamentals-Java-Computer-Science-Essentials/dp/0619267232

No comments: