Finding specific number in prime number array - java

I'm trying to find prime numbers with a specific condition in Java.
The challenge is to show all the prime numbers (under 100.000) which contain a '3' four times.
I already have a code which shows all the prime numbers under 100.000, but I can't seem to figure out how to count the ones that contain the number '3' four times.
I can however count all the prime numbers.
Can someone help me with this?
Here's the code I have, where am I going to put the numbers into strings?
package Proeftentamen;
import java.util.regex.*;
/**
*
* #author Stefan
*/
public class Vraag_6 {
/// priemgetallen waar 4x een 3 in voor komt???? wtf...
public static void main(String[] args) {
boolean[] lijst = new boolean[1000000]; // hoeveelheid getallen
vularray(lijst);
lijst = zeef(lijst);
drukaf(lijst);
}
public static void vularray(boolean[] lijst) {
for (int i = 2; i < lijst.length; i++) {
lijst[i] = true;
}
}
public static boolean[] zeef(boolean[] lijst) {
for (int i = 2; i < lijst.length / 2; i++) {
if (lijst[i]) {
for (int j = 2 * i; j < lijst.length; j += i) {
lijst[j] = false;
}
}
}
return lijst;
}
public static void drukaf(boolean[] lijst) {
int count = 0;
for (int i = 2; i < lijst.length; i++) {
if (lijst[i] == true) {
System.out.println(i + " " + lijst[i]);
count++;
}
}
System.out.println("Aantal priemgetallen: " + count);
}
}

