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