#include <iostream>
using namespace std;

class Student
{
private:
  // packing student info in 2 bytes:
  //
  //   13    8  7  6   2   10
  // .. xxxxxx  x  xxxxx   xx
  //
  // Year    in  bits  0..1:  2 bits for 4 options  (00, 01, 10, 11)
  // Credits in  bits  2..6:  5 bits for 32 options (0..31)
  // Major   in  bit      7:  1 bits for 2 options  (T/F)
  // GPA     in  bits 8..13:  6 bits for 45 options (0..44)
  //
  // bits 14 and 15 are not used  
  
  unsigned short data;
  

public:
  void setYear(short year)
  {
    unsigned short mask = 0x0003; // or 0b0000.0000.0000.0011

    data = data & ~mask;          // last 2 bits of data are 00, rest unchanged
                                  // note mask inverted before use

    year = year - 1;              // convert 1,2,3,4, i.e. 01, 10, 11, 100
                                  // into    0,1,2,3, i.e. 00, 01, 10, 11
    
    data = data | year;           // last 2 bits of data have year, rest unchanged
  }

  int getYear()
  {
    unsigned short mask = 0x0003;      // or 0b0000.0000.0000.0011

    unsigned short year = data & mask; // extract only last two bits, rest are 0

    return year + 1;                   // convert 0,1,2,3 back to 1,2,3,4
  }

  void setCredits(short credits)
  {
    unsigned short mask = 0x001F; // or   0b0000.0000.0001.1111  (5 bits)
    mask = mask << 2;             // move by 2 to position under bits 2..6
                                  //      0b0000.0000.0111.1100
    mask = ~mask;                 // flip 0b1111.1111.1000.0011
                                  // so that desired 5 bits can be cleared

    data = data & mask;           // bits 2..6 are 0, rest unchanged

    credits = credits << 2;       // move by 2 to position under bits 2..6
      
    data = data | credits;        // bits 2..6 have credits, rest unchanged
  }

  short getCredits()
  {
    unsigned short mask = 0x001F;          // or   0b0000.0000.0001.1111  (5 bits)
    
    mask = mask << 2;                      // move by 2 to position under bits 2..6
                                           //      0b0000.0000.0111.1100

    unsigned short credits = data & mask;  // credits has bits 2..6, rest are 0

    credits = credits >> 2;                // move by 2 to position at beginning
    
    return credits;
  }

  void print()
  {
    cout << "Student details:" << endl
	 << "- year   : " << getYear() << endl
	 << "- credits: " << getCredits() << endl;
      // << "- major  : " << getMajor() << endl
      // << "- gpa    : " << getGPA() << endl;
  }
};


int main()
{
  Student s;

  s.setYear(2);
  cout << s.getYear() << endl;

  s.setCredits(17);
  cout << s.getCredits() << endl;

  s.print();

  s.setYear(3);
  cout << s.getYear() << endl;

  s.setCredits(23);
  cout << s.getCredits() << endl;
  
  s.print();
}