How to get the last digits of 2 power - java

I’m working on a problem where its demanded to get the last 100 digits of 2^1001. The solution must be in java and without using BigInteger, only with int or Long. For the moment I think to create a class that handle 100 digits. So my question is, if there is another way the handle the overflow using int or long to get a number with 100 digits.
Thanks for all.

EDITED: I was off by a couple powers of 10 in my modulo operator (oops)
The last 100 digits of 2^1001 is the number 2^1001 (mod 10^100).
Note that 2^1001 (mod 10^100) = 2*(2^1000(mod 10^100)) (mod 10^100).
Look into properties of modulo: http://www.math.okstate.edu/~wrightd/crypt/lecnotes/node17.html
This is 99% math problem, 1% programming problem. :)
With this approach, though, you wouldn't be able to use just an integer, as 10^100 won't fit in an int or long.
However, you could use this to find, say, the last 10 digits of 2^1001, then use a separate routine to find the next 10 digits, etc, where each routine uses this feature...

The fastest way to do it (coding wise) is to create an array of 100 integers and then have a function which starts from the ones place and doubles every digit. Make sure to take the modulus of 10 and carry over 1s if needed. For the 100th digit, simply eliminate the carry over. Do it 1001 times and you're done.

Related

Suffix array nlogn creation

I have been learning suffix arrays creation, & i understand that We first sort all suffixes according to first character, then according to first 2 characters, then first 4 characters and so on while the number of characters to be considered is smaller than 2n.
But my doubt is why don't we choose the first 3 characters, then 9... and so on. Why only 2 characters are taken into account since the strings are a part of same strings and not different random strings?
I haven't analyzed the suffix array construction algorithm thoroughly, but still would like to share my thoughts.
In my humble opinion, your question is similar to the following ones:
Why do computers use binary encoding of information instead of ternary?
Why does binary search bisect the range instead of trisecting it?
Why are there two sexes rather than three?
The reason is that the number 2 is special - it is the smallest plural number. The difference between 1 and 2 is qualitative, whereas the difference between 2 and 3 (as well as any other positive integer) is quantitative and therefore not as drastic.
As a result, binary formulation of many algorithms and data structures turns out to be the simplest one, though some of them may be generalized, with various degrees of added complexity, for an arbitrary base.
Answer is given from the post you linked. And as #Leon answered, the algorithm work because it use a dichotomous approach to solve the sorting problem. if you correctly read the answer, the main purpose is to divide word be small 2 character fragments. So that 4 characters can be easily sort base on the arrangement of the 2 pair of characters, 6 characters with 4-2 or 2-4 or 2-2-2 and so one. Thus have a word of 3 letters in the table is non-sense since word of 3 characters may be seen has 2 characters + the position in the alphabet of the last character.
I think you are considering only the speed of 2^x versus 3^x where you obviously would prefer the latter.
But you have to consider the effort you need for each step.
Since 3^x needs about 1.58 less steps than 2^x you would need to be able to compute a single step for the 3^x growth in less than 1.58 times what you need for a single step in the 2^x growth to perform better.
Generally the problems will get much more complex when you have to handle three elements in each step instead of two.
Also if you could expand it to 3^x you could also do it for a bigger n^x and then with big n your algorithm is suddenly not exponential but effectively linear.

Pigeonhole principle in Algorithm problems

I am reading Editorial about a problem on Codefoces but still not able to understand it beacuse as it is using PigeonHole principle , I am not getting how to apply pigeonhole priniciple on this problem
Here's problem Editorial:
In this problem we use the septimal number system. It is a very important limitation. Let's count how many digits are showed on the watch display and call it cnt. If cnt more than 7, the answer is clearly 0 (because of pigeonhole principle). If cnt is not greater than 7, then you can just bruteforces all cases.
Here' Problem Statement
http://codeforces.com/contest/686/problem/C
Robbers, who attacked the Gerda's cab, are very successful in covering from the kingdom police. To make the goal of catching them even harder, they use their own watches.
First, as they know that kingdom police is bad at math, robbers use the positional numeral system with base 7. Second, they divide one day in n hours, and each hour in m minutes. Personal watches of each robber are divided in two parts: first of them has the smallest possible number of places that is necessary to display any integer from 0 to n - 1, while the second has the smallest possible number of places that is necessary to display any integer from 0 to m - 1. Finally, if some value of hours or minutes can be displayed using less number of places in base 7 than this watches have, the required number of zeroes is added at the beginning of notation.
Note that to display number 0 section of the watches is required to have at least one place.
Little robber wants to know the number of moments of time (particular values of hours and minutes), such that all digits displayed on the watches are distinct. Help her calculate this number.
The "Pigeonhole Principle" is just this: if I try to put more than seven pigeons into seven pigeonholes, one of the holes has more than one pigeon in it.
Here, the septimal digits are the pigeonholes and the places in a time representation are the pigeons. So, if you can determine (quickly) for a given case that more than seven places would be needed to represent the time, the pigeonhole principle tells you there can be no representations having distinct digits, and you can skip the really slow work of counting such representations by brute-force and go on to the next case.

Changing A Decimal to a whole number (NOT Rounding Off)

