1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Diagnostics;
  5.  
  6. namespace CSharp
  7. {
  8.     class Program
  9.     {
  10.         static Dictionary<uint, bool?> happyNumbers = new Dictionary<uint, bool?> { {1, true} };
  11.        
  12.         static void Main (string [] args)
  13.         {
  14.             while (true) {
  15.                 happyNumbers.Clear ();
  16.                 Console.Write ("Pick an upper bound: ");
  17.                 var input = Console.ReadLine ();
  18.                 if (string.IsNullOrEmpty (input)) break;
  19.                 var upperBound = uint.Parse (input);
  20.                 var stopWatch = new Stopwatch ();
  21.                 stopWatch.Start ();
  22.                 var happies = HappyNumbers (upperBound);
  23.                 stopWatch.Stop ();
  24.                 Console.WriteLine ("Time taken to calculate numbers: {0}", stopWatch.Elapsed);
  25.                 Console.WriteLine ("{0} happy number(s) between 0 and {1}.", happies.Count (), upperBound);
  26.                 // I know this is slow, but I'm not timing the generation of the string
  27.                 Console.Write ("Do you want the list? (Y/N)");
  28.                 var list = Console.ReadLine ();
  29.                 if (list.ToUpper ().Equals ("Y")) {
  30.                     var numberList = string.Join (",", happies.Select (num => num.ToString ()).ToArray ());
  31.                     Console.WriteLine ("Number list: {0}", numberList);
  32.                 }
  33.             }
  34.         }
  35.    
  36.         static IEnumerable<uint> HappyNumbers (uint upperBound) {
  37.             var numbers = new List<uint> { 1 };
  38.             for (uint current = 2; current < upperBound; ++current) {
  39.                 var happiness = IsHappy (current);
  40.                 if (happiness.HasValue && happiness.Value) numbers.Add (current);
  41.             }
  42.             return numbers;
  43.         }
  44.    
  45.         static bool? IsHappy (uint value)
  46.         {
  47.             bool? happiness;
  48.  
  49.             if (happyNumbers.TryGetValue (value, out happiness)) {
  50.                 if (happiness == null) return happyNumbers[value] = false;
  51.             } else {
  52.                 happyNumbers[value] = happiness = null;
  53.                 uint newValue = 0;
  54.    
  55.                 for (uint i = value; i != 0; i /= 10) {
  56.                     uint lsd = i % 10;
  57.                     newValue += lsd * lsd;
  58.                 }
  59.    
  60.                 if (newValue == 1) happiness = true;
  61.                 else happiness = IsHappy (newValue);
  62.    
  63.                 if (happiness.HasValue && happiness.Value) happyNumbers[value] = true;
  64.                 else happyNumbers[value] = happiness;
  65.             }
  66.  
  67.             return happiness;
  68.         }
  69.     }  
  70. }