Midterm Practice SolutionsΒΆ

  1. Write a program that calculates the percentage score on an exam. It should ask the user how much the exam is out of, and then ask what score the user got on it. Then it prints the percentage score.

    Here’s a sample run:

    What is the exam out of? 34
    What is your score? 29.5
    You scored 86.7647%
    

    Your program should do the following error-checking:

    • If the user enters 0, or less, for what the exam is out of, then use cmpt::error to throw an exception.
    • If the user enters less than 0 for their score, then use cmpt::error to throw an exception. Note that there is no highest possible score, and so, for instance, someone could get a score higher than what the exam is out of (and so they will get a % over 100).

    Sample solution:

    #include "cmpt_error.h"
    #include <iostream>
    
    using namespace std;
    
    int main() {
        cout << "What is the exam out of? ";
        double out_of = 0.0;
        cin >> out_of;
        if (out_of <= 0.0) {
            cmpt::error("exam must be out of more than 0");
        }
    
        cout << "What is your score? ";
        double score = 0.0;
        cin >> score;
        if (score < 0.0) {
            cmpt::error("score must be 0 or higer");
        }
    
        double pct = 100.0 * score / out_of;
        cout << "You scored " << pct << "%\n";
    }
    
  2. Suppose a, b, and c are all variables of type int. They have been created, but we don’t know the exact value any of them contain.

    Write a fragment of code that prints “yes” if either a, b, and c are all different, or they are all the same. Otherwise, print “no”.

    Sample solution:

    if ((a == b && b == c) || (a != b && a != c && b != c)) {
       cout << "yes"
    } else {
       cout << "no"
    }
    
  3. Re-write the following loops as equivalent while-loops:

    // loop 1
    for(int i = 0; i < 100; i++) {
        cout << i*i;
    }
    
    // loop 2
    for(int j = 750; j >= 0; j-=2) {
        cout << j;
    }
    

    Sample solution:

    // loop 1
    int i = 0;
    while (i < 100) {
       cout << i * i;
       i++;
    }
    
    // loop 2
    int j = 750;
    while (j >= 0) {
       cout << j;
       j -= 2;
    }
    
  4. Write a fragment of code that is an infinite loop that prints “hello” forever. Do it in the following ways:

    1. Using a for-loop
    2. Using a while-loop
    3. Without using an explicit loop

    Sample solution: Many different answers are possible. For example:

    // a
    for (;;) {
       cout << "hello\n";
    }
    
    // b
    while (true) {
       cout << "hello\n";
    }
    
    // c
    void hello() {
       cout << "hello";
       hello();
    }
    
  5. Write a function that prints a fancy title on the screen. For example, if your program has this statement:

    title("Geometry Helper");
    

    Then this text should appear on the screen:

    ---------------
    Geometry Helper
    ---------------
    

    The passed-in string should be sandwiched between lines of '-' characters that are the same length as the string.

    Sample solution:

    void title(const string& s) {
      for(int i = 0; i < s.size(); ++i) {
         cout << "-";
      }
      cout << "\n";
      cout << s;
      cout << "\n";
      for(int i = 0; i < s.size(); ++i) {
         cout << "-";
      }
      cout << "\n";
    }
    
  6. Suppose you’re a hacker trying to break into a digital safe protected by a 3-digit combination of the form abc, where a, b, and c are all between 0 and 9 (inclusive).

    1. Write a program that prints all 3-digit safe combinations on the screen, in order from smallest to biggest, like this:

      000
      001
      002
      ...
      567
      568
      ...
      998
      999
      

      Sample solution:

      void safe_a() {
          for(int i = 0; i < 1000; ++i) {
              if (i < 10) {
                  cout << "00" << i << "\n";
              } else if (i < 100) {
                  cout << "0" << i << "\n";
              } else {
                  cout << i << "\n";
              }
          }
      }
      
    2. It turns out that any combination whose 3rd digit is a 3 will trigger an alarm. So, write a program that prints all 3-digit safe combinations on the screen, in order from smallest to biggest, that don’t end with a 3:

      000
      001
      002
      004
      ...
      361
      362
      364
      ...
      998
      999
      

      Sample solution:

      void safe_b() {
          for(int i = 0; i < 1000; ++i) {
              if (i % 10 != 3) {
                  if (i < 10) {
                      cout << "00" << i << "\n";
                  } else if (i < 100) {
                      cout << "0" << i << "\n";
                  } else {
                      cout << i << "\n";
                  }
              }
          }
      }
      
    3. A new version of the safe triggers an alarm if the final digit of the combination is an odd number. Write a program that prints all 3-digit safe combinations on the screen, in order from smallest to biggest, that don’t end with an odd digit:

      000
      002
      004
      006
      ...
      362
      364
      366
      ...
      994
      996
      998
      

      Sample solution:

      void safe_c() {
          for(int i = 0; i < 1000; ++i) {
              int last_digit = i % 10;
              if (last_digit % 2 == 0) {
                  if (i < 10) {
                      cout << "00" << i << "\n";
                  } else if (i < 100) {
                      cout << "0" << i << "\n";
                  } else {
                      cout << i << "\n";
                  }
              }
          }
      }
      
    4. An even newer version of the safe triggers an alarm if one or more of the digits in the combination are odd. Write a program that prints all 3-digit safe combinations on the screen, in order from smallest to biggest, that don’t contain an odd digit:

      000
      002
      004
      ...
      008
      020
      022
      ...
      086
      088
      200
      202
      204
      ...
      884
      886
      888
      

      Sample solution:

      void safe_d() {
          for(int d1 = 0; d1 < 10; ++d1) {
              for(int d2 = 0; d2 < 10; ++d2) {
                  for(int d3 = 0; d3 < 10; ++d3) {
                      if (d1 % 2 == 1 || d2 % 2 == 1 || d3 % 2 == 1) {
                          // do nothing
                      } else {
                          cout << d1 << d2 << d3 << "\n";
                      }
                  }
              }
          }
      }
      
    5. Due to customer complaints about the previous version of the safe having too many alarm-triggering combinations, the safe was modified with a software update such that any combination with exactly one odd digit will trigger an alarm. Write a program that prints all 3-digit safe combinations on the screen, in order from smallest to biggest, that contain either 0, 2, or 3 odd digits:

      000
      002
      004
      006
      ...
      008
      011
      013
      015
      017
      ...
      097
      099
      101
      103
      105
      ...
      110
      111
      112
      113
      114
      115
      116
      ...
      997
      998
      999
      

      Sample solution:

      void safe_e() {
          for(int d1 = 0; d1 < 10; ++d1) {
              for(int d2 = 0; d2 < 10; ++d2) {
                  for(int d3 = 0; d3 < 10; ++d3) {
                      int count = 0;
                      if (d1 % 2 == 1) count++;
                      if (d2 % 2 == 1) count++;
                      if (d3 % 2 == 1) count++;
                      if (count != 1) {
                          cout << d1 << d2 << d3 << "\n";
                      }
                  }
              }
          }
      }
      
  7. Write a function called set_to_next_letter that works as follows:

    char c = 'a';
    set_to_next_letter(c);
    cout << c;               // prints 'b'
    set_to_next_letter(c);
    cout << c;               // prints 'c'
    set_to_next_letter(c);
    cout << c;               // prints 'd'
    
    c = 'z';
    set_to_next_letter(c);
    cout << c;  // prints 'a'
    

    Notice that if c is 'z', then set_to_next_letter(c) sets c to be 'a', i.e. it “wraps around”.

    You can assume that only lowercase letters in the range 'a' to 'z' will be passed to set_to_next_letter.

    Sample solution:

    void set_to_next_letter(char& letter) {
        if (letter == 'z') {
            letter = 'a';
        } else {
            letter++;
        }
    }
    
  8. The following questions are based on this table of hexadecimal and decimal digits:

    Hex Digit Decimal Digit
    0 0
    1 1
    2 2
    3 3
    4 4
    5 5
    6 6
    7 7
    8 8
    9 9
    a, A 10
    b, B 11
    c, C 12
    d, D 13
    e, E 14
    f, F 15
    1. Write a function that returns true if a character is a hex digit, and false otherwise. It should have this header:

      bool is_hex(char c)
      

      For example, is_hex('2'), is_hex('e'), and is_hex('F') all return true, while is_hex('$'), is_hex('g'), and is_hex('-') all return false.

      Sample solution:

      bool is_hex(char c) {
        return (c >= '0' && c <= '9')
            || (c >= 'a' && c <= 'f')
            || (c >= 'A' && c <= 'F');
      }
      
    2. Write a test driver program that asks the user to enter a character, and then prints whether or not the character is a hex digit. The test driver loop should stop when the user types the '!' character. For example:

      --> a
      a is a hex digit
      --> 2
      2 is a hex digit
      --> $
      $ is not a hex digit
      --> !
      (done)
      

      Sample solution:

      void test_char(char c) {
        if (is_hex(c)) {
          cout << c << " is a hex digit\n";
        } else {
          cout << c << " is not a hex digit\n";
        }
      }
      
      int main() {
        char c = ' ';
        while (c != '!') {
          cout << "Please enter a char: ";
          cin >> c;
          test_char(c);
        }
      }
      
    3. Re-write the following function so that it behaves exactly the same, but it does not use a switch statement:

      int hex_to_int(char c) {
         switch (c) {
            case '0': return 0;
            case '1': return 1;
            case '2': return 2;
            case '3': return 3;
            case '4': return 4;
            case '5': return 5;
            case '6': return 6;
            case '7': return 7;
            case '8': return 8;
            case '9': return 9;
            case 'a': case 'A': return 10;
            case 'b': case 'B': return 11;
            case 'c': case 'C': return 12;
            case 'd': case 'D': return 13;
            case 'e': case 'E': return 14;
            case 'f': case 'F': return 15;
            default:
                cmpt::error("unknown hex digit");
                return -1; // to satisfy compiler
            }
       }
      

      Sample solution:

      int hex_to_int(char c) {
        if (c == '0') { return 0; }
        else if (c == '1') { return 1; }
        else if (c == '2') { return 2; }
        else if (c == '3') { return 3; }
        else if (c == '4') { return 4; }
        else if (c == '5') { return 5; }
        else if (c == '6') { return 6; }
        else if (c == '7') { return 7; }
        else if (c == '8') { return 8; }
        else if (c == '9') { return 9; }
        else if (c == 'a' || c == 'A') { return 10; }
        else if (c == 'b' || c == 'B') { return 11; }
        else if (c == 'c' || c == 'C') { return 12; }
        else if (c == 'd' || c == 'D') { return 13; }
        else if (c == 'e' || c == 'E') { return 14; }
        else if (c == 'f' || c == 'F') { return 15; }
        else {
          cmpt::error("unknown hex digit");
          return -1; // to satisfy compiler
        }
      }
      
    4. Write a function that takes a single int n as input, and returns the char that corresponds to the hex digit of n. If n is less than 0 or greater than 16, then use the cmpt::error function to throw an exception.

      Sample solution:

      char int_to_hex(int n) {
        switch (n) {
          case 0: return '0';
          case 1: return '1';
          case 2: return '2';
          case 3: return '3';
          case 4: return '4';
          case 5: return '5';
          case 6: return '6';
          case 7: return '7';
          case 8: return '8';
          case 9: return '9';
          case 10: return 'a';
          case 11: return 'b';
          case 12: return 'c';
          case 13: return 'd';
          case 14: return 'e';
          case 15: return 'f';
          default:
            cmpt::error("n out of range");
            return ' ';
          }
      }