views:

168

answers:

2

When solving an interview question

Question A six digit number need to be found in such a manner when it is multiplied by an integer between 2 and 9 gives the original six digit number when its digits are reversed.

Example:

Suppose I multiply 219978 * 4 i get 879912 ,when reverse 879912 I will get 219978 back.

I solved it using

for (long l = 100000; l < 999999; l++)
{
 var num = l.ToString();

for (int i = 3; i < 9; i++)
{
  var mul = l * i;
  string str = mul.ToString();
  char[] splitDigits = str.ToCharArray();
  string reversedDigit =
  new  string(splitDigits.Reverse().ToArray());

  if (reversedDigit.CompareTo(num) == 0)
    {
      Console.WriteLine("{0} * {1}= {2},
       when multiplied {3} ", num, i, mul,reversedDigit);

    }

 }
}

The original task was to solve it using linq. I have bit confusion in handling temp calculations for example

when i use

   var = from l in Enumerable.Range(100000,999999)
         from i in Enumerable.Range(3,9)

What is the way to handle temporary calculations like var num = l.ToString(),etc in linq.It confused me a lot to finish it in Linq.Help is appreciated.

+5  A: 

You want let...

    // NOTE: buggy; see below
    var qry =  from l in Enumerable.Range(100000, 999999)
               from i in Enumerable.Range(3, 9)
               let s = l.ToString()
               let t = (l * i).ToString()
               where s.Reverse().SequenceEqual(t)
               select new { l, i };

    var a = qry.First();
    Console.WriteLine("an answer...");
    Console.WriteLine("{0} x {1} = {2}", a.l, a.i, a.l * a.i);

    Console.WriteLine("all answers...");
    foreach (var row in qry)
    {
        Console.WriteLine("{0} x {1} = {2}", row.l, row.i, row.l * row.i);
    }

with first answer (note the inclusion of 9 is taken from your original version of the code, but it may be desirable to use Range(3,8) instead):

109989 x 9 = 989901


Optimised version (and correct range):

    var qry =  from l in Enumerable.Range(100000, 999999 - 100000)
               let s = l.ToString()
               let sReversed = new string(s.Reverse().ToArray())
               let wanted = int.Parse(sReversed)
               from i in Enumerable.Range(3, 8 - 3) 
               where l * i == wanted
               select new { l, i };

This reduces the number of strings created, uses integer equality, and correctly uses the range (the second parameter to Range is the count, not the end).

Marc Gravell
Write the answer Yuiry :) I'm curious to see it.
Gregory
I just don't know about solving all these, you gotta make people figure it out for themselves ones in a while
Yuriy Faktorovich
@Yuriy - note that he already has a working implementation... so I'm not sure this is so much an issue; the issue was over temp values (`let`).
Marc Gravell
Oops! One thing is clear, if you regularly use "stackoverflow" and getting answer from prodigies like Marc,Jon Skeet you can bag any offer letter.Thanks Marc.Still few puzzles are there,let me try it,incase of doubt i will post it.
Your solution was better anyway, my VS isn't showing the LINQ extensions for string, so I did a bunch of ToCharArray's for no reason. Weird.
Yuriy Faktorovich
An interesting and promising-looking answer Marc but a couple of things: When i ran your code i was surprised at how long it took to execute to end. And, part of the answer is a seven digit number even six is supposed to be the most digits. Here's my output:an answer...109989 x 9 = 989901all answers...109989 x 9 = 989901219978 x 4 = 8799121099989 x 9 = 9899901Press any key to continue . . .
Paul Sasik
Ah, fixed that ;-p
Marc Gravell
Oops another optimized,implemantation,if you think in this way,one day or another,you may tell that your mother tounge is C# .
@Marc, Thanks for following up on this. i have just started learning Linq and this question and answer is very interesting. ... Weird thing on the slowness i mentioned above. It actually happens on the foreach loop that is outputting the answer. The linq statement that creates the answers collection is quite fast. Any idea why foreach on that collection would behave so slowly?
Paul Sasik
Or perhaps i should post that last question separately?
Paul Sasik
@Marc: question asked here: http://stackoverflow.com/questions/1582210/strange-slownes-while-iterating-over-linq-result
Paul Sasik
@Marc - your multiplier range is incorrect. From the problem statement: "...when it is multiplied by an integer between _2 and 9_...". Enumerable.Range(3, 8 - 3) returns the numbers 3,4,5,6,7 only. This will NOT return all of the solutions because one of them is only found when you multiply by 9 :-)
Robert Venables
@Robert - see my explanation in the text; that was taken from the OPs example...
Marc Gravell
+1  A: 

Here's another solution that matches the problem statement with a few helper methods for clarity (which could be moved into the original linq query):

    private static IEnumerable<int> SixDigitNumbers = Enumerable.Range(100000, (999999 - 100000));
    private static IEnumerable<int> Multipliers = Enumerable.Range(2, 8);

    static void Main(string[] args)
    {

        var Solutions = from OriginalNumber in SixDigitNumbers
                              from Multiplier in Multipliers
                              let MultipliedNumber = (OriginalNumber * Multiplier)
                              where MultipliedNumber < 999999 && ResultIsNumericPalindrome(OriginalNumber, Multiplier)
                              select new { MultipliedNumber, OriginalNumber, Multiplier };


        var AllSolutions = Solutions.ToList();

    }

    private static string Reverse(string Source)
    {
        return new String(Source.Reverse().ToArray());
    }

    private static bool ResultIsNumericPalindrome(int Original, int Multiplier)
    {
        return (Original.ToString() == Reverse((Original * Multiplier).ToString()));
    }

Here are ALL of the solutions:

{ MultipliedNumber = 989901, OriginalNumber = 109989, Multiplier = 9 }
{ MultipliedNumber = 879912, OriginalNumber = 219978, Multiplier = 4 }

Be careful with Enumerable.Range - I see one person responding to this question made the mistake of excluding two numbers requested in the problem statement.

Robert Venables
Thank you Robert.Acknowledged.