piclist 1996\04\08\214903a >
www.piclist.com/techref/index.htm?key=challenge
BY : John Payson email (remove spam text)

> Damn, you beat me to it Erik! But I have some code...
>
> This is exactly the idea I had too. I'll give a couple of examples pertinent
> to the specific problem. First note that the "digits" in our divide-by-3 case
> are really pairs of binary bits. If we had the number 33 in base ten then the
> hex and binary numbers are:
> 33 = 0x11 = 00100001b
>
> Rewrite the binary number to show how the bits are paired to form digits:
> 00 10 00 01
>
> Sum up the 4 "digits": 00 + 10 + 00 + 01 = 11b
> which of course is divisible by three.

Actually, I think it's easier to observe that 16%3=1 and do something like
either this:

swapf   Number,w
addwf   Number,f        ; Note [MSN of Number] % 3 == old Number % 3
rrf     Number,w        ; We want to add what are now upper and lower
rlf     Number,f        ;   two bits of MSN; 00 or 11 would be good.
bsf     Number,4        ; By setting prev two bit of both addends,
iorlw   \$10             ;   we turn 00 and 11 into 01 and 00.
addwf   Number,f        ; Now we're interested in Number:6
btfss   Number,6        ; If set, not multiple of three
retlw  0               ; Return "nope"
retlw   1               ; Return "yep"

11 cycles constant execution time in 10 words, including the retlw.  Let's
see a demo... [column headings are starting values in num]

Inst    00      01      02      03      90      A8      F5      FF

swap    00      10      20      30      09      8A      5F      FF
add.    00      11      22      33      99      32      54      FE
rrf     00      08      11      29      4C      99      AA      FF
rlf     00      23      44      67      33      64      A8      FD
bsf     10      33      54      77      33      74      B8      FD
bsf     10      18      11      39      5C      99      BA      FF
add     20      4B      65      B0      8F      1D      72      FC

Res.    yup     nope    nope    yup     yup     yup     nope    yup

Slightly faster but bigger:
swapf   Number,w
swapf   Number,w
andlw   \$0F