Sunday, February 5, 2017

Programming Challenge 7.8 - Lo Shu Magic Square

/* Lo Shu Magic Square - The Lo Shu Magic Square is a grid with 3 rows
   and 3 columns:
                       15
                     ´
   ***** ***** *****
   * 4 * * 9 * * 2 * > 15
   ***** ***** *****
   * 3 * * 5 * * 7 * > 15
   ***** ***** *****
   * 8 * * 1 * * 6 * > 15
   ***** ***** *****
     v     v     v   ` 15
     15    15    15  
 
   The Lo Shu Magic Square has the following properties:

      * The grid contains the numbers 1 through 9
      * The sum of each row, each column, and each diagonal all add up
        to the same number.

   This program uses a two dimensional array to simulate the magic square.
   It uses a function that accepts a two-dimensional array as an argument,
   and determines whether the array is a Lo Shu Magic Square. The function
   is tested in this program. */

#include "Utility.h"

/* Global Constants: Magic number X, Magic number Y, Array size */
const int MAGIC_NUM_X = 3,
          MAGIC_NUM_Y = 3,
          ARR_SIZE = 3;

/* Prototype: Show menu, Show intro, Get numbers, Lo Shu Magic */
void showMenu();
void showIntro();
void getNumbers(int loShuMagic[][MAGIC_NUM_Y], int ARR_SIZE);
void isLoShu(const int loShuMagic[][MAGIC_NUM_Y], int ARR_SIZE);

int main()
{
   /* Call: showMenu */
   showMenu();

   pauseSystem();
   return 0;
}

/* **********************************************************
   Definition: showMenu

   This function display a menu for the user to choose from.
   ********************************************************** */

void showMenu()
{
   /* Constant: Menu */
   const int MENU = 3;

   /* Array variables: Menu, Lo Shu Magic */
   int choice[MENU] = { 1, 2, 3 };
   int loShuMagic[MAGIC_NUM_X][MAGIC_NUM_Y] = { { 0 }, { 0 } };

   /* Variable: Menu */
   int menu = choice[MENU];

   do
   {
      /* Display: The menu */
      cout << "\t\tLO SHU MAGIC SQUARE\n\n"
         << "Please select one of the following menu-items:\n\n"
         << " *1: View Introduction\n"
         << " *2: Enter Numbers\n"
         << " *3: Quit.\n\n"
         << "Your choice: ";
      cin >> menu;

      /* Validate: Input */
      while (menu < 1 || menu > 3)
      {
         cout << "\nYou made an invalid menu selection!\n"
            << "Your choice: ";
         cin >> menu;
      }

      /* Call: showIntro, showMenu, getNumbers, isLoShu*/
      switch (menu)
      {
         case 1:
         showIntro();
         showMenu();
         break;

         case 2:
         getNumbers(loShuMagic, ARR_SIZE);
         isLoShu(loShuMagic, ARR_SIZE);
         break;

         case 3:
         cout << "\nThis program will now exit.\n\n";
         break;
      }
   } while (menu != 3);
}

/* **********************************************************
   Definition: showIntro

   This function display information about this program and
   its purpose.
   ********************************************************** */

void showIntro()
{
   cout << "\n\t\tLO SHU MAGIC SQUARE\n\n"
      << "\t\t\t     15\n"
      << "\t\t\t  ´\n"
      << "\t ***** ***** ***** \n"
      << "\t * 4 * * 9 * * 2 * > 15\n"
      << "\t ***** ***** ***** \n"
      << "\t * 3 * * 5 * * 7 * > 15\n"
      << "\t ***** ***** ***** \n"
      << "\t * 8 * * 1 * * 6 * > 15\n"
      << "\t ***** ***** *****\n"
      << "\t v     v     v     ` 15\n"
      << "\t 15    15    15\n\n"
      << "This program lets you enter a series of 9 numbers,\n"
      << "which are then displayed in a row and column oder.\n"
      << "Once you have finished entering your numbers, this\n"
      << "program will then determine whether it is actually\n"
      << "a magic square or not. This depends on the following\n"
      << "factors:\n\n"
      << " * When the sum of each row (left to right) is equal\n"
      << " * When the sum of each column (top to bottom) is equal\n"
      << " * When the sum of the diagonals, left-top, right-bottom\n"
      << "   and vice versa is equal\n\n"
      << "If these conditions are met it is a 'Lo Shu Magic Square'.\n\n";
}

