Virtual Functions

The last challenge in the Introduction set for C++ at HackerRank is described in the following URL: https://www.hackerrank.com/challenges/virtual-functions

The description of the requirements is not too clear.

Following is a screen capture of the Windows console when using the Sample Input data with my own main() (more on this later in this post):

4

1

Walter 56 99

Walter 56 99 1 <== OUTPUT

2

Jesse 18 50 48 97 76 34 98

Jesse 18 403 1 <== OUTPUT

2

Pinkman 22 10 12 0 18 45 50

Pinkman 22 135 2 <== OUTPUT

1

White 58 87

White 58 87 2 <== OUTPUT

The Sample Output according to HackerRank follows:

Walter 56 99 1

Jesse 18 403 1

Pinkman 22 135 2

White 58 87 2

Seems like my solution worked. The issue is that the output is mixed with the input. Take a look at the main() used to test the classes provided by HackerRank:

int main(){

int n, val;

cin>>n; //The number of objects that is going to be created.

Person *per[n];

for(int i = 0;i < n;i++){

cin>>val;

if(val == 1){

// If val is 1 current object is of type Professor

per[i] = new Professor;

}

else per[i] = new Student; // Else the current object is of type Student

per[i]->getdata(); // Get the data from the user.

}

for(int i=0;i<n;i++)

per[i]->putdata(); // Print the required output for each object.

return 0;

}

When you attempt to compile the test with such C++ code, the Microsoft Visual Studio 2013 Professional IDE fails as follows:

error C2057: expected constant expression

error C2466: cannot allocate an array of constant size 0

error C2133: ‘per’ : unknown size

IntelliSense: expression must have a constant value

The culprit is the following line:

Person *per[n];

I spent time researching if there is a flag in the Visual Studio IDE to allow C99 compliance. I was not able to find one. If you know how to set a flag or pragma to address this issue I would like to hear from you.

Following is the code I wrote to test my solution (Vs2013 C++ is happy with the code surrounded by #ifdef _DEBUG):

/*

*/

int main () {

#ifdef CAKE

// **** test code from HackerRank follows: ****

int n, val;

// **** number of objects that is going to be created ****

cin >> n;

       Person *per[n];      // <== VS2013 DOES NOT LIKE THIS LINE !!!

for (int i = 0; i < n; i++)

{

cin >> val;

if (val == 1)

{

// If val is 1 current object is of type Professor

per[i] = new Professor;

}

else per[i] = new Student; // Else the current object is of type Student

per[i]->getdata(); // Get the data from the user.

}

for (int i = 0; i<n; i++)

per[i]->putdata(); // Print the required output for each object.

return 0;

#endif

#ifdef _DEBUG

// **** my test code follows: ****

int           N;

int           personType;

// **** ****

cin >> N;

//     cout << “N: ” << N << endl;

// **** ****

for (int n = 0; n < N; n++) {

cin >> personType;

//            cout << “personType: ” << ((personType == 1) ? “professor” : “student”) << endl;

// **** professor ****

if (personType == 1) {

Professor professor;

professor.getdata();

professor.putdata();

}

// **** student ****

else {

Student student;

student.getdata();

student.putdata();

}

}

// **** ****

return 0;

#endif

}

After spending time researching on-line I called some colleagues and they did not know of a flag that could be set on Visual Studio to address this issue. I did find out that Visual Studio is able to swap the VS C++ compiler with other compilers (e.g., Clang or a GCC compiler).

Following is the C++ code for my solution (main() excluded):

#include <string>

#include <cmath>

#include <cstdio>

#include <vector>

#include <iostream>

#include <algorithm>

using namespace std;

/*

*/

class Person {

// **** ****

static int professorId;

static int studentId;

// **** ****

protected : string name;

protected : int age;

// **** constructor ****

public : Person() {

}

public : Person(string personName, int personAge) {

this->name    = personName;

this->age     = personAge;

}

// **** ****

public : virtual void getdata() = 0;

public : virtual void putdata() = 0;

// **** other methods ****

public : int getSetProffesorID() {

int id = this->professorId;

this->professorId++;

return id;

}

public : int setSetStudentID() {

int id = this->studentId;

this->studentId++;

return id;

}

};

// **** initialize the IDs ****

int Person::professorId = 1;

int Person::studentId = 1;

/*

*/

class Professor : public Person {

// **** ****

public : int publications;

public : int cur_id;

// **** constructor ****

public : Professor()

: Person() {

this->cur_id = this->getSetProffesorID();

}

//public : Professor(string profName, int profAge, int profPublications)

//     : Person(profName, profAge) {

//     this->cur_id = this->getSetProffesorID();

//     this->publications = profPublications;

//}

// **** other methods ****

public : void getdata () {

cin >> this->name;

cin >> this->age;

cin >> this->publications;

}

public : void putdata() {

cout << this->name << ” ” << this->age << ” ” << this->publications << ” ” << this->cur_id << endl;

}

};

/*

*/

class Student : public Person {

// **** ****

public : int marks[6];

public : int cur_id;

// **** constructor ****

public : Student()

: Person() {

this->cur_id = this->setSetStudentID();

}

//public : Student(string studentName, int studentAge, int grades[], int count)

//     : Person(studentName, studentAge) {

//     this->cur_id = this->setSetStudentID();

//     for (int i = 0; i < count; i++) {

//            this->marks[i] = grades[i];

//     }

//}

// **** other methods ****

public : void getdata() {

cin >> this->name;

cin >> this->age;

for (int i = 0; i < 6; i++) {

cin >> this->marks[i];

}

}

public : void putdata() {

int sum       = 0;

for (int i = 0; i < 6; i++) {

sum += this->marks[i];

}

cout << this->name << ” ” << this->age << ” ” << sum << ” ” << this->cur_id << endl;

}

};

What I did to attempt to solve the challenge was to place my solution and use the main() provided by HackerRank. It passed all 13 test cases.

If you have comments / questions regarding this post or any other post in this blog, please do not hesitate and send me a message via email. I will not use your name unless you explicitly let me know.

John

john.canessa@gmail.com

Follow me on Twitter: @john_canessa

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.