Clearer code
- To: mathgroup at smc.vnet.net
- Subject: [mg101904] Clearer code
- From: Ray Koopman <koopman at sfu.ca>
- Date: Wed, 22 Jul 2009 06:22:32 -0400 (EDT)
I have two functions that work but whose code is more obscure than I
would like. I would appreciate any suggestions for code that is both
clearer and no slower.
iterout[n] is a decision rule for reporting the results of the n'th
iteration. It returns True if n < 10 or if its first two decimal
digits are one of {10,12,14,16,18,20,25,30,35,40,45,50,60,70, 80,90}
and the remaining digits (if any) are all zeros.
An equivalent rule, that turns out to give faster code, is to return
True if n is a multiple of k/10, where k is the first number >= n in
the sequence {10,20,50,100,200,500,...}.
iterout = Compile[{{n,_Integer}},
Module[{k = 10}, While[k < n, k *= 10];
Mod[Which[2n >= k, 10, 5n >= k, 20, True, 50]*n, k] == 0]]
s = Select[Range[-9,10^4],iterout]
{-9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
12, 14, 16, 18, 20, 25, 30, 35, 40, 45, 50, 60, 70, 80, 90, 100, 120,
140, 160, 180, 200, 250, 300, 350, 400, 450, 500, 600, 700, 800, 900,
1000, 1200, 1400, 1600, 1800, 2000, 2500, 3000, 3500, 4000, 4500,
5000, 6000, 7000, 8000, 9000, 10000}
nextout[n] returns the first number > n
for which iterout would return True.
nextout = Compile[{{n,_Integer}},
If[n < 10, n+1, Quotient[n,#]*#+# & @
Module[{k = 100}, While[k <= n, k *= 10];
Quotient[k, Which[2n >= k, 10, 5n >= k, 20, True, 50]]]]]
Rest@NestList[nextout,s[[1]]-1,Length@s] === s
True