1+ // src/algorithms/dynamic-programming/fibonacciAlgo.js
2+
3+ export function fibonacciTopDown ( n ) {
4+ const memo = new Array ( n + 1 ) . fill ( null ) ;
5+ const steps = [ ] ;
6+
7+ function solve ( k ) {
8+ steps . push ( {
9+ type : "call" ,
10+ index : k ,
11+ memo : [ ...memo ] , // Clone memo to capture current state
12+ message : `Calling fib(${ k } ).`
13+ } ) ;
14+
15+ if ( k <= 1 ) {
16+ steps . push ( {
17+ type : "base_case" ,
18+ index : k ,
19+ value : k ,
20+ memo : [ ...memo ] ,
21+ message : `Base case: fib(${ k } ) = ${ k } .`
22+ } ) ;
23+ memo [ k ] = k ;
24+ return k ;
25+ }
26+
27+ if ( memo [ k ] !== null ) {
28+ steps . push ( {
29+ type : "memo_hit" ,
30+ index : k ,
31+ value : memo [ k ] ,
32+ memo : [ ...memo ] ,
33+ message : `Memoization hit: fib(${ k } ) is already computed as ${ memo [ k ] } .`
34+ } ) ;
35+ return memo [ k ] ;
36+ }
37+
38+ const res = solve ( k - 1 ) + solve ( k - 2 ) ;
39+ memo [ k ] = res ;
40+
41+ steps . push ( {
42+ type : "store" ,
43+ index : k ,
44+ value : res ,
45+ memo : [ ...memo ] ,
46+ message : `Computed fib(${ k } ) = fib(${ k - 1 } ) + fib(${ k - 2 } ) = ${ res } . Storing in memo.`
47+ } ) ;
48+ return res ;
49+ }
50+
51+ const result = solve ( n ) ;
52+
53+ // After the initial run, clean up steps that are too verbose for final display
54+ // For Top-Down, the array shown will be the 'memo'
55+ const visualSteps = steps . map ( step => ( {
56+ array : step . memo ,
57+ currentIndex : step . index ,
58+ message : step . message ,
59+ value : step . value // Value computed/retrieved at this step
60+ } ) ) ;
61+
62+ return { steps : visualSteps , result } ;
63+ }
64+
65+
66+ export function fibonacciBottomUp ( n ) {
67+ const dp = new Array ( n + 1 ) . fill ( null ) ;
68+ const steps = [ ] ;
69+
70+ // Base cases
71+ if ( n >= 0 ) {
72+ dp [ 0 ] = 0 ;
73+ steps . push ( {
74+ type : "base_case" ,
75+ index : 0 ,
76+ value : 0 ,
77+ dp : [ ...dp ] ,
78+ message : `Initializing dp[0] = 0.`
79+ } ) ;
80+ }
81+ if ( n >= 1 ) {
82+ dp [ 1 ] = 1 ;
83+ steps . push ( {
84+ type : "base_case" ,
85+ index : 1 ,
86+ value : 1 ,
87+ dp : [ ...dp ] ,
88+ message : `Initializing dp[1] = 1.`
89+ } ) ;
90+ }
91+
92+ // Iterate and fill DP table
93+ for ( let i = 2 ; i <= n ; i ++ ) {
94+ dp [ i ] = dp [ i - 1 ] + dp [ i - 2 ] ;
95+ steps . push ( {
96+ type : "compute" ,
97+ index : i ,
98+ value : dp [ i ] ,
99+ dp : [ ...dp ] ,
100+ message : `Computing dp[${ i } ] = dp[${ i - 1 } ] + dp[${ i - 2 } ] = ${ dp [ i - 1 ] } + ${ dp [ i - 2 ] } = ${ dp [ i ] } .`
101+ } ) ;
102+ }
103+
104+ // After the initial run, clean up steps that are too verbose for final display
105+ // For Bottom-Up, the array shown will be the 'dp' table
106+ const visualSteps = steps . map ( step => ( {
107+ array : step . dp , // Use 'dp' as the array for bottom-up
108+ currentIndex : step . index ,
109+ message : step . message ,
110+ value : step . value
111+ } ) ) ;
112+
113+ return { steps : visualSteps , result : dp [ n ] } ;
114+ }
0 commit comments