#include <iostream>
#include <sstream>
#include <vector>
#include <cmath>
#include <limits>
#include <map>
using namespace std;
//Position at a given time
struct Point
{
double x;
double y;
double time;
};
//A vehicle and all its locations through time
class Vehicle
{
public:
int id;
vector<Point> points;
//Calculate the average speed of the vehicle
double averageSpeed(double maxAcceptableSpeed);
};
//All the vehicles
map<int, Vehicle> data;
//Input safety function to check if a string can be converted to an int
//Example: isParsableInt(1) = true, isParsableInt("bonjour") = false
double isParsableInt(string s)
{
int value;
istringstream iss(s);
if (iss.eof())
return false;
iss >> value;
if (iss.fail())
return false;
return true;
}
//Input safety function to check if a string can be converted to a double
//Example: isParsableDouble(1.0) = true, isParsableDouble("5.j'apprécie les fruits au sirop") = false
double isParsableDouble(string s)
{
double value;
istringstream iss(s);
if (iss.eof())
return false;
iss >> value;
if (iss.fail())
return false;
return true;
}
//Building our dataset from collected data
void parseDataset(string input)
{
istringstream split(input);
string line;
while(getline(split, line, ';')) //For each vehicle
{
auto separator = line.find('|');
if (separator != line.npos) //Aborting vehicle if no '|'
{
string stringId = line.substr(0,separator);
string stringPoints = line.substr(separator+1);
if (!isParsableInt(stringId)) //Aborting vehicle if id cannot be converted to int
{
cerr << "Invalid id: " << stringId << endl;
}
else
{
int id = stoi(stringId);
if(data.find(id) != data.end()) //Aborting if id is already used by another vehicle
{
cerr << "This id was already used: " << id << endl;
}
else
{
Vehicle vehicle;
vehicle.id = id;
double lastTime = 0.0;
istringstream split(stringPoints);
string stringPoint;
while(getline(split, stringPoint, '/')) //For each point
{
string stringX, stringY, stringTime;
istringstream split(stringPoint);
getline(split, stringX, '*');
getline(split, stringY, '*');
getline(split, stringTime, '*');
if (!isParsableDouble(stringX)
|| !isParsableDouble(stringY)
|| !isParsableDouble(stringTime)) // Aborting point if incorrect format
{
cerr << "Invalid point, expected x*y*time, got: " << stringPoint << endl;
}
else
{
double x = stod(stringX);
double y = stod(stringY);
double time = stod(stringTime);
if ((time <= lastTime) && !(time == lastTime && time == 0.0)) //Aborting point if timing is incoherent
{
cerr << "Time value is not coherent" << endl;
}
else
{
vehicle.points.push_back({x,y,time});
lastTime = time;
}
}
}
data[id] = vehicle;
}
}
}
}
}
//Calculate the average speed of the vehicle
//Use maxAcceptableSpeed to filter speeds likely to be incorrect data
double Vehicle::averageSpeed(double maxAcceptableSpeed)
{
double sum = 0.0;
int count = 0;
for (int p=1;p<points.size();p++)
{
Point& previousPoint = points[p-1];
Point& point = points[p];
double dx = point.x - previousPoint.x;
double dy = point.y - previousPoint.y;
double distance = sqrt(dx*dx+dy*dy);
double speed = distance / (point.time - previousPoint.time);
if (maxAcceptableSpeed < speed)
{
//Reject speed if outside criteria
}
else
{
sum += speed;
count++;
}
}
if (count == 0) //Avoid division by zero
{
return 0.0;
}
else
{
return sum / double(count);
}
}
//Get ids of vehicle, filtered according to speed criteria
//Use maxAcceptableSpeed to filter speeds likely to be incorrect data
vector<int> selectVehicles(bool selector(double speed), double maxAcceptableSpeed)
{
vector<int> ids;
auto iterator = data.begin();
while (iterator != data.end())
{
Vehicle& vehicle = iterator->second;
double averageSpeed = vehicle.averageSpeed(maxAcceptableSpeed);
if (selector(averageSpeed))
{
ids.push_back(vehicle.id);
}
iterator++;
}
return ids;
}
int main()
{
string input;
cin >> input;
parseDataset(input);
auto batch_0 = selectVehicles([](double speed) { return 5.0 < speed; }, numeric_limits<double>::max());
cout << "Number of vehicles with average speed above 5: " << batch_0.size() << endl;
if (batch_0.size() != 0)
{
cout << "List of ids: ";
for (int i=0;i<batch_0.size();i++)
{
if (i)
cout << ',';
cout << batch_0[i];
}
cout << endl;
}
auto batch_1 = selectVehicles([](double speed) { return 5.0 < speed; }, 10.0);
cout << "Number of vehicles with average speed above 5, after filtering: " << batch_1.size() << endl;
if (batch_1.size() != 0)
{
cout << "List of ids: ";
for (int i=0;i<batch_1.size();i++)
{
if (i)
cout << ',';
cout << batch_1[i];
}
cout << endl;
}
return 0;
} Write, Run & Share C++ code online using OneCompiler's C++ online compiler for free. It's one of the robust, feature-rich online compilers for C++ language, running on the latest version 17. Getting started with the OneCompiler's C++ compiler is simple and pretty fast. The editor shows sample boilerplate code when you choose language as C++ and start coding!
OneCompiler's C++ online compiler supports stdin and users can give inputs to programs using the STDIN textbox under the I/O tab. Following is a sample program which takes name as input and print your name with hello.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string name;
cout << "Enter name:";
getline (cin, name);
cout << "Hello " << name;
return 0;
}
C++ is a widely used middle-level programming language.
When ever you want to perform a set of operations based on a condition If-Else is used.
if(conditional-expression) {
//code
}
else {
//code
}
You can also use if-else for nested Ifs and If-Else-If ladder when multiple conditions are to be performed on a single variable.
Switch is an alternative to If-Else-If ladder.
switch(conditional-expression){
case value1:
// code
break; // optional
case value2:
// code
break; // optional
......
default:
code to be executed when all the above cases are not matched;
}
For loop is used to iterate a set of statements based on a condition.
for(Initialization; Condition; Increment/decrement){
//code
}
While is also used to iterate a set of statements based on a condition. Usually while is preferred when number of iterations are not known in advance.
while (condition) {
// code
}
Do-while is also used to iterate a set of statements based on a condition. It is mostly used when you need to execute the statements atleast once.
do {
// code
} while (condition);
Function is a sub-routine which contains set of statements. Usually functions are written when multiple calls are required to same set of statements which increases re-usuability and modularity. Function gets run only when it is called.
return_type function_name(parameters);
function_name (parameters)
return_type function_name(parameters) {
// code
}