Learning from the annual reports of the airport in Sydney

#include <iostream> #include <vector> #include <tuple> #include <algorithm> #include <iomanip> using namespace std; void print_vector(vector<double> vec) { for(auto item : vec) {cout << item << endl;} }; double min(vector<double> vec) { return *min_element(vec.begin(), vec.end()); }; double max(vector<double> vec) { return *max_element(vec.begin(), vec.end()); }; double percent_increase(double high, double low) { return 100 * (high - low) / low; }; double avg_yearly_increase_perc(vector<double> vec) { return percent_increase(max(vec), min(vec)) / vec.size(); }; int argmax(vector<double> vec) { double max_val = max(vec); for(size_t i = 0; i < vec.size(); i++) { if(vec[i] == max_val) {return i;} } return -1; }; vector<double> matrix_col(vector<vector<double>> vec, size_t col) { vector<double> v; for(size_t i = 0; i < vec.size(); i++) { for(size_t j = 0; j < vec[i].size(); j++) { if(j == col) {v.push_back(vec[i][j]);} } } return v; }; vector<double> percentage_changes(vector<double> vec) { vector<double> percentages; for(size_t i = 1; i < vec.size(); i++) { percentages.push_back(percent_increase(vec[i], vec[i-1])); } return percentages; }; template<typename num> vector<num> range(num start, num stop, num step = 1) { vector<num> v; int iterations = (stop - start) / step + 1; for(int i = 0; i < iterations; i++) { v.push_back(start + i*step); } return v; }; vector<string> revenue_stream_types = { "aeronautical (excl. security recovery)", "retail", "property and car rental", "parking and ground transport" }; int revenue_streams_size = revenue_stream_types.size(); struct RevenueStreams { int type_idx; double revenue_million_dollar; }; struct SydneyAirportAnnualReport { int year; double passengers_million; double revenue_million_dollar; double operating_expenditure_million_dollar; double ebitda_million_dollar; double net_operating_receipts_million_dollar; double distribution_to_investors_cents; vector<RevenueStreams> revenue_streams; }; void find_ebitda_change_over_years( vector<SydneyAirportAnnualReport> annual_reports ) { for(const SydneyAirportAnnualReport& rep : annual_reports) { cout << rep.ebitda_million_dollar << ", "; } cout << endl; }; void find_year_with_highest_increase_ebitda( vector<SydneyAirportAnnualReport> annual_reports, vector<int> years ) { vector<double> ebit_diffs; for(size_t i = 1; i < annual_reports.size(); ++i) { ebit_diffs.push_back(annual_reports[i].ebitda_million_dollar - annual_reports[i-1].ebitda_million_dollar); } cout << years[argmax(ebit_diffs)] << endl; } void find_revenue_category_and_year_to_max_increase( vector<SydneyAirportAnnualReport> annual_reports, vector<int> years, int reports_count ) { vector<vector<double>> revenues( reports_count, vector<double>(revenue_streams_size) ); for(size_t i = 0; i < annual_reports.size(); i++) { int col = 0; for(auto stream : annual_reports[i].revenue_streams) { revenues[i][col] = stream.revenue_million_dollar; col++; } } double perc; string revtype; int year; vector<tuple<double, string, int>> perc_revtype_year; for(size_t i = 0; i < revenue_stream_types.size(); i++) { vector<double> mat_col = matrix_col(revenues, i); string revenue_type = revenue_stream_types[i]; vector<double> perc_changes = percentage_changes(mat_col); int max_year = years[argmax(perc_changes)]; double max_change = max(perc_changes); perc_revtype_year.push_back(make_tuple(max_change, revenue_type, max_year)); } sort(perc_revtype_year.rbegin(), perc_revtype_year.rend()); tie(perc, revtype, year) = perc_revtype_year[0]; cout << fixed << setprecision(2) << revtype << ", " << year << ": " << perc << "%" << endl; }; void find_avg_yearly_increase_passengers_perc( vector<SydneyAirportAnnualReport> annual_reports ) { vector<double> passengers; for(const SydneyAirportAnnualReport& rep : annual_reports) { passengers.push_back(rep.passengers_million); } cout << avg_yearly_increase_perc(passengers) << "%" << endl; }; int main() { // See Sydney Airport Annual Reports vector<SydneyAirportAnnualReport> annual_reports = { {2014, 38.5, 1163.5, 215.3, 948.3, 525.1, 23.5, {{0, 486.8}, {1, 255.2}, {2, 194.0}, {3, 139.9}}}, {2015, 39.7, 1228.9, 225.4, 1003.6, 577.8, 25.5, {{0, 523.4}, {1, 263.5}, {2, 201.2}, {3, 150.6}}}, {2016, 41.9, 1364.6, 257.8, 1106.7, 696.0, 31.0, {{0, 614.2}, {1, 295.6}, {3, 204.2}, {3, 156.1}}}, {2017, 43.3, 1483.3, 284.5, 1198.9, 789.8, 34.5, {{0, 670.6}, {1, 333.1}, {2, 221.4}, {3, 159.5}}} }; int reports_count = annual_reports.size(); vector<int> years = range(2014, 2017); // How has EBITDA changed over the years? find_ebitda_change_over_years(annual_reports); // 948.3, 1003.6, 1106.7, 1198.9, // Which year saw the highest increase in EBITDA? find_year_with_highest_increase_ebitda(annual_reports, years); // 2015 // In which revenue stream category and which year has been registered the highest relative revenue increase in percent and how much was it? find_revenue_category_and_year_to_max_increase(annual_reports, years, reports_count); // aeronautical (excl. security recovery), 2015: 17.35% // How much is the average absolute increase in the number of passengers over the years (in percent)? find_avg_yearly_increase_passengers_perc(annual_reports); // 3.12% return 0; }

Note: We assume that the questions are independent and unknown in advance. Otherwise the code could have been more efficient by reusing already existing loops.