Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
uni_functional_example.C
Go to the documentation of this file.
1
141#include <iostream>
142#include <iomanip>
143#include <string>
144#include <vector>
145#include <list>
146#include <deque>
147
148#include <tclap/CmdLine.h>
149
150#include <htlist.H>
151#include <tpl_dynArray.H>
152#include <ah-uni-functional.H>
153
154using namespace std;
155using namespace Aleph;
156
157// =============================================================================
158// Helper functions
159// =============================================================================
160
161void print_section(const string& title)
162{
163 cout << "\n" << string(60, '=') << "\n";
164 cout << " " << title << "\n";
165 cout << string(60, '=') << "\n\n";
166}
167
168void print_subsection(const string& title)
169{
170 cout << "\n--- " << title << " ---\n";
171}
172
173template <typename Container>
174void print_stl(const string& label, const Container& c)
175{
176 cout << label << ": [";
177 bool first = true;
178 for (const auto& x : c)
179 {
180 if (not first) cout << ", ";
181 cout << x;
182 first = false;
183 }
184 cout << "]" << endl;
185}
186
187template <typename Container>
188void print_aleph(const string& label, const Container& c)
189{
190 cout << label << ": [";
191 bool first = true;
192 for (auto it = c.get_it(); it.has_curr(); it.next())
193 {
194 if (not first) cout << ", ";
195 cout << it.get_curr();
196 first = false;
197 }
198 cout << "]" << endl;
199}
200
201// =============================================================================
202// 1. Same API for Different Containers
203// =============================================================================
204
206{
207 print_section("UNIFIED API - Same Function, Any Container");
208
209 cout << "The key insight: ONE function works with ALL container types!\n\n";
210
211 // Different container types
212 vector<int> stl_vec = {1, 2, 3, 4, 5};
213 list<int> stl_list = {1, 2, 3, 4, 5};
214 DynList<int> aleph_list = {1, 2, 3, 4, 5};
215
216 print_stl("std::vector", stl_vec);
217 print_stl("std::list", stl_list);
218 print_aleph("DynList", aleph_list);
219
220 // Same uni_map works on all!
221 print_subsection("uni_map() on all containers");
222
223 auto vec_squares = uni_map([](int x) { return x * x; }, stl_vec);
224 auto list_squares = uni_map([](int x) { return x * x; }, stl_list);
225 auto aleph_squares = uni_map([](int x) { return x * x; }, aleph_list);
226
227 print_stl(" vector squared", vec_squares);
228 print_stl(" list squared", list_squares);
229 print_stl(" DynList squared", aleph_squares);
230
231 // Same uni_foldl works on all!
232 print_subsection("uni_foldl() on all containers");
233
234 int vec_sum = uni_foldl(0, [](int a, int b) { return a + b; }, stl_vec);
235 int list_sum = uni_foldl(0, [](int a, int b) { return a + b; }, stl_list);
236 int aleph_sum = uni_foldl(0, [](int a, int b) { return a + b; }, aleph_list);
237
238 cout << " vector sum: " << vec_sum << endl;
239 cout << " list sum: " << list_sum << endl;
240 cout << " DynList sum: " << aleph_sum << endl;
241}
242
243// =============================================================================
244// 2. Map and Filter
245// =============================================================================
246
248{
249 print_section("MAP AND FILTER");
250
251 vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
252 print_stl("numbers", numbers);
253
254 // uni_map
255 print_subsection("uni_map()");
256 auto doubled = uni_map([](int x) { return x * 2; }, numbers);
257 print_stl("Doubled", doubled);
258
259 auto as_strings = uni_map([](int x) { return "n" + to_string(x); }, numbers);
260 print_stl("As strings", as_strings);
261
262 // uni_mapi (with index)
263 print_subsection("uni_mapi() - with index");
264 auto indexed = uni_mapi([](size_t i, int x) {
265 return "[" + to_string(i) + "]=" + to_string(x);
266 }, numbers);
267 print_stl("Indexed", indexed);
268
269 // uni_filter
270 print_subsection("uni_filter()");
271 auto evens = uni_filter([](int x) { return x % 2 == 0; }, numbers);
272 print_stl("Evens", evens);
273
274 auto greater_5 = uni_filter([](int x) { return x > 5; }, numbers);
275 print_stl("> 5", greater_5);
276
277 // uni_filteri (with index)
278 print_subsection("uni_filteri() - with index");
279 auto even_positions = uni_filteri([](size_t i, int) { return i % 2 == 0; }, numbers);
280 print_stl("Even positions", even_positions);
281}
282
283// =============================================================================
284// 3. Fold and Reduce
285// =============================================================================
286
288{
289 print_section("FOLD AND REDUCE");
290
291 DynList<int> nums = {1, 2, 3, 4, 5};
292 print_aleph("nums", nums);
293
294 // uni_foldl
295 print_subsection("uni_foldl()");
296 int sum = uni_foldl(0, [](int a, int b) { return a + b; }, nums);
297 cout << "Sum: " << sum << endl;
298
299 int product = uni_foldl(1, [](int a, int b) { return a * b; }, nums);
300 cout << "Product: " << product << endl;
301
302 int max_val = uni_foldl(nums.get_first(), [](int a, int b) {
303 return a > b ? a : b;
304 }, nums);
305 cout << "Max: " << max_val << endl;
306
307 // String concatenation
308 DynList<string> words = {"Hola", "desde", "Colombia"};
309 print_aleph("words", words);
310
311 string sentence = uni_foldl(string(""), [](const string& a, const string& b) {
312 return a.empty() ? b : a + " " + b;
313 }, words);
314 cout << "Sentence: \"" << sentence << "\"" << endl;
315
316 // uni_sum and uni_product
317 print_subsection("uni_sum() / uni_product()");
318 cout << "uni_sum: " << uni_sum(nums) << endl;
319 cout << "uni_product: " << uni_product(nums) << endl;
320}
321
322// =============================================================================
323// 4. Predicates
324// =============================================================================
325
327{
328 print_section("PREDICATES");
329
330 vector<int> all_positive = {1, 2, 3, 4, 5};
331 vector<int> mixed = {-1, 2, -3, 4, 5};
332 vector<int> all_negative = {-1, -2, -3};
333
334 print_stl("all_positive", all_positive);
335 print_stl("mixed", mixed);
336 print_stl("all_negative", all_negative);
337
338 auto is_positive = [](int x) { return x > 0; };
339
340 // uni_all
341 print_subsection("uni_all()");
342 cout << "All positive in all_positive? "
343 << (uni_all(is_positive, all_positive) ? "yes" : "no") << endl;
344 cout << "All positive in mixed? "
345 << (uni_all(is_positive, mixed) ? "yes" : "no") << endl;
346
347 // uni_exists / uni_any
348 print_subsection("uni_exists() / uni_any()");
349 cout << "Exists positive in mixed? "
350 << (uni_exists(is_positive, mixed) ? "yes" : "no") << endl;
351 cout << "Exists positive in all_negative? "
352 << (uni_any(is_positive, all_negative) ? "yes" : "no") << endl;
353
354 // uni_none
355 print_subsection("uni_none()");
356 cout << "None positive in all_negative? "
357 << (uni_none(is_positive, all_negative) ? "yes" : "no") << endl;
358
359 // uni_mem
360 print_subsection("uni_mem() - membership");
361 cout << "3 in all_positive? " << (uni_mem(3, all_positive) ? "yes" : "no") << endl;
362 cout << "10 in all_positive? " << (uni_mem(10, all_positive) ? "yes" : "no") << endl;
363
364 // uni_count
365 print_subsection("uni_count()");
366 cout << "Count positive in mixed: " << uni_count(is_positive, mixed) << endl;
367}
368
369// =============================================================================
370// 5. Access Functions
371// =============================================================================
372
374{
375 print_section("ACCESS FUNCTIONS");
376
377 DynList<string> cities = {"Bogota", "Medellin", "Cali", "Barranquilla", "Cartagena"};
378 print_aleph("cities", cities);
379
380 // uni_first, uni_last
381 print_subsection("uni_first() / uni_last()");
382 auto first = uni_first(cities);
383 auto last = uni_last(cities);
384
385 if (first) cout << "First: " << *first << endl;
386 if (last) cout << "Last: " << *last << endl;
387
388 // uni_nth
389 print_subsection("uni_nth()");
390 auto third = uni_nth(2, cities);
391 if (third) cout << "Third (index 2): " << *third << endl;
392
393 auto tenth = uni_nth(10, cities);
394 cout << "Tenth exists? " << (tenth ? "yes" : "no") << endl;
395
396 // uni_find
397 print_subsection("uni_find()");
398 auto found = uni_find([](const string& s) {
399 return s.length() > 8;
400 }, cities);
401
402 if (found) cout << "First with length > 8: " << *found << endl;
403
404 // uni_length
405 print_subsection("uni_length()");
406 cout << "Length: " << uni_length(cities) << endl;
407}
408
409// =============================================================================
410// 6. Slicing
411// =============================================================================
412
414{
415 print_section("SLICING");
416
417 vector<int> nums = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
418 print_stl("nums", nums);
419
420 // uni_take
421 print_subsection("uni_take()");
422 auto first_3 = uni_take(3, nums);
423 print_stl("First 3", first_3);
424
425 // uni_drop
426 print_subsection("uni_drop()");
427 auto after_3 = uni_drop(3, nums);
428 print_stl("After dropping 3", after_3);
429
430 // uni_take_while
431 print_subsection("uni_take_while()");
432 auto less_than_5 = uni_take_while([](int x) { return x < 5; }, nums);
433 print_stl("Take while < 5", less_than_5);
434
435 // uni_drop_while
436 print_subsection("uni_drop_while()");
437 auto from_5 = uni_drop_while([](int x) { return x < 5; }, nums);
438 print_stl("Drop while < 5", from_5);
439
440 // uni_partition
441 print_subsection("uni_partition()");
442 auto [evens, odds] = uni_partition([](int x) { return x % 2 == 0; }, nums);
443 print_stl("Evens", evens);
444 print_stl("Odds", odds);
445}
446
447// =============================================================================
448// 7. Statistics
449// =============================================================================
450
452{
453 print_section("STATISTICS");
454
455 DynList<double> temps = {14.2, 24.5, 25.1, 28.3, 29.0, 18.5, 22.7};
456 print_aleph("temperatures", temps);
457
458 // uni_min, uni_max
459 print_subsection("uni_min() / uni_max()");
460 auto min_temp = uni_min(temps);
461 auto max_temp = uni_max(temps);
462
463 if (min_temp) cout << "Min: " << *min_temp << "°C" << endl;
464 if (max_temp) cout << "Max: " << *max_temp << "°C" << endl;
465
466 // uni_min_max (returns optional<pair>)
467 print_subsection("uni_min_max()");
469 if (min_max_opt)
470 {
471 auto [min_v, max_v] = *min_max_opt;
472 cout << "Range: " << min_v << "°C to " << max_v << "°C" << endl;
473 cout << "Spread: " << (max_v - min_v) << "°C" << endl;
474 }
475
476 // Calculate average using fold
477 print_subsection("Average (using uni_foldl)");
478 double total = uni_foldl(0.0, [](double a, double b) { return a + b; }, temps);
479 size_t count = uni_length(temps);
480 cout << "Average: " << fixed << setprecision(2) << (total / count) << "°C" << endl;
481}
482
483// =============================================================================
484// 8. Conversion
485// =============================================================================
486
488{
489 print_section("CONVERSION");
490
491 DynList<int> aleph_list = {1, 2, 3, 4, 5};
492 print_aleph("Aleph DynList", aleph_list);
493
494 // uni_to_vector
495 print_subsection("uni_to_vector()");
496 vector<int> stl_vec = uni_to_vector(aleph_list);
497 print_stl("Converted to std::vector", stl_vec);
498
499 // Chain operations
500 print_subsection("Chaining operations");
501 auto result = uni_to_vector(
502 uni_filter([](int x) { return x % 2 == 0; },
503 uni_map([](int x) { return x * 10; }, aleph_list))
504 );
505 print_stl("map(*10) -> filter(even) -> vector", result);
506}
507
508// =============================================================================
509// 9. Practical Example
510// =============================================================================
511
513{
514 print_section("PRACTICAL: Sales Data Processing");
515
516 // Sales from different systems (STL from database, Aleph from processing)
517 vector<string> products = {"Cafe", "Panela", "Arroz", "Frijol", "Azucar"};
518 DynList<double> prices = {25.0, 8.0, 12.0, 15.0, 10.0};
519 vector<int> quantities = {100, 250, 180, 120, 200};
520
521 print_stl("products (vector)", products);
522 cout << "prices (DynList): [25.0, 8.0, 12.0, 15.0, 10.0]" << endl;
523 print_stl("quantities (vector)", quantities);
524
525 // Calculate totals
526 print_subsection("Calculate total revenue");
527
528 // First, get prices as vector
530
531 // Calculate revenue for each product
532 vector<double> revenues;
533 for (size_t i = 0; i < products.size(); i++)
534 revenues.push_back(prices_vec[i] * quantities[i]);
535
536 cout << "Revenue by product:\n";
537 for (size_t i = 0; i < products.size(); i++)
538 cout << " " << setw(8) << left << products[i]
539 << ": $" << fixed << setprecision(2) << revenues[i] << endl;
540
541 double total = uni_sum(revenues);
542 cout << "\nTotal revenue: $" << total << endl;
543
544 // Find most valuable product
545 print_subsection("Find best seller");
546 auto max_rev = uni_max(revenues);
547 if (max_rev)
548 {
549 size_t idx = 0;
550 for (size_t i = 0; i < revenues.size(); i++)
551 if (revenues[i] == *max_rev) idx = i;
552 cout << "Best seller: " << products[idx] << " ($" << *max_rev << ")" << endl;
553 }
554
555 // Filter high-value sales
556 print_subsection("High-value products (> $1500)");
557 for (size_t i = 0; i < products.size(); i++)
558 {
559 if (revenues[i] > 1500)
560 cout << " " << products[i] << ": $" << revenues[i] << endl;
561 }
562
563 // Statistics
564 print_subsection("Statistics");
565 cout << "Products: " << uni_length(products) << endl;
566 cout << "Avg price: $" << (uni_sum(prices) / uni_length(prices)) << endl;
567 cout << "Total units: " << uni_sum(quantities) << endl;
568}
569
570// =============================================================================
571// Main
572// =============================================================================
573
574int main(int argc, char* argv[])
575{
576 try
577 {
578 TCLAP::CmdLine cmd(
579 "Unified functional programming example for Aleph-w.\n"
580 "Same functions work with STL and Aleph containers.",
581 ' ', "1.0"
582 );
583
584 TCLAP::ValueArg<string> sectionArg(
585 "s", "section",
586 "Run only specific section: unified, map, fold, predicates, "
587 "access, slicing, statistics, conversion, practical, or 'all'",
588 false, "all", "section", cmd
589 );
590
591 cmd.parse(argc, argv);
592
593 string section = sectionArg.getValue();
594
595 cout << "\n";
596 cout << "============================================================\n";
597 cout << " ALEPH-W UNIFIED FUNCTIONAL PROGRAMMING EXAMPLE\n";
598 cout << " (Same API for STL and Aleph containers!)\n";
599 cout << "============================================================\n";
600
601 if (section == "all" or section == "unified")
603
604 if (section == "all" or section == "map")
606
607 if (section == "all" or section == "fold")
609
610 if (section == "all" or section == "predicates")
612
613 if (section == "all" or section == "access")
614 demo_access();
615
616 if (section == "all" or section == "slicing")
617 demo_slicing();
618
619 if (section == "all" or section == "statistics")
621
622 if (section == "all" or section == "conversion")
624
625 if (section == "all" or section == "practical")
627
628 cout << "\n" << string(60, '=') << "\n";
629 cout << "Unified functional programming demo completed!\n";
630 cout << string(60, '=') << "\n\n";
631
632 return 0;
633 }
634 catch (TCLAP::ArgException& e)
635 {
636 cerr << "Error: " << e.error() << " for argument " << e.argId() << endl;
637 return 1;
638 }
639 catch (exception& e)
640 {
641 cerr << "Error: " << e.what() << endl;
642 return 1;
643 }
644}
645
Unified functional programming utilities for both STL and Aleph containers.
int main()
Dynamic singly linked list with functional programming support.
Definition htlist.H:1423
T & get_first() const
Return the first item of the list.
Definition htlist.H:1675
size_t size() const noexcept
Count the number of elements of the list.
Definition htlist.H:1319
Singly linked list implementations with head-tail access.
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
bool uni_none(Pred &&pred, const Container &c)
Check if no element satisfies predicate.
auto uni_filter(Pred &&pred, const Container &c)
Filter elements satisfying predicate.
auto uni_nth(size_t n, const Container &c)
Get n-th element.
size_t uni_length(const Container &c)
Get container length.
auto uni_drop_while(Pred &&pred, const Container &c)
Drop elements while predicate is true, return the rest.
auto uni_product(const Container &c)
Product of all elements.
auto uni_find(Pred &&pred, const Container &c)
Find first element satisfying predicate.
bool uni_mem(const T &target, const Container &c)
Check if element exists in container (mem in ML).
T product(const Container &container, const T &init=T{1})
Compute product of all elements.
auto uni_filteri(Pred &&pred, const Container &c)
Filter with index (filteri in ML).
auto uni_map(Op &&op, const Container &c)
Map operation - transform each element.
auto uni_last(const Container &c)
Get last element.
auto uni_min_max(const Container &c)
Get both min and max in a single pass.
auto uni_min(const Container &c)
Get minimum element.
size_t uni_count(Pred &&pred, const Container &c)
Count elements satisfying predicate.
std::string to_string(const time_t t, const std::string &format)
Format a time_t value into a string using format.
Definition ah-date.H:140
T uni_foldl(T init, Op &&op, const Container &c)
Left fold (foldl) - reduce from left to right.
auto uni_drop(size_t n, const Container &c)
Drop first n elements, return the rest.
auto uni_max(const Container &c)
Get maximum element.
auto uni_take_while(Pred &&pred, const Container &c)
Take elements while predicate is true.
bool uni_all(Pred &&pred, const Container &c)
Check if all elements satisfy predicate.
auto uni_first(const Container &c)
Get first element.
auto uni_partition(Pred &&pred, const Container &c)
Partition elements by predicate.
auto uni_to_vector(const Container &c)
Convert container to std::vector.
auto uni_mapi(Op &&op, const Container &c)
Map with index (mapi in ML).
bool uni_any(Pred &&pred, const Container &c)
Alias for uni_exists.
auto uni_take(size_t n, const Container &c)
Take first n elements.
auto uni_sum(const Container &c)
Sum all elements.
bool uni_exists(Pred &&pred, const Container &c)
Check if any element satisfies predicate.
DynList< T > maps(const C &c, Op op)
Classic map operation.
Itor::difference_type count(const Itor &beg, const Itor &end, const T &value)
Count elements equal to a value.
Definition ahAlgo.H:127
T sum(const Container &container, const T &init=T{})
Compute sum of all elements.
STL namespace.
Lazy and scalable dynamic array implementation.
void demo_statistics()
void demo_slicing()
void print_subsection(const string &title)
void print_stl(const string &label, const Container &c)
void demo_conversion()
void demo_fold_reduce()
void print_section(const string &title)
void demo_access()
void print_aleph(const string &label, const Container &c)
void demo_predicates()
void demo_unified_api()
void demo_practical()
void demo_map_filter()