I am struggling to understand why code wouldn't work. According to the truth table/logic gates for AND and OR https://en.wikipedia.org/wiki/Truth_table I would assume that I would be able to have an if statement inside the for-loop such that (p < 2 || p % i == 0) would work for finding prime numbers but it fails when considering negative numbers.
I know that if you if take out the p < 2 and write it as an if statement outside this for-loop it works, but if the p < 2 is inside the for-loop it does not work. Why is this so?
public class test {
public static void main(String [] args) {
System.out.println("Hello World!");
int a = 7;
System.out.println("A is Prime: " + isPrime(a));
System.out.println();
int b = 4;
System.out.println("B is Prime: " + isPrime(b));
System.out.println();
int c = -7;
System.out.println("C is Prime: " + isPrime(c));
System.out.println();
int d = 53;
System.out.println("D is Prime: " + isPrime(d));
}
public static boolean isPrime(int p) {
for (int i = 2; i < p; i++) {
if (p < 2 || p % i == 0) {
return false;
}
}
return true;
}
}
Because for p < 2, the body of the for loop is never performed. Indeed:
for (int i = 2; i < p; i++) {
// ...
}
If p = 2, then it initializes i = 2, and then checks i < p which fails, and hence the body is never executed. It skips the for loop, and thus returns true.
We can fix it by performing a check before (or after) the for loop, and even boost the performance of the loop slighly:
public static boolean isPrime(int p) {
if(p <= 2) {
return p == 2;
}
if(p % 2 == 0) {
return false;
}
for (int i = 3; i*i <= p; i += 2) {
if (p % i == 0) {
return false;
}
}
return true;
}
We can simply return false first for all values less than 2, and true for 2. Furthermore we only need to iterate up to √p, since if there is a value j larger than √p that divides p, then there is a smaller value i = p/j that is smaller than √p that will already be checked. We furthermore only need to check odd numbers, since even numbers are already implied by the division by 2.
You may want to invest in Math.abs(int):
public static boolean isPrime(int p) {
p = Math.abs(p);
for (int i = 2; i < p; i++) {
...
This will ensure that p is always non-negative, and your initial assumptions about how the loop should behave are justified.
Related
public class StairCase {
public static int Solution(int n) {
int sum, count = 0;
//Funtion to calculate stair case and use factorial because a solution can have many ways.
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= n; j++) {
for (int k = 0; k <= n; k++) {
sum = i + (j * 2) + (k * 3);
if (sum == n) {
count = count + (fact.fact1(i + j + k) / (fact.fact1(i) * fact.fact1(j) * fact.fact1(k)));
}
}
}
/*logic behind this funtion is that like we have to find no of arrangement abbbccde can we written so we write (8!/(3!*2!))
so after getting like ijk= 1,2,3 I rearranged them in that man ways
(i+j+k)!/i!*j!k! !=factorial/
}
return count;
}
public static void doTestPass() {
boolean result = true;
result = result && (Solution(3) == 4);
result = result && (Solution(4) == 7);
result = result && (Solution(11) == 504);
result = result && (Solution(12) == 927);
result = result && (Solution(13) == 1705);
//working fine till 13 not after that
System.out.println(Solution(14));
System.out.println(Solution(20));
System.out.println(Solution(21));
//14--3127 20--68603 21--94351(orignal ans-- 3136,121415,223317)
if (result) {
System.out.println("All Test Cases Passed");
} else {
System.out.println("Test Case Failed");
}
}
public static void main(String[] Args) {
doTestPass();
}
public class fact
{
static int fact1(int n)
{
//this funtion is to create factorial
int res = 1;
for (int i = 2; i <= n; i++)
{
res = res * i;
}
return res;
}
}
}
The problem has to do with using primitive integers for your factorial method and overflowing the integer limit of 2,147,483,647.
Take a look at trial runs of your factorial code below:
fact1(12) outputs 479001600 which is correct for 12!
fact1(13) outputs 1932053504 which is not 13! which should be 6227020800
This means when you execute fact.fact1(i) in your code, it will be outputting the wrong answer for any value greater than 12. This would require you to rework the data structure you use to hold these big numbers to BigInteger.
The reworked fact method would look like this:
BigInteger fact1(int n) {
// this funtion is to create factorial
BigInteger res = BigInteger.ONE;
for (int i = 2; i <= n; i++) {
res = res.multiply(BigInteger.valueOf(i));
}
return res;
}
With the output of fact1(13) being the correct value of 6227020800 now.
You will need to rework the other aspects of your code now with BigInteger, but you should understand now what your issue was.
I want to write a little program which is able to find the first 10 digit long prime number out of the euler number.
The number on the 99th place is the number I am searching for, but the isPrim() method does not respond correctly. Do you see what went wrong?
My Code
public class Main {
public static final String e = "27182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274274663919320030599218174135966";
public static void main(String[] args) {
System.out.println(e);
for (int i = 0; i < e.length() - 10; i++) {
String str = e.substring(i, i + 10);
long num = Long.parseLong(str);
boolean isPrim = isPrim(num);
if (isPrim == true) {
System.out.println("First prime: " + num);
break;
}
System.out.println(i + " " + str + " " + isPrim);
}
}
public static boolean isPrim(long number) {
if (number % 2 == 0) {
return false;
}
for (int j = 3; j * j < number; j+=2) {
if (number % j == 0) {
return false;
}
}
return true;
}
}
Should be j * j <= number, otherwise you will treat squares of primes as primes. I.e. your method says that 9 is prime, because there are no dividers less than sqrt(9).
Also, your code will probably find prime that is shorter than 10 digits, because it checks all 10-digits substrings of E, including those with leading zeros, such as 0452353602.
Also, you need to change type of j to long to avoid overflow.
Given a range of [1, 1000000000] we need to find prime numbers and all the digits of the prime number must be odd. (Example: 23 is not okay, 31 is okay)
If we go on by looping through each number and checking if it is prime etc, it is very slow. Is there a way to make this close to O(N) ?
I tried to eliminate as much as possible by looking at digits first. But after eliminating numbers with even digits the prime test is too slow.
for all numbers in [1, N]
check all digits, if any even digit, continue
check primality (this step is very slow)
And the primality test should not be very complex (probabilistic etc. is not possible, it must be possible to implement in a few minutes). The one I use is:
private static boolean isPrime(int n) {
boolean isPrime = true;
for (int divisor = 2; divisor <= n / 2; divisor++) {
if (n % divisor == 0) {
isPrime = false;
break;
}
}
return isPrime;
}
Maybe there is a trick to ensure a quick primality test but I couldn't find. Any suggestions? Thanks for reading.
You don't need to check all milliard numbers. Generate all numbers with only odd digits - there are at most 5^9~2 millions of them. Exclude those ending with 5 and not generate numbers divisible by 3 (in the moment of the last digit generation)
Then check these numbers for primality. Note that loop limit might be sqrt(n)
Ideone
class Ideone
{
static int oddcnt;
public static void checkprime(int x) {
for (int i=3; i <= Math.sqrt(x); i +=2)
if ((x % i) == 0)
return;
oddcnt++;
}
public static void genodd(int x, int curlen, int maxlen) {
x *= 10;
for (int i=1; i<10; i+=2) {
int nx = x + i;
checkprime(nx);
if (curlen < maxlen)
genodd(nx, curlen + 1, maxlen);
}
}
public static void main (String[] args) throws java.lang.Exception
{
genodd(0, 1, 8);
System.out.println(oddcnt);
}
}
The best way I can think of is to run a Prime Sieve of Eratosthenes to find all the primes in the range (0; sqrt(1000000000)) - which is around (0, 31622) - and time complexity O(n*log(log(n))) where n=31622. We will need those prime for a faster primality test.
Then, just loop through each number with odd digits - there are 5^10 = 9765625 ~ 10000000 such numbers. You saved 1000 times compared to iterating through all number in the original range.
The primality test using the primes we found in step 1 can be fast, as you only need to check with primes < sqrt(n), and you already have the primes. Even for the largest number in the range which is 999999999, the number of candidate primes is just 3432.
The following is a Java implementation
public class Execute {
private ArrayList<Long> primes = new ArrayList<>();
#org.junit.Test
public void findOddDecimalPrimes() {
primeSieve(32000);
System.out.println(primes.size());
for (int i = 0; i < 9765625; i++) {
String inBase5 = convertFromBaseToBase(i);
long evenDec = convertToOddDecimal(inBase5);
if (isPrime(evenDec)) {
System.out.println(evenDec);
}
}
}
private String convertFromBaseToBase(long i) {
return Long.toString(i, 5);
}
private long convertToOddDecimal(String str) {
StringBuilder s = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
s.append(1 + 2 * Integer.parseInt("" + str.charAt(i)));
}
return Long.parseLong(s.toString());
}
private boolean isPrime(long n) {
for (int i = 0; i < primes.size(); i++) {
if (primes.get(i) * primes.get(i) > n) break;
long divisor = n / primes.get(i);
if (divisor * primes.get(i) == n) return false;
}
return true;
}
/**
* References: www.geeksforgeeks.org
*/
private void primeSieve(int n)
{
// Create a boolean array "prime[0..n]" and initialize
// all entries it as true. A value in prime[i] will
// finally be false if i is Not a prime, else true.
boolean prime[] = new boolean[n+1];
for(int i=0;i<n;i++)
prime[i] = true;
for(int p = 2; p*p <=n; p++)
{
// If prime[p] is not changed, then it is a prime
if(prime[p] == true)
{
// Update all multiples of p
for(int i = p*p; i <= n; i += p)
prime[i] = false;
}
}
for (int i = 2; i < prime.length; i++) {
if (prime[i]) this.primes.add(Long.valueOf(i));
}
}
}
If your numbers are in order, you can optimize your isPrime function.
Here is a js sample version.
var primes = [];
function checkDigits(n) {
while(n > 1) {
var d = n % 10;
if ( d % 2 == 0) { return false; }
n = parseInt(n/10,10);
}
return true;
}
function isPrime(n) {
for(var i = 1; i < primes.length; i++) {
if(n % primes[i] == 0) {
return false;
}
}
var lastPrime = primes.length > 2 ? primes[primes.length - 1] : 1;
var inc = 2;
for(var i = lastPrime + inc; i < Math.sqrt(n); i += inc) {
if(n % i == 0) {
return false;
}
}
primes.push(n);
return true;
}
for(var i = 1; i < 100; i++) {
if(checkDigits(i) && isPrime(i)) {
console.log(i);
}
}
This is an open question in math and computer science in general.
In a nutshell no, there is no know way to solve that problem in O(1) to get your loop running in O(N) over the whole range.
If you solve that, dont tell anyone, and go get rich by breaking most of the encryptions today that use large prime numbers.
What you could do though, is make the loop over the devisor a bit smaller by useing sqrt(n).
That will bring that inner loop down from O(N^2) to O(sqrt(N))
And the whole complexity from O(N^2) to O(N*sqrt(N))=O(N^(3/2))
Anotger optimization would be to check the odd digits first beforre doing the complex Prime calculation
sorry for the "fix my code" post
EDIT: related more to syntax of a for loop than prime numbers, also solved now.
My task is to take an int from the console and print out (on separate lines) all the prime numbers from 1 to n inclusive.
My method starts at n, checks if its prime, then increments n down by one and loops until n=2.
To check if a number is prime I run a loop, checking is the remainder of diving the number by x is equal to zero, with x starting at 2 and stopping at root(n).
Now this all works in theory, and reading my code I don't see where it goes wrong.
public class Prime {
public static boolean isPrime(int n) {
boolean result = true;
for (int x = 2; x>=sqrt(n); x++) {
if ((n % x) == 0) {
result = false;
break;
} else {
x++;
}
}
return result;
}
public static void main(String[] args) {
Scanner intIn = new Scanner(System.in);
int i = intIn.nextInt();
while (i>=2) {
if (isPrime(i)) {
System.out.println(i);
i--;
} else {
i--;
}
}
}
}
For example an input of 10 will return 10 (along with 9,8,7,6,5,3), even though isPrime() checks if 10 % 2 == 0, then sets result to false.
What am I missing here??
Again I apologise for the annoying (slightly duplicate) question.
The condition in the for loop is the condition to continue the loop, not the condition to stop it. You need to replace >= with <=:
for (int x = 2; x<=sqrt(n); x++) {
// Here -----^
You are incrementing x twice, and the loop's condition should be x<=sqrt(n) :
for (int x = 2; x>=sqrt(n); x++) { // here
if ((n % x) == 0) {
result = false;
break;
} else {
x++; // and here
}
}
The correct logic should be:
public static boolean isPrime(int n) {
for (int x = 2; x<=sqrt(n); x++) {
if ((n % x) == 0) {
return false;
}
}
return true;
}
In the loop x must be less than or equal to
So change the expression for (int x = 2; x>=sqrt(n); x++) to
for (int x = 2; x<=sqrt(n); x++)
Try it this way, it's much clearer and concise.
public static boolean isPrime(int candidate) {
int candidateRoot = (int) Math.sqrt((double) candidate);
return IntStream.rangeClosed(2, candidateRoot)
.noneMatch(i -> candidate % i == 0); // return true if the candidate
// isn't divisible for any of the
// numbers in the stream
}
public static void main(String[] args) {
Scanner intIn = new Scanner(System.in);
int i = intIn.nextInt();
List<Integer> primeList = IntStream.rangeClosed(2, i)
.filter(candidate -> isPrime(candidate))
.boxed()
.collect(toList());
System.out.println(primeList);
// Another way
Map<Boolean, List<Integer>> primeAndNotPrimeMap = IntStream.rangeClosed(2, i)
.boxed()
.collect(partitioningBy(candidate -> isPrime(candidate)));
System.out.println(primeAndNotPrimeMap);
}
i want to create java program for a number when divided by 2, 3, 4, 5, 6 leaves a remainder of 1 but it is divided by 7 completely.
I tried this logic
for (int a=1;a<=500;a++){
if (a%2==1 && a%3==1 && a%4==1 && a%5==1 && a%6==1 && a%7==0)
and it works fine but I want it by this logic
for (int a=1;a<=500;a++){
for(int b=2;b<=6; b++){
if (a%b==1 && a%7==0){
System.out.println(a);
help me if it is possible to create in this way?Thank you
You could count how many of the iterations pass your test, like this:
for (int a=1; a<=500; a++) {
int flag=0;
for (int b=2; b<=6; b++) {
if (a%b == 1) {
flag += 1;
} else {
break;
}
}
if (flag == 5) {
if (a%7 == 0) {
System.out.println("Value "+a);
}
}
}
If any of the tests fail, flag will be less than 5 at the end of the loop. If you change the number of tests, you will need to remember to update that magic number.
you could name the outer loop and check and continue it in the inner loop like this:
public static void main(String[]args){
// That´s your mainloop
mainLoop: for (int a=1; a<=500; a++){
for(int b=2; b<7;++b) {
// If anything doesn´t leave a remainder of 1 youll continue with the mainloop here
if(a%b != 1) {
continue mainLoop;
}
}
// 2-6 had a remainder of 1, so just check if the number is dividible by 7 now, if so print it.
if(a%7 ==0) {
System.out.println(a);
}
}
}
It can make things easier if you split your code into functions. Start with the outer (a) loop:
public static void main(String[] args)
{
for (int a = 1; a <= 5000; ++a)
if (test(a))
System.out.println(a);
}
We've deferred the actual logic to the test() function, and assumed we'll define that later.
Now write the test. As soon as any of the sub-tests fail, we can return false immediately. If all tests pass and we reach the end, then we must return true:
static boolean test(int x)
{
// i is the candidate factor
for (int i = 2; i <= 7; ++i) {
int expected = i==7 ? 0 : 1;
if (x%i != expected)
return false;
}
return true;
}
We can simplify further through use of a magic number to encode the different values of expected:
static boolean test(int x)
{
for (int i = 2; i <= 7; ++i)
if (x%i != 301%i)
return false;
return true;
}
You can iterate over all the b values, and set a flag if any of them fail the test. If the flag is unset at the end of the loop, you know they all passed:
for (int a=1; a<=500; a++) {
int flag = 0;
for (int b=2; b<=6; b++) {
if (a%b!=1 || a%7!=0) {
// doesn't satisfy the condition, so flag it
flag = 1;
break; // exit the inner loop
}
}
if (flag == 0)
// If we got here without setting flag, it means that all of the
// 'b' values passed the test.
System.out.println(a);
}