Lab 4
             Identifying and Exploiting Repeating Patterns

 Introduction
 ============
 In lab 3, we explored how to make decisions.  Decision making allows
 us to write much more interesting programs because we have programs
 with multiple paths of execution.  This week we will be looking at
 loops and patterns.  Looping is the control structure which allows
 us to write programs which are far more useful.  Unfortunately, loop
 behavior can be a bit difficult to comprehend.  In this lab, we will
 explore using loops to create repeating patterns.  In both the
 guided and self labs, we will explore problems which have
 non-obvious solutions, and they will seem a little complicated.  The
 key to solving these problems will be in spotting the underlying
 pattern in them.


 Part I (Guided) - Fun With Etruscan Sheep
 =========================================

 In the land of Tuscany, before the birth of Romulus and Remus, there
 lived two shepherds named Reg and Stan.  One morning, Reg noticed
 that something was amiss.  "Stan, does it seem like we have fewer
 sheep today than we did yesterday?", he asked.  Stan replied, "I
 don't know.  Tell you what.  Let's take this bone and cut a notch
 into it for each sheep, then we can recount it in the morning and
 see if there may be a wolf in our midst."  That day, they set out
 doing just that.  They took a lamb bone and carved notches:

   ||||

 The next day, they repeated the same task:

   |||

 "Aha!", exclaimed Reg, "We are down by one.  Let's stay up tonight
 and see what's happening to the sheep."  That night they found a
 wolf prowling their fields.  They killed the wolf by pelting it with
 rocks, thus preserving the number of their flock.  Now, Reg and
 Stan became the most successful shepherds in all of Tuscany, and
 they had also made one of the first steps for building a mechanical
 computer.  Their success, however, turned to dismay after a
 particularly successful lambing season.  Reg returned with the
 following notches:

   |||||||||||||||||||||

 Stan took one look and said "I just can't handle that many notches!
 It's hard to read at a glance.  We'll spend all our time counting
 notches!"  Reg thought it over and then said, "What if we change
 every 5th mark?"  He then carved a new bone:

   ||||/\||||/\||||/\||||/\|

 Stan took one look and said, "Ah!  So every fifth mark is /\.  Now
 we can count by fives.  What if we extend it further, and made
 every tenth mark be overlapping 5's like this."  Stan took the bone
 and carved:

   ||||/\||||X||||/\||||X|

 Reg took one look and liked what he saw.  "Now we can see at a
 glance, that we have 2 10's and 1 left over notch.  That's bloody
 brilliant!" (All 7th century BC Etruscans used British slang.  Just
 roll with it!).  They then decided to expand this just a little
 further.  They made a symbol for every 5th X and for every 2nd 50.
 Thus the Etruscan counting bone system was:

   Number  Symbol
   ------  ------

     1       |

     5       /\

     10      X
            /|\
     50      |

     100    >|<

 They didn't go above 100, because that was more sheep than they had
 ever seen in their lives.  It's easy to see that this is a method
 that can be used for counting large numbers efficiently.  Thus the
 Etruscan counting bone became one of the world's first manual
 computers!

 In time, Reg and Stan decided they wanted to chart their business
 over long periods of time.  Now that they had over 50 sheep, they
 were going through a lot of bones.  One day as Stan was recording a
 year's worth of sheep he started to get tired.  He had carved:

                                                              /|\
   ||||/\||||X||||/\||||X||||/\||||X||||/\||||/\||||X||||/\|||||

 As Stan was massaging his swollen wrist it hit him.  "Oy! These
 notches are brilliant for adding, but they are rubbish for recording
 data."  After a little thinking he said, "I have it!  We can just
 take everything prior to the largest symbol as read, so I could just
 carve:

   /|\
    |

 "and we'll know that those exhausting marks came before it.  I could
 also just do groups of those, for instance, I could do XX for 20
 sheep."  Reg liked the idea, but there was just one small problem.
 "What about when you have one less than the big one?"  "Oh yeah..."
 Almost at the same instant, a bolt of genius hit them.  "What if we
 put the notch just before the big group.  Like |X would mean 9 and
 we'd just understand that the 3 others are there.  You know, they'd
 have to build up to it anyway."  So they practiced and found that
 this worked well.  |X for 9, |/\ for 4...  and all was well.

 Then came the rise of Populous Romanus.  They liked Reg and Stan's
 counting method.  They especially liked how it work for both
 counting and recording, but they thought the symbols looked like
 something that a shepherd would come up with.  So, they decided to
 use letters.  | became I, /\ became V, and so on.  This made it easy
 for Roman stone carvers to carve numbers into Roman walls.  They
 also extended the system a bit, so the total table of symbols
 became:

   Decimal  Symbol
   -------  ------
       1      I
       5      V
      10      X
      50      L
     100      C
     500      D
    1000      M

 They also decided to call these things "Roman Numerals."  Our
 Etruscan friends were none too pleased by this.  "Bloody Romans!"
 they muttered, "What have they ever done for us?"


 Problem
 -------
 We want to create a program which will convert any decimal number
 to Roman Numerals.  At first glance, this seems like a monumental
 task.  Up to 10 is easy, but I want to be able to do the following:

    1024 - MXXIV
    3900 - MMMCM
    249  - CCXLIX

 A sample run of the program which you are going to write is:

 -- Begin Sample Run --
 Enter Number: 597
 DXCVII
 -- End Sample Run --


 Developing a Solution
 ---------------------
 In order to solve this problem, we need to identify a repeating
 pattern.  Using the standard set of Roman numerals would allow us to
 count to 3,999 before the pattern will break.  A later addition used
 the drawing of bars over the letters to multiply them by 1000.  So
   _
   M

 Would become 1,000,000.  This is a bit too much for us to handle at
 the present state of our knowledge of C++, however, so we are going
 to make 3,999 our maximum number.  You could solve every single
 Roman numeral and then have a 4,000 element switch statement, but
 that would be very tiring.  Instead, we want to work smarter, not
 harder!  Take a look at the story above, especially the tables and
 the notches.  Can you see a pattern to what they are doing?  Ponder
 it a bit before you read the next paragraph.

 They are using an ordinal counting system, where the total value of
 the numbers accumulate from left to right.  The largest amount of
 the values is always at the left.  For instance, X would be
 preceded by 9 marks prior to the X.  That's how they came up with
 the short form |X (or IX for the Romans).  So if we want to convert
 numbers to Roman numerals, we are going to start by subtracting out
 the larger parts and record their symbols.  For instance, let's say
 we look at 2013.  We can see that the highest part of the number is
 in the thousands.  So we record as many thousands as we can:

   MM

 This leaves us with 13.  13 is less than 500, 100, and 50.  Now we
 record as many 10's as we can:

   MMX

 this leaves us with 3.  There can be no 5's, but there can be ones.
 We record the remaining 1's.

   MMXIII

 So pseudocode at the first attempt at this would work as follows:

   For each letter in {M, D, C, L, X, V, I}
     if num >= value of letter
       print num / value of that letter
       num = num % value  (the remainder)
     end if
   end for

 There is, of course one problem with this.  Can you see what it is?
 Try a hand trace of the above for the number 40.  You'll end up with
 "XXXX" which is invalid.  So we have to think about this some more.
 We know that the base symbols are {M, D, C, L, X, V, and I}.  Just
 like Reg and Stan, we are faced with the problem of boundaries
 between these symbols.  So we could augment the above algorithm with
 these boundaries:

   For each letter in {M, D, CD, C, XC, L, XL, X, IX, V, IV, I}
     if num >= value of letter
       print num / value of that letter
       num = num % value  (the remainder)
     end if
   end for

 This algorithm will work.  But how can we implement it?  After all,
 how will the computer know the value of the numbers?  In order to
 implement this, we are going to use an iterative design and
 implementation process.  This is a technique which allows us to go
 back and forth between pseudocode and C++ code in an effort to
 develop the program over time.  The first detail we will look at is
 the issue of the values of these separations.  Observe the following
 table of symbols (including the boundaries):

   Decimal  Symbol
   -------  ------
    1000       M
     900      CM
     500       D
     400      CD
     100       C
      90      XC
      50       L
      40      XL
      10       X
       9      IX
       5       V
       4      IV
       1       I

 Now, if we look closely at this, we can see an underlying pattern.
 Notice how we keep repeating 9,5,4,1?  We do this once at each
 multiple of 10.  That is, we have 900, 500, 400, 100; and we also
 have 90, 50, 40, 10.  So we could iterate over these values by
 keeping track of where we are in the sequence.  We will need a
 counter for each of the positions. There are 4 states in the
 sequence:

   for counter=3 to 0
     case 3
         value = 9
     case 2
         value = 5
     case 1
         value = 4
     case 0
         value = 1

     print value
   end for

 This will, of course, handle our sequence 9,5,4,1 but not the full
 counting that we want.  The full counting needs to loop through each
 decade, starting at 1000 and decreasing to 1.  We will stay in each
 decade for a count of 4.  We can combine all this into one large
 loop by observing that we decrease the decade only once the counter
 reaches 0. The pseudocode for all this is:

   counter=0
   decade=1000
   while decade > 0
     switch(counter)
       case 3
         value = 9 * decade
       case 2
         value = 5 * decade
       case 1
         value = 4 * decade
       case 0
         value = decade
         decade = decade / 10
         counter = 4
     end switch
     counter = counter - 1

     display the value
   end while

 As you can see, we are getting close to C++ code, so let's go
 ahead and write some C++.  Create a file called "roman.cpp" and
 enter the following code:

 -- Begin roman.cpp --
 /*
  * File: roman.cpp
  * Purpose: A little program to compute the roman numeral sequence.
  */
 #include <iostream>

 using namespace std;

 int main(void)
 {
   int counter=0;
   int decade=1000;
   int val=1000;

   // run through all decades
   while(decade) {
     //update the value
     switch(counter) {
     case 3:
       val = 9 * decade;
       break;
     case 2:
       val = 5 * decade;
       break;
     case 1:
       val = 4 * decade;
       break;
     case 0:
       val = decade;
       decade /= 10;  //new decade!
       counter=4;
       break;
     }

     //update the counter
     counter --;

     //output the value
     cout << val << endl;
   }

   return 0;
 }
 -- End roman.cpp --

 Run this code and verify that it prints:

 1000
  900
  500
  400
  100
   90
   50
   40
   10
    9
    5
    4
    1

 Now we can iterate over the correct values, we want to add to it
 iteration over the correct symbols.  Of course, this is pretty
 simple in that we can just add in the following switch statement.
 Instead of

     //output the value
     cout << val << endl;

 What we really want is:

     //output the correct symbol
     switch(val) {
     case 1000:
       cout << "M" << endl;
       break;
     case 900:
       cout << "CM" << endl;
       break;
     case 500:
       cout << "D" << endl;
       break;
     case 400:
       cout << "CD" << endl;
       break;
     case 100:
       cout << "C" << endl;
       break;
     case 90:
       cout << "XC" << endl;
       break;
     case 50:
       cout << "L" << endl;
       break;
     case 40:
       cout << "XL" << endl;
       break;
     case 10:
       cout << "X" << endl;
       break;
     case 9:
       cout << "IX" << endl;
       break;
     case 5:
       cout << "V" << endl;
       break;
     case 4:
       cout << "IV" << endl;
       break;
     case 1:
       cout << "I" << endl;
       break;
     }

 Make that change and run the program.  Verify that it runs through
 the correct symbols.  Now we can implement the technique for
 conversion we discussed above.  First, we need to make new variables
 for the number we want to convert, and also counters for the number
 of each symbol.  Let's create the variables first.  Add the
 following to the appropriate place in code:

   int i, n, num;

 Before we enter the loop, we want to get the number we are going to
 convert.  Add the following before the loop:

   //get the number
   cout << "Number: ";
   cin >> num;

 Now we want to surround the printing of symbols in the following
 around the switch case which prints out the letters

   n=num / val;
   for(i=0; i<n; i++) {
     /* the switch case from above goes here.  */
   }
   num = num % val;

 Now run the program.  It almost works!  Though it would be nice if
 we printed all the symbols on one line, wouldn't it?  Go through the
 switch statement and remove all the endl parts.   Add 1 end of line
 just before we return 0 at the end.  The end of the main function
 should end with:

   cout << endl;
   return 0;

 Run the program and you'll see that it works beautifully!  Well done!
 Try out some of the harder test cases for roman numerals.  Look back
 over the code and make sure you understand all the reasoning we used
 to get there.  Fully understanding what you are to do, identifying
 patterns, and then implementing those patterns is a very powerful
 technique in computer science.  Mastering this type of thinking is
 not easy, but once you do you'll be able to tackle any coding
 challenge anyone throws at you!

 As a final step, create a script file which contains a listing of
 your code and a few sample runs.  Submit this using the turnin script.



 Part II (Self) Realizing a Misanthropic Dream
 =============================================
 Another long day at the Analytical Society in Cambridge has passed.
 The foolish men I must surround myself with have been particularly
 tiring of late, and far less than helpful in the design of complex
 machines.  I seldom think that many men are up to the task of
 reasoning as I can.  "Mr. Babbage" this, and "Mr. Babbage" that, Why
 do they call after me all the time?  And now, I must walk home amid
 the mob.  How I detest the mob.

 It's not that we could do without them.  Oh no, we need their labour,
 and we need their taxes to fund our higher purposes.  What we do not
 need is their tendency to break my plate glass windows.  Oh yes, I
 know it is they that do it.  I have outlined a table of the ways
 they break and destroy, and yet I have to walk home among them.  I
 have to pass through their parks, with their infernal offspring
 grabbing at my coat tails.  I have to see their "musicians", if one
 uses the term loosely, playing on the street corners.  I know the
 organ grinder will be there.  I hate organ grinder music.  It
 distracts and infuriates me!  The suffering and pecuniary effects of
 these half rated vagabonds astounds the mind.  At least I am almost
 at my door.  I turn back and realize that the one thing I cannot
 stomach is the mob's noise.  All the noise, noise, NOISE!

 At least my chamber is quiet.  I think I will turn to my
 computations, and find solace in my math.  Ah, computation, how
 wonderfully exact, obedient, and ready to serve.  Wait.  What's
 this?  My table tells me the log of 1231 is 3.0901?!  Outrageous,
 even a fool knows that log(1231) is 3.0903 if rounded at 4 places.
 They will not get away with this!  These tables affect every aspect
 of computations, and they have the gall to make an error.  No, this
 will not do.  This cannot be trusted to the minds of men, for the
 computers* will make error upon error and their error will grow to
 catastrophe.  I shall build a machine, for it is to the machine we
 should entrust all that is important.  I shall build a difference
 engine!

 * NOTE: Prior to 1947, the term "Computer" referred exclusively to a
         professional person who's sole task was to carry out
         mathematical computation.  This is why ENIAC was called an
         "Electronic Computer."  By the 1960's, the term came to be
         used almost exclusively for electrical and mechanical
         devices.  The computer profession is dead.  No one you will
         meet will claim to be a computer.  (At least not the sane ones.)

 Problem
 -------
 The above rant is my attempt to think like Charles Babbage, a truly
 embittered man (though he had a few friends with whom he was
 tender.)  He set out to build a table of logarithms via machine, and
 to this end he designed the difference engine.  The difference
 engine would have been the world's first general purpose mechanical
 computer.  However, his designed proved to be far more involved and
 expensive than originally anticipated.  Also, he had started the
 design of the analytic engine which would have been more powerful.
 His parliamentary backers decided to fund the analytic engine
 instead.  The analytic engine also proved too expensive and so it
 was ultimately abandoned.  He did succeed in building parts of both
 engines, and it has been shown that his machines would have worked.
 Modern engineers have built his designs, showing that Babbage really
 did know his stuff!

 As another side note, the analytic engine was programmable.  A woman
 by the name of Ada Lovelace, a long time friend of Babbage, wrote
 programs for the analytic engine.  This has lead to the wonderful
 bit of trivia that the world's first computer programmer was a
 woman, even though it is now a male dominated field.

 The task which the difference engine was originally designed for was
 the computation of logarithms.  Logarithms were much more important
 to day to day computation during Babbage's time as they were used to
 multiply numbers efficiently.  This follows from the definition of
 the log:
    x
   b  = y

   log y = x

 Suppose we multiply two exponentials of a common base.  By the laws
 of exponents:

    x    y    x + y
   b  * b  = b

 So if you want to multiply two numbers, you find the log of both
 numbers, then add them, and then take the antilog using your log
 table.  For instance

   123 * 412

 becomes

   log(123) + log(412)
  e

   4.8121 + 6.0210
  e

   10.8331
  e

  50670

 Which is close to the answer.  A skilled log table user would be
 able to extract the last digit, which is 6.  50676 is the exact
 answer.  Note that everything except the addition step is just a
 table lookup in a book.  Thus the more accurate and precise your log
 tables, the more accurate and precise your multiplications.  Also
 note that here, when I write "log" I mean natural log.  Up until the
 advent of the pocket calculator, log always referred to natural log,
 and in most engineering circles, it still does.

 So now, here's your problem.  You are going to realize Charles
 Babbage's dream, and you are going to construct a program which
 generates a nice and neat log table.  The table will be in four
 columns, and it will allow for the user to select the number of
 lines per page, and the number of pages to print.  For example, here
 is a sample run of my program:

 -- Begin Sample Run --
 Welcome to the Babbage Log Engine

 Lines Per Page: 5
 Pages: 3
 0.1                                                                 2.0
 -----------------------------------------------------------------------
    0.1 -2.3026        0.6 -0.5108        1.1  0.0953        1.6  0.4700
    0.2 -1.6094        0.7 -0.3567        1.2  0.1823        1.7  0.5306
    0.3 -1.2040        0.8 -0.2231        1.3  0.2624        1.8  0.5878
    0.4 -0.9163        0.9 -0.1054        1.4  0.3365        1.9  0.6419
    0.5 -0.6931        1.0  0.0000        1.5  0.4055        2.0  0.6931
 -----------------------------------------------------------------------


 2.1                                                                 4.0
 -----------------------------------------------------------------------
    2.1  0.7419        2.6  0.9555        3.1  1.1314        3.6  1.2809
    2.2  0.7885        2.7  0.9933        3.2  1.1632        3.7  1.3083
    2.3  0.8329        2.8  1.0296        3.3  1.1939        3.8  1.3350
    2.4  0.8755        2.9  1.0647        3.4  1.2238        3.9  1.3610
    2.5  0.9163        3.0  1.0986        3.5  1.2528        4.0  1.3863
 -----------------------------------------------------------------------


 4.1                                                                 6.0
 -----------------------------------------------------------------------
    4.1  1.4110        4.6  1.5261        5.1  1.6292        5.6  1.7228
    4.2  1.4351        4.7  1.5476        5.2  1.6487        5.7  1.7405
    4.3  1.4586        4.8  1.5686        5.3  1.6677        5.8  1.7579
    4.4  1.4816        4.9  1.5892        5.4  1.6864        5.9  1.7750
    4.5  1.5041        5.0  1.6094        5.5  1.7047        6.0  1.7918
 -----------------------------------------------------------------------
 -- End Sample Run --

 Note how each "page" begins with a header showing the first and last
 logarithms on the page.  Also note that everything is neatly
 aligned.  There is a lot of iomanip action going on in this
 program.  I want you to reproduce this output exactly as it appears
 here.

 Clearly, hand computing test cases here will be highly impractical.
 Instead, what we should do is just spot check a few of the
 logarithms.

 Hints & Observations
 --------------------
 1.  You've probably realized that cout lets you do line output, but
     you can't come back up to a line.  This means that each line has
     to be printed all at once.  You'll be doing 4 logarithms per
     loop iteration.  The key here is knowing the starting point of
     each column.

 2.  Look at the cmath documentation on cplusplus.com to see how to
     compute logarithms.

 3.  Try to identify patterns in how to determine the first and last
     log on a page as well as the start of each column.

 4.  Try using setw and setfill to do most of your formatting.  You
     shouldn't have to write a loop to do the "---" separator lines!

 5.  You may want to discuss the design with your peers.  Bouncing
     ideas off of each other can be a big help with problems like this.


 Extra Credit (20 points)
 ------------------------
 Charles Babbage did publish a logarithm table.  It wasn't
 mechanically computed, but it was more accurate than the ones he
 started with.  Head over to
 http://archive.org/details/tableoflogarithm00char to see Babbage's
 log table.  If you can make your program output a table formatted like
 Babbage's original table, I will give you 20 points.  Yes, you can
 score a 120 on the lab!  Good luck!