for (int i = lo; i <= hi; i++)
{
boolean isPrime = true; // each value of i starts out assuming it IS prime
// Write a loop below that divides i by 2,3,4,5 etc upto i/2
// If at any time you find a divisor that evenly divides i
// Then set isPrime to false
/* your prime checking loop HERE */
for (int j = 2; j <= hi / 2; j++)
{
if (i % j == 0)
{
isPrime = false;
}
}
// DO NOT REMOVE OR MODIFY LINE BELOW
if ( isPrime )
System.out.print( i + " " );
}
Okay, here is the code I currently have and i'm assuming the problem lies within. The program takes a text input file and sets the first value as lo (in the text demo I have, the lo = 3 and hi = 73.) For whatever reason, the only numbers that are output as 'prime' start at 41 and then go totally fine after that. I have no idea why the first half of the numbers aren't being outputted at all.
Keep in mind I must use for loops for this project, methods and such are not in the 'vocabulary' at the moment. Trying to keep it simple. I'd appreciate the help guys.
Read the comment block again. It says to loop until i/2. You're looping until hi/2.
The issue is that you keep using modulus of the number on itself.
3 % 3 is zero, but 3 is prime.
the prime checking loop, choose one:
for (int j = 2; j < i / 2; j++)
or
for (int j = 2; j <= sqrt(i); j++)
Related
How do I count up from 1 to a given number in triangular fashion?
Attempt
while (numbers <= number) {
System.out.println(numbers);
numbers++;
}
Target Output
1
1 2
1 2 3
I recommend you read about looping in Java, this is a base to start from.
int num = 10;
for(int i = 1; i < num; i++)
{
for(int j = 1; j <= i; j++)
{
System.out.print(j + " ");
}
System.out.print("\n");
}
This should provide the triangular structure you are looking for. Definitely do take a look at the link above. Since you are new to Java, you should take a walk through this code before simply copying it. Really try to see how it works and more importantly, why it works.
In Self tests of chapter 2 Schildt's Java Beginners Guide there is an exercise to write a program that finds all of the prime numbers between 2 and 100.
The correct answer that the author gives is as follows:
class Prime {
puЬlic static void main(String args[]) {
int i, j;
boolean isprime;
for(i=2; i < 100; i++) {
isprime = true;
for (j=2; j <= i/j; j++)
if((i%j) == 0) isprime = false;
if (isprime)
System.out.println(i +" - is a prime number.");
}
}
}
I can not understand two things
1) Condition of second FOR loop:
j <= i/j;
Is this some kind of mathematical algorithm for finding primes?
My version of the condition looks like
j < i;
2) If in the condition of the second loop put i <= j instead of i < j, then the output of the program will be empty. Why?
Thank you for help!
Explanation of second question:
When I solved this problem, relying on "my" version of the definition of a prime number, my code looked like this:
for(i=2; i < 100; i++) {
isprime = true;
for (j=2; j <= i; j++)
if((i%j) == 0) isprime = false;
if (isprime)
System.out.println(i +" - is a prime number.");
}
Pay attention to the condition of the second cycle:
i <= j. Less or equal
If you rely on "my" definition of a prime number, then the equal sign in the condition should be.
Try running the program. The output will be empty.
But if the condition removes the equal sign for (j=2; j < i; j++), the program will work correctly.
what is the reason?
Let's focus onto these for loops.
for(i=2; i < 100; i++) {
isprime = true;
for (j=2; j <= i/j; j++)
if((i%j) == О) isprime = false;
if (isprime)
System.out.println(i +" - is a prime number.");
}
The first loop iterates through all numbers you want to test. Easy enough to understand, it simply tells "I want to perform the following test on all numbers from 2 to 100".
for (j=2; j <= i/j; j++)
if((i%j) == О) isprime = false;
Now this loop is pure math.
Mathematically, a prime number :
is a natural number greater than 1 that cannot be formed by
multiplying two smaller natural numbers.
(source : Wikipedia)
You therefore iterate through all numbers that, multiplied, would form i.
But do you really need to ?
If, as an example, i = 3*25, do you need to iterate all the way to 25 to know i is not a prime number ?
The answer is obviously no, since after testing for j=3, you already know i is composite.
Mathematically, multiple algorithms exist to check whether a number is prime or composite., but a reasonably correct way to do it is to check whether a number is a multiple of any number between 2 and its own square root. You are performing a rounded-up version of this.
Checking for all numbers between 2 and i is redundant for reasons cited above.
EDIT : Answer to 2)
When using
for (j=2; j <= i; j++)
if((i%j) == 0) isprime = false;
you are telling the compiler to stop looping after performing the test on j==i. Of course, when j equals i, (i%j) == 0 always evaluates to true.
In non-informatical terms, you are checking whether a number is composed of any number, excluding 1, including itself, whereas you should check whether it is composed of any number, excluding 1 and itself.
This is due to Java's way of implementing for loops : they stop when the middle condition evaluates to false.
I have debugged this code and it appears to run a for loop even though the termination condition is met.
This program takes two types of input:
Line 1 - How many data points there are following (N)
Lines 2 to N - The data points
The program should then print the smallest difference between all of the data points.
So, for instance, a sample input would be (on separate lines): 3 5 8 9
There are 3 data points (5 8 9), and the smallest difference is between 8 and 9, so the program should return 1.
I am trying to build the program in a way in which the data points are populated into an array at the same time as the comparisons are made. Obviously I could separate those concerns, but I am experimenting. Here it is:
package com.m3c.vks.test;
import java.util.*;
import java.io.*;
import java.math.*;
class Solution {
public static void main(String args[]) {
Scanner in = new Scanner(System.in);
int N = in.nextInt(); //How many data points there will be
int strengthArray[] = new int[N]; //Initialise the array to be of length = N, the first input line
int tempStrengthDifference=99999; //junk difference set arbitrarily high - bad practice I know
int lowestStrengthDifference=99999;
for (int i = 0; i < N; i++) //Go through all elements of array
{
strengthArray[i] = in.nextInt(); //read a value for the ith element
System.out.println("i: " + i); //test
if (i > 0) //do not execute the next for loop if i = 0 as cannot evaluate sA[-1]
{
for (int j = i - 1; j < 1; j--) // **this is line 20** from wherever the array has populated up to, work backwards to compare the numbers which have been fed in thus far
{
System.out.println("j: " + j); //test
tempStrengthDifference = Math.abs(strengthArray[i] - strengthArray[j]); //finding the difference between two values
if (tempStrengthDifference < lowestStrengthDifference) //store the lowest found thus far in lowestSD
{
lowestStrengthDifference = tempStrengthDifference;
}
}
}
}
System.out.println(lowestStrengthDifference);
}
}
Everything is fine up until when i = 1 on line 20. At this point, j is set to i - 1 = 0 and the difference is found. However, when the for loop comes back around again, the termination condition of j < 1 is not met, and instead the loop continues to set j = -1, at which point it throws an out of bounds error as it clearly cannot evaluate strengthArray[-1]
Any ideas? Thanks
Have a look at your loop: for (int j = i - 1; j < 1; j--)
You start with j = 0 when i == 1 and thus j < 1 is ok.
The next iteration has j = -1 (0-1) and hence you get the problem.
Do you mean to use j >= 0 as your loop condition instead? Note that the second parameter is not a termination condition but a continuation condition, i.e. as long as that condition is met the loop will execute.
The reason behind your failure is the inner loop variable change.
When i=1, j=0 and after executing the loop once, J is decremented, and thus j becomes - 1. The condition j<1 is satisfied since you have written j--, change it to j++ and you should be fine.
I am attempting to create a fillArray method that fills and array with 20 random values and sums every third value. I am getting an ArrayExceptionOutOfBounds at line 21 which is when the method is called. Through the debug I have watched the array fill with proper values and the sum properly calculated. I am wondering what the error is.
public static void fillArray(){
//adding up A[0], A[3], A[6}, ...
double[] A = new double[20];
for(int i = 0; i < A.length; i++)
A[i] = Math.random();
double sum = 0;
int k = 0;
do{
k += 3;
sum += A[k];
}while(k < 20);
System.out.println("sum = " + sum);
}
Again I am looking to determine the reason for the error not necessarily a way to fix it.
Here is your problem:
do{
k += 3;
sum += A[k];
}while(k < 20);
K will be equal to 0, then 3, then 6, etc, up until it reaches 21 and then you try and access A[21] which is out of bounds.
This is because when k = 18 on the 6th iteration of the while loop, (k < 20) is true and therefore the while loop continues and adds another 3 to k making it 21. After that, the while loop stops as k is not less than 20 anymore leaving k with a value of 21.
You're getting the error because you're hitting 21 on a array with the size of 20. To fix:
do{
k += 3;
if(k <= 20){
sum += A[k];
}
}while(k < 20);
Your second loop, where you calculate the sum, is a do/while loop, meaning the condition will always get checked after the loop body is executed. You count k up in steps of 3, meaning it will reach 21 at some point before the while (k < 20) condition returns false, resulting in your error.
I think the problem is that k is incrementing and being used as an array index, before the <20 test.
something like this might work better:
for (int k = 0; k < 20; k = k + 3) {
sum += A[k];
}
In general, i think the do while construct here is a bit of unnecessary complexity. The version above is easier to read and is a more common pattern.
With the current logic, k will be 3,6,9,12,15,18 and 21. The last value is responsible for the out of bounds exception. Your loop will not stop at 18 as it is smaller than 20. You could resolve the bug by changing your code to this:
do{
k += 3;
sum += A[k];
}while(k < 18);
You increment the array index before using it. So you are not only going beyond the array index in last pass, you are also not adding the element at 0 index.
for (int i = 0; i < 3; ++i) {
for (int k = 0; k < 7; ++k) {
for (int h = i; h < 4 + i; ++h) {
result = state.getAt(k, h);
if (result == 1) {
++firstpl;
}
if (result == 2) {
++secondpl;
}
if (firstpl > 0 && secondpl > 0) {
break;
}
//y = k;
}
if (firstpl == 0 && secondpl == 0) {
break;
} else if (firstpl > secondpl) {
score += firstpl * firstpl;
//if(state.getHeightAt(y)-3 < 3) score += 3+firstpl*2;
} else {
score -= secondpl * secondpl;
//if(state.getHeightAt(y)-3 < 3) score -= 3+secondpl*2;
}
firstpl = 0;
secondpl = 0;
}
}
basically I have a 7 by 6 grid. I am going through 7 columns and looking at every 4 consecutive blocks vertically. Since there is 6 blocks upward. There is 3 four consecutive block for each column. State.getAt(k,h) takes in a x and y and returns a value.
I don't think you can improve on this, unless you can figure out an alternative representation for this "state" that allows this computation to be performed incrementally.
And since you have failed to properly explained what the state or the calculation actually mean, it is difficult for anyone but you to figure out whether an alternative approach is even feasible. (And I for one am not going to attempt to reverse engineer the meaning from your code.)
OK. For Connect4, the win / lose is a line of 4 checkers horizontally, vertically or diagonally in the 7x6 grid. So what you could do is represent the score-state as an array of counters, corresponding to each of the columns, rows and diagonals in which a winning line could be made. (7 + 5 + 4 + 4 = 20 of them => 20 counters) Then construct a static mapping from an (x,y) position to the indexes of lines that pass through that. When you add a checker at point (x,y) you look up the counters and increment them. When you remove a checker ... decrement.
I'm not sure how that relates to your existing scoring function ... but then I don't see how that function relates to a strategy that would win the game. Either way, you could potentially use the approach above to calculate scores incrementally.