Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
fibonacci.C
Go to the documentation of this file.
1
2/*
3 Aleph_w
4
5 Data structures & Algorithms
6 version 2.0.0b
7 https://github.com/lrleon/Aleph-w
8
9 This file is part of Aleph-w library
10
11 Copyright (c) 2002-2026 Leandro Rabindranath Leon
12
13 Permission is hereby granted, free of charge, to any person obtaining a copy
14 of this software and associated documentation files (the "Software"), to deal
15 in the Software without restriction, including without limitation the rights
16 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 copies of the Software, and to permit persons to whom the Software is
18 furnished to do so, subject to the following conditions:
19
20 The above copyright notice and this permission notice shall be included in all
21 copies or substantial portions of the Software.
22
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 SOFTWARE.
30*/
31
32
174# include <iostream>
175# include <cstdlib>
176# include <chrono>
177# include <tclap/CmdLine.h>
178# include <tpl_arrayStack.H>
179# include <ah-errors.H>
180
181using namespace std;
182using namespace Aleph;
183
184// ============================================================================
185// Method 1: Classic Recursive Implementation
186// ============================================================================
187
202long long fib_recursive(int n)
203{
204 if (n <= 0)
205 return 0;
206 if (n == 1)
207 return 1;
208
209 return fib_recursive(n - 1) + fib_recursive(n - 2);
210}
211
212// ============================================================================
213// Method 2: Iterative Implementation
214// ============================================================================
215
227long long fib_iterative(int n)
228{
229 if (n <= 0)
230 return 0;
231 if (n == 1)
232 return 1;
233
234 long long fi_2 = 0; // fib(i-2)
235 long long fi_1 = 1; // fib(i-1)
236 long long fi = 0; // fib(i)
237
238 for (int i = 2; i <= n; i++)
239 {
240 fi = fi_1 + fi_2;
241 fi_2 = fi_1;
242 fi_1 = fi;
243 }
244
245 return fi;
246}
247
248// ============================================================================
249// Method 3: Stack-based with Explicit Activation Records
250// ============================================================================
251
264{
265 int n;
266 long long f1;
267 long long result;
269};
270
272constexpr char P1 = 1;
273constexpr char P2 = 2;
274
276# define NUM(p) ((p)->n)
277# define F1(p) ((p)->f1)
278# define RESULT(p) ((p)->result)
279# define RETURN_POINT(p) ((p)->return_point)
280
309long long fib_stack(int n)
310{
312
313 // Create dummy caller record (to receive final result)
315
316 // Create first real activation record for fib(n)
318 NUM(current_ar) = n;
319
320 // ========== Function body starts here ==========
321start:
322 // Base case: fib(0) = 0, fib(1) = 1
323 if (NUM(current_ar) <= 1)
324 {
325 RESULT(caller_ar) = (NUM(current_ar) <= 0) ? 0 : 1;
326 goto return_from_fib;
327 }
328
329 // ---------- First recursive call: fib(n-1) ----------
330 // Save return point for when fib(n-1) completes
332
333 // Push new activation record for fib(n-1)
334 NUM(&stack.pushn()) = NUM(current_ar) - 1;
335
336 // Update pointers to reflect new stack state
337 caller_ar = &stack.top(1); // Previous current is now caller
338 current_ar = &stack.top(); // New record is current
339
340 goto start; // "Call" fib(n-1)
341
342p1: // Return point after fib(n-1) completes
343 // Save result of fib(n-1) in local variable f1
345
346 // ---------- Second recursive call: fib(n-2) ----------
347 // Save return point for when fib(n-2) completes
349
350 // Push new activation record for fib(n-2)
351 NUM(&stack.pushn()) = NUM(current_ar) - 2;
352
353 // Update pointers
354 caller_ar = &stack.top(1);
355 current_ar = &stack.top();
356
357 goto start; // "Call" fib(n-2)
358
359p2: // Return point after fib(n-2) completes
360 // Compute final result: f1 + fib(n-2)
361 // Note: RESULT(current_ar) holds fib(n-2) from the return
363
364 // ========== Return sequence ==========
366 // Pop current activation record
367 stack.pop();
368
369 // If only dummy record remains, we're done
370 if (stack.size() == 1)
371 return RESULT(caller_ar);
372
373 // Update pointers after pop
374 caller_ar = &stack.top(1);
375 current_ar = &stack.top();
376
377 // Jump to saved return point (continuation)
378 switch (RETURN_POINT(current_ar))
379 {
380 case P1: goto p1;
381 case P2: goto p2;
382 default: AH_ERROR("Invalid return point: %d", RETURN_POINT(current_ar));
383 }
384
385 return 0; // Never reached
386}
387
388// Cleanup macros
389# undef NUM
390# undef F1
391# undef RESULT
392# undef RETURN_POINT
393
394// ============================================================================
395// Main Program
396// ============================================================================
397
398int main(int argc, char *argv[])
399{
400 try
401 {
402 TCLAP::CmdLine cmd(
403 "Fibonacci number computation using three methods:\n"
404 " recursive - Classic recursive (slow for large n)\n"
405 " iterative - Bottom-up loop (fast)\n"
406 " stack - Explicit activation records (educational)\n",
407 ' ', "1.0");
408
409 TCLAP::ValueArg<int> nArg("n", "number",
410 "Fibonacci index to compute",
411 false, 10, "int");
412 cmd.add(nArg);
413
414 vector<string> allowedMethods = {"all", "recursive", "iterative", "stack"};
415 TCLAP::ValuesConstraint<string> methodConstraint(allowedMethods);
416 TCLAP::ValueArg<string> methodArg("m", "method",
417 "Method to use (all, recursive, iterative, stack)",
418 false, "all", &methodConstraint);
419 cmd.add(methodArg);
420
421 TCLAP::SwitchArg timeArg("t", "time",
422 "Show execution time for each method",
423 false);
424 cmd.add(timeArg);
425
426 cmd.parse(argc, argv);
427
428 int n = nArg.getValue();
429 string method = methodArg.getValue();
430 bool showTime = timeArg.getValue();
431
432 cout << "Fibonacci Number Computation" << endl;
433 cout << "============================" << endl;
434 cout << "Computing fib(" << n << ")" << endl << endl;
435
436 // Warning for large n with recursive method
437 if ((method == "all" || method == "recursive") && n > 40)
438 {
439 cout << "WARNING: n > 40 with recursive method will be very slow!" << endl;
440 cout << " Consider using -m iterative or -m stack" << endl << endl;
441 }
442
443 auto measure_time = [](auto func, int n, const string& name, bool show) {
444 auto start = chrono::high_resolution_clock::now();
445 long long result = func(n);
446 auto end = chrono::high_resolution_clock::now();
447 auto duration = chrono::duration_cast<chrono::microseconds>(end - start);
448
449 cout << name << ": fib(" << n << ") = " << result;
450 if (show)
451 cout << " [" << duration.count() << " us]";
452 cout << endl;
453
454 return result;
455 };
456
457 long long result_iter = 0, result_rec = 0, result_stack = 0;
458
459 if (method == "all" || method == "iterative")
460 {
462 }
463
464 if (method == "all" || method == "stack")
465 {
467 }
468
469 if (method == "all" || method == "recursive")
470 {
471 if (n <= 40) // Skip recursive for large n
472 {
473 result_rec = measure_time(fib_recursive, n, "Recursive", showTime);
474 }
475 else
476 {
477 cout << "Recursive: SKIPPED (n > 40 too slow)" << endl;
478 }
479 }
480
481 // Verify all methods give same result
482 if (method == "all" && n <= 40)
483 {
484 cout << endl;
486 cout << "Verification: All methods agree!" << endl;
487 else
488 cout << "ERROR: Methods disagree!" << endl;
489 }
490
491 cout << endl << "Done." << endl;
492 }
493 catch (TCLAP::ArgException &e)
494 {
495 cerr << "Error: " << e.error() << " for arg " << e.argId() << endl;
496 return 1;
497 }
498
499 return 0;
500}
Exception handling system with formatted messages for Aleph-w.
#define AH_ERROR(format, args...)
Print an error message (always enabled).
Definition ahDefs.H:271
int main()
Stack implemented with simple dynamic array and with bounds verification.
T & top() const
Return a modifiable reference to youngest element of stack (called the top)
size_t size() const noexcept
Return the number of elements stored in the stack.
T & pushn(const size_t &n=1)
Push n cells into the stack.
T pop()
Extract the last more recently inserted element.
#define RESULT(p)
Definition fibonacci.C:278
long long fib_recursive(int n)
Compute Fibonacci number recursively.
Definition fibonacci.C:202
long long fib_iterative(int n)
Compute Fibonacci number iteratively.
Definition fibonacci.C:227
constexpr char P2
Return point after second recursive call fib(n-2)
Definition fibonacci.C:273
#define F1(p)
Definition fibonacci.C:277
constexpr char P1
Return point labels (simulating goto targets after recursive calls)
Definition fibonacci.C:272
long long fib_stack(int n)
Compute Fibonacci number using explicit stack management.
Definition fibonacci.C:309
#define RETURN_POINT(p)
Definition fibonacci.C:279
#define NUM(p)
Accessor macros for top of stack (current activation record)
Definition fibonacci.C:276
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
DynList< T > maps(const C &c, Op op)
Classic map operation.
STL namespace.
Activation record structure for stack-based Fibonacci.
Definition fibonacci.C:264
long long f1
Local variable: stores result of fib(n-1)
Definition fibonacci.C:266
int n
Parameter: which Fibonacci number to compute.
Definition fibonacci.C:265
char return_point
Continuation: where to resume after return.
Definition fibonacci.C:268
long long result
Return value to pass to caller.
Definition fibonacci.C:267
Stack implementations backed by dynamic or fixed arrays.