How can I complete my code about the Sieve of Erathostenes? - java

It's about finding the prime numbers from 2 to 1000 using this method but I can't get the solution and I've been thinking and trying to solve this issue for three days. I'm desperate for help so if anyone can help me I would really appreciate it
I tried another for loop and an if statement since my teacher said that I only need another loop or just one more code line but I can't seem to get the solution. I'm really bad at this so I'm sorry if my code seems cringeworthy
public class Practica {
public static void main(String []
byte []marcado = new byte [1000];
for (int i = 2; i < 1000; i++);
if (marcado[i] == 1) {
for (int j = 2; i*j < 1000; j++) {
marcado [i*j] = 0;
}
}
I expect to have all the prime numbers printed

Give it a shot:
public static void main(String[] args) {
byte[] marcado = new byte[1000];
for (int i = 2; i*i < 1000; i++) {
if (marcado[i] == 0) {
for (int j = 2; i * j < 1000; j++) {
marcado[i * j] = 1;
}
}
}
// print the numbers:
for (int i = 1; i < 1000; i++) {
if(0 == marcado[i]){
System.out.print(" " + i);
}
}
}
Besides removing syntax errors, I reversed the logic such that marcado[i]==0 indicates a prime and noneprime otherwise.
The other possibility based on your aproach would be to initialize all the array elements with "1"(eg. with fill);

Related

Not sure how to print this?

I'm supposed to modify code that I've written for an assignment:
public class ToweringStrings2 {
public static final int H = 2; //constant for the tower
public static void main(String[] args) {
drawTowers(H);
}
public static void drawTowers(int H) {
for (int i = 1; i <= H; i++) {
System.out.print(" ");
for (int j = 1; j <= i; j++) {
System.out.print("+");
}
System.out.println();
}
for (int k = 1; k <= H + 2; k++) {
System.out.print("#");
}
System.out.println();
}
}
so that it prints sequential numbers starting at 1, instead of +s. Currently, it prints:
This is what the new code is supposed to print:
and so on.
For some reason I'm just really stuck and can't figure it out.
You can create an extra variable to print and increment
Like that:
public class ToweringStrings2 {
public static final int H = 10; //constant for the tower
public static void main(String[] args) {
drawTowers(H);
}
public static void drawTowers(int H) {
int count = 1;
for (int i = 1; i <= H; i++) {
System.out.print(" ");
for (int j = 1; j <= i; j++) {
System.out.print(count++ + " ");
}
System.out.println();
}
for (int k = 1; k <= H + 2; k++) {
System.out.print("# ");
}
System.out.println();
}
}
Step 1 - make it print a variable rather than a hard-coded string. Instead of System.out.print("+"), System.out.print(counter).
For this to work you need to have declared counter somewhere in the same scope as the statement: int counter = 0.
Run this. You'll see it print "0" where it used to print "+".
Step 2 - Now you need to make counter increase by one every time it prints.
Find the right place to add:
counter = counter + 1;
Run it and see it work.
Further notes
A more concise alternative to var = var + 1 is var++.
You can even do this at the same time as you use the value of a variable:
System.out.println(var++);
This can be used to express some algorithms very concisely -- but it can be confusing for beginners, so feel free to not use this technique until you're comfortable with the basics.

Calculate factorial of 50 using array only in java

I'm a total beginner of java.
I have a homework to write a complete program that calculates the factorial of 50 using array.
I can't use any method like biginteger.
I can only use array because my professor wants us to understand the logic behind, I guess...
However, he didn't really teach us the detail of array, so I'm really confused here.
Basically, I'm trying to divide the big number and put it into array slot. So if the first array gets 235, I can divide it and extract the number and put it into one array slot. Then, put the remain next array slot. And repeat the process until I get the result (which is factorial of 50, and it's a huge number..)
I tried to understand what's the logic behind, but I really can't figure it out.. So far I have this on my mind.
import java.util.Scanner;
class Factorial
{
public static void main(String[] args)
{
int n;
Scanner kb = new Scanner(System.in);
System.out.println("Enter n");
n = kb.nextInt();
System.out.println(n +"! = " + fact(n));
}
public static int fact(int n)
{
int product = 1;
int[] a = new int[100];
a[0] = 1;
for (int j = 2; j < a.length; j++)
{
for(; n >= 1; n--)
{
product = product * n;
a[j-1] = n;
a[j] = a[j]/10;
a[j+1] = a[j]%10;
}
}
return product;
}
}
But it doesn't show me the factorial of 50.
it shows me 0 as the result, so apparently, it's not working.
I'm trying to use one method (fact()), but I'm not sure that's the right way to do.
My professor mentioned about using operator / and % to assign the number to the next slot of array repeatedly.
So I'm trying to use that for this homework.
Does anyone have an idea for this homework?
Please help me!
And sorry for the confusing instruction... I'm confused also, so please forgive me.
FYI: factorial of 50 is 30414093201713378043612608166064768844377641568960512000000000000
Try this.
static int[] fact(int n) {
int[] r = new int[100];
r[0] = 1;
for (int i = 1; i <= n; ++i) {
int carry = 0;
for (int j = 0; j < r.length; ++j) {
int x = r[j] * i + carry;
r[j] = x % 10;
carry = x / 10;
}
}
return r;
}
and
int[] result = fact(50);
int i = result.length - 1;
while (i > 0 && result[i] == 0)
--i;
while (i >= 0)
System.out.print(result[i--]);
System.out.println();
// -> 30414093201713378043612608166064768844377641568960512000000000000
Her's my result:
50 factorial - 30414093201713378043612608166064768844377641568960512000000000000
And here's the code. I hard coded an array of 100 digits. When printing, I skip the leading zeroes.
public class FactorialArray {
public static void main(String[] args) {
int n = 50;
System.out.print(n + " factorial - ");
int[] result = factorial(n);
boolean firstDigit = false;
for (int digit : result) {
if (digit > 0) {
firstDigit = true;
}
if (firstDigit) {
System.out.print(digit);
}
}
System.out.println();
}
private static int[] factorial(int n) {
int[] r = new int[100];
r[r.length - 1] = 1;
for (int i = 1; i <= n; i++) {
int carry = 0;
for (int j = r.length - 1; j >= 0; j--) {
int x = r[j] * i + carry;
r[j] = x % 10;
carry = x / 10;
}
}
return r;
}
}
How about:
public static BigInteger p(int numOfAllPerson) {
if (numOfAllPerson < 0) {
throw new IllegalArgumentException();
}
if (numOfAllPerson == 0) {
return BigInteger.ONE;
}
BigInteger retBigInt = BigInteger.ONE;
for (; numOfAllPerson > 0; numOfAllPerson--) {
retBigInt = retBigInt.multiply(BigInteger.valueOf(numOfAllPerson));
}
return retBigInt;
}
Please recall basic level of math how multiplication works?
2344
X 34
= (2344*4)*10^0 + (2344*3)*10^1 = ans
2344
X334
= (2344*4)*10^0 + (2344*3)*10^1 + (2344*3)*10^2= ans
So for m digits X n digits you need n list of string array.
Each time you multiply each digits with m. and store it.
After each step you will append 0,1,2,n-1 trailing zero(s) to that string.
Finally, sum all of n listed string. You know how to do that.
So up to this you know m*n
now it is very easy to compute 1*..........*49*50.
how about:
int[] arrayOfFifty = new int[50];
//populate the array with 1 to 50
for(int i = 1; i < 51; i++){
arrayOfFifty[i-1] = i;
}
//perform the factorial
long result = 1;
for(int i = 0; i < arrayOfFifty.length; i++){
result = arrayOfFifty[i] * result;
}
Did not test this. No idea how big the number is and if it would cause error due to the size of the number.
Updated. arrays use ".length" to measure the size.
I now updated result to long data type and it returns the following - which is obviously incorrect. This is a massive number and I'm not sure what your professor is trying to get at.
-3258495067890909184

Sudden infinite loop above certain input argument?

While learning Java I'm redoing some of the Project Euler problems.
This is about Problem 14 - Longest Collatz sequence: https://projecteuler.net/problem=14
My programm runs just fine for a lower CEILING like 1000, but when executed like posted it loops infinitely, I think? What goes wrong here?
public class Test {
public static void main(String[] args) {
int tempMax = 0;
final int CEILING = 1_000_000;
for (int j = 1; j < CEILING; ++j) {
tempMax = Math.max(tempMax, collatzLength(j));
}
System.out.println(tempMax);
}
static int collatzLength(int n) { //computes length of collatz-sequence starting with n
int temp = n;
for (int length = 1; ; ++length) {
if (temp == 1)
return length;
else if (temp % 2 == 0)
temp /= 2;
else
temp = temp * 3 + 1;
}
}
}
Calling System.out.println(collatzLength(1000000)); seperately works just fine so I think we can rule an error here out.
You should use long instead of int. The int overflows while doing your calculations in collatzLength and that causes the infinite loop. From the problem description:
NOTE: Once the chain starts the terms are allowed to go above one million.
The number causing the problem: 113383
The long version gives a result, which is still incorrect because you are printing the length of the longest chain, but you need the number which produces the longest chain.
public static void main(String[] args)
{
int tempMax = 0;
final int CEILING = 1_000_000;
for (int j = 1; j < CEILING; ++j)
{
tempMax = Math.max(tempMax, collatzLength(j));
}
System.out.println(tempMax);
}
static int collatzLength(long n)
{
long temp = n;
for (int length = 1;; ++length)
{
if (temp == 1)
return length;
else if (temp % 2 == 0)
temp /= 2;
else
temp = temp * 3 + 1;
}
}

How do I trim the leading zeros in an array of digits without using an arraylist in java?

I have an array made that represents digits and I am trying to make a method so that if there are zeros in front of the first significant digit I want to trim them, I understand you can't re size arrays so I have created a new array, but my code doesn't seem to run correctly?
Here is my code I can't figure out what is wrong I've tried everything: (I put stars around the error** It gives an arrayoutofbounds error **)
package music;
import java.util.Random;
/**Music Array
*
* #author Ryan Klotz
* #version February 3, 2015
*/
public class Music
{
private int length; // length of the array
private int numOfDigits; // number of actual digits in the array
int[] musicArray;
/**Explicit Constructor
* #param x The length of the array
*/
public Music(int x)
{
length = x;
musicArray = new int[length];
Random rand = new Random();
numOfDigits = rand.nextInt(length);
int posOrNeg; // determines positive or negative sign
int digit;
for (int i = 0; i <= numOfDigits; i++)
{
digit = rand.nextInt(10);
posOrNeg = rand.nextInt(2);
if (posOrNeg == 0)
{
digit *= -1;
musicArray[i] = digit;
}
else
{
musicArray[i] = digit;
}
}
}
public void trimLeadingSilence(Music x)
{
while (x.musicArray[0] == 0)
{
int[] newMusicArray;
int count = 0;
**while (x.musicArray[count] == 0)**
{
count++;
}
if (count == x.numOfDigits)
{
newMusicArray = new int[1];
newMusicArray[0] = 0;
x.numOfDigits = 1;
x.musicArray = newMusicArray;
}
else
{
newMusicArray = new int[x.numOfDigits - count];
for (int i = 0; i <= x.numOfDigits - count; i++)
{
newMusicArray[i] = x.musicArray[i + count];
}
x.numOfDigits -= count;
x.musicArray = newMusicArray;
}
}
}
}
i <= x.numOfDigits - count should use < instead. But Arrays.copyOfRange is probably a better solution.
for (int i = 0; i <= numOfDigits; i++)
Should be
for (int i = 0; i < numOfDigits; i++)
Currently you are generating 1 more digit than numOfDigits is. This will not give you any exceptions in any case since randInt(length) will be in range of 0 and length - 1.
while (x.musicArray[count] == 0)
{
count++;
}
Will throw an exception if all values in array are 0.
while (count < x.musicArray.length && x.musicArray[count] == 0){
count++;
}
Will fix that for you.
for (int i = 0; i <= x.numOfDigits - count; i++)
Will also throw you ArrayIndexOutOfBoundsException so you should fix it to:
for (int i = 0; i < x.numOfDigits - count; i++)
Anyway, this is very inefficient since if you have 10 "0" values at the start you are creating 10 new arrays. Take a look at Arrays.copyOfRange method, you should be able to do the same job in less than 10 lines of code.
Inside your for loop, use i < x.numOfDigits - count (you were using <=).
That will solve the problem.

Prime generating number finder not producing correct output

I'm working on this problem:
Consider the divisors of 30: 1,2,3,5,6,10,15,30.
It can be seen that for every divisor d of 30, d+30/d is prime.
Find the sum of all positive integers n not exceeding 100 000 000
such that for every divisor d of n, d+n/d is prime.
and I thought for sure I had it, but alas, it's apparently giving me the wrong answer (12094504411074).
I am fairly sure my sieve of Eratosthenes is working (but maybe not), so I think the problem is somewhere in my algorithm. It seems to get the right answer for n = 30 (1+2+6+10+22+30 = 71 - is this correct?), but as numbers get larger, it apparently stops working.
Here is my Java code:
import java.util.HashSet;
public class Generators {
static HashSet<Integer> hSet = new HashSet<Integer>();
public static void main(String[] args) {
// TODO Auto-generated method stub
int n = 100000000;
sieveErat(n + 1); //Fill a hashSet with prime numbers
System.out.println("Sieve complete");
int check = 0;
long sum = 3;
for(int i = 2; i <= n; i++){
int numDivisors = 0;
int numPrimeChecks = 0;
boolean done = false;
if(!hSet.contains(i+1)){ //i+1 must be a prime number for i to be prime generating
continue;
}
else{
for(int j = 2; j < i/2; j++){
if(i%j == 0){
numDivisors++;
check = j + i/j;
if(hSet.contains(check)){
done = true;
numPrimeChecks++;
}
}else{
break;
}
}
if(numPrimeChecks == numDivisors && done){
sum += i;
}
}
}
System.out.println(sum);
}
public static void sieveErat(int N){
boolean[] isPrime = new boolean[N + 1];
for (int i = 2; i <= N; i++) {
isPrime[i] = true;
//count++;
}
// mark non-primes <= N using Sieve of Eratosthenes
for (int i = 2; i*i <= N; i++) {
// if i is prime, then mark multiples of i as nonprime
// suffices to consider mutiples i, i+1, ..., N/i
if (isPrime[i]) {
for (int j = i; i*j <= N; j++) {
isPrime[i*j] = false;
// count--;
}
}
}
for(int i = 2; i < isPrime.length; i++){
if(isPrime[i]){
hSet.add(i);
}
}
// System.out.println(count);
}
}
The maths of your sieve looks fine to me. I hacked it around to use a BitSet which is much more space efficient. Is 5761455 primes below 100,000,000 correct?
Once I got your code working I got the same figure you get (12094504411075) what figure should you be getting?
I think this bit is wrong (I have changed the variable names to match the question for clarity)
for(int d = 2; d < Math.sqrt(n+3); d++) {
if (n % d == 0) {
numDivisors++;
int check = d + n / d;
if (primes.get(check)) {
// **** What does done mean??? ****
//done = true;
numPrimeChecks++;
} else {
// **** Added! Got a divisor that did not check. No point in going on.
break;
}
} else {
// **** Why break here??? ****
//break;
}
}
NB I have edited this code to reflect what we finally decided was a correct solution.
Why are you breaking out of the d loop as soon as you hit a d that does not divide n? Surely that cannot be right.
However, I think you can break out of the d loop when you have a divisor that does not check.
Also, what is your intended functionality of done? It seems to have no real function.
And, why do you start sum at 3?
Removing the break I now get the value 1739023853139. Is this correct?
Added
Here's my sieve. Identical to yours but builds a BitSet which is a much more efficient structure than a HashSet in this case:
public static BitSet sieveOfEratosthenes(int n) {
BitSet isPrime = new BitSet(n);
// Iniially all numbers are prime.
for (int i = 2; i <= n; i++) {
isPrime.set(i);
}
// mark non-primes <= N using Sieve of Eratosthenes
for (int i = 2; i * i <= n; i++) {
// if i is prime, then mark multiples of i as nonprime
// suffices to consider mutiples i, i+1, ..., N/i
if (isPrime.get(i)) {
for (int j = i; i * j <= n; j++) {
isPrime.clear(i * j);
}
}
}
//System.out.println("Found " + isPrime.cardinality() + " primes");
return isPrime;
}

Categories