Knuth's power tree: Difference between revisions

m
→‎{{header|REXX}}: changed/added comments and whitespace, changed indentations, made other cosmetic changes.
m (changed a comment in the task's definition section.)
m (→‎{{header|REXX}}: changed/added comments and whitespace, changed indentations, made other cosmetic changes.)
Line 563:
 
=={{header|REXX}}==
This REXX version supports results up to 1,000 decimal digits   (which can be expanded with the   '''numeric digits nnn'''   REXX statement.   Also, negative powers are supported.
<lang rexx>/*REXX program produces & shows a power tree for P, and calculates & shows X^P*/
numeric digits 1000 /*be able to handle some large numbers.*/
parse arg nums /*get set stuff: sets of three numbers.*/
if nums='' then nums='2 -4 17 3 191 191 1.1 81' /*Not specified? Use defaults*/
/*X lowPow highPow ··· repeat*/
do until nums=''
parse var nums x pL pH nums; x=x/1 /*get X, lowP, highP; and normalize X. */
if pH='' then pH=pL /*No highPower? Then assume lowPower. */
 
Also, negative powers are supported.
do e=pL to pH; p=abs(e)/1 /*use a range of powers; use │E│ */
<lang rexx>/*REXX program produces & showsdisplays a power tree for P, and calculates & showsdisplays X^P.*/
$=powerTree(p); w=length(pH) /*construct the power tree, (pow list).*/
numeric digits 1000 /*be able [↑]to handle W≡lengthsome forlarge shownumbers.*/
parse arg XP do i=1 for words($); @.i=word($,i); end /*buildget asets: fast pow arrayX, low power, high power.*/
if numsXP='' then numsXP='2 -4 17 3 191 191 1.1 81' /*Not specified? Use defaultsThen use the default.*/
/*────── X LP HP X LP HP X LP ◄── X, low power, high power ··· repeat*/
do until numsXP=''
parse var numsXP x pL pH nums XP; x=x/1 /*get X, lowP, highP; and normalize X. */
if pH='' then pH=pL /*No highPower? Then assume lowPower. */
 
if p= do e=0pL thento dopH; z p=abs(e)/1; call show; iterate; end /*handleuse casea range of 0powers; use │E│ power.*/
!.=.; z $=xpowerTree(p); !.1=z; prvw=zlength(pH) /*defineconstruct the first power oftree, (pow Xlist). */
/*X lowPow[↑] highPow ···W≡length repeatfor an aligned display*/
do i=1 for words($); @.i=word($,i) /*build a fast Knuth's power tree array*/
end /*ki*/
 
if p==0 then do; kz=21; tocall words($)show; n=@.kiterate; end /*obtainhandle thecase powerof (number)zero to be usedpower.*/
!.=.; prev z=k-1x; !.1=z; diff prv=n-@.prevz /*these are used for the odd powers. /*define/construct the first power of X*/
if n//2==0 then z=prv**2 /*Even power? Then square the number.*/
else z=z*!.diff /* Odd " " mult. by pow diff.*/
!.n=z /*remember for other multiplications. */
prv=z /*remember for squaring the numbers. */
end /*k*/
call show /*display the expression and its value.*/
end /*e*/
end /*until nums ···*/
exit /*stick a fork in it, we're all done. */
/*────────────────────────────────POWERTREE subroutine────────────────────────*/
powerTree: arg y 1 oy; $= /*Z is the result; $ is the power tree.*/
if y=0 | y=1 then return y /*handle special cases for zero & unity*/
#.=0; @.=0; #.0=1 /*define default & initial array values*/
/* [↓] add blank "flag" thingy──►list.*/
do while \(y//2); $=$ ' ' /*reduce "front" even power #s to odd #*/
if y\==oy then $=y $ /*(only) ignore the first power number*/
y=y%2 /*integer divide the power (it's even).*/
end /*while ···*/
 
if $\=='' then $=y $ do k=2 to words($); n=@.k /*re─introduceobtain the last power (number.) to be used.*/
$=$ oy prev=k-1; diff=n-@.prev /*these are used for the odd powers. /*insert last power number 1st in list.*/
if y>1 then do while if @.yn//2==0; then z=prv**2 n=#.0; /*Even power? m=0 Then square the number.*/
do while n\= else z=0;z*!.diff /* Odd q=0; " s=n " mult. by pow diff.*/
!.n=z do while s\==0; _=n+s /*remember for other multiplications. */
prv=z if @._==0 then do; if q==0 then m_=_; #._=q; @ /*remember for squaring the numbers._=n; q=_ */
end end/*k*/
call show /*display the expression and its value.*/
s=@.s
end end /*while s¬==0e*/
end /*until ifXP q\==0 then do; #.m=q; m=m_; end···*/
exit /*stick a fork in it, we're all done. */
n=#.n
/*──────────────────────────────────────────────────────────────────────────────────────*/
end /*while n¬==0*/
powerTree: arg y 1 oy; $= /*Z is the result; $ is the power tree.*/
#.m=0
if y=0 | y=1 then return y end /*whilehandle @.y==0special cases for zero & unity*/
#.=0; @.=0; #.0=1 /*define default & initial array values*/
z=@.y
do while z\==0; $=z $; z=@.z; end /*build power[↓] add blank "flag" listthingy──►list.*/
do while \(y//2); $=$ ' ' /*reduce "front" even power #s to odd #*/
return space($)
if n//2y\==0oy then z$=prv**2y $ /*Even power? Then/*(only) square ignore the first power number.*/
/*────────────────────────────────SHOW subroutine─────────────────────────────*/
y=y%2 /*integer [↓] divide addthe blankpower "flag"(it's thingy──►listeven).*/
show: if e<0 then z=format(1/z,,40)/1; _=right(e,w) /*use reciprocal ? */
say left('power tree for ' _ " is: " $,60) '═══' x"^"_ ' is:end ' z; return</lang>*while*/
 
if y$\==oy'' then $=y $ /*(only) ignore /*re─introduce the firstlast power number. */
prv $=z$ oy /*rememberinsert forlast squaringpower the numbers.number 1st in list.*/
if y>1 then do while @.y==0; n=#.0; m=0
do while n\==0; q=0; s=n
do while s\==0; _=n+s
if @._==0 then do; if q==0 then m_=_; #._=q; @._=n; q=_
else z=z*!.diff /* Odd " " mult. by pow diff.*/ end
s=@.s
parse arg nums /*get setend stuff: sets of three/*while numbers.s¬==0*/
if q\==0 then do; #.m=q; m=m_; end
n=#.n
y=y%2 end /*integerwhile divide the power (it's even).n¬==0*/
end /*while n¬= #.m=0*/
!.n=z end /*rememberwhile for other multiplications@. y==0*/
end /*e*/z=@.y
do while z\==0; $=z $; z=@.z; end /*build power list*/
return space($) /*del extra blanks*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
show: if e<0 then z=format(1/z, , 40)/1; _=right(e, w) /*use reciprocal ? */
say left('power tree for ' _ " is: " $,60) '═══' x"^"_ ' is: ' z; return</lang>
'''output''' when using the default inputs:
<pre>