Monthly Archives: March 2007

[optimus]

If you’re on Facebook (who isn’t these days?), you’ll notice a recruiting ad/new programming puzzle for Facebook in your news feed this morning.  These guys actually have some pretty interesting puzzles.  (The ads are always prefixed with "Can you solve this programming puzzle?" which always reads to me in a sly and somewhat condescending tone, "Betcha you can’t..")  This new puzzle, known as Prime Bits, in particular, is fairly simple:

Define P(x) as true if the number of 1 bits set in the binary representation of x is prime, false otherwise.

Implement the function uint64 prime_bits(uint64 a, uint64 b) where prime_bits returns the number of values between a and b inclusive for which P(x) is true.

I sometimes like to take problems that other people are attempting to solve and attempt to solve them in a less powerful language.  More often than not, people needlessly pick a powerful language just because they are comfortable with it and end up with some bloated solution (like using a jackhammer to dig a hole to plant a seed).  But trying to accomplish the same objective in a less advanced language can actually come up with some pretty neat solutions sometimes, and it actually forces you to *think*.  Imagine that.

Now this implementation won’t get you a job at Facebook (this solution is much too simple and batch scripting isn’t on their list of approved languages), so I figure I’m safe in posting this here.  Chances are that if you have to copy this solution you don’t know enough to get hired anyway.  (According to Mark Zuckerberg, you have to be young and technical.  "Young people are just smarter."  Great article, by the way.)   

 

@echo off
setlocal ENABLEEXTENSIONS
setlocal ENABLEDELAYEDEXPANSION
setlocal

REM Author: DevDuck
REM Date: March 29, 2007

set A=%1
set B=%2

if "%A%"==""   ( goto :USAGE )
if "%B%"==""   ( goto :USAGE )
if %A% GTR %B% ( goto :USAGE )
if %A% LSS 0   ( goto :USAGE )
if %B% LSS 0   ( goto :USAGE )

set CUMULATIVE=0
for /l %%i in (%A%,1,%B%) do (
    call :PX %%i
)
echo %CUMULATIVE%

goto :EOF

 

:PX

REM Number of bits set:
REM 0: 0
REM 1: 1 2 4 8
REM 2: 3 5 6 9 A C
REM 3: 7 B D E
REM 4: F

set NUM=%1
set COUNT=0
REM 2^64 has max 16 hex digits, but since 2^32 is the largest num size
REM for batch scripts, we use 8
for /l %%i in (1,1,8) do (
    if !NUM! GTR 0 (
        set /a REMAINDER = !NUM! ^& 15
        for %%j in (1 2 4 8) do (
            if !REMAINDER! == %%j ( set /a COUNT += 1 )
        )
        for %%j in (3 5 6 9 10 12) do (
            if !REMAINDER! == %%j ( set /a COUNT += 2 )
        )
        for %%j in (7 11 13 14) do (
            if !REMAINDER! == %%j ( set /a COUNT += 3 )
        )
        if !REMAINDER! == 15 ( set /a COUNT += 4 )
    )
    set /a NUM ^>^>= 4
)

REM There are only 18 prime numbers less than 64.
for %%i in (2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61) do (
    if %COUNT% == %%i (
        set /a CUMULATIVE += 1
    )
)

goto :EOF

 

:USAGE

echo Usage:
echo %0 ^<A^> ^<B^>
echo %0 returns the number of values between A and B for which P(x)
echo is true. P(x) returns true if the # of 1 bits set in the binary
echo representation of x is prime.
goto :EOF

Not bad, eh?  How does this work?  Simple.  First, it iterates through each number in the range specified in the user.  For each number, it first counts the number of bits set in four bit chunks (2^4, or 16).  Note that the (really really) simple solution would have been to count each individual bit by dividing by two/right-shifting by 1 (much like you learnt in high school)–this way is just a little bit faster (.. although arguably it isn’t since you can’t jump to the next iteration of a for loop a la "continue".  There are numerous ways to do this part more efficiently and I’ll leave that as an exercise to the reader (ie: "I don’t feel like doing it.")).  Finally, it checks if the count is a prime number, and if it is, it increments the cumulative number count.   Also, due to the limitation of batch scripts, precision is limited to 32-bits (although this should be a very simple port to Perl).