/* **********************************************************
   Definition: getNumbers

   This function gets the numbers for the Lo Shu magic square
   and stores these in a two dimensional array.
   ********************************************************** */

void getNumbers(int loShuMagic[][MAGIC_NUM_Y], int size)
{
     /* Variables: Input control, User numbers, Index x,
                 Index y (loop counters) */
       idxX = 0,
       idxY = 0,
       inpCtrl = 0;

   /* Get the user numbers */
   cout << "\nPlease enter your numbers:\n\n";

   for (idxX = 0; idxX < size; idxX++)
   {    
      cout << "Col #" << (idxX + 1) << ":"
           << setw(5) << right << " "
           << "\n-------\n";

      for (idxY = 0; idxY < size; idxY++)
      {
         cout << "Row #" << (idxY + 1) << ":"
            << setw(5) << right << " "
            << "-*-*-*- \t";
         cin >> loShuMagic[idxX][idxY];
    
         /* If the user enters a negative number, he or she is
            informed about the mistake and asked to repeat the
            input */
         for (inpCtrl = 0; loShuMagic[idxX][idxY] <= 0; inpCtrl++)
         {
            cout << "\nInput Failure: You entered an invalid number.\n"
                 << "Only positive values are allowed. Please repeat\n"
                 << "your input.\n\n"
                 << "Row #" << (idxY + 1) << ":"
                 << setw(5) << right << " "
                 << "-*-*-*- \t";
            cin >> loShuMagic[idxX][idxY];
         }
      }
      cout << endl;
   }

   /* Display: The numbers the user has entered as a square */
   cout << "This is your square of numbers:\n\n";

   for (idxX = 0; idxX < size; idxX++)
   {
      for (idxY = 0; idxY < size; idxY++)
      {
         cout << setw(5) << right << loShuMagic[idxX][idxY]
              << " \t" << setw(5) << right;
      }
      cout << "\n\n";
   }
}

/* **********************************************************
   Definition: isLoShu

   This function accepts the following array as its argument:
 
      * loShuMagic[][]

   It determines whether the numbers entered form a Lo Shu
   magic square or not.
   ********************************************************** */

void isLoShu(const int loShuMagic[][MAGIC_NUM_Y], int size)
{
   /* Variables: Diagonal sum, Sum X, Sum Y, Sum XY, Sum YX
                 (accumulators), Index X, Index Y (loop counters) */
   int sumX = 0,
       sumY = 0,
       sumXY = 0,
       sumYX = 0,
       idxX = 0,
       idxY = 0,
       diag = 0;

   /* The sums of each row and each column are determined, vertically,
      horizontally and in both diagonal directions */
   for (idxX = 0; idxX < size; idxX++)
   {
      sumX = 0;
      sumY = 0;

      for (idxY = 0; idxY < size; idxY++)
      {
         sumX += loShuMagic[idxX][idxY];
         sumY += loShuMagic[idxY][idxX];

         if (diag == diag + idxY + idxX - 2)
         {
            sumXY += loShuMagic[idxY][idxX];
         }

         if (idxX == idxY)
         {
            sumYX += loShuMagic[idxY][idxX];
         }
      }
   }

   /* This ternary operator determines whether each row, each
      column, and each diagonal sum match up or not */
   ((sumYX == sumX) && (sumYX == sumY)) &&
   ((sumXY == sumX) && (sumXY == sumY)) &&
   ((sumX == sumY) && (sumY == sumX)) ? cout << "This is a magic square!\n\n" :
                                        cout << "This is no magic square ...\n\n";}

Example Output:






No comments:

Post a Comment