Skip to content

Instantly share code, notes, and snippets.

@pgsin
Created April 21, 2017 20:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save pgsin/a5922feb0dec3f1a51c35f79cd603891 to your computer and use it in GitHub Desktop.
Save pgsin/a5922feb0dec3f1a51c35f79cd603891 to your computer and use it in GitHub Desktop.
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