#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
#include <string>
#include <utility>
#if defined(_WIN32)
#include <windows.h>
#elif defined(__linux__) || defined(__APPLE__)
#include <unistd.h>
#endif
using namespace std;
string getParentPath(const string& filePath) {
size_t found = filePath.find_last_of("/\\");
return filePath
.substr(0, found
); }
typedef pair<string, double> DayData;
typedef vector<DayData> RateData;
RateData read_csv(const string &filename) {
RateData data;
string line;
// to skip the first line because it contains the column names
while (getline
(file, line
)) { stringstream linestream(line);
double value;
getline
(linestream
, date, ','); linestream >> value;
data
.emplace_back
(date, value
); }
return data;
}
void heapify(RateData &arr, int n, int i, bool is_max_heap) {
int extreme = i;
int left = 2 * i + 1;
int right = 2 * i + 2;
if (left < n && (is_max_heap ? arr[left].second > arr[extreme].second : arr[left].second < arr[extreme].second))
extreme = left;
if (right < n && (is_max_heap ? arr[right].second > arr[extreme].second : arr[right].second < arr[extreme].second))
extreme = right;
if (extreme != i) {
swap(arr[i], arr[extreme]);
heapify(arr, n, extreme, is_max_heap);
}
}
void build_max_heap(RateData &arr) {
int n = arr.size();
int start_index = (n / 2) - 1;
for (int i = start_index; i >= 0; i--) {
heapify(arr, n, i, true);
}
}
void build_min_heap(RateData &arr) {
int n = arr.size();
int start_index = (n / 2) - 1;
for (int i = start_index; i >= 0; i--) {
heapify(arr, n, i, false);
}
}
vector<double> get_changes(RateData &data) {
vector<double> changes;
for (size_t i = 1; i < data.size(); i++) {
changes.push_back(data[i].second - data[i - 1].second);
}
return changes;
}
double max_subseq_sum(
const RateData &data,
string &start_date,
string &end_date,
const vector<double> &changes
) {
double max_so_far = 0, max_ending_here = 0;
int start
= 0, end = 0, s
= 0;
for (int i = 0; i < changes.size(); ++i) {
max_ending_here += changes[i];
if (max_ending_here > max_so_far) {
max_so_far = max_ending_here;
start = s;
} else if (max_ending_here < 0) {
max_ending_here = 0;
s = i + 1;
}
}
start_date = data[start + 1].first;
end_date
= data
[end + 1].first
; return max_so_far;
}
RateData get_extremes(RateData &heap, bool is_max, int N) {
RateData extremes;
if (is_max) {
build_max_heap(heap);
} else {
build_min_heap(heap);
}
for (int i = 0; i < N; ++i) {
extremes.push_back(heap[0]);
heap[0] = heap.back();
heap.pop_back();
heapify(heap, heap.size(), 0, is_max);
}
return extremes;
}
void print_extremes(const RateData &extremes, const string &label) {
cout << label << " days:" << endl;
for (const auto &day: extremes) {
cout << "Date: " << day.first << ", Change: " << day.second << endl;
}
}
int main() {
int num_days;
cout << "Number of days: ";
cin >> num_days;
// Manually specify the file path
string filename = "euro-dollar.csv";
auto data = read_csv(filename);
auto changes = get_changes(data);
string start_date, end_date;
double max_sum = max_subseq_sum(data, start_date, end_date, changes);
cout << "The maximum subsequence sum is: " << max_sum << endl;
cout << "Start date: " << start_date << ", End date: " << end_date << endl;
RateData changes_for_heap;
for (int i = 0; i < data.size() - 1; ++i) {
double change = data[i + 1].second - data[i].second;
changes_for_heap.emplace_back(data[i + 1].first, change);
}
// find the N highest days
auto maximum_heap = changes_for_heap;
auto highest_days = get_extremes(maximum_heap, true, num_days);
print_extremes(highest_days, "Highest");
// find the N lowest days
RateData minimum_heap = changes_for_heap;
RateData lowest_days = get_extremes(minimum_heap, false, num_days);
print_extremes(lowest_days, "Lowest");
return 0;
}