This question really sounds like a homework, so you should write down what you have come up with and what you tried so far.
There are a lot of ways to count numbers. Just to give you a clue, you can use the reminder operation (in Java - %):
56 % 10 = 6
25 % 5 = 0
So, when you divide by 10 and use a reminder operation you can get the last digit of your number. Now use a loop and counter and you'll be fine.
Another option (very ugly, so don't really use it :) ) - to turn your number into a String and iterate (loop) over its characters.
Hope this helps and good luck!

This code generate 50 permutation of numbers that has four '3' in it's digits
so check each number that is prime or not
public void generateNumbers() {
StringBuilder s = new StringBuilder();
s.append("3333");
for (int i = 0; i < 5; i++) {
for (int j = 0; j <= 9; j++) {
if (j%3==0) continue;
s.insert(i,String.valueOf(j));
int number=Integer.parseInt(s.toString());
System.out.println(number);
s.delete(i,i+1);
}
}
}

Iterate across each prime number.
For each prime number, convert it to a string using the Integer.toString(int) static method.
With this string, iterate over every character (use a for loop and the non-static method String.charAt(int index)) and count the number of times that method returns '3'. (The character '3', not the String "3").
Unless you have some other purpose for an array of prime-number Strings, don't bother to store them anywhere outside the loop.

Please refer below code to validate all such prime numbers.
void getPrimes(int num ,int frequency,char digit) {
int count = 0;
String number=Integer.toString(num);
for (int i = 0; i < number.length(); i++) {
if (count < frequency) {
if (number.charAt(i) == digit)
count++;
}
if (count == frequency)
{
System.out.println(number);
return ;
}
}
}

Using the primes function from an exercise on the Sieve of Eratosthenes, as well as the digits and filter functions from the Standard Prelude, this Scheme expression finds the seven solutions:
(filter
(lambda (n)
(= (length
(filter
(lambda (d) (= d 3))
(digits n)))
4))
(primes 100000))
The outer filter runs over all the primes less than 100000 and applies the test of the outer lambda to each. The inner filter computes the digits of each prime number and keeps only the 3s, then the length function counts them and the equality predicate keeps only those that have 4 3s. You can run the program and see the solution at http://codepad.org/e98fow2u.

you only have at most five digits, four of which must be 3. So what can you say about the remaining digit?
It's not hard to just write out the resulting numbers by hand, and then test each one for primality. Since there are no more than 50 numbers to test, even the simplest trial division by odds will do.
But if you want to generate the numbers programmatically, just do it with 5 loops: add 10,000 to 03333 9 times; add 1,000 to 30333 9 times; add 100 to 33033 9 times; etc. In C++:
int results[50];
int n_res = 0;
int a[5] = {13333, 31333, 33133, 33313, 33331};
for( int i=0, d=10000; i<5; ++i, d/=10)
for( int j=1; j<9; ++j, a[i]+=d )
if( is_prime(a[i]) )
results[n_res++] = a[i];

Related

Why can I not enter large values (e.x. n = 100000) in this program that calculates all prime numbers from 0 to n inclusive?

I'm fairly new to coding, I just started learning Java this semester. I was messing around and created this java program that finds all prime numbers from 0 to n inclusive. It uses modulus and a nested for loop and outputs it in an arraylist. Now, I tested it with n = 5, n= 100, n = 1000 and n= 10000 and it worked completely fine and gave me accurate results, however when I inputted n = 100000, the console simply was blank and didnt give me any output at all. I realize that with large numbers it will take longer, so I was expecting to wait for it to number-crunch it all, but it just "gave up".
Is this the result of some calculation time-out? Is there a overide so I can calculate this with larger numbers? I realize this is not the most efficient code (i.e. there are calculations in the for loops that may be done twice) but thats not what the issue is here. The issue is why does a certain number stop output and is there any way to bypass this.
I put my code below, separated into two blocks because I have it in two different classes.
Thanks :)
General.java
import java.util.ArrayList;
import java.util.Scanner;
public class General
{
public static void main(String[] args)
{
Scanner number = new Scanner(System.in);
ArrayList<Integer> result = new ArrayList<Integer>();
System.out.print("What is the number you want to find all the primes that are smaller than it: ");
long n = number.nextInt();
PrimeNumberSeeker pNS = new PrimeNumberSeeker();
result = pNS.PrimesFromZero(n);
for (int m = 0; m < result.size(); m++)
{
System.out.print(result.get(m));
if (m+1 >= (result.size()))
System.out.print(".");
else
System.out.print(", ");
}
}
}
PrimeNumberSeeker.java
import java.util.ArrayList;
public class PrimeNumberSeeker
{
ArrayList<Integer> primes = new ArrayList<Integer>();
public ArrayList<Integer> PrimesFromZero(long n)
{
for (int i = 0; i <= n; i++) //selects all numbers from 0 - n inclusive
{
int check = 0;
//System.out.println(i);
for (int j = 1; j <= i; j++) //we make sure not to include 1 and itself (n)
{
if (i % j == 0)
check += 1;
//System.out.println(i + " " + j);
}
if (check == 2)
primes.add(i);
}
return primes;
}
}
It is just a problem of computational complexity, your algorithm could be optimized under different aspects to lower its complexity:
you don't need the check variable
you can limit the j range from 2 to sqrt(i)
if i%j==0 you can stop your investigation on i: it is not prime
Other advice:
always use parenthesis
use lowerCamelCase for functions' names
don't mix ints and longs, for your purposes ints are enough
This algorithm is not the best but works well with numbers up to 10.000.000 (or something more):
class PrimeNumberSeeker {
public ArrayList<Integer> primesFromZero(int n) {
ArrayList<Integer> primes = new ArrayList<Integer>();
for (int i = 1; i <= n; i++) {
boolean isPrime = true; // say your number is prime (we'll verify)
for (int j = 2; j <= Math.sqrt(i); j++) { // verify if it really is
if (i % j == 0) {
isPrime = false; // it isn't
break; // no more checks are needed, go out from this for cycle
}
}
if (isPrime) { // if isPrime is still true then i is prime
primes.add(i);
}
}
return primes;
}
}
Your program is running. I just tested it. You can visualize the progress by printing every found prime imediatly:
if (check == 2) {
primes.add(i);
System.out.println(i);
}
What you can also see, is that the progress becomes slower the bigger the numbers get. That is because your rumtime complexity is O(n^2) (squared). For each number you test each number that is lower. That means if you go from n=10.000 to n=100.000 your programm needs far more than 10 times the time.
For prime calculation check out the algorithm Sieve of Eratosthenes. This is far more efficient in terms of calculation time.

