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