Combinations with repetitions/Square digit chain: Difference between revisions

(→‎{{header|Ruby}}: added zkl)
Line 177:
#(k=17) in the range 1 to 99999999999999999
#12024696404768024 numbers produce 1 and 87975303595231975 numbers produce 89
</pre>
 
=={{header|zkl}}==
{{trans|Ruby}}
<lang zkl>fcn countNumberChains(K){
F:=(K+1).pump(List,fcn(n){ (1).reduce(n,'*,1) }); #Some small factorials
g:=fcn(n){
gn,res:=L(n,0),0;
while(gn[0]>0){ gn=gn[0].divr(10); res+=gn[1].pow(2); }
if(res==89) 0 else res
};
#An array: N[n]==1 means that n translates to 1, 0 means that it does not.
n,G:=K*81+1,n.pump(List,g);
N:=n.pump(List,'wrap(n){ n=g(n); while(n>1){ n=G[n] } n });
var z=0; #Running count of numbers translating to 1
[0..9].pump(List,fcn(n){ n*n }):Utils.Helpers.combosK(K,_) # combos of (0,1,4,9,16,25,36,49,64,81)
.pump(Void,'wrap(ds){ #Iterate over unique digit combinations
if(N[ds.sum(0)]==0) return(); #Count only ones
nn:=Dictionary(); #Determine how many numbers this digit combination corresponds to
ds.pump(Void,nn.incV); #and (eg (0,0,0,0,0,1,9)-->(0:5, 1:1, 9:1)
z+=nn.values.reduce( #Add to the count of numbers terminating in 1
'wrap(gn,n){ gn/F[n] },F[K]);
});
println("\nk=(%d) in the range 1 to %,d".fmt(K,(10).pow(K)-1));
println("%,d numbers produce 1 and %,d numbers produce 89".fmt(z,(10).pow(K)-1-z));
}</lang>
<lang zkl>foreach K in (T(7,8,11,14)){ countNumberChains(K) }</lang>
{{out}}
<pre>
k=(7) in the range 1 to 9,999,999
1,418,853 numbers produce 1 and 8,581,146 numbers produce 89
 
k=(8) in the range 1 to 99,999,999
15,674,519 numbers produce 1 and 84,325,480 numbers produce 89
 
k=(11) in the range 1 to 99,999,999,999
15,106,873,875 numbers produce 1 and 84,893,126,124 numbers produce 89
 
k=(14) in the range 1 to 99,999,999,999,999
13,785,960,153,559 numbers produce 1 and 86,214,039,846,440 numbers produce 89
</pre>
Anonymous user