Created
April 21, 2017 20:41
-
-
Save pgsin/a5922feb0dec3f1a51c35f79cd603891 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 BenchmarkDotNet.Reports; | |
using BenchmarkDotNet.Running; | |
using BenchmarkDotNet.Attributes; | |
namespace Test { | |
public class PalindromNumber { | |
//Thanks to @Velial and @Denis | |
private static bool IsPalindromicNumber(int i) { | |
string testNumber = Convert.ToString(i); | |
for (int j = testNumber.Length / 2; j >= 0; j--) { | |
if (testNumber[j] != testNumber[testNumber.Length - 1 - j]) { | |
return false; | |
} | |
} | |
return true; | |
} | |
[Benchmark] | |
public static string LargestPalindromeOriginal() { | |
int test = 0; | |
int left = 0; | |
int right = 0; | |
int biggestNumber = 0; | |
int maxNumber = 999; | |
for (left = maxNumber; left >= 99; left--) { | |
for (right = maxNumber; right >= 99; right--) { | |
test = left * right; | |
if (IsPalindromicNumber(test)) { | |
break; | |
} | |
} | |
if (test <= biggestNumber) continue; | |
biggestNumber = test; | |
} | |
return biggestNumber.ToString(); | |
} | |
[Benchmark] | |
public static string LargestPalindromeDenis() { | |
int max = 0; | |
for (int i = 100; i < 1000; i++) { | |
for (int j = i + 1; j < 1000; j++) { | |
int ij = i * j; | |
if (max < ij && IsPalindromicNumber(ij)) { | |
max = ij; | |
} | |
} | |
} | |
return max.ToString(); | |
} | |
[Benchmark] | |
public static string LargestPalindromeEric() { | |
var query = from first in ThreeDigitNumbers() | |
from second in ThreeDigitNumbers() | |
let product = first * second | |
where IsPalindromicNumber(product) | |
select product; | |
return query.Max().ToString(); | |
} | |
private static IEnumerable<int> ThreeDigitNumbers() { | |
for (int i = 100; i < 999; i++) { | |
yield return i; | |
} | |
} | |
[Benchmark] | |
public static string LargestPalindromePgs() { | |
int largestPalindrome = 0, b, delta; | |
for (int a = 999; a >= 100; a--) { | |
if (a % 11 == 0) { | |
b = 999; | |
delta = 1; | |
} else { | |
b = 990; | |
delta = 11; | |
} | |
while (b >= a) { | |
int ab = a * b; | |
if (ab <= largestPalindrome) | |
break; | |
if (IsPalindromicNumber(ab)) { | |
largestPalindrome = ab; | |
} | |
b -= delta; | |
} | |
} | |
return largestPalindrome.ToString(); | |
} | |
[Benchmark] | |
public static string LargestPalindromeDavislor() => | |
LargestPalindromeDavislorImpl().First(HasFactors).ToString(); | |
private static IEnumerable<Int32> LargestPalindromeDavislorImpl() { | |
for (Int32 a = 9; a >= 1; --a) | |
for (Int32 b = 9; b >= 0; --b) | |
for (Int32 c = 9; c >= 0; --c) | |
yield return a * 100001 + b * 10010 + c * 1100; | |
} | |
private static bool HasFactors(Int32 p) { | |
Int32 lower1 = (p / 999 + 10) / 11, | |
lower = Math.Max(10, lower1); | |
Int32 upper1 = p / 1100, | |
upper = Math.Min(90, upper1); | |
Int32 count = Math.Max(upper - lower + 1, 0); | |
return Enumerable.Range(lower, count).Any(x => p % x == 0); | |
} | |
[Benchmark] | |
public static string LargestPalindromeDavislor2() => | |
LargestPalindromeDavislorImpl().First(p => XCandidates(p).Any(x => p % x == 0)).ToString(); | |
private static IEnumerable<int> XCandidates(int p) { | |
int q = p / 11; | |
int lower = Math.Max(10, (q + (999 - 1)) / 999); | |
int upper = Math.Min(90, q / 100); | |
int k = q % 6; | |
if (k == 1 || k == 5) { | |
int r = lower % 6; | |
bool mod1 = r <= 1; | |
int i = lower - r + (mod1 ? 1 : 5); | |
while (i <= upper) { | |
yield return i; | |
i += mod1 ? 4 : 2; | |
mod1 = !mod1; | |
} | |
} else if (k == 2 || k == 4) { | |
int r = lower % 6; | |
int m = (r == 3 || r == 0) ? r + 1 : r; | |
int i = lower - r + m; | |
while (i <= upper) { | |
yield return i; | |
if (m == 5) { | |
i += 2; | |
m = 1; | |
} else if (m == 2) { | |
i += 2; | |
m = 4; | |
} else { | |
++i; | |
++m; | |
} | |
} | |
} else if (k == 3) { | |
int i = lower + 1 - lower % 2; | |
while (i <= upper) { | |
yield return i; | |
i += 2; | |
} | |
} else { | |
for (int i = lower; i <= upper; ++i) | |
yield return i; | |
} | |
} | |
[Benchmark] | |
public static string LargestPalindrome_t3chb0t() { | |
var isPalindrom = new Func<(int left, int right, int product), bool>(t => { | |
var str = t.product.ToString(); | |
for (int i = 0, j = str.Length - 1; i < str.Length; i++, j--) { | |
if (str[i] != str[j]) return false; | |
} | |
return true; | |
}); | |
int max = 2000; | |
(int left, int right, int product) result = | |
Enumerable | |
.Range(0, max) | |
.Select(x => Enumerable.Range(0, max).Select(y => (left: x, right: y, product: x * y))) | |
.SelectMany(results => results) | |
.AsParallel() | |
.Where(isPalindrom) | |
.OrderByDescending(x => x.product) | |
.FirstOrDefault(); | |
return result.Item3.ToString(); | |
} | |
} | |
class Program { | |
static void Main() { | |
Summary summary = BenchmarkRunner.Run<PalindromNumber>(); | |
Console.ReadKey(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment