Huddled Masses
The internet home of Joel "Jaykul" Bennett...
Browse: Home / 2008 Scripting Games – Solution for Advanced Event 6

2008 Scripting Games – Solution for Advanced Event 6

By Joel 'Jaykul' Bennett on 28-Feb-2008

This continues my series of solution posts for the 2008 Scripting Games with my solution for the Advanced Event 6. This was an interesting challenge because it’s a basic algorithms test … Mow, the scripting guy came up with some interesting brute-force solutions … but nearly everyone else just implemented the Sieve of Eratosthenes, since it’s the easiest of the prime sieves to understand.

I was slightly annoyed to be porting this simple algorithm to PowerShell, but I didn’t have the time to use an improved sieve, so I just ported it as directly as I could, without optimizing it for the PowerShell syntax, or removing any steps:


param($max = 200)                   # We will find all primes less than this number
$sieve = new-object bool[] ($max+1) # By sorting this sieve as Eratosthenes would
$n = 2                              # We know that 2 is the first prime
$p = $n*$n                          # Lowest possible unmarked non-prime is it's square
while($p -lt $max){                 # Test up to the sqrt of $max
  do{                              
    $sieve[$p] = $true              # mark it as not a prime
    $p += $n                        # if it's a multiple of a prime
  } while($p -le $max)              # all the way up to MAX
  do{++$n}while($sieve[$n])         # the next unmarked number is prime
  $p = $n*$n                        # the lowest possible unmarked non-prime is it's square
}                                   # all NON-PRIME numbers were flagged
for($p=2;$p -le $max;++$p){
   if(!$sieve[$p]) { $p }           # so we print out the ones that weren't
}

Mow asked about performance (because he wrote a brute -force solution, since the challenge was only to find up to 200) ... and I was reluctant to even mention it, because my script is such a direct port of the generalized algorithm that it’s guaranteed not to perform well, but I thought I’d post these numbers because they show how good Chris’s solution is. Remember these are numbers from my deliberately underpowered machine at work — don’t compare them to numbers from other computers — if you want to know how these scripts compare to yours, copy the code and run them all on your PC.


[82]: gph 6

Duration Lines Words Chars Type   Commmand
-------- ----- ----- ----- ----   --------
 0.01300    10    54   311 Script $n = C:\Scripts\Chris6.ps1 200
 0.11000    10    54   311 Script $n = C:\Scripts\Chris6.ps1 2000
 1.23200    10    54   311 Script $n = C:\Scripts\Chris6.ps1 20000
 0.25800    15   138   938 Script $n = C:\Scripts\Event6.ps1 200
 0.61500    15   138   938 Script $n = C:\Scripts\Event6.ps1 2000
 7.01600    15   138   938 Script $n = C:\Scripts\Event6.ps1 20000

Oh, and by the way, that output is from a Get-PerformanceHistory script…

Postscript

The guys in #PowerShell on IRC were making fun, and claiming that my problem was the initialization of the bool array (it’s not), so I had to explain the performance difference … and it’s really quite simple. Chris used $p = $n*$n to calculate the square of the iterator, which is a lot faster than $p = [Math]::Pow($n,2) which is what I used originally. I changed the script above to use $n*$n because that’s clearly a better choice for calculating squares … I wouldn’t want people using [Math]::Pow after seeing that difference. Here’s the new speed report (and yes, I made a new version of Get-PerformanceHistory which calculates averages if your command starts with a range like 1..10):


[95]: gph 2

Duration   Average Lines Words Chars Type   Commmand
--------   ------- ----- ----- ----- ----   --------
1:24.17800 8.41780    10    54   311 Script 1..10 | % { $a = .\Chris6.ps1 100000 }
1:08.36800 6.83680    15   137   948 Script 1..10 | % { $b = .\Event6.ps1 100000 }

In the interests of full disclosure … (and because I’m and algorithms optimization geek, in case you haven’t noticed) that loop on the end of my script that outputs the values … and the fact that I therefore break out of the calculation loop when I hit the square root of the $max value … makes my script slightly faster for huge values of max (as above) , and somewhat slower for small values:


Duration Average Lines Words Chars Type   Commmand
-------- ------- ----- ----- ----- ----   --------
34.40500 3.44050    15   138   988 Script 1..10 |  % { $b = .\Event6UsingPow.ps1 10000 }
 6.44300 0.64430    15   137   948 Script 1..10 |  % { $b = .\Event6.ps1 10000 }
 5.86300 0.58630    10    54   311 Script 1..10 |  % { $b = .\Chris6.ps1 10000 }

Similar Posts:

  • PowerBoots 0.3 – The Faster Edition
  • How to Import Binary Modules from Network Shares
  • Logging Robocopy errors to the Event Log using PowerShell
  • Solving the “failed to grant minimum permission requests” error
  • Are you interested in a virtual PowerShell brown-bag event?

Posted in Huddled | Tagged 2008 Scripting Games, PowerShell, Scripting, Solutions

« Previous Next »

Lijit Search

Tags

.Net .Net 2008 Scripting Games Automation Bugs Design Development Funny Gadgets GeoShell GUI Huddled Masses Internet licensing Microsoft Modules My Software News Personal PInvoke Pipeline Politics PoshCode PoshConsole PowerBoots PowerShell PowerShell Functions PowerTips Rants Recommender Repository Scripting ShowUI Software Solutions Textile Tips User Group UserInterface WalkThrough WebHosting Windows 7 WordPress WPF Xml

About Huddled Masses

This is web site is dedicated to the musings of Joel Bennett (aka Jaykul) about technology, software, software development, the web, and the world.

Any resemblance of the views expressed and the views of my employer, my terminal, or the view out my window are purely coincidental. The resemblance between them and my own views is non-deterministic. The question of the existence of views in the absence of anyone to hold them is left as an exercise for the reader.

P.S.: I occasionally link to things I think are great. When I do, I occasionally find a "referral code" so I can make a little cash. I promise that I don't link to anything just because of that cash (I wouldn't cross the street for the amount of cash those links bring in, never mind write a whole blog post) ... but I do not promise that things I link to will stay great as time passes, nor that you will agree with me about their greatness!

Archives

  • January 2012
  • October 2011
  • August 2011
  • July 2011
  • June 2011
  • March 2011
  • February 2011
  • January 2011
  • November 2010
  • August 2010

Copyright © 2012 Joel Bennett.

Powered by WordPress and Hybrid.