So I am making an application that can solve problems with Empirical Formulae and I need some code that would do something like:
If numbers are 2.5, 1, 3 it should change them to 2.5*2 = 5, 1*2 = 2, 3*2 = 6 so that the number with the decimal is converted to a whole number and the other numbers are adjusted appropriately.
I thought of this logic:
for(n = 1; (Math.round(simplestRat[0]) * n) != (int)SimplestRat[0]; n++)
to increment a counter that would multiply an integer to do what I want it to but I am skeptical about this code even at this phase and do not think it will work.
It would be a lot of help if someone could suggest a code for this or improve upon this code or even give me a link to another post for this problem as I was unable to find anything regarding this type of problem.
Any help is appreciated. Thanks
Okay, so you have to have a few steps. First, get them all into whole numbers. The easiest way is to find an appropriate power of ten to multiply them all by that leaves them as integers. This is a useful check: How to test if a double is an integer.
Then cast them to integers, and start working through them looking for common prime factors. This'll be a process similar to Eratosthenes' Sieve (http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes) but with division at the end. For each prime, see if all 3 numbers divide by it exactly (modulo prime == 0). If they do, divide and reset the primes to 2. If they don't, next prime.
This should give you the lowest common ratio between the numbers. Any additional multiplier that came from the original stage is shaved off by the common primes method.

Representing large numbers using linked lists and performing operations

I need to store two extremely large numbers (Strings, since they won't fit in int) in two linked lists, add them and then display the result (again, a String).
I can store the numbers directly into the list.
312312 can be stored as 2->1->3->2->1->3 (actual number will be extremely long)
111119 can be stored as 9->1->1->1->1->1
Then I can add them
11->2->4->3->2->4
Normally I could do 11*10^0 + 2*10^1 +...+ 4*10^5 and get 423431 but all those operations (multiplication, addition and exponentiation) would again be integer operations and since the actual numbers are going to be extremely big, int or long won't support the operations. The final result has to be a string.
So I need a way to convert 11->2->4->3->2->4 into 423431 without using int. Also, I cannot use BigInteger. Can anyone help me?
Well, first thing you need to do is implement carry.
For each digit (that is >= 10), you need to increase the next digit by that digit /10 and set that digit to that digit %10.
So 11->2->... becomes 1->3->....
Then to actually produce the string.
For the most performant option, I suggest StringBuilder.
Just append each digit in the linked-list, then just reverse().toString() (since you started with the smallest number).
Think about how you would do it by hand on paper. If the sum of a pair digits is greater than 9 you write down a carry digit of 1, which you add into the sum of the next pair of digits.
In a computer program you can use a local variable for that: add digits from first and last numbers and the carry from earlier, if sum is greater than.. set carry to 1, else set carry to 0, move on to the next pair...

Strange Numbers

Here are the properties of "strange numbers" in the problem I'm doing:
1) They have an even number of decimal digits (no leading zeros).
2) Define left half to be the number represented by the most significant half of digits of the original number, and right half to be the one represented by the least significant half. The right half may have leading zeros. The strange number is the square of the sum of its halves: 81 = (8 + 1)^2
Here are some other examples: 998001 = (998 + 001)^2, 3025 = (30 + 25)^2
How can I write a program that lists all the strange numbers in increasing order that have no more than 18 decimal digits?
I understand how to do this by looking at all the possibilities (numbers with 2 digits, 4 digits, 6 digits, ... , 18 digits), but that would take days to run. Are there any patterns to this, so I can output all the strange numbers in a matter of seconds? I would prefer answers in Java, but pseudo code is okay also.
All these 'strange' numbers are perfect squares. So you can start by going through all the numbers and squaring them (until the square has more than 18 digits). And for each square, check to see if it is 'strange'.
Edit
I'll also add that the reason this speeds things up so much is that it changes the solution from O(n) to O(√n)
Besides #spatulamania's speed-up, you can use modulo arithmetic to further speed up the checks.
To check every perfect square, you'll have to split the number into the two parts, add them, square the sum and compare it with the original number. (I'll name this as "full-check")
Instead, you can first check only the last digits of the two parts (and square their sum). For example, for number 99980001, take digits 8 and 1, take the square of (8+1)^2 = 9^2 = 81 and test that the last digit (1 in this case), is same as the last digit of 99980001 (I'll name this as "small-check"). If yes, then proceed with the full-check.
Since there are only 10x10=100 such combinations, this just needs to be done once. You'll create an array of acceptable combinations, that you can use:
0 0
0 1
8 1
4 4
8 4
0 5
0 6
8 6
4 9
8 9
Using this, you'll need to do only the "small-check" for about 82% of the perfect squares (those that fail the small-check) and both checks for the rest 18% (that pass the small-check, so "full-check" will be needed too). Therefore, if the "small-check" can be done fast enough, you'll gain some speed.
You may find even faster to expand this table for the last 2 digits of the two parts and use it (when n is large enough).
class strange_number
{
int number(int n)
{
int x = n;
String a = Integer.toString(n);
int d = a.length();
if(((int)(Math.pow(((x%(int)(Math.pow(10,d/2)))+(x/(int)(Math.pow(10,d/2)))),2))) == x)
return 1;
else
return 0;
}
}
can try this way. This may help u.

Categories