Why does this for-loop only run once?

The goal of my code: To be able to write a program where I can enter in any number int as a command-line argument and displays how many digits in the integer number are 7s.
My problem is that I don't understand why my code only runs through the for-loop once. I inserted the system.out.println(sevens); to see how many times this loop works when I compile with a random number like 456789.
I could only think of a for-loop to use for this one and fixed some simple mistakes in the beginning. I also checked my brackets
public class TestingSevens {
public static void main(String[] args) {
int sevens = Integer.parseInt(args[0]);
int count = 0;
for (int i = 0; i < args.length; i++) {
if (sevens%10 == 7) {
count += 1;
}
sevens = sevens/10;
System.out.println(sevens);
}
System.out.println(count);
}
}
The result of inputting a number like 456789 is "45678" for the first print and the second print is "0." I know the number for some reason only runs through the loop once since it cuts off the last number before jumping out of the loop to print the count...any advice?
I presume you want to iterate over each digit of sevens. Since sevens initialized from args[0], the loop limit should match and look at args[0].length() rather than args.length.
for (int i = 0; i < args[0].length(); i++)
An alternate way to write the loop is to iterate until sevens reaches 0. That lines up better with the loop body; both use the same variable.
while (sevens > 0) {
if (sevens%10 == 7) {
count += 1;
}
sevens /= 10;
System.out.println(sevens);
}
Your code has logic errors, so to check if the iterated number is number 7 you need to turn the number into a string and check if the character is the desired character using: numberString.charAt(index)
Below is the corrected code:
public static void main(String[] args) {
int sevens = Integer.parseInt(args[0]);
String numberString = String.valueOf(sevens);
int count = 0;
for (int i = 0; i < numberString.length(); i++) {
char c = numberString.charAt(i);
if (c == '7') {
count += 1;
}
System.out.println("Input number: " + sevens);
}
System.out.println("Count of 7 numbers: " + count);
}

I am stuck at implementing Radix sort recursively

