Count the coins: Difference between revisions

Content added Content deleted
m (→‎{{header|REXX}}: added/changed whitespace and comments, added support for fractional cent glyphs, used templates for the output sections.)
Line 2,538: Line 2,538:
numeric digits 20 /*be able to handle large amounts of $.*/
numeric digits 20 /*be able to handle large amounts of $.*/
parse arg N $ /*obtain optional arguments from the CL*/
parse arg N $ /*obtain optional arguments from the CL*/
if N='' | N="," then N=100 /*Not specified? Then Use $1 (≡100¢).*/
if N='' | N="," then N= 100 /*Not specified? Then Use $1 (≡100¢).*/
if $='' | $="," then $=1 5 10 25 /*Use penny/nickel/dime/quarter default*/
if $='' | $="," then $= 1 5 10 25 /*Use penny/nickel/dime/quarter default*/
if left(N,1)=='$' then N=100*substr(N,2) /*the amount was specified in dollars.*/
if left(N, 1)=='$' then N= 100 * substr(N, 2) /*the count was specified in dollars. */
coins=words($) /*the number of coins specified. */
coins= words($) /*the number of coins specified. */
NN=N; do j=1 for coins /*create a fast way of accessing specie*/
NN= N; do j=1 for coins /*create a fast way of accessing specie*/
_=word($,j) /*define an array element for the coin.*/
_= word($, j) /*define an array element for the coin.*/
if _=='1/2' then _=.5 /*an alternate spelling of a half-cent.*/
if _=='1/2' then _=.5 /*an alternate spelling of a half-cent.*/
if _=='1/4' then _=.25 /* " " " " " quarter-¢.*/
if _=='1/4' then _=.25 /* " " " " " quarter-¢.*/
$.j=_ /*assign the value to a particular coin*/
$.j= _ /*assign the value to a particular coin*/
end /*j*/
end /*j*/
_=n//100; cnt=' cents' /* [↓] is the amount in whole dollars?*/
_= n//100; cnt=' cents' /* [↓] is the amount in whole dollars?*/
if _=0 then do; NN='$' || (NN%100); cnt=; end /*show the amount in dollars, not cents*/
if _=0 then do; NN= '$' || (NN%100); cnt= /*show the amount in dollars, not cents*/
end /*show the amount in dollars, not cents*/
say 'with an amount of ' commas(NN)cnt", there are " commas( MKchg(N, coins) )
say 'with an amount of ' comma(NN)cnt", there are " comma( MKchg(N, coins) )
say 'ways to make change with coins of the following denominations: ' $
say 'ways to make change with coins of the following denominations: ' $
exit /*stick a fork in it, we're all done. */
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
commas: procedure; parse arg _; n=_'.9'; #=123456789; b=verify(n,#,"M")
comma: procedure; parse arg _; n= _'.9'; #= 123456789; b= verify(n, #, "M")
e=verify(n,#'0',,verify(n,#"0.",'M'))-4
e= verify(n, #'0', , verify(n, #"0.", 'M')) - 4
do j=e to b by -3; _=insert(',',_,j); end /*j*/; return _
do j=e to b by -3; _= insert(',', _, j); end /*j*/; return _
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
MKchg: procedure expose $.; parse arg a,k /*this function is invoked recursively.*/
MKchg: procedure expose $.; parse arg a,k /*this function is invoked recursively.*/
if a==0 then return 1 /*unroll for a special case of zero. */
if a==0 then return 1 /*unroll for a special case of zero. */
if k==1 then return 1 /* " " " " " " unity. */
if k==1 then return 1 /* " " " " " " unity. */
if k==2 then f=1 /*handle this special case of two. */
if k==2 then f= 1 /*handle this special case of two. */
else f=MKchg(a, k-1) /*count, and then recurse the amount. */
else f= MKchg(a, k-1) /*count, and then recurse the amount. */
if a==$.k then return f+1 /*handle this special case of A=a coin.*/
if a==$.k then return f+1 /*handle this special case of A=a coin.*/
if a <$.k then return f /* " " " " " A<a coin.*/
if a <$.k then return f /* " " " " " A<a coin.*/
return f+MKchg(a-$.k,k) /*use diminished amount ($) for change.*/</lang>
return f+MKchg(a-$.k,k) /*use diminished amount ($) for change.*/</lang>
'''output''' &nbsp; when using the default input:
{{out|output|text=&nbsp; when using the default input:}}
<pre>
<pre>
with an amount of $1, there are 242
with an amount of $1, there are 242
ways to make change with coins of the following denominations: 1 5 10 25
ways to make change with coins of the following denominations: 1 5 10 25
</pre>
</pre>

'''output''' &nbsp; when using the following input: &nbsp; <tt> $1 &nbsp; 1/4 &nbsp; 1/2 &nbsp; 1 &nbsp; 2 &nbsp; 3 &nbsp; 5 &nbsp; 10 &nbsp; 20 &nbsp; 25 &nbsp; 50 &nbsp; 100 </tt>
{{out|output|text=&nbsp; when using the following input: &nbsp; &nbsp; <tt> $1 &nbsp; 1/4 &nbsp; 1/2 &nbsp; 1 &nbsp; 2 &nbsp; 3 &nbsp; 5 &nbsp; 10 &nbsp; 20 &nbsp; 25 &nbsp; 50 &nbsp; 100 </tt>}}
<pre>
<pre>
with an amount of $1, there are 29,034,171
with an amount of $1, there are 29,034,171
Line 2,582: Line 2,584:
numeric digits 20 /*be able to handle large amounts of $.*/
numeric digits 20 /*be able to handle large amounts of $.*/
parse arg N $ /*obtain optional arguments from the CL*/
parse arg N $ /*obtain optional arguments from the CL*/
if N='' | N="," then N=100 /*Not specified? Then Use $1 (≡100¢).*/
if N='' | N="," then N= 100 /*Not specified? Then Use $1 (≡100¢).*/
if $='' | $="," then $=1 5 10 25 /*Use penny/nickel/dime/quarter default*/
if $='' | $="," then $= 1 5 10 25 /*Use penny/nickel/dime/quarter default*/
if left(N,1)=='$' then N=100*substr(N,2) /*the amount was specified in dollars.*/
if left(N,1)=='$' then N= 100 * substr(N, 2) /*the amount was specified in dollars.*/
coins=words($) /*the number of coins specified. */
NN= N; coins= words($) /*the number of coins specified. */
!.=.; NN=N; do j=1 for coins /*create a fast way of accessing specie*/
!.= .; do j=1 for coins /*create a fast way of accessing specie*/
_=word($,j); ?=_ ' coin' /*define an array element for the coin.*/
_= word($, j); ?= _ ' coin' /*define an array element for the coin.*/
if _=='1/2' then _=.5 /*an alternate spelling of a half-cent.*/
if _=='½' | _=="1/2" then _= .5 /*an alternate spelling of a half─cent.*/
if _=='1/4' then _=.25 /* " " " " " quarter-¢.*/
if _=='¼' | _=="1/4" then _= .25 /* " " " " " quarter─¢.*/
$.j=_ /*assign the value to a particular coin*/
$.j= _ /*assign the value to a particular coin*/
end /*j*/
end /*j*/
_=n//100; cnt=' cents' /* [↓] is the amount in whole dollars?*/
_= n // 100; cnt=' cents' /* [↓] is the amount in whole dollars?*/
if _=0 then do; NN='$' || (NN%100); cnt=; end /*show the amount in dollars, not cents*/
if _=0 then do; NN= '$' || (NN%100); cnt= /*show the amount in dollars, not cents*/
end
say 'with an amount of ' commas(NN)cnt", there are " commas( MKchg(N, coins) )
say 'with an amount of ' comma(NN)cnt", there are " comma( MKchg(N, coins) )
say 'ways to make change with coins of the following denominations: ' $
say 'ways to make change with coins of the following denominations: ' $
exit /*stick a fork in it, we're all done. */
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
commas: procedure; parse arg _; n=_'.9'; #=123456789; b=verify(n,#,"M")
comma: procedure; parse arg _; n= _'.9'; #= 123456789; b= verify(n, #, "M")
e=verify(n,#'0',,verify(n,#"0.",'M'))-4
e= verify(n, #'0', , verify(n, #"0.", 'M')) - 4
do j=e to b by -3; _=insert(',',_,j); end /*j*/; return _
do j=e to b by -3; _= insert(',', _, j); end /*j*/; return _
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
MKchg: procedure expose $. !.; parse arg a,k /*function is recursive. */
MKchg: procedure expose $. !.; parse arg a,k /*function is recursive. */
if !.a.k\==. then return !.a.k /*found this A & K before? */
if !.a.k\==. then return !.a.k /*found this A & K before? */
if a==0 then return 1 /*unroll for a special case*/
if a==0 then return 1 /*unroll for a special case*/
if k==1 then return 1 /* " " " " " */
if k==1 then return 1 /* " " " " " */
if k==2 then f=1 /*handle this special case.*/
if k==2 then f= 1 /*handle this special case.*/
else f=MKchg(a, k-1) /*count, recurse the amount*/
else f= MKchg(a, k-1) /*count, recurse the amount*/
if a==$.k then do; !.a.k=f+1; return !.a.k; end /*handle this special case.*/
if a==$.k then do; !.a.k= f+1; return !.a.k; end /*handle this special case.*/
if a <$.k then do; !.a.k=f ; return f ; end /* " " " " */
if a <$.k then do; !.a.k= f ; return f ; end /* " " " " */
!.a.k=f + MKchg(a-$.k, k); return !.a.k /*compute, define, return. */</lang>
!.a.k= f + MKchg(a-$.k, k); return !.a.k /*compute, define, return. */</lang>
'''output''' &nbsp; when using the following input for the optional test case: &nbsp;
{{out|output|text=&nbsp; when using the following input for the optional test case: &nbsp; &nbsp; <tt> $1000 &nbsp; 1 &nbsp; 5 &nbsp; 10 &nbsp; 25 &nbsp; 50 &nbsp; 100 </tt>}}
<tt> $1000 &nbsp; 1 &nbsp; 5 &nbsp; 10 &nbsp; 25 &nbsp; 50 &nbsp; 100 </tt>
<pre>
<pre>
with an amount of $1,000, there are 13,398,445,413,854,501
with an amount of $1,000, there are 13,398,445,413,854,501
Line 2,623: Line 2,625:
numeric digits 20 /*be able to handle large amounts of $.*/
numeric digits 20 /*be able to handle large amounts of $.*/
parse arg N $ /*obtain optional arguments from the CL*/
parse arg N $ /*obtain optional arguments from the CL*/
if N='' | N="," then N=100 /*Not specified? Then Use $1 (≡100¢).*/
if N='' | N="," then N= 100 /*Not specified? Then Use $1 (≡100¢).*/
if $='' | $="," then $=1 5 10 25 /*Use penny/nickel/dime/quarter default*/
if $='' | $="," then $= 1 5 10 25 /*Use penny/nickel/dime/quarter default*/
X=N /*save original for possible error msgs*/
X= N /*save original for possible error msgs*/
if left(N,1)=='$' then do /*the amount has a leading dollar sign.*/
if left(N,1)=='$' then do /*the amount has a leading dollar sign.*/
_=substr(N,2) /*the amount was specified in dollars.*/
_= substr(N, 2) /*the amount was specified in dollars.*/
if \isNum(_) then call ser "amount isn't numeric: " N
if \isNum(_) then call ser "amount isn't numeric: " N
N=100*_ /*change amount (in $) ───► cents (¢).*/
N= 100 * _ /*change amount (in $) ───► cents (¢).*/
end
end
max$=10**digits() /*the maximum amount this pgm can have.*/
max$= 10 ** digits() /*the maximum amount this pgm can have.*/
if \isNum(N) then call ser X " amount isn't numeric."
if \isNum(N) then call ser X " amount isn't numeric."
if N=0 then call ser X " amount can't be zero."
if N=0 then call ser X " amount can't be zero."
if N<0 then call ser X " amount can't be negative."
if N<0 then call ser X " amount can't be negative."
if N>max$ then call ser X " amount can't be greater than " max$'.'
if N>max$ then call ser X " amount can't be greater than " max$'.'
coins=words($); !.=.; NN=N; p=0 /*#coins specified; coins; amount; prev*/
coins= words($); !.= .; NN= N; p= 0 /*#coins specified; coins; amount; prev*/
@.=0 /*verify a coin was only specified once*/
@.= 0 /*verify a coin was only specified once*/
do j=1 for coins /*create a fast way of accessing specie*/
do j=1 for coins; _= word($, j) /*create a fast way of accessing specie*/
_=word($,j); ?=_ ' coin' /*define an array element for the coin.*/
?= _ ' coin' /*define an array element for the coin.*/
if _=='1/2' then _=.5 /*an alternate spelling of a half-cent.*/
if _=='½' | _=="1/2" then _= .5 /*an alternate spelling of a half─cent.*/
if _=='1/4' then _=.25 /* " " " " " quarter-¢.*/
if _=='¼' | _=="1/4" then _= .25 /* " " " " " quarter─¢.*/
if \isNum(_) then call ser ? "coin value isn't numeric."
if \isNum(_) then call ser ? "coin value isn't numeric."
if _<0 then call ser ? "coin value can't be negative."
if _<0 then call ser ? "coin value can't be negative."
if _<=0 then call ser ? "coin value can't be zero."
if _<=0 then call ser ? "coin value can't be zero."
if @._ then call ser ? "coin was already specified."
if @._ then call ser ? "coin was already specified."
if _<p then call ser ? "coin must be greater than previous:" p
if _<p then call ser ? "coin must be greater than previous:" p
if _>N then call ser ? "coin must be less or equal to amount:" X
if _>N then call ser ? "coin must be less or equal to amount:" X
@._=1; p=_ /*signify coin was specified; set prev.*/
@._= 1; p= _ /*signify coin was specified; set prev.*/
$.j=_ /*assign the value to a particular coin*/
$.j= _ /*assign the value to a particular coin*/
end /*j*/
end /*j*/
_=n//100; cnt=' cents' /* [↓] is the amount in whole dollars?*/
_= n // 100; cnt= ' cents' /* [↓] is the amount in whole dollars?*/
if _=0 then do; NN='$' || (NN%100); cnt=; end /*show the amount in dollars, not cents*/
if _=0 then do; NN= '$' || (NN%100); cnt= /*show the amount in dollars, not cents*/
end
say 'with an amount of ' commas(NN)cnt", there are " commas( MKchg(N, coins) )
say 'with an amount of ' comma(NN)cnt", there are " comma( MKchg(N, coins) )
say 'ways to make change with coins of the following denominations: ' $
say 'ways to make change with coins of the following denominations: ' $
exit /*stick a fork in it, we're all done. */
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
isNum: return datatype(arg(1), 'N') /*return 1 if arg is numeric, 0 if not.*/
isNum: return datatype(arg(1), 'N') /*return 1 if arg is numeric, 0 if not.*/
ser: say; say '***error***'; say; say arg(1); say; exit 13 /*error msg.*/
ser: say; say '***error***'; say; say arg(1); say; exit 13 /*error msg.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
commas: procedure; parse arg _; n=_'.9'; #=123456789; b=verify(n,#,"M")
comma: procedure; parse arg _; n= _'.9'; #= 123456789; b= verify(n, #, "M")
e=verify(n,#'0',,verify(n,#"0.",'M'))-4
e= verify(n, #'0', , verify(n, #"0.", 'M')) - 4
do j=e to b by -3; _=insert(',',_,j); end /*j*/; return _
do j=e to b by -3; _= insert(',', _, j); end /*j*/; return _
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
MKchg: procedure expose $. !.; parse arg a,k /*function is recursive. */
MKchg: procedure expose $. !.; parse arg a,k /*function is recursive. */
if !.a.k\==. then return !.a.k /*found this A & K before? */
if !.a.k\==. then return !.a.k /*found this A & K before? */
if a==0 then return 1 /*unroll for a special case*/
if a==0 then return 1 /*unroll for a special case*/
if k==1 then return 1 /* " " " " " */
if k==1 then return 1 /* " " " " " */
if k==2 then f=1 /*handle this special case.*/
if k==2 then f= 1 /*handle this special case.*/
else f=MKchg(a, k-1) /*count, recurse the amount*/
else f= MKchg(a, k-1) /*count, recurse the amount*/
if a==$.k then do; !.a.k=f+1; return !.a.k; end /*handle this special case.*/
if a==$.k then do; !.a.k= f+1; return !.a.k; end /*handle this special case.*/
if a <$.k then do; !.a.k=f ; return f ; end /* " " " " */
if a <$.k then do; !.a.k= f ; return f ; end /* " " " " */
!.a.k=f + MKchg(a-$.k, k); return !.a.k /*compute, define, return. */</lang>
!.a.k= f + MKchg(a-$.k, k); return !.a.k /*compute, define, return. */</lang>
'''output''' &nbsp; is the same as the previous REXX versions. <br><br>
{{out|output|text=&nbsp; is the same as the previous REXX version.}}<br><br>


=={{header|Ring}}==
=={{header|Ring}}==