Random iteration

I have a project I’m working on at the moment that has an incrementing series {1,2,3,n=n+1,…n} and I need to convert that into a repeating series like so {1,2,3,3,1,2,3,3,etc}. This is in coldfusion and the obvious solution is as follows:

<cfloop from="1" to="20" index="n">
  <!--- gives us 1,2,3,0,1,2,3,0 --->
  <cfset iCount = n MOD 4 />
  <!--- manually set to 3 if iCount=0 --->
  <cfif iCount EQ 0>
    <cfset iCount = 3 />
  </cfif>
  <cfoutput>#iCount#<br></cfoutput>
</cfloop>

Well that’s great. It’s simple and probably runs fast (In production I’m only actually running from 1 to 20ish). I believe I’ve mentioned that I’m stubborn and LOVE clever solutions. We’re already running some math functions so I don’t feel bad calling it more.

Random pseudo code I’m making up as I go:

n = {1,2,3,4,...n=n+1}
n = (n-1) % 4
// 0,1,2,3, 0,1,2,3
n = n+1
// 1,2,3,4 1,2,3,4

// In binary...
// 0001 0010 0011 0100

k = n SRL 2
// 0000 0000 0000 0001
// 0,0,0,1, 0,0,0,1

n = n - k
// 1,2,3,3, 1,2,3,3

Bitwise operations ftw. There is probably some other solution involving BitAnd BitXOr.


<cfloop from="0" to="20" index="k">
<cfoutput>
  #((k MOD 4)+1) - BitSHRN((k MOD 4)+1,2)#
</cfoutput>
</cfloop>

One Comment

  • joshua says:

    heh heh:

    (0..20).each {|k|
    foo = ((i%4)+1) – (((i%4)+1)>>2)
    print “#{foo} ”
    }

    clevar, but it really would only work for this exact problem, wouldn’t it? What if you wanted 1,2,3,4,4? You’d need a totally different algorithm to come up with a value for foo.

Leave a Comment

You must be logged in to post a comment.