1+ export function rodCuttingTopDown ( prices ) {
2+ const n = prices . length ;
3+ const memo = new Array ( n + 1 ) . fill ( null ) ;
4+ const steps = [ ] ;
5+
6+ function solve ( k ) {
7+ steps . push ( {
8+ array : [ ...memo ] ,
9+ currentIndex : k ,
10+ readingIndices : [ ] ,
11+ priceIndex : null ,
12+ message : `Calling solve(k = ${ k } ).`
13+ } ) ;
14+
15+ if ( k === 0 ) {
16+ steps . push ( {
17+ array : [ ...memo ] ,
18+ currentIndex : k ,
19+ readingIndices : [ ] ,
20+ priceIndex : null ,
21+ message : `Base case: solve(0) = 0.`
22+ } ) ;
23+ return 0 ;
24+ }
25+
26+ if ( memo [ k ] !== null ) {
27+ steps . push ( {
28+ array : [ ...memo ] ,
29+ currentIndex : k ,
30+ readingIndices : [ ] ,
31+ priceIndex : null ,
32+ message : `Memo hit: solve(${ k } ) is already computed as ${ memo [ k ] } .`
33+ } ) ;
34+ return memo [ k ] ;
35+ }
36+
37+ let currentMaxProfit = - 1 ;
38+
39+ for ( let j = 1 ; j <= k ; j ++ ) {
40+ steps . push ( {
41+ array : [ ...memo ] ,
42+ currentIndex : k ,
43+ readingIndices : [ ] ,
44+ priceIndex : j - 1 ,
45+ message : `... for k = ${ k } , trying cut j = ${ j } . Need to find solve(${ k - j } ).`
46+ } ) ;
47+
48+ const remainingProfit = solve ( k - j ) ;
49+ let profit = prices [ j - 1 ] + remainingProfit ;
50+
51+ steps . push ( {
52+ array : [ ...memo ] ,
53+ currentIndex : k ,
54+ readingIndices : [ k - j ] ,
55+ priceIndex : j - 1 ,
56+ message : `... cut j = ${ j } gives profit = prices[${ j - 1 } ] (${ prices [ j - 1 ] } ) + solve(${ k - j } ) (${ remainingProfit } ) = ${ profit } .`
57+ } ) ;
58+
59+ if ( profit > currentMaxProfit ) {
60+ currentMaxProfit = profit ;
61+ }
62+ }
63+
64+ memo [ k ] = currentMaxProfit ;
65+
66+ steps . push ( {
67+ array : [ ...memo ] ,
68+ currentIndex : k ,
69+ readingIndices : [ ] ,
70+ priceIndex : null ,
71+ message : `Computed solve(${ k } ) = ${ currentMaxProfit } . Storing in memo[${ k } ].`
72+ } ) ;
73+
74+ return currentMaxProfit ;
75+ }
76+
77+ const result = solve ( n ) ;
78+
79+ steps . push ( {
80+ array : [ ...memo ] ,
81+ currentIndex : n ,
82+ readingIndices : [ ] ,
83+ priceIndex : null ,
84+ message : `Computation complete. Max profit for a rod of length ${ n } is ${ result } .`
85+ } ) ;
86+
87+ return { steps, result } ;
88+ }
89+
90+
91+ export function rodCuttingBottomUp ( prices ) {
92+ const n = prices . length ;
93+ const dp = new Array ( n + 1 ) . fill ( 0 ) ;
94+ const steps = [ ] ;
95+
96+ steps . push ( {
97+ array : [ ...dp ] ,
98+ currentIndex : 0 ,
99+ readingIndices : [ ] ,
100+ priceIndex : null ,
101+ message : `Base case: Max profit for length 0 is 0. dp[0] = 0.`
102+ } ) ;
103+
104+ for ( let i = 1 ; i <= n ; i ++ ) {
105+ let currentMaxProfit = - 1 ;
106+
107+ steps . push ( {
108+ array : [ ...dp ] ,
109+ currentIndex : i ,
110+ readingIndices : [ ] ,
111+ priceIndex : null ,
112+ message : `Calculating max profit for length i = ${ i } .`
113+ } ) ;
114+
115+ for ( let j = 1 ; j <= i ; j ++ ) {
116+ let profit = prices [ j - 1 ] + dp [ i - j ] ;
117+
118+ steps . push ( {
119+ array : [ ...dp ] ,
120+ currentIndex : i ,
121+ readingIndices : [ i - j ] ,
122+ priceIndex : j - 1 ,
123+ message : `... trying cut j = ${ j } . Profit = prices[${ j - 1 } ] (${ prices [ j - 1 ] } ) + dp[${ i - j } ] (${ dp [ i - j ] } ) = ${ profit } .`
124+ } ) ;
125+
126+ if ( profit > currentMaxProfit ) {
127+ currentMaxProfit = profit ;
128+ }
129+ }
130+
131+ dp [ i ] = currentMaxProfit ;
132+
133+ steps . push ( {
134+ array : [ ...dp ] ,
135+ currentIndex : i ,
136+ readingIndices : [ ] ,
137+ priceIndex : null ,
138+ message : `Max profit for length ${ i } is ${ currentMaxProfit } . Storing in dp[${ i } ].`
139+ } ) ;
140+ }
141+
142+ steps . push ( {
143+ array : [ ...dp ] ,
144+ currentIndex : n ,
145+ readingIndices : [ ] ,
146+ priceIndex : null ,
147+ message : `Computation complete. Max profit for a rod of length ${ n } is ${ dp [ n ] } .`
148+ } ) ;
149+
150+ return { steps, result : dp [ n ] } ;
151+ }
0 commit comments