I have written the following code in C#. I have looked at it in every way and I think it should work but it isn't giving any output even though I let it running overnight. What is the issue? Thanks in advance.
namespace Palymdrome
{
class Multiple
{
private int x;
private int y;
public int ProductY
{
get
{
return y;
}
set
{
y = value;
}
}
public int ProductX
{
get
{
return x;
}
set
{
x = value;
}
}
public int Value
{
get
{
return x * y;
}
}
public Multiple(int x, int y)
{
this.x = x;
this.开发者_开发百科y = y;
}
}
class Program
{
static bool IsPalimdrome(int palimdrome)
{
string sPalimdrome = palimdrome.ToString();
int decrescent = sPalimdrome.Length-1;
string sInverted = "";
for (decrescent=sPalimdrome.Length-1;decrescent>=0;decrescent--)
{
sInverted += sPalimdrome[decrescent];
}
if (sPalimdrome == sInverted)
{
return true;
}
return false;
}
static void Main(string[] args)
{
Multiple multiple = new Multiple(999, 999);
int[] values = new int[999999];
int i = 0;
while (multiple.ProductY > 0)
{
multiple.ProductX--;
if (multiple.ProductX == 0)
{
multiple.ProductY--;
multiple.ProductX = 999;
}
if (IsPalimdrome(multiple.Value) && multiple.Value != 0)
{
values[i] = multiple.Value;
i++;
}
/*if (multiple.ProductY < 10)
{
Console.WriteLine("100 reached, waiting for confirmation");
Console.Read();
}*/
}
Console.WriteLine(values.Max());
Console.Read();
}
}
}
I didn't follow the code all the way to see exactly why it doesn't work, but man oh man are you making things complicated.
For one, implementing IsPalindrome
is trivial with LINQ:
static bool IsPalindrome(int number)
{
var s = number.ToString();
return s.Reverse().SequenceEqual(s);
}
Also, when looping you certainly don't need to take into account values of x
and y
less than 100 because the product would not be the product of two 3-digit numbers by definition. Moreover, you don't need to check both x * y
and y * x
for any fixed values of x
, y
because again the product will be identical. This means that for any one value of x
you can disregard all values of y
that are less than x
.
Finally, you don't need to allocate an array with 999999 elements. A List<int>
will do just fine.
So, you can simply do:
var results = new List<int>();
for(var x = 100; x < 1000; ++x) {
for(var y = x; y < 1000; ++y) {
if (IsPalindrome(x * y)) {
results.Add(x*y);
}
}
}
And if we go all in for LINQ:
var result =
Enumerable.Range(100, 900).
SelectMany(x => Enumerable.Range(x, 1000 - x).Select(y => x * y)).
Where(IsPalindrome).
Max();
Your program works fine for me and spits out the number 906609
- which is the correct solution to the Project Euler Problem 4 that you are referring to. Could it be that you just had a breakpoint left somewhere and program execution was paused?
I'm going to guess that the algorithm is completing but the program isn't finishing because you forgot that you have to press Enter to exit.
A possibly-faster way of doing this is to look at the possible range of "multiple of 3-digit numbers" (it is the closed range from 100*100 to 999*999) and generate all palindromic numbers in this range (loop from 999 down to 100, for each three-digit number abc, generate abccba; factor this and see if you can generate two 3-digit numbers from the prime factors, if you can't loop over teh same range and generate abcba).
The difference here is that you try to map from possible answers to possible precursors, in a way that allows you to finish as soon as you can possibly find an answer. The flip side is that factorisation isn't entirely cheap (but, then, it's all pretty small numbers and you can simply generate a list of all primes less than 1000 for your trialling, as any palindrome with a prime factor larger than 999 will not be a product of two three-digit numbers).
精彩评论