I'm required to implement a programm that sorts numbers ranging from 0 to 99999 recursively (this is basically Radix sort). The process itself is kinda simpel: The user types in an array that contains those numbers in the main method. Then, the main method calls for the sort-method where I create a two-dimensional array named 'space' with 10 rows and 1 column. Then, I divide every number in the array by the digit, which would be 10.000 in the first run. So, for example, 23456 / 10000 = 2,3456 = 2 (in java), hence, the programm puts this number in space[2][0], so in the second row. Then, we take this entire row and extend it, which is done in the putInBucket-method. We do this in order to make sure that we can put another number into the same row.
We do this for every number that is inside the 'numbers'-array. Then, we want to work with these rows and sort them again by the same principle, but now we take a look at the second digit. We want to do this from left to right, not from right to left. So, if our second row would look like this
[23456, 24567],
we'd want to compare the 3 and the 4, which leads to 23456 < 24567.
We do this with the help of the recursive call at the end of the sort method. Now, this is where I am lost. I simply don't know how to manipulate the digit-variable in order to be able to work with the second, third, ... digit of each number. In the first run, as you see, this can be simply done by dividing through 10.000, but I didn't find a way to go further from here.
Please note: Yes, this is a homework question, hence, I'm only allowed to use primitives here. We didn't go through stuff like math.pow(...) yet. Thanks in advance!
public static int[] sort(int[] numbers, int digit) {
if (numbers.length == 0)
return numbers;
int[][]space = new int[10][1];
int i, j = 0;
for (j = 0; j < numbers.length; j++) {
i = numbers[j] / digit;
space[i][0] = numbers[j];
space[i] = putInBucket(space[i], numbers[j]);
}
for (i = 0; i < space[i].length; i++) {
sort(space[i], digit); //not sure how to work with digit here
}
return ... //not sure what to return here
}
private static int[] putInBucket(int[] bucket, int number) {
int[] bucket_new = new int[bucket.length+1];
for (int i = 1; i < bucket_new.length; i++) {
bucket_new[i] = bucket[i-1];
}
return bucket_new;
}
public static void main (String [] argv) {
int[] numbers = IO.readInts("Numbers: ");
int digit = 10000;
int[] bucket = sort(numbers, digit);
}
To extract the last digit, the remainder operator % is your friend:
123 % 10 == 3
if you haven't covered the % operator yet, you can use
123 % 10 == 123 - (123 / 10 * 10) == 3
To extract another digit, you can first move it to the end with /:
123 / 10 == 12
12 % 10 == 2
You can therefore extract an arbitrary digit using
(number / mask) % 10
where mask ∈ {..., 10000, 1000, 100, 10, 1}.
Extra credit
Radix sort is usually implemented in the binary number system instead because a binary digit (or a sequence thereof) can be extracted without performing a division, which is more efficient:
x % 16 == x & 15;
x \ 16 == x >> 4;
Also, if you are implementing this for real, you'd need a more efficient way to grow buckets (your implementation takes O(n) to add a single element to the bucket, adding n elements to the bucket therefore takes O(n^2), which makes your radix sort slower than insertion sort). Dynamic arrays are usually implemented with a more efficient geometric expansion.
This should work:
public static int[] sort(int[] numbers, int digit) {
if (numbers.length == 0 || digit <= 0)
return numbers;
int[][]space = new int[10][10];
int[] len = new int[10];
int i, j = 0;
for (j = 0; j < numbers.length; j++) {
i = (numbers[j] / digit) % 10;
len[i]++;
for (int k = len[i] - 1; k > 0; k--) {
space[i][k] = space[i][k - 1];
}
space[i][0] = numbers[j];
}
for (i = 0; i < 10; i++) {
int[] bucket = new int[len[i]];
for (int k = 0; k < len[i]; k++)
bucket[k] = space[i][k];
space[i] = sort(bucket, digit / 10);
}
int k = 0;
for (i = 0; i < 10; i++) {
for (j = 0; j < len[i]; j++) {
numbers[k] = space[i][j];
k++;
}
}
return numbers;
}
a) Firstly, space is allocated as having only one column. So, space[i] = bucket will not work.
Instead, you could declare it as int[10][10]. (Note: it will only support max of 10 values in one bucket). Or you may allocate new arrays programmatically. Or of course, a List might be better suited.
b) i = (numbers[j] / digit) % 10;
To get the required digit only. For eg: if the number is 12130, and digit = 1000, we want to set i to 2, not 12.
c) putInBucket replaced with an in-place loop.
d) For each bucket of space, we sort it by one digit lower by calling sort recursively.
e) Finally, the result to be returned (numbers), can be created by looping through space from digit 0 to 9.
Note:
This solution could probably be made better.

Create all possible binary permutations with a given number of ones in Java