That was fun.  Any other cool solutions out there?

Windows Live Core

From LiveSide: Windows Live Core – the Software as a Service platform.

My favourite quote, though, comes from Mary Jo Foley:

It looks like Microsoft is putting a lot of its All Stars on the Live Core team.
. . .
Does throwing big names at a big project spell automatic success? No.

Darn it!  I thought that’s all there was to it.  Well, that, knowing what you don’t do, and avoiding the Top 10 Signs Your Software Project is Doomed.

Nice detective work, Chris.

Redux

Well I haven’t posted in 4 months as I’ve somewhat fallen "off the grid".  (Not like the film; I missed last year’s.)  I unplugged myself and wasn’t really following any of the A-list bloggers.  There wasn’t any reason in particular–I took a short trip to Asia, and then there were holidays, etc. etc.  It was actually nice to get away from it all.  Anyway, I have started obsessively refreshing Digg, Facebook, and watching my Live.com feeds again.  What have I missed?  Something about someone trying to make a humourous point with Wikipedia and TechCrunch and getting a ton of flak.  What else?  VistaiPhone?  Back to the present.  Word of the week is Twitter.  (I suppose it takes the idea of Facebook mini-feeds to a whole new level.  It shouts, "Please stalk me!  I think I’m worthy of stalking!")  Eh.

So the LiveSide folks are in town for the MVP Summit and I went to their little get-together dinner last night at Cutter’s Bayhouse.  It’s not easy to find (free) parking downtown.  Smaller and less animated than last time, but still lots of fun.  These guys still hear about rumours faster and know more about what’s going on around here than I do.  (We developer-types are generally holed up in their little cubbies either coding away, surfing the ‘net, or chatting on IM.)  I think I managed to keep my mouth shut about what I’m working on too.  (No alcohol :P)  From what I heard though, that seems to be a recurring theme throughout Windows Live at the moment.

Anyway, I’m back to give my unsolicited and ungrounded and unofficial opinions on random topics at work, in the industry, and whatever else suits my fancy.

Calculating the Size of your Boat with a Slide Rule

I’ve always had a soft spot for writing scripts.  They are quite powerful when you know what you’re doing, although the result can look quite cryptic at times.  Even with a simplistic language like the Windows batch scripts, you can do some pretty neat things.

From David‘s two posts:

In brief, in order to figure out (and project) the storage requirements for his photo collection, David wrote a simple little C# program to enumerate the sizes of his collection.  I couldn’t help but wonder, could I create a lightweight batch script that did the same thing as his ~70 line C# program?  It turns out you can 🙂

@echo off
setlocal ENABLEEXTENSIONS
setlocal ENABLEDELAYEDEXPANSION
setlocal

set OUTPUTFILENAME=SizeOfFilesCreatedOnDate.csv
set FILE_TYPES=*.jpg *.gif *.tif *.raw *.mov *.avi *.wmv

REM Tally the contents of each specified directory
for /f "tokens=2,3,6 delims=/t " %%i in (
    ‘dir /s /-c %FILE_TYPES% ^| findstr /r
"../../…."’
) do (
    set /a SUM_%%j_%%i += %%k
)

REM Output all date/size pairs to a CSV file in the current directory
set FORMULA=
echo Date,Size,Cumulative > %OUTPUTFILENAME%
for /f "tokens=2,3,4 delims=_=" %%i in (‘set SUM’) do (
    set FORMULA=!FORMULA!+%%k
    echo %%j-%%i,%%k,=!FORMULA! >> %OUTPUTFILENAME%
)

Cool eh?  Basically what this does is use the directory listing command ‘dir’ to recursively go through folders, listing each file on the file system.  It extracts out the last written time (see last note in David’s second post above) and the size for each file and sums it.  It then spits out a CSV file that you can open up in your favourite graphing program.  Note that I was unable to use "set /a" to calculate the cumulative size, because it turns out that the "set" command wraps around at 0x7FFFFFFF (!), so instead I had to create the formula (which your graphing software should interpret).  (Unfortunately, this also means that if a single month has more than 2147483647 bytes, or 2 GBs of media, this script as written won’t work anymore.)

Scripting is cool.