#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ld long double
#define fastio \
ios_base::sync_with_stdio(false); \
cin.tie(NULL);
void filein()
{
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
}
struct Request
{
long timestamp;
string id;
double amount;
string cardNumber;
string merchantName;
bool status;
Request(long timestamp, string id, double amount, string cardNumber, string merchantName)
{
this->timestamp = timestamp;
this->id = id;
this->amount = amount;
this->cardNumber = cardNumber;
this->merchantName = merchantName;
this->status = true;
}
};
struct Rule
{
long timestamp;
unordered_map<string, string> field;
Rule(long timestamp, string fieldKey, string value)
{
field[fieldKey] = value;
this->timestamp = timestamp;
}
};
vector<string> parseRequestString(string request, char delimiter)
{
int len = request.length();
vector<string> splits;
int i;
string current = "";
for (i = 0; i < len; i++)
{
if (request[i] == delimiter)
{
splits.push_back(current);
current = "";
}
else
{
current += request[i];
}
}
if (current.length())
{
splits.push_back(current);
}
return splits;
}
void sortRequests(vector<Request> &requests)
{
auto cmp = [](Request &r1, Request &r2)
{
return r1.timestamp < r2.timestamp;
};
sort(requests.begin(), requests.end(), cmp);
}
void printOutput(vector<Request> &requests)
{
for (auto request : requests)
{
cout << request.timestamp << " " << request.id << " " << request.amount << " "
<< "APPROVE" << endl;
}
}
bool isAuthorized(Request request, vector<Rule> rules)
{
for (auto rule : rules)
{
if (rule.timestamp > request.timestamp)
{
continue;
}
if (rule.field.find("merchant") != rule.field.end())
{
if (request.merchantName == rule.field["merchant"])
{
return false;
}
}
if (rule.field.find("cardnumber") != rule.field.end())
{
if (request.cardNumber == rule.field["cardnumber"])
{
return false;
}
}
}
return true;
}
bool isAuthorizedPostProcessing(Request request, vector<Rule> rules)
{
for (auto rule : rules)
{
if (rule.field.find("merchant") != rule.field.end())
{
if (request.merchantName == rule.field["merchant"])
{
return false;
}
}
if (rule.field.find("card_number") != rule.field.end())
{
if (request.cardNumber == rule.field["card_number"])
{
return false;
}
}
}
return true;
}
void printWithStatus(Request request, string status)
{
cout << request.timestamp << " " << request.id << " " << request.amount << " "
<< status << endl;
}
void solve(vector<string> requests, vector<string> rules)
{
// # 5,R1,5.60,4242424242424242,bobs_burgers
// # 10,R2,500.00,4242111111111111,a_corp
// # 5 R1 5.60 APPROVE
// # 10 R2 500.00 APPROVE
// # time,field,value
// # 1,merchant,bobs_burgers
// # 20,card_number,4242111111111111
// # 5 R1 5.60 REJECT
// # 10 R2 500.00 APPROVE
vector<Request> requestsObjects;
vector<Rule> ruleObjects;
for (auto request : requests)
{
vector<string> splits = parseRequestString(request, ',');
long timestamp = stol(splits[0]);
string id = splits[1];
double amount = stod(splits[2]);
string cardNumber = splits[3];
string merchantName = splits[4];
requestsObjects.push_back(Request(timestamp, id, amount, cardNumber, merchantName));
}
for (auto rule : rules)
{
vector<string> ruleSplits = parseRequestString(rule, ',');
long timestamp = stol(ruleSplits[0]);
string key = ruleSplits[1];
string value = ruleSplits[2];
ruleObjects.push_back(Rule(timestamp, key, value));
}
sortRequests(requestsObjects);
double fraudAmount = 0;
for (auto &requestObject : requestsObjects)
{
if (isAuthorized(requestObject, ruleObjects))
{
printWithStatus(requestObject, "APPROVE");
requestObject.status = true;
}
else
{
printWithStatus(requestObject, "REJECT");
requestObject.status = false;
}
}
// Post processing
for(auto requestObject : requestsObjects) {
bool status = isAuthorizedPostProcessing(requestObject,ruleObjects);
// cout<<status<<" "<<requestObject.id<<" "<<requestObject.status<<" "<<requestObject.amount<<" "<<requestObject.cardNumber<<endl;
if(status == false && requestObject.status == true){
fraudAmount+= requestObject.amount;
}
}
cout<<"Fraud amount : "<<fraudAmount<<endl;
}
int main()
{
filein();
fastio;
// int t;
// cin>>t ;
vector<string> requests;
vector<string> rules;
requests.push_back("5,R1,5.60,4242424242424242,bobs_burgers");
requests.push_back("10,R2,500.00,4242111111111111,a_corp");
rules.push_back("1,merchant,bobs_burgers");
rules.push_back("20,card_number,4242111111111112");
solve(requests,rules);
return 0;
}