I want to find all possible binary permutations with a given number of ones in Java:
x is the desired number of ones in each sequence
n is the desired length of each sequence
For an example:
x=2, n=4
Output: 1100, 0011, 1010, 1001, 0101, 0110
I'm searching for an elegant and fast way to do this. Can you help me?
I've tested eboix solution in Print list of binary permutations but it is unfortunately too slow because the algorithm in this example is searching for all 2^n binary permutations.
I want to find sequences with a length of 50 or 100.
First of all, you're missing 0110 as an output case.
It's fairly intuitive that there are n choose x possibilities. You're finding all valid arrangements of x identical items among n total slots. So you can find the total number of sequences in O(1).
As a hint, try simply finding all permutations of the bitstring consisting of x ones followed n - x zeros.
To specifically address the problem, try creating a recursive algorithm that decides at every ith iteration to either include 1 or 0. If 1 is included, you need to decrement the count of 1's available for the rest of the string.
Actually, there may be an elegant way, but no fast way to do this. The number of string permutations is given by the binomial coefficient (see https://en.wikipedia.org/wiki/Binomial_coefficient). For example, x=10, n= 50 gives over 10 million different strings.
Here is just a basic version that will generate your desired output. Please work on it to make it more accurate/efficient -
This will not generate all the combinations, but you will get the idea of how to do it. Off course, for all the possible combinations generated by this, you will have to generate all the other possible combinations.
public class Test {
static int iter = 0;
public static void main(String args[]){
int n = 50;
int x = 5;
byte[] perms = new byte[n];
for(int i=0; i<x; i++){
perms[i] = 1;
}
print(perms);
for(int j=x-1; j>=0; j--){
for(int i=1; i<(n/2-j); i++){
iter++;
swap(perms, j, i);
}
}
}
public static void swap(byte[] perms, int pos, int by){
byte val = perms[pos+by];
perms[pos+by] = perms[pos];
perms[pos] = val;
print(perms);
val = perms[pos+by];
perms[pos+by] = perms[pos];
perms[pos] = val;
}
public static void print(byte[] perms){
System.out.println("iter = "+iter);
for(int i=0; i<perms.length; i++){
System.out.print(perms[i]);
}
System.out.println();
for(int i=perms.length-1; i>=0; i--){
System.out.print(perms[i]);
}
System.out.println();
}
}
Another inspiration for you. A dirty version which works. It allocates extra array space (you should adjust size) and uses String Set at the end to remove duplicates.
public static void main(String[] args) {
int x = 2;
int n = 4;
Set<BigInteger> result = new LinkedHashSet<>();
for (int j = x; j > 0; j--) {
Set<BigInteger> a = new LinkedHashSet<>();
for (int i = 0; i < n - j + 1; i++) {
if (j == x) {
a.add(BigInteger.ZERO.flipBit(i));
} else {
for (BigInteger num : result) {
if (num != null && !num.testBit(i) && (i >= (n - j) || num.getLowestSetBit() >= i-1))
a.add(num.setBit(i));
}
}
}
result = a;
}
String zeros = new String(new char[n]).replace("\0", "0");
for (BigInteger i : result) {
String binary = i.toString(2);
System.out.println(zeros.substring(0, n - binary.length()) + binary);
}
}
EDIT: changed the primitives version to use BigInteger instead to support larger n,x values.

Efficient way of generating all combinations of 12 numbers that add to 100 in Java [duplicate]

This question already has an answer here:
How to iterate through array combinations with constant sum efficiently?
(1 answer)
Closed 9 years ago.
I have 12 products at a blend plant (call them a - l) and need to generate varying percentages of them, the total obviously adding up to 100%.
Something simple such as the code below will work, however it is highly inefficient. Is there a more efficient algorithm?
*Edit: As mentioned below there are just too many possibilities compute, efficiently or not. I will change this to only having a maximum of 5 or the 12 products in a blend and then running it against the number of ways that 5 products can be chosen from the 12 products.
There is Python code that some of you have pointed to that seems to work out the possibilities from the combinations. However my Python is minimal (ie 0%), would one of you be able to explain this in Java terms? I can get the combinations in Java (http://www.cs.colostate.edu/~cs161/Fall12/lecture-codes/Subsets.java)
public class Main {
public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {
for(int a=0;a<=100;a++){
for(int b=0;b<=100;b++){
for(int c=0;c<=100;c++){
for(int d=0;d<=100;d++){
for(int e=0;e<=100;e++){
for(int f=0;f<=100;f++){
for(int g=0;g<=100;g++){
for(int h=0;h<=100;h++){
for(int i=0;i<=100;i++){
for(int j=0;j<=100;j++){
for(int k=0;k<=100;k++){
for(int l=0;l<=100;l++){
if(a+b+c+d+e+f+g+h+i+j+k+l==100)
{
System.out.println(a+" "+b+" "+c+" "+d+" "+e+" "+f+" "+g+" "+h+" "+i+" "+j+" "+k+" "+l);
}}}}}}}}}}}}}
}
}
Why make it so difficult. Think simple way.
To explain the scenario simpler, consider 5 numbers to be generated randomly. Pseudo-code should be something like below.
Generate 5 random number, R1, R2 ... R5
total = sum of those 5 random number.
For all item to produce
produce1 = R1/total; // produce[i] = R[i]/total;
Please, don't use nested for loops that deep! Use recursion instead:
public static void main(String[] args) {
int N = 12;
int goal = 100;
generate(N, 0, goal, new int[N]);
}
public static void generate(int i, int sum, int goal, int[] result) {
if (i == 1) {
// one number to go, so make it fit
result[0] = goal - sum;
System.out.println(Arrays.toString(result));
} else {
// try all possible values for this step
for (int j = 0; j < goal - sum; j++) {
// set next number of the result
result[i-1] = j;
// go to next step
generate(i-1, sum + j , goal, result);
}
}
}
Note that I only tested this for N = 3 and goal = 5. It absolutely makes no sense to try generating all these possibilities (and would take forever to compute).
Let's take your comment that you can only have 5 elements in a combination, and the other 7 are 0%. Try this:
for (i = 0; i < (1<<12); ++i) {
if (count_number_of_1s(i) != 5) { continue; }
for (j = 0; j < 100000000; ++j) {
int [] perc = new int[12];
int val = j;
int sum = 0;
int cnt = 0;
for (k = 0; k < 12; ++k) {
if (i & (1 << k)) {
cnt++;
if (cnt == 5) {
perc[k] = 100 - sum;
}
else {
perc[k] = val % 100;
val /= 100;
}
sum += perc[k];
if (sum > 100) { break; }
}
else { perc[k] = 0; }
}
if (sum == 100) {
System.out.println(perc[0] + ...);
}
}
}
The outer loop iterates over all possible combinations of using 12 items. You can do this by looping over all numbers from 1:2^12, and the 1s in the binary representation of that number are the elements you're using. The count_number_of_1s is a function that loops over all the bits in the parameter and returns the number of 1s. If this is not 5, then just skip this iteration because you said you only want at most 5 mixed. (There are 792 such cases).
The j loop is looping over all the combinations of 4 (not 5) items from 0:100. There are 100^4 such cases.
The inner loop is looping over all 12 variables, and for those that have a 1 in their bit-position in i, then it means you're using that one. You compute the percentage by taking the next two decimal digits from j. For the 5th item (cnt==5), you don't take digits, you compute it by subtracting from 100.
This will take a LONG time (minutes), but it won't be nearly as bad as 12 nested loops.
for(int a=0;a<=100;a++){
for(int b=0;b<=50;b++){
for(int c=0;c<=34;c++){
for(int d=0;d<=25;d++){
for(int e=0;e<=20;e++){
for(int f=0;f<=17;f++){
for(int g=0;g<=15;g++){
for(int h=0;h<=13;h++){
for(int i=0;i<=12;i++){
for(int j=0;j<=10;j++){
for(int k=0;k<=10;k++){
for(int l=0;l<=9;l++){
if(a+b+c+d+e+f+g+h+i+j+k+l==100)
{
// run 12 for loops for arranging the
// 12 obtained numbers at all 12 places
}}}}}}}}}}}}}
In Original approach(permutation based), the iterations were 102^12 = 1.268e24. Even though the 102th iteration was false, it did check the loop terminating condition for 102th time.
So you had 102^12 condition checks in "for" loops, in addition to "if" condition checks 101^12 times, so in total, 2.4e24 condition checks.
In my solution(combination based),No of for loop checks reduces to 6.243e15 for outer 12 loops, &
if condition checks = 6.243e15.
Now, the no of for loops(ie inner 12 for loops) for every true "if" condition, is 12^12 = 8.9e12.
Let there be x number of true if conditions. so total condition checks
=no of inner for loops*x
= 8.9e12 * x + 6.243e15
I'm not able to find the value of x. however, I believe it wouldnt be large enough to make total conditon checks greater than 2.4e24

Categories