Last active
October 9, 2017 21:21
-
-
Save copernicus365/6e896f0d84cfce4c57cc28569b98006b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using DotNetXtensions; | |
using static System.Console; | |
namespace Play1 | |
{ | |
public class Prog | |
{ | |
static void Main() | |
{ | |
var sillyDigitSum = new SillyDigitSumFun(); | |
int[] hits = sillyDigitSum.GetHits(0, int.MaxValue); | |
$@"Hits Count: {hits.Length} | |
{hits.JoinToString(n => n.ToString("n0"), "\r\n")}".Print(); | |
ReadLine(); | |
} | |
} | |
public class SillyDigitSumFun | |
{ | |
public readonly int[] DigitsToItselfArray; | |
public SillyDigitSumFun() | |
{ | |
var arr = DigitsToItselfArray = new int[10]; | |
for (int num = 0; num < arr.Length; num++) | |
arr[num] = num == 0 ? 0 : (int)Math.Pow(num, num); | |
} | |
public int[] GetHits(int min, int max) | |
{ | |
if (min < 0 || min >= max) throw new ArgumentOutOfRangeException(); | |
List<int> hits = new List<int>(); | |
for (int num = min; num < max; num++) { | |
if (num % 10_000_000 == 0) | |
WriteLine($"... on number {num.ToString("n0")}"); | |
List<int> digits = SplitNumberIntoDigits(num); | |
if (IsHit(num, digits)) { | |
hits.Add(num); | |
WriteLine($"HIT! - {num.ToString("n0")}"); | |
} | |
} | |
return hits.ToArray(); | |
} | |
public bool IsHit(int num, List<int> digits) | |
{ | |
if (digits == null) throw new ArgumentNullException(); | |
int sum = 0; | |
for (int i = 0; i < digits.Count; i++) { | |
int digit = digits[i]; | |
int digitToItself = DigitsToItselfArray[digit]; // we've cached these once, much more performant; | |
sum += digitToItself; | |
// above in 1 line, but harder to grasp: sum += DigitsToItselfArray[digits[i]]; | |
if (sum > num) | |
return false; | |
} | |
return sum == num; | |
} | |
/// <summary> | |
/// Modified from source: https://stackoverflow.com/a/4808815/264031. | |
/// I'm guessing this is a lot more performant than the to string, split the string, and back route. | |
/// </summary> | |
public static List<int> SplitNumberIntoDigits(int num) | |
{ | |
List<int> listOfInts = new List<int>(); | |
while (num > 0) { | |
int digit = num % 10; | |
listOfInts.Add(digit); | |
num = num / 10; | |
} | |
listOfInts.Reverse(); | |
return listOfInts; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment