Java Program for Prime numbers - java

Problem
In this project you will write a Java program that reads a positive integer n from standard input, then
prints out the first n prime numbers. We say that an integer m is divisible by a non-zero integer d if there
exists an integer k such that m = k d , i.e. if d divides evenly into m. Equivalently, m is divisible by d if
the remainder of m upon (integer) division by d is zero. We would also express this by saying that d is a
divisor of m. A positive integer p is called prime if its only positive divisors are 1 and p. The one
exception to this rule is the number 1 itself, which is considered to be non-prime. A positive integer that
is not prime is called composite. Euclid showed that there are infinitely many prime numbers. The prime
and composite sequences begin as follows:
Primes: 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, …
Composites: 1, 4, 6, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 22, 24, 25, 26, 27, 28, …
There are many ways to test a number for primality, but perhaps the simplest is to simply do trial
divisions. Begin by dividing m by 2, and if it divides evenly, then m is not prime. Otherwise, divide by 3,
then 4, then 5, etc. If at any point m is found to be divisible by a number d in the range 2 d m−1, then
halt, and conclude that m is composite. Otherwise, conclude that m is prime. A moment’s thought shows
that one need not do any trial divisions by numbers d which are themselves composite. For instance, if a
trial division by 2 fails (i.e. has non-zero remainder, so m is odd), then a trial division by 4, 6, or 8, or any
even number, must also fail. Thus to test a number m for primality, one need only do trial divisions by
prime numbers less than m. Furthermore, it is not necessary to go all the way up to m−1. One need only
do trial divisions of m by primes p in the range 2 p m . To see this, suppose m >1 is composite.
Then there exist positive integers a and b such that 1 < a < m, 1 < b < m, and m = ab . But if both
a > m and b > m , then ab > m, contradicting that m = ab . Hence one of a or b must be less than
or equal to m .
To implement this process in java you will write a function called isPrime() with the following
signature:
static boolean isPrime(int m, int[] P)
This function will return true or false according to whether m is prime or composite. The array
argument P will contain a sufficient number of primes to do the testing. Specifically, at the time
isPrime() is called, array P must contain (at least) all primes p in the range 2 p m . For instance,
to test m = 53 for primality, one must do successive trial divisions by 2, 3, 5, and 7. We go no further
since 11 > 53 . Thus a precondition for the function call isPrime(53, P) is that P[0] = 2 , P[1] = 3 ,
P[2] = 5, and P[3] = 7 . The return value in this case would be true since all these divisions fail.
Similarly to test m =143 , one must do trial divisions by 2, 3, 5, 7, and 11 (since 13 > 143 ). The
precondition for the function call isPrime(143, P) is therefore P[0] = 2 , P[1] = 3 , P[2] = 5, P[3] = 7 ,
and P[4] =11. The return value in this case would be false since 11 divides 143. Function isPrime()
should contain a loop that steps through array P, doing trial divisions. This loop should terminate when
2
either a trial division succeeds, in which case false is returned, or until the next prime in P is greater
than m , in which case true is returned.
Function main() in this project will read the command line argument n, allocate an int array of length n,
fill the array with primes, then print the contents of the array to stdout according to the format described
below. In the context of function main(), we will refer to this array as Primes[]. Thus array Primes[]
plays a dual role in this project. On the one hand, it is used to collect, store, and print the output data. On
the other hand, it is passed to function isPrime() to test new integers for primality. Whenever
isPrime() returns true, the newly discovered prime will be placed at the appropriate position in array
Primes[]. This process works since, as explained above, the primes needed to test an integer m range
only up to m , and all of these primes (and more) will already be stored in array Primes[] when m is
tested. Of course it will be necessary to initialize Primes[0] = 2 manually, then proceed to test 3, 4, …
for primality using function isPrime().
The following is an outline of the steps to be performed in function main().
Check that the user supplied exactly one command line argument which can be interpreted as a
positive integer n. If the command line argument is not a single positive integer, your program
will print a usage message as specified in the examples below, then exit.
Allocate array Primes[] of length n and initialize Primes[0] = 2 .
Enter a loop which will discover subsequent primes and store them as Primes[1] , Primes[2],
Primes[3] , ..., Primes[n −1] . This loop should contain an inner loop which walks through
successive integers and tests them for primality by calling function isPrime() with appropriate
arguments.
Print the contents of array Primes[] to stdout, 10 to a line separated by single spaces. In other
words Primes[0] through Primes[9] will go on line 1, Primes[10] though Primes[19] will go
on line 2, and so on. Note that if n is not a multiple of 10, then the last line of output will contain
fewer than 10 primes.
Your program, which will be called Prime.java, will produce output identical to that of the sample runs
below. (As usual % signifies the unix prompt.)
% java Prime
Usage: java Prime [PositiveInteger]
% java Prime xyz
Usage: java Prime [PositiveInteger]
% java Prime 10 20
Usage: java Prime [PositiveInteger]
% java Prime 75
2 3 5 7 11 13 17 19 23 29
31 37 41 43 47 53 59 61 67 71
73 79 83 89 97 101 103 107 109 113
127 131 137 139 149 151 157 163 167 173
179 181 191 193 197 199 211 223 227 229
233 239 241 251 257 263 269 271 277 281
283 293 307 311 313 317 331 337 347 349
353 359 367 373 379
%
3
As you can see, inappropriate command line argument(s) generate a usage message which is similar to
that of many unix commands. (Try doing the more command with no arguments to see such a message.)
Your program will include a function called Usage() having signature
static void Usage()
that prints this message to stderr, then exits. Thus your program will contain three functions in all:
main(), isPrime(), and Usage(). Each should be preceded by a comment block giving it’s name, a
short description of it’s operation, and any necessary preconditions (such as those for isPrime().) See
examples on the webpage.
Attempted Solution
class Prime {
public static void main(String[] args) {
int num1 = 0;
int num2 = 0;
int num3;
for (num1 = 1; num1 < 101; num1++)
System.out.println(num1);
for (num2 = 1; num2 < 101; num1++)
System.out.println(num2);
num3 = num2 % num1;
if (num3 == 0)
System.out.println("The prime numbers are " + num1);
else
System.out.println("The prime numbers are " + (num1 += 1));
}
}

Ben, it looks like you are attempting something that is far beyond your current capability. Start with some much simpler problems. Talk to your teacher and consider taking a more rudimentary course. You don't appear to understand either what the program is supposed to do, or how to write a program that might satisfy the requirements, and nothing we say here can overcome that - you have to develop more understanding of math and programming. We're happy to help with that, but just writing your program here won't help you, and you are too far away from a solution for suggestions to help. I'm sorry if this sounds harsh; honestly, I mean it constructively. Please stay with it - but start simpler.

Your example solution doesn't really follow the problem's specification at all. You should focus first on writing the static boolean isPrime(int m, int[] P) method. All that method needs to do is:
Iterate over the contents of P
If an element evenly divides m, m is composite -- return false
If an element's square is greater than m, m is prime -- return true. It sounds like from the problem description this won't ever happen, P will only have the primes from 2 to the one just before crossing the sqrt(m) boundary
If all the elements of P have been tested, m is prime -- return true
After that you can write main to make the primes array and build it up using the described loop, and finally do argument checking and implement the static void Usage() function to call if the arguments are invalid

Related

Concatenation of Consecutive Binary Numbers, Modulo Operation discussion behavior

Here I am contributing the Java Solution for the problem.
Concatenation of Consecutive Binary Numbers:
Given an integer n, return the decimal value of the binary string formed by concatenating the binary representations of 1 to n in order, modulo 10^9 + 7.
class Solution {
public int concatenatedBinary(int n) {
long sum = 0;
for(int i = 1; i <= n; i++){
sum = ((sum << Integer.toBinaryString(i).length()) + i) % 1000000007;
}
return (int) sum;
}
}
Now I have a doubt that is when we are modulating at each step within for loop. It will not impact the result till 1000000007 but after that, it will change the sum variable, and this cycle will repeat. Now, why doesn't this modulo impacting the overall result? Thanks in advance.
Let's take a simpler problem: Take the number 1000, write it as bits, then take the number 1001, write that as bits, concatenate the two, what's that, in decimal?
1000 in bits is 11 1110 1000
1001 in bits is 11 1110 1001
Thus, the answer'd be 1111 1010 0011 1110 1001, or 1025001.
But, let's do a more mathy take on this: "concatenate the two" boils down to: "Shift the bits in the first number to the left to make enough room, then add the second number". And "shift left by X" is the same as 'multiply by 2X'. Just like if I have the number '1234', and I tell you to 'shift that left by 2 spots', it's the same as multiplying by 100: That turns it into 123400, which is 1234*100, and 100 is just 102. So, 'shift left by X spots' is the same as 'multiply by bX' where b is the 'base' of the number system we use; 2 in binary, 10 in decimal.
Thus, a different way to state the same result is: 'Take the number 1000, multiply it by 210, add 1001 to it. Sure enough: 1000 * 2^10 + 1001 is indeed 1025001.
Thus, a single 'loop' in your algorithm is effectively: Take the result we have so far, multiply it by 2 a bunch of times (X times, where X is the position of the highest 1-bit in the number we're processing this loop), then add the new number.
So, it's just multiplication and addition.
Modulo has the property that it is stable for those operations.
Consider basic math: You were probably taught about the number line. A horizontal line, infinite in size.
A modulo system is no different, except the number line is a big loop. It's a circle. In modulo 1000000007 space, the numbers '5 and 6' are just as adjacent as the numbers '0 and 1000000006' are.
Given, on the normal number line, a * b = c, modulo has the property that this also means that (a%Z * b%Z)%Z = c%Z for any Z. The same goes for addition; if a + b = c, then (a%Z + b%Z)%Z = c%Z is also true. You can try a bunch of numbers and witness this, or try to prove this yourself, or search the web for proof of this property.
Example:
12 * 18 = 216
(12%7 * 18%7)%7 = 216%7
Yup, that checks out:
5 * 4 = 20
20%7 = 6.
216%7 is also 6.
Thus:
Your question boils down to a lot of applications of multiplying and addition.
multiply and add translate to modulo math without issue.
Therefore, your algorithm works.

Effiecient Algorithm for Finding if a Very Big Number is Divisible by 7

So this was a question on one of the challenges I came across in an online competition, a few days ago.
Question:
Accept two inputs.
A big number of N digits,
The number of questions Q to be asked.
In each of the question, you have to find if the number formed by the string between indices Li and Ri is divisible by 7 or not.
Input:
First line contains the number consisting on N digits. Next line contains Q, denoting the number of questions. Each of the next Q lines contains 2 integers Li and Ri.
Output:
For each question, print "YES" or "NO", if the number formed by the string between indices Li and Ri is divisible by 7.
Constraints:
1 ≤ N ≤ 105
1 ≤ Q ≤ 105
1 ≤ Li, Ri ≤ N
Sample Input:
357753
3
1 2
2 3
4 4
Sample Output:
YES
NO
YES
Explanation:
For the first query, number will be 35 which is clearly divisible by 7.
Time Limit: 1.0 sec for each input file.
Memory Limit: 256 MB
Source Limit: 1024 KB
My Approach:
Now according to the constraints, the maximum length of the number i.e. N can be upto 105. This big a number cannot be fitted into a numeric data structure and I am pretty sure thats not the efficient way to go about it.
First Try:
I thought of this algorithm to apply the generic rules of division to each individual digit of the number. This would work to check divisibility amongst any two numbers, in linear time, i.e. O(N).
static String isDivisibleBy(String theIndexedNumber, int divisiblityNo){
int moduloValue = 0;
for(int i = 0; i < theIndexedNumber.length(); i++){
moduloValue = moduloValue * 10;
moduloValue += Character.getNumericValue(theIndexedNumber.charAt(i));
moduloValue %= divisiblityNo;
}
if(moduloValue == 0){
return "YES";
} else{
return "NO";
}
}
But in this case, the algorithm has to also loop through all the values of Q, which can also be upto 105.
Therefore, the time taken to solve the problem becomes O(Q.N) which can also be considered as Quadratic time. Hence, this crossed the given time limit and was not efficient.
Second Try:
After that didn't work, I tried searching for a divisibility rule of 7. All the ones I found, involved calculations based on each individual digit of the number. Hence, that would again result in a Linear time algorithm. And hence, combined with the number of Questions, it would amount to Quadratic Time, i.e. O(Q.N)
I did find one algorithm named Pohlman–Mass method of divisibility by 7, which suggested
Using quick alternating additions and subtractions: 42,341,530
-> 530 − 341 = 189 + 42 = 231 -> 23 − (1×2) = 21 YES
But all that did was, make the time 1/3rd Q.N, which didn't help much.
Am I missing something here? Can anyone help me find a way to solve this efficiently?
Also, is there a chance this is a Dynamic Programming problem?
There are two ways to go through this problem.
1: Dynamic Programming Approach
Let the input be array of digits A[N].
Let N[L,R] be number formed by digits L to R.
Let another array be M[N] where M[i] = N[1,i] mod 7.
So M[i+1] = ((M[i] * 10) mod 7 + A[i+1] mod 7) mod 7
Pre-calculate array M.
Now consider the expression.
N[1,R] = N[1,L-1] * 10R-L+1 + N[L,R]
implies (N[1,R] mod 7) = (N[1,L-1] mod 7 * (10R-L+1mod 7)) + (N[L,R] mod 7)
implies N[L,R] mod 7 = (M[R] - M[L-1] * (10R-L+1 mod 7)) mod 7
N[L,R] mod 7 gives your answer and can be calculated in O(1) as all values on right of expression are already there.
For 10R-L+1 mod 7, you can pre-calculate modulo 7 for all powers of 10.
Time Complexity :
Precalculation O(N)
Overall O(Q) + O(N)
2: Divide and Conquer Approach
Its a segment tree solution.
On each tree node you store the mod 7 for the number formed by digits in that node.
And the expression given in first approach can be used to find the mod 7 of parent by combining the mod 7 values of two children.
The time complexity of this solution will be O(Q log N) + O(N log N)
Basically you want to be able to to calculate the mod 7 of any digits given the mod of the number at any point.
What you can do is to;
record the modulo at each point O(N) for time and space. Uses up to 100 KB of memory.
take the modulo at the two points and determine how much subtracting the digits before the start would make e.g. O(N) time and space (once not per loop)
e.g. between 2 and 3 inclusive
357 % 7 = 0
3 % 7 = 3 and 300 % 7 = 6 (the distance between the start and end)
and 0 != 6 so the number is not a multiple of 7.
between 4 and 4 inclusive
3577 % 7 == 0
357 % 7 = 0 and 0 * 10 % 7 = 0
as 0 == 0 it is a multiple of 7.
You first build a list of digits modulo 7 for each number starting with 0 offset (like in your case, 0%7, 3%7, 35%7, 357%7...) then for each case of (a,b) grab digits[a-1] and digits[b], then multiply digits[b] by 1-3-2-6-4-5 sequence of 10^X modulo 7 defined by (1+b-a)%6 and compare. If these are equal, return YES, otherwise return NO. A pseudocode:
readString(big);
Array a=[0]; // initial value
Array tens=[1,3,2,6,4,5]; // quick multiplier lookup table
int d=0;
int l=big.length;
for (int i=0;i<l;i++) {
int c=((int)big[i])-48; // '0' -> 0, and "big" has characters
d=(3*d+c)%7;
a.push(d); // add to tail
}
readInt(q);
for (i=0;i<q;i++) {
readInt(li);
readInt(ri); // get question
int left=(a[li-1]*tens[(1+ri-li)%6])%7;
if (left==a[ri]) print("YES"); else print("NO");
}
A test example:
247761901
1
5 9
61901 % 7=0. Calculating:
a = [0 2 3 2 6 3 3 4 5 2]
li = 5
ri = 9
left=(a[5-1]*tens[(1+9-5)%6])%7 = (6*5)%7 = 30%7 = 2
a[ri]=2
Answer: YES

divide and conquer: computing the time elapsed

I have to do a little assignment at my university:
I have a server that runs 'n' independent services. All these services started at the same time in the past. And every service 'i' writes 'b[i]' lines to a log file on the server after a certain period of time 's[i]' in seconds. The input consist of 'l' the number of lines of the log file and 'n' the number of services. Then we have in the next 'n' lines for every service i: 's[i]' the period as mentioned and 'b[i]' the number of lines the services writes to the log file.
I have to compute from the number of lines in the log file, how long ago, in seconds, the programs all started running. Example:
input:
19 3
7 1
8 1
10 2
Output:
42
I have to use divide and conquer, but I can't even figure out how to split this in subproblems. Also I have to use this function, where ss is the array of the periods of the services and bs the number of lines which each services writes to the log file:
long linesAt(int t, int[] ss, int[] bs) {
long out = 0;
for (int i = 0; i < ss.length; i++) {
// floor operation
out += bs[i] * (long)(t/ss[i]);
}
return out;
ss and bs are basically arrays of the input, if we take the example they will look like this, where the row above is the index of the array:
ss:
0 1 2
7 8 10
bs:
0 1 2
1 1 2
It is easily seen that 42 should be the output
linesAt(42) = floor(42/7)*1+floor(42/8)*1+floor(42/10)*2 = 19
Now I have to write a function
int solve(long l, int[] ss, int[] bs)
I already wrote some pseudocode in brute force, but I can't figure out how to solve this with the divide and conquer paradigm, my pseudocode looks like this:
Solve(l, ss, bs)
out = 0
t = 0
while (out != l)
out = linesAt(t, ss, bs)
t++
end while
return t
I think I have to split l in some way, so to calculate the time for smaller lengths. But I don't really see how, because when you look at this it doesn't seem to be possible:
t out
0..6 0
7 1
8 2
9 2
10 4
11..13 4
14 5
15 5
16 6
17..19 6
20 8
...
40 18
42 19
Chantal.
Sounds like a classic binary search would fit the bill, with a prior step to obtain a suitable maximum. You start with some estimate of time 't' (say 100) and call linesAt to obtain the lines for that t. If the value returned is too small (i.e. smaller than l), you double 't' and try again, until the number of lines is too large.
At this point, your maximum is t and your minimum is t/2. You then repeatedly:
pick t as the point halfway between maximum and minimum
call linesAt(t,...) to obtain the number of lines
if you've found the target, stop.
if you have too many lines, adjust the maximum: maximum = t
if you have too few lines adjust the minimum: minimum = t
The above algorithm is a binary search - it splits the search space in half each iteration. Thus, it is an example of divide-and-conquer.
You are trying to solve an integer equation:
floor(n/7)*1+floor(n/8)*1+floor(n/10)*2 = 19
You can remove the floor function and solve for n and get a lower bound and upper bound, then search between these two bounds.
Solving the following equation:
(n/7)*1+(n/8)*1+(n/10)*2 = 19
n=19/(1/7+1/8+2/10)
Having found n, which range of value m0 will be such that floor (m0 / 7) = floor (n/7)?
floor (n/7) * 7 <= m0 <= (ceiling (n/7) * 7) - 1
In the same manner, calculate m1 and m2.
Take max (mi) as upperbound and min(mi) as lowerbound for i between 1 and 3 .
A binary search at this point will probably be an overkill.

Returning an integer whose digits sum exactly to n

My question is related to digits sum.
In a digit sum system, a digits sum of number 39 = 3 + 9 = 12.
However in my case, I would like to write a method where the user input 12, and the
method will return 39, given that 39 is the smallest number to achieve digits sum of 12.
It will be good if we can discuss this in psuedo-code as I am more interested in learnign to develop a method/algorithm/formula to solve this puzzle.
The hint was given to use a queue. I have also tried the following:
number%9; number/9, which is close but does not seems to work for all cases.
An Example will be:
12%9 = 3
12/9 = 1; if( ans = 1, return 9)
therefore 3 and 9 will be 39. I know I am close but I tried using the same for numbers like 111, and this does not work anymore.
The smallest number is always of the form "x9...9999" where x is a single digit (possibly 0).
All you need to do is find:
The value of x: n % 9
How many 9s there are: n / 9.
For 111:
n % 9 is 3.
n / 9 is 12.
So the answer is 3999999999999.
I think the smallest number n to have a digit sum equal to k will always be of the form
i99999
Where i is some digit.
Using this, you have
i = n % 9
j = floor(n / 9)
Then you construct your number by concatenating i then 9 j times.
For n = 12 this yields 39.
For n = 111 this yields 3999999999999 (the 9 appears twelve times)

Find an integer n > 0 which holds the following three conditions

Some definition for starters: flip(n) is the 180 degree rotation of a seven segment display font number, so a 2 in seven segment font will be flipped to a 2. 0,1,2,5,8 will be mapped to themselfs. 6 -> 9, 9 -> 6 and 3,4,7 are not defined. Therefore any number containing 3,4,7 will not be flippable. More examples: flip(112) = 211, flip(168) = 891, flip(3112) = not defined.
(By the way, I am quite sure that flip(1) should be undefined, but the homework says that flip(168) = 891 so regarding this assignment flip(1) is defined)
The original challenge: Find an integer n > 0 which holds the following three conditions:
flip(n) is defined and flip(n) = n
flip(n*n) is defined
n is divisible by 2011 -> n % 2011 == 0
Our solution which you can find below seems to work, but it does not find an answer at least not for 2011. If I am using 1991 instead (I searched for some "base" number for which the problem could be solved) I am getting a pretty fast answer saying 1515151 is the one. So the basic concept seems to work but not for the given "base" in the homework. Am I missing something here?
Solution written in pseudo code (We have an implementation in Small Basic and I made a multithreading one in Java):
for (i = 1; i < Integer.MaxValue; i++) {
n = i * 2011;
f = flip(n, true);
if (f != null && flip(n*n, false) != null) {
print n + " is the number";
return;
}
}
flip(n, symmetry) {
l = n.length;
l2 = (symmetry) ? ceil(l/2) : l;
f = "";
for (i = 0; i < l2; i++) {
s = n.substr(i,1);
switch(s) {
case 0,1,2,5,8:
r = s; break;
case 6:
r = 9; break;
case 9:
r = 6; break;
default:
r = "";
}
if (r == "") {
print n + " is not flippable";
return -1;
} elseif (symmetry && r != n.substr(l-i-1,1)) {
print n + " is not flip(n)";
return -1;
}
f = r + f;
}
return (symmetry) ? n : f;
}
Heuristically (with admittedly minimal experimentation and going mainly on intuition), it is not so likely you will find a solution without optimising your search technique mathematically (e.g. employing a method of construction to build a perfect square that doesn't contain 3,4,7 and is flippably symmetrical. as opposed to optimising the computations, which will not change the complexity by a noticeable amount):
I'll start with a list of all numbers who satisfy 2 criteria (that the number and it's flip be the same, i.e. flippably symmetrical, and that it be a multiple of 2011), less than 10^11:
192555261 611000119 862956298
988659886 2091001602 2220550222
2589226852 6510550159 8585115858
10282828201 12102220121 18065559081
18551215581 19299066261 20866099802
22582528522 25288188252 25510001552
25862529852 28018181082 28568189582
28806090882 50669869905 51905850615
52218581225 55666299955 58609860985
59226192265 60912021609 68651515989
68828282889 69018081069 69568089569
85065859058 85551515558 89285158268
91081118016 92529862526 92852225826
95189068156 95625052956 96056895096
96592826596 98661119986 98882128886
98986298686
There are 46 numbers there, all flippably symmetrical according to the definition and multiples of 2011, under 10^11. Seemingly multiples of 2011 that satisfy this condition will become scarcer because as the number of digits increases, less of the multiples will be palindromes, statistically.
I.e. for any given range, say [1, 10^11] (as above), there were 46. For the adjacent range of equal width: [10^11+1, 2*10^11], we might guess to find another 46 or thereabouts. But as we continue up with intervals of the same width in higher powers of 10, the number of numbers is the same (because we analyse equal width intervals) although the palindrome condition now falls on more digits because the number of digits increases. So approaching infinity we expect the number of palindromes on any fixed with interval to approach 0. Or, more formally (but without proof) for every positive value N, with probability 0 a given interval (of predetermined width) will have more than N multiples of 2011 that are palindromes.
So the number of palindromes we can find will decrease as an exhaustive search continues. As per the probability that for any found palindrome the square will be flippable, we assume uniform distribution of the squares of palindromes (since we have no analysis to tell us otherwise, and no reason to believe otherwise) and then the probability that any given square of d digits length will be flippable is (7/10)^d.
Let's start with the smallest such square we found
192555261 ^ 2 = 37077528538778121
which is already 17 digits long, giving it a probability of around 0.002 (approx. 1/430) that it's flippably defined. But already by the time we've reached the last on the list:
98986298686 ^ 2 = 9798287327554005326596
which is 24 digits long, and has a probability of less than 1/5000 of being flippably defined.
So as the search continues in higher numbers, the number of palindromes decreases, and the probability that any found palindrome's square is flippable also decreases - a double edged blade.
What's left is to find some sort of ratio of densities and accordingly see how improbable finding a solution is... Although it's clear intuitively that finding a solution gets much less likely probabilistically speaking (which by no means rules out that one or even a large number of solutions exist (possibly an infinite number?)).
Good luck! I hope someone solves this. As with many problems, the solutions are often not as simple as running the algorithm on a faster machine or with more parallelism or for a longer period of time or whatnot, but with a more advanced technique or more inventive methods of attacking the problem, which themselves further the field. The answer, a number, is of much less interest (usually) than the method used to derive it.
You are searching through all of the numbers divisible by 2011, then checking whether they are the flip of themselves. But after you've reached 7 digit numbers the condition that it be a flip of itself is more restrictive than the condition that it be divisible by 2011. So I'd suggest that you instead iterate through all of the numbers that can be constructed without the digits 3, 4, 7, then construct the number that is flip of itself prepended to itself, possibly squishing a middle digit if the middle digits are 11, 22, 55, or 88. Then test for divisibility by 2011, then test whether n*n is flippable.
Be very, very aware of the possibility that n*n will hit integer overflow. By the time you've reached a 5-digit number for the base, your n will be 9 or 10 digits long, and n*n will be 18-21 digits long.
Not necessarily a complete solution, more like thought process which may help you on the way.
n = flip(n) => n is a palindrome (180° rotation in flip()), n consists only of numbers which map to themselves in flip() i.e.: 0, 1, 2, 5, 8
flip(n*n) is defined. Thus n*n may not contain 3, 4, 7
n % 2011 = 0.
n > 0.

Categories