1

I was trying to solve this problem: http://www.spoj.com/problems/LASTDIG/ where it takes a base and exponent and I have to output the last digit of the result of theexponentiation, but online judge says that my program gives wrong answers though for typical test cases, my outputs are right.

N.B.: I have to use Fast Modular Exponentiation algorithm, here's a nice explanation for that: https://www.khanacademy.org/computing/computer-science/cryptography/modarithmetic/a/fast-modular-exponentiation

using System;

public class Test
{
    public static void Main()
    {
        int val = Convert.ToInt32(Console.ReadLine());
        for (int i=0; i<val; i++ )
        {
            string input = Console.ReadLine();
            int a = Convert.ToInt32(input.Split()[0]);
            int b = Convert.ToInt32(input.Split()[1]);
            if (a==0)
            {
                Console.WriteLine(0);
            } else if(b==0)
            {
                Console.WriteLine(1);
            } else {
                a=a%10;
                string bToBinary=Convert.ToString(b, 2);
                double temp = 1;
                for(int j=bToBinary.Length-1, k=0; j>=0; j--, k++)
                {
                    if (bToBinary[j] == '1')
                    {
                        temp = temp*(Math.Pow(a, Math.Pow(2, k)));
                    }
                }
                Console.WriteLine(temp%10);
            }
        }
    }
}

Sample Input:

4
3 10
6 2
14 11
1 0

Output from this program:

9
6
4
1
Sharif Mamun
  • 3,508
  • 5
  • 32
  • 51
  • Did the judge provide you with the test cases used and their answers? – Michael McGriff Jun 08 '16 at 17:36
  • nope, it's sad and that's why I am here. – Sharif Mamun Jun 08 '16 at 17:36
  • 1
    Fast Modular Exponentiation is not actually required here. The question demands only the last number which can be computed by looking at the last digit of base and figuring out the pattern in the last digits of its various exponents. – Shubham Jun 08 '16 at 17:38
  • 1
    As shown here: http://stackoverflow.com/a/7214528/106159 (Warning: Spoilers! ;)/ – Matthew Watson Jun 08 '16 at 17:38
  • 1
    They are likely expecting integer math, and you're using floating point. – hatchet - done with SOverflow Jun 08 '16 at 17:38
  • @hatchet could be, will give that a try. – Sharif Mamun Jun 08 '16 at 17:40
  • Note that the exponent can be 2,147,483,000. A double will forget the last numbers, as it has a precision of only about 15 digits. So you will get 0 for large exponents - which probably will be wrong. – Hans Kesting Jun 08 '16 at 17:41
  • If you look on the right of the page with the problem, it states "Source limit: 700B". Your code as presented has over 900 characters. – Andrew Morton Jun 08 '16 at 17:47
  • It's already passed that 700B limit and ran on the server, then gave me the wrong answer. – Sharif Mamun Jun 08 '16 at 17:51
  • Why I always need a lot of time to understand what is given and what is required from interview questions like this :( – Khalil Khalaf Jun 08 '16 at 17:56
  • 1
    This would be a stupid interview question, because it would amount to "do you happen to have come across this not particularly useful (to programmers) piece of mathematics?". A bit like the annoying interview question about detecting cycles in a linked list. Sometimes I wonder if the interviewer isn't just asking questions to make themselves look clever (when they almost certainly read the answer in a book or online without working it out themselves anyway...) – Matthew Watson Jun 08 '16 at 18:04
  • @MatthewWatson to me, those kind of questions are made to eliminate number of interviewees or to see who went through certain level of hard work. Nothing else. – Sharif Mamun Jun 08 '16 at 18:13
  • @MatthewWatson You always start with the FooBar question and marvel at the number of programmers that cannot answer it. – juharr Jun 08 '16 at 18:14
  • @HansKesting you were right, the solution I had was getting overflow problem. For larger values like 9^2,147,483,000, no built in data types can't hold the value and that was the problem. – Sharif Mamun Jun 08 '16 at 18:56
  • @juharr Did you mean "FizzBuzz question"? – Simon Forsberg Jun 08 '16 at 19:58
  • @SharifMamun The "find a cycle in a linked list" question is, I feel, [not an appropriate interview question](http://www.nomachetejuggling.com/2014/06/24/the-worst-programming-interview-question/). ;) – Matthew Watson Jun 08 '16 at 19:59
  • @SimonForsberg "FooBar" is Microsoft's name for the "FizzBuzz" question, I believe. – Matthew Watson Jun 08 '16 at 20:02

2 Answers2

2

Every power repeats either in either 1, 2 or 4.

Here is the pattern written out

1 = {1,1,1,1}
2 = {2,4,8,6}
3 = {3,9,7,1}
4 = {4,6,4,6}
5 = {5,5,5,5}
6 = {6,6,6,6}
7 = {7,9,3,1}
8 = {8,4,2,6}
9 = {9,1,9,1}

And as you already know the pattern for powers with the same unit e.g. the pattern for 13 is the same as for 3

So you should be able to write your program as such

public class Test
{
    public static void Main()
    {
        int val = Convert.ToInt32(Console.ReadLine());
        for (int i=0; i<val; i++ )
        {
            string input = Console.ReadLine();
            int a = Convert.ToInt32(input.Split()[0]);
            int b = Convert.ToInt32(input.Split()[1]);
            if (a==0)
            {
                Console.WriteLine(0);
            } else if(b==0)
            {
                Console.WriteLine(1);
            } else {
               Console.WriteLine (Math.Pow(a%10,b%4 + 4) %10);  
            }
        }
    }
}
Sharif Mamun
  • 3,508
  • 5
  • 32
  • 51
Conrad Frix
  • 51,984
  • 12
  • 96
  • 155
  • There's a small problem. You are missing case when if (b%4 == 0) then b = 4; Anyways, I got the short explanation but you can describe a bit more for people who will come here in future. Thanks for your answer. – Sharif Mamun Jun 08 '16 at 18:50
  • @SharifMamun Yeah I missed that because I tested with a = 3. Adding 4 to the result will fix that and still keep the values small enough so you don't get overflow. e.g. a = 20 b = 2,147,483,000 – Conrad Frix Jun 08 '16 at 19:34
  • This answer is missing any kind of proof that "Every power repeats either in either 1, 2 or 4", though. But there's one [here](http://stackoverflow.com/a/7214528/106159) (sort of). – Matthew Watson Jun 08 '16 at 20:04
0

You aren't supposed to brute force the solution. The problem specifically ask for the last digit of the result, not the whole thing.

There is should be some kind of pattern in the multiplication that you can abuse. Let's drop the power 0 for the moment, because that is a specific edge case. For instance, we know that 10 or 20 to power of any positive integer will ends in 0, and 5 will always ends in 5. We can abuse this pattern, because no matter how many times we raise the power, the last digit will always be within this pattern.

The pattern can be extracted as such :

IEnumerable<int> FindExpLastDigitPattern(int i)
{
    var result = 1;

    var list = new List<int>();
    while (!list.Contains(result = (result * i) % 10))
    {
        list.Add(result);
        yield return result;
    }
}

And we can also predict the position within this pattern based on the power, which is index = (power - 1) % pattern.Count.

With that in mind, we can compute the last digit of an exponentiation :

int ComputeLastDigitOfExponentiation(int i, int power)
{
    // arguments guard...

    // handles specific case
    if (power == 0)  return 1;

    var pattern = FindExpLastDigitPattern(i).ToList();

    return pattern[(power - 1) % pattern.Count];
}
Xiaoy312
  • 14,292
  • 1
  • 32
  • 44