Thursday 1 June 2017

Chapter 6 // Exercise 10 - Principles & Practice Using C++

Chapter 6 // Exercise 10


"Design a program that asks users for two numbers, and asks them whether they want to calculate permutations or combinations, and prints out the result. This will have several parts. Do an analysis of the above requirements. Write exactly what the program will have to do. Then, go into the design phase. Write pseudo code for the program and break it into sub-components. This program should have error-checking. Make sure that all erroneous inputs will generate good error messages."

OK, at first this sounds pretty daunting and there are some rather large(ish) equations given in the book however when you actually break down what he's asking, it becomes a pretty simple task.

We have already been given the formulas so it's just a matter of getting some numbers from the user and throwing them at some functions which solve the formulas, the pseudo code could look like this:

Ask user for two numbers
>numbers
Does user want combination or permutation?
>answer

If answer == Combination
       pass numbers to function and place into equation
       print combinations

If answer == Permutation
       pass numbers to function and place into equation
       print permutations

Pause & Quit

For some more information on combinations and permutations, check out this site. After reading this, it would appear that there are two ways to solve each problem but Bjarne only gives the formula to solve combinations without repetition. According to the site above, solving combinations with repetition requires a slightly different formula. So which one do we use?

For this exercise, I'm just going to stick to the formulas given.



#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include <cctype>

#undef max //undefine max so it can be used in getInt

using namespace std;

double a;
double b;

//this function was taken from http://www.cplusplus.com/forum/beginner/21595/
//it makes sure that only numbers can be used
double getInt()
{
  double x = 0;

  while (!(cin >> x)) 
  {
    cin.clear();
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
    cout << "You need to input a number: ";
 }

 return x;
}

//this gets two numbers and asks if the users wants permutations or combinations
//erroneous input is checked by getInt() and only allows P or C to be chosen
char permOrComb()
{
  cout << "Please enter the maximum amount of numbers: " << endl;
  a = getInt();
  cout << "Please enter how many numbers are needed: " << endl;
  b = getInt();

  cout << "\n\nWould you like to perform Permutation (p) or Combination (c)?: " << endl;
  char answer;
  cin >> answer;
  answer = toupper(answer); //converts letter to upper case

  while (answer != 'P' && answer != 'C')
  {
    cout << "You need to enter (p) or (c): ";
    cin >> answer;
    answer = toupper(answer);
  }

  return answer;
}

//this works out a factorial and returns the result
double getFactorial(double n)
{
  if (n == 0)
     n = 1;

  double factorial = n;

  for (double i = n - 1; i > 1; --i)
  {
    factorial = factorial*i;
  }

  return factorial;
}

//this solves permutations
double getPermutation()
{
  double p;
  double temp = a - b;

  //if a - b is a minus, flip it to positive
  if (temp < 0)
    temp *= -1;

  p = (getFactorial(a) / getFactorial(temp));

  return p;
}

//this solves combinations (where there is no repitition)
double getCombination()
{
  double c;
  double tempP = getPermutation();

  c = (tempP) / (getFactorial(b));
 
  return c; 
}

bool getQuit()
{
  char temp;
  bool qTemp = true;

  cout << "\n\nWould you like to quit (q) or continue (c): ";
  cin >> temp;
  temp = toupper(temp);

  while (temp != 'Q' && temp != 'C')
  {
    cout << "You need to enter (q) or (c): ";
    cin >> temp;
    temp = toupper(temp);
  }

  if (temp == 'Q')
    qTemp = false;
  if (temp == 'P')
    qTemp = true;

  return qTemp;
}


int main()
{
  bool quit = true;

  while (quit)
  {
    char answer = permOrComb();

    if (answer == 'P')
    {
      double temp = getPermutation();
      cout << "\nThere are " << temp << " permutations with these numbers.\n";
      quit = getQuit();
    }

   if (answer == 'C')
   {
     double temp = getCombination();
     cout << "\nThere are " << temp << " combinations with these numbers.\n";
     quit = getQuit();
   }

  }

  return 0;
}


I used the factorial function I created in Chapter 6 - Exercise 3 to solve for ! and then it was simply a case of checking for erroneous input. 

As I said above, this only solves combinations where there is no repetition, but it would be simple to create another function which solves for that using the formula given from the link above. Then just ask the user if repetition is allowed or not.