1+ /* *
2+ Different ways to compute the prefix sum of a list of numbers.
3+ */
4+
5+ #include < iostream>
6+ #include < vector>
7+ #include < numeric>
8+ #include < algorithm>
9+ #include < stdexcept>
10+
11+ using std::vector;
12+
13+ vector<int >
14+ compute_prefix_sum1 (const vector<int >& nums)
15+ {
16+ if (nums.empty ()) {
17+ return {};
18+ }
19+ vector<int > prefix_sum (nums.size ());
20+ prefix_sum[0 ] = nums[0 ];
21+ for (size_t i = 1 ; i < nums.size (); ++i) {
22+ prefix_sum[i] = prefix_sum[i - 1 ] + nums[i];
23+ }
24+ return prefix_sum;
25+ }
26+
27+ vector<int >
28+ compute_prefix_sum2 (const vector<int >& nums)
29+ {
30+ if (nums.empty ()) {
31+ return {};
32+ }
33+ vector<int > prefix_sum (nums.size ());
34+ inclusive_scan (nums.begin (), nums.end (), prefix_sum.begin (), std::plus<int >());
35+ return prefix_sum;
36+ }
37+
38+ vector<int >
39+ compute_prefix_sum3 (const vector<int >& nums)
40+ {
41+ if (nums.empty ()) {
42+ return {};
43+ }
44+ vector<int > prefix_sum (nums.size ());
45+ partial_sum (nums.begin (), nums.end (), prefix_sum.begin ());
46+ return prefix_sum;
47+ }
48+
49+ vector<int >
50+ compute_prefix_sum4 (const vector<int >& nums)
51+ {
52+ if (nums.empty ()) {
53+ return {};
54+ }
55+
56+ vector<int > prefix_sum;
57+ prefix_sum.reserve (nums.size ());
58+ int sum = 0 ;
59+ for (const auto & num : nums) {
60+ sum += num;
61+ prefix_sum.push_back (sum);
62+ }
63+ return prefix_sum;
64+ }
65+
66+ vector<int >
67+ compute_prefix_sum5 (const vector<int >& nums)
68+ {
69+ if (nums.empty ()) {
70+ return {};
71+ }
72+
73+ vector<int > prefix_sum (nums.size ());
74+ std::transform (
75+ std::begin (nums), std::end (nums), std::begin (prefix_sum), [n = 0 ](int num) mutable { return n += num; });
76+ return prefix_sum;
77+ }
78+
79+ vector<int >
80+ compute_prefix_sum6 (const vector<int >& nums)
81+ {
82+ if (nums.empty ()) {
83+ return {};
84+ }
85+
86+ vector<int > prefix_sum;
87+ prefix_sum.reserve (nums.size ());
88+ std::accumulate (nums.begin (), nums.end (), 0 , [&prefix_sum](int acc, int num) {
89+ int new_sum = acc + num;
90+ prefix_sum.push_back (new_sum);
91+ return new_sum;
92+ });
93+ return prefix_sum;
94+ }
95+
96+ vector<int >
97+ compute_prefix_sum7 (const vector<int >& nums)
98+ {
99+ if (nums.empty ()) {
100+ return {};
101+ }
102+
103+ vector<int > prefix_sum;
104+ prefix_sum.reserve (nums.size ());
105+ int sum = 0 ;
106+ std::for_each (nums.begin (), nums.end (), [&prefix_sum, &sum](int num) {
107+ sum += num;
108+ prefix_sum.push_back (sum);
109+ });
110+ return prefix_sum;
111+ }
112+
113+ vector<int >
114+ assert_equal (const vector<int >& a, const vector<int >& b)
115+ {
116+ if (a.size () != b.size ()) {
117+ throw std::runtime_error (" Vectors have different sizes" );
118+ }
119+ if (std::equal (a.begin (), a.end (), b.begin ())) {
120+ return a;
121+ }
122+ // if (std::any_of(a.begin(), a.end(), [&, i = 0](int val) mutable {
123+ // return val != b[i++];
124+ // })) {
125+ // throw std::runtime_error("Vectors differ");
126+ // }
127+ // if (std::all_of(a.begin(), a.end(), [&, i = 0](int val) mutable {
128+ // return val == b[i++];
129+ // })) {
130+ // return a;
131+ // }
132+ throw std::runtime_error (" Vectors differ" );
133+ }
134+
135+ int
136+ main ()
137+ {
138+ vector<int > nums = {1 , 2 , 3 , 4 , 5 };
139+ vector<int > prefix_sum_expected = {1 , 3 , 6 , 10 , 15 };
140+
141+ // Method 1: simple loop implementation
142+ auto prefix_sum1 = compute_prefix_sum1 (nums);
143+ assert_equal (prefix_sum1, prefix_sum_expected);
144+
145+ // Method 2: using inclusive_scan
146+ auto prefix_sum2 = compute_prefix_sum2 (nums);
147+ assert_equal (prefix_sum2, prefix_sum_expected);
148+
149+ // Method 3: using partial_sum
150+ auto prefix_sum3 = compute_prefix_sum3 (nums);
151+ assert_equal (prefix_sum3, prefix_sum_expected);
152+
153+ // Method 4: using push_back in a loop
154+ auto prefix_sum4 = compute_prefix_sum4 (nums);
155+ assert_equal (prefix_sum4, prefix_sum_expected);
156+
157+ // Method 5: using transform with a mutable lambda
158+ auto prefix_sum5 = compute_prefix_sum5 (nums);
159+ assert_equal (prefix_sum5, prefix_sum_expected);
160+
161+ // Method 6: using accumulate with a lambda that updates a vector
162+ auto prefix_sum6 = compute_prefix_sum6 (nums);
163+ assert_equal (prefix_sum6, prefix_sum_expected);
164+
165+ // Method 7: using for_each with a lambda that updates a vector
166+ auto prefix_sum7 = compute_prefix_sum7 (nums);
167+ assert_equal (prefix_sum7, prefix_sum_expected);
168+
169+ std::cout << " All tests passed!" << std::endl;
170+ return 0 ;
171+ }
0 commit comments