About Me

My photo
Northglenn, Colorado, United States
I'm primarily a BI Developer on the Microsoft stack. I do sometimes touch upon other Microsoft stacks ( web development, application development, and sql server development).
Showing posts with label problem. Show all posts
Showing posts with label problem. Show all posts

Friday, March 15, 2013

Just for kicks: Project Euler Problem #1

Just wanted to try a variety of methods to a solution. I wanted to do a variety of parallel, plinq, and straight forward logic test. I also wanted to implement a extension method and use func<> for better refactoring. As a test, I considered doing Euler's #1:
http://projecteuler.net/problem=1


Here are the several methods I created:
Code Snippet
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using System.Threading;
  7.  
  8. namespace ProjectEuler
  9. {
  10.     /*
  11.      *   Q: If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
  12.      *      Find the sum of all the multiples of 3 or 5 below 1000.
  13.      *
  14.      *   A: 233168
  15.      *   
  16.      *   Results:
  17.                     Method 1 Avg Time:  0.000007768
  18.                     Method 2a Avg Time: 0.000040169
  19.                     Method 2b Avg Time: 0.000029314
  20.                     Method 2c Avg Time: 0.000347431
  21.                     Method 2d Avg Time: 0.000175544
  22.                     Method 3a Avg Time: 0.00017445
  23.                     Method 3b Avg Time: 0.000144669
  24.                     Method 3c Avg Time: 0.002392947
  25.                     Method 3d Avg Time: 0.001309331
  26.      *   
  27.      */
  28.     class Problem1
  29.     {
  30.         int[] items = Enumerable.Range(1, 999).ToArray();
  31.         ReaderWriterLockSlim rw = new ReaderWriterLockSlim();
  32.         int sum = 0;
  33.  
  34.         //KISS Logic
  35.         public int RunMethod1()
  36.         {
  37.             sum = 0;
  38.  
  39.             foreach(int s in items)
  40.             {
  41.                 if (s % 3 == 0 || s % 5 == 0)
  42.                 {
  43.                     sum += s;
  44.                 }
  45.             };
  46.  
  47.             return sum;
  48.         }
  49.  
  50.         //Lazy Method
  51.         public int RunMethod2a()
  52.         {
  53.             return items.Where(n => n % 3 == 0 || n % 5 == 0).Sum();
  54.         }
  55.  
  56.         //Lazy Method on the fly
  57.         public int RunMethod2b()
  58.         {
  59.             return Enumerable.Range(1, 999).Where(n => n % 3 == 0 || n % 5 == 0).Sum();
  60.         }
  61.  
  62.         //Parallel Lazy Method
  63.         public int RunMethod2c()
  64.         {
  65.             return items.AsParallel().Where(n => n % 3 == 0 || n % 5 == 0).Sum();
  66.         }
  67.  
  68.         //Parallel Lazy Method on the fly
  69.         public int RunMethod2d()
  70.         {
  71.             return Enumerable.Range(1, 999).AsParallel().Where(n => n % 3 == 0 || n % 5 == 0).Sum();
  72.         }
  73.  
  74.         //Basic Parallel Method
  75.         public int RunMethod3a()
  76.         {
  77.             List<int> multOf3Or5 = new List<int>();
  78.  
  79.             Parallel.ForEach(items, s =>
  80.                 {
  81.                     if (s % 3 == 0 || s % 5 == 0)
  82.                     {
  83.                         lock (multOf3Or5)
  84.                         {
  85.                             multOf3Or5.Add(s);
  86.                         }
  87.                     }
  88.                 }
  89.             );
  90.  
  91.             return multOf3Or5.Sum();
  92.         }
  93.  
  94.         //Parallel it, but slice the work up
  95.         public int RunMethod3b()
  96.         {
  97.             List<int> multOf3Or5 = new List<int>();
  98.  
  99.             Parallel.ForEach(items.Slice(100), s =>
  100.             {
  101.                 foreach (int item in s)
  102.                 {
  103.                     if (item % 3 == 0 || item % 5 == 0)
  104.                     {
  105.                         lock (multOf3Or5)
  106.                         {
  107.                             multOf3Or5.Add(item);
  108.                         }
  109.                     }
  110.                 }
  111.             });
  112.  
  113.             return multOf3Or5.Sum();
  114.         }
  115.  
  116.  
  117.         //Basic Parallel Method just sum it
  118.         public int RunMethod3c()
  119.         {
  120.             sum = 0;
  121.  
  122.             Parallel.ForEach(items, s =>
  123.             {
  124.                 if (s % 3 == 0 || s % 5 == 0)
  125.                 {
  126.                     rw.EnterWriteLock();
  127.                     sum += s;
  128.                     rw.ExitWriteLock();
  129.                 }
  130.             });
  131.  
  132.             return sum;
  133.         }
  134.  
  135.         //Basic Parallel Method just slice & sum it
  136.         public int RunMethod3d()
  137.         {
  138.             sum = 0;
  139.             
  140.             Parallel.ForEach(items.Slice(100), s =>
  141.             {
  142.                 foreach (int item in s)
  143.                 {
  144.                     if (item % 3 == 0 || item % 5 == 0)
  145.                     {
  146.                         rw.EnterWriteLock();
  147.                         sum += item;
  148.                         rw.ExitWriteLock();
  149.                     }
  150.                 }
  151.             });
  152.  
  153.             return sum;
  154.         }
  155.     }
  156. }

Method 1: is the straight forward logic I would have used, and seems to be the quickest.
Method 2s: is probably something I would use as well, and to clean code up.
Method 3s: using Parallel programming, doesn't always speed things up. Depends on how much work needs to be done. I used an Extension method called Slice which expands the use of enumerable. I mainly got the idea to do this after reading about extention methods from http://www.blackrabbitcoder.net/archive/2013/03/08/c.net-little-wonders-extension-methods-demystified.aspx

For the Slice Extension, I used this:
Code Snippet
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5.  
  6. namespace ProjectEuler
  7. {
  8.     public static class EnumerableExtensions
  9.     {
  10.         //Source and Inspiration: http://www.blackrabbitcoder.net/archive/2013/03/08/c.net-little-wonders-extension-methods-demystified.aspx
  11.  
  12.         public static IEnumerable<IEnumerable<T>> Slice<T>(this IEnumerable<T> source, int size)
  13.         {
  14.             // can't slice null sequence
  15.             if (source == null) throw new ArgumentNullException("source");
  16.             if (size < 1) throw new ArgumentOutOfRangeException("size", "The size must be positive.");
  17.  
  18.             // force into a list to take advantage of direct indexing. Could also force into an
  19.             // array, use LINQ grouping, do a Skip()/Take(), etc...
  20.             var sourceList = source.ToList();
  21.             int current = 0;
  22.      
  23.             // while there are still items to "slice" off, keep going
  24.             while (current < sourceList.Count)
  25.             {
  26.                 // return a sub-slice using an iterator for deferred execution
  27.                 yield return sourceList.GetRange(current, Math.Min(size, sourceList.Count - current));
  28.                 current += size;
  29.             }
  30.         }
  31.     }
  32. }

The Main program. I hate repeating myself, so after some refactoring I came up with this to use delegates.
Code Snippet
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Diagnostics;
  6.  
  7. namespace ProjectEuler
  8. {
  9.     class Program
  10.     {
  11.         public static Stopwatch sw = new Stopwatch();
  12.         public delegate int fPointer();
  13.  
  14.         static void Main(string[] args)
  15.         {
  16.             //Initialize Problem(s)
  17.             Problem1 p1 = new Problem1();
  18.  
  19.             Func<fPointer,int, double> timeIt = (d,runCount) =>
  20.             {
  21.                 List<double> times = new List<double>();
  22.  
  23.                 for (int i = 0; i < runCount; i++)
  24.                 {
  25.                     sw.Reset();
  26.                     sw.Start();
  27.                     d();
  28.                     sw.Stop();
  29.                     times.Add(sw.Elapsed.TotalSeconds);
  30.                 }
  31.                 return times.Average();
  32.             };
  33.  
  34.             //Get Times of Running Methods
  35.             Console.WriteLine("Method 1 Avg Time: " + timeIt(p1.RunMethod1,100));
  36.             Console.WriteLine("Method 2a Avg Time: " + timeIt(p1.RunMethod2a, 100));
  37.             Console.WriteLine("Method 2b Avg Time: " + timeIt(p1.RunMethod2b, 100));
  38.             Console.WriteLine("Method 2c Avg Time: " + timeIt(p1.RunMethod2c, 100));
  39.             Console.WriteLine("Method 2d Avg Time: " + timeIt(p1.RunMethod2d, 100));
  40.             Console.WriteLine("Method 3a Avg Time: " + timeIt(p1.RunMethod3a, 100));
  41.             Console.WriteLine("Method 3b Avg Time: " + timeIt(p1.RunMethod3b, 100));
  42.             Console.WriteLine("Method 3c Avg Time: " + timeIt(p1.RunMethod3c, 100));
  43.             Console.WriteLine("Method 3d Avg Time: " + timeIt(p1.RunMethod3d, 100));
  44.  
  45.             Console.ReadKey();
  46.         }
  47.     }
  48. }

Tuesday, October 05, 2010

Mimic Domain for SQL Server or other executables.

One tiresome thing about being a consultant is the lack of ability to use Windows Authentication when on site. Your computer is on a separate domain and you run into the "I need permissions" issue.

One solution to this is to use the run as command in a shortcut's target.

First create a shortcut of the executable.

For this example, I used SQL Server.

C:\Windows\System32\runas.exe /netonly /user:consultantDomain\wandrus "C:\Program Files\Microsoft SQL Server\100\Tools\Binn\VSShell\Common7\IDE\Ssms.exe"

The highlighted yellow is what was added, where I set the domain\user_name to what I would like to use. When this shortcut is then clicked, it will prompt for your password.