count the odd numbers in a specified range - java

How do I a get the counter to count the odd number under 100 in this program?
public class checkpassfail {
public static void main(String[] args) {
int sum =0;
double avr;
int lower = 1;
int uper = 100;
int num=lower;
int counter =0;
while( num <= uper){
sum= sum+(num+=3);
counter+=3;
}
System.out.println("the sum of these nubers is\t" +sum);
System.out.println(counter);
double s =(double)sum;
avr =s/counter;
System.out.println("the average of these nubers is \t"+avr);
}

What do you actually want to do?
If I'm not wrong you want to find odd numbers in between lower_bound and upper_bound.
int lower_bound = 0, upper_bound = 10;
ArrayList<Integer> odds = new ArrayList<Integer>();
while(lower_bound < upper_bound)
{
if(lower_bound % 2 == 1)
odds.add(lower_bound);
lower_bound++;
}
// Number of odd numbers found
int numberOfOddsFound = odds.size();

Welcome to StackOverflow :)
Using the for-loop, you calculate these aggregated values with:
final int lower = 1; // Lower bound
final int upper = 100; // Upper bound
int sum = 0; // Default sum
int count = 0; // Default count
double average = Double.NaN; // Default average
int i = lower; // Init the "runnig" variable
while (i <= upper){ // Until the upper bound is reached, do:
sum += i; // Add the number to the overall sum
count++; // One more number has been used - count it
i += 2; // Add 2 since you mind odd values only
}
average = sum / count; // Calculate the average
// And enjoy the results below
System.out.println("Count: " + count);
System.out.println("Sum: " + sum);
System.out.println("Average: " + average);
There also other ways of using the formulas to calculate these characteristics of a regular sequence of numbers or with Stream-API using IntStream.range(..) which allows calculating the aggregation values directly. However, in the beginning, stick with the for-loop.

You don't have to do all of this I guess. If you already know the highest value and the lowest value, and you want to count how many odd numbers between that range, you can code it like below.
int odd_count = (upper + 1) / 2 - lower / 2;
public class checkpassfail {
public static void main(String[] args) {
int lower = 1;
int upper = 100;
int odd_count = (upper + 1) / 2 - lower / 2;
System.out.println("Odd numbers count = "odd_count);
}
}
This will print Odd numbers count = 50.

Related

Finding the minimum sum and maximum sum of a list of integers in an array

I am currently working on a HackerRank practice question and I only pass 5 test cases and I have no idea why. I've thought of all edge cases that I can think of myself but I fail most test cases.
Problem:
Given five positive integers, find the minimum and maximum values that can be calculated by summing exactly four of the five integers. Then print the respective minimum and maximum values as a single line of two space-separated long integers.
Example -
The minimum sum is 1 + 3 + 5 + 7 = 16 and the maximum sum is 3 + 5 + 7 + 9 = 24. The function prints
16 24
This is my solution so far:
public static void miniMaxSum(List<Integer> arr) {
// Write your code here
Collections.sort(arr);
int max = 0;
int min = 0;
int sum = 0;
int smallest = arr.get(0);
int largest = arr.get(4);
for (int i=0; i<arr.size(); i++) {
sum += arr.get(i);
}
min = sum - largest;
max = sum - smallest;
System.out.print(min+ " " + max);
}
I have no idea what test cases I'm failing since it doesn't tell me. I've tried arrays with duplicates, massive numbers, unsorted, and it all gives me expected answer. Please help!
Use long datatype because there is possibility of Integer overflowing or use 16 bit Integer.
public static void miniMaxSum(List<Integer> arr) {
// Write your code here
Collections.sort(arr);
long max = 0;
long min = 0;
long sum = 0;
long smallest = arr.get(0);
long largest = arr.get(4);
for (int i=0; i<arr.size(); i++) {
sum += arr.get(i);
}
min = sum - largest;
max = sum - smallest;
System.out.print(min+ " " + max);
}
}

Reducing the time complexity/Optimizing the solution

The motto is to find the sum of all the multiples of 3 or 5 below N.
Here's my code:
public class Solution
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int t = in.nextInt();
long n=0;
long sum=0;
for(int a0 = 0; a0 < t; a0++)
{
n = in.nextInt();
sum=0;
for(long i=1;i<n;i++)
{
if(i%3==0 || i%5==0)
sum = sum + i;
}
System.out.println(sum);
}
}
}
It's taking more than 1sec to execute for some of the test cases. Can anyone please help me out so as to reduce the time complexity?
We can find the sum of all multiples of number d that are below N as a sum of an arithmetic progression (their sum is equal to d + 2*d + 3*d + ...).
long multiplesSum(long N, long d) {
long highestMultiple = (N-1) / d * d;
long numberOfMultiples = highestMultiple / d;
return (d + highestMultiple) * numberOfMultiples / 2;
}
Then the result will be equal to:
long resultSum(long N) {
return multiplesSum(N, 3) + multiplesSum(N, 5) - multiplesSum(N, 3*5);
}
We need to subtract multiplesSum(N, 15) because there are numbers that are multiples of both 3 and 5 and we added them twice.
Complexity: O(1)
You can't reduce the time complexity in this case as there are still O(N) of each set of numbers. However you can reduce the constant multiplier by using integer division:
static int findMultiples(int N, int s)
{
int c = N / s, sum = 0;
for (int i = 0, k = s; i < c; i++, k += s)
sum += k;
return sum;
}
This way you only loop through the multiples themselves instead of the whole range [0, N].
Note that you will need to do findMultiples(N, 3) + findMultiples(N, 5) - findMultiples(N, 15), to remove the duplicated multiples of both 3 and 5. The number of loops is therefore N/3 + N/5 + N/15 = 0.6N instead of N.
EDIT: in general the solution for an arbitrary number of divisors is sum(findMultiples(N,divisor_i) - findMultiples(N,LCM(all_divisors)); however it is only worth doing this if sum(1/divisor_i) + 1/LCM(all_divisors) < 1, otherwise there will be more loops. Luckily this will never be true for 2 divisors.
The sum of all numbers from 1 to (including) N is known to be N(N+1)/2 (no need for iteration).
So, the sum of all multiples of K, from K to KM is K times the above formula, giving KM(M+1)/2.
Combine this with #meowgoesthedog's findMultiples(N, 3) + findMultiples(N, 5) - findMultiples(N, 15) idea, and you have a constant-time solution.
A solution for your problem.Fastest method for solving your problem.
import java.util.*;
class Solution {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int t = in.nextInt();
while(t!=0)
{
long a=in.nextLong();
long q=a-1;
long aa=q/3;
long bb=q/5;
long cc=q/15;
long aaa=((aa*(aa+1))/2)*3;
long bbb=((bb*(bb+1))/2)*5;
long ccc=((cc*(cc+1))/2)*15;
System.out.println(aaa+bbb-ccc);
t-=1;}
}
}

Sum and Averages of an Array

I am working on an array problem for my college course and I'm trying to find the sum and the average of an array. Here's the code I have so far.
public class Module55
{
public static void main(String args[])
{
//declare the array to have 10 items for 10 weeks
//also declare sum as an int and average as a double to accommodate for decimal points
int[] weeks = new int[10];
int sum = 0;
double average = 0;
//declare the array values
weeks[0]= 2;
weeks[1]= 4;
weeks[2]= 8;
weeks[3]= 10;
weeks[4]= 14;
weeks[5]= 16;
weeks[6]= 20;
weeks[7]= 22;
weeks[8]= 24;
weeks[9]= 26;
// determine sum of the array values
for (int index = 0; index < weeks.length; index++) weeks[index] = index;
sum = sum + weeks[index];
System.out.println("The total miles ran in 10 weeks is " + sum);
// determine the average of the array values
if (weeks.length != 0)
average = sum / weeks.length;
else
average = 0;
System.out.println("The average of the miles ran in 10 weeks is " + average);
}
}
I know that the average works but I'm stuck on the sum. The problem I'm having is I cant seem to initialize the values in the array so that I can provide a sum for them. What am I doing wrong or what am I missing?
You have two problems in your code;
A) For-loop assignment
You don't need to make the first assignment, just adding sum to the week[index] is ok;
for (int index = 0; index < weeks.length; index++)
sum = sum + weeks[index];
B) Calculating the average
Sum is defined as an int which is a primitive integer, because of that, the division of an integer to an integer, the output is an integer which is not precise. Output of the division (45/10) is casted to integer, then assigned to double which is rounded off to 4, then casted to double again, and '4.0' became the result.
To avoid this unprecise result, cast sum to the double as below;
average = (double)sum / weeks.length;
The corrected version of your code is as below;
Demo
public class Module55 {
public static void main(String args[]) {
// declare the array to have 10 items for 10 weeks
// also declare sum as an int and average as a double to accommodate for
// decimal points
int[] weeks = new int[10];
int sum = 0;
double average = 0;
// declare the array values
weeks[0] = 2;
weeks[1] = 4;
weeks[2] = 8;
weeks[3] = 10;
weeks[4] = 14;
weeks[5] = 16;
weeks[6] = 20;
weeks[7] = 22;
weeks[8] = 24;
weeks[9] = 26;
// determine sum of the array values
for (int index = 0; index < weeks.length; index++)
sum = sum + weeks[index];
System.out.println("The total miles ran in 10 weeks is " + sum);
// determine the average of the array values
if (weeks.length != 0)
average = (double)sum / weeks.length;
else
average = 0;
System.out.println("The average of the miles ran in 10 weeks is " + average);
}
}
Output
The total miles ran in 10 weeks is 146
The average of the miles ran in 10 weeks is 14.6
And a note for scope
And one last note about the scope, check out this code;
for (int index = 0; index < weeks.length; index++)
weeks[index] = index;
sum = sum + weeks[index];
System.out.println("The total miles ran in 10 weeks is " + sum);
In the for-loop, because that no brackets are used, only the first statement under the for-loop will be considered in the scope of the loop by the compiler. That's why, for the next line, the compiler is giving error about the index because index is defined inside the scope of the for-loop.
you need to use brackets in your for loop. currently your code is evaluating like this:
for (int index = 0; index < weeks.length; index++)
{
weeks[index] = index;
}
sum = sum + weeks[index];
System.out.println("The total miles ran in 10 weeks is " + sum);
you want your code to evaluate like this
for (int index = 0; index < weeks.length; index++)
{
weeks[index] = index; //logical issue, what does this line achieve?
sum = sum + weeks[index];
}
System.out.println("The total miles ran in 10 weeks is " + sum);
This will at least solve your procedural problems but you will still need to take a look at your logic. Try using breakpoints to debug your code.
A very simple way to achieve this in Java 8 is to use the built in mechanisms for gathering statistics:
int[] weeks = {3, 4, 6, 9, 10};
IntSummaryStatistics stats = IntStream.of(weeks).summaryStatistics();
System.out.println("sum = " + stats.getSum() + "; average = " + stats.getAverage());
for (int i = 0;i < weeks.length) {
sum += weeks[i];
}
System.out.println("Sum is:" + sum);
First of all, you simply don't need the line weeks[index] = index;.
And for average you have to cast the sum to double if you want to get the average in double as you have declared the sum as int.
public class Module55
{
public static void main(String args[])
{
//declare the array to have 10 items for 10 weeks
//also declare sum as an int and average as a double to accommodate for decimal points
int[] weeks = {2,4,8,10,14,16,20,22,24,26};
int sum = 0;
double average = 0;
// determine sum of the array values
for (int index = 0; index < weeks.length; index++)
//weeks[index] = index;
sum = sum + weeks[index];
System.out.println("The total miles ran in 10 weeks is " + sum);
// determine the average of the array values
if (weeks.length != 0)
average = (double)sum / weeks.length;
else
average = 0;
System.out.println("The average of the miles ran in 10 weeks is " + average);
}
}
The total miles ran in 10 weeks is 146
The average of the miles ran in 10 weeks is 14.6
Summing an array of numbers and dividing by n to get the average like this will not get the correct value - you should not compute the average using integer division.
Also, this approach might work for the example shown, but not in general. For example, try using this code to find the average of these two value: (INT_MAX-6) and (INT_MAX-2).
The corrected code. While calculating average you have cast on of the varibale to double else you will get the average as integer
public class Mod55 {
public static void main(String args[]) {
//declare the array to have 10 items for 10 weeks
//also declare sum as an int and average as a double to accommodate for decimal points
int[] weeks = new int[]{2, 4, 8, 10, 14, 16, 20, 22, 24, 26};
int sum = 0;
double average = 0;
// determine sum of the array values
for (int index = 0; index < weeks.length; index++) {
sum += weeks[index];
}
System.out.println("The total miles ran in 10 weeks is " + sum);
// determine the average of the array values
if (weeks.length != 0) {
average = (double)sum / weeks.length;
} else {
average = 0;
}
System.out.println("The average of the miles ran in 10 weeks is " + average);
}
}
Java8 You could achieve the same thing like this.
int[] weeks = new int[]{2, 4, 8, 10, 14, 16, 20, 22, 24, 26};
int sum = Arrays.stream(weeks)
.sum();
double average = Arrays.stream(weeks).average().orElse(0);
you can find this handy with lambdas.The code looks something like this.
int weeks[] = {1,2,3,4};
List<Integer> asd = IntStream.of(weeks).boxed().collect(Collectors.toList());
//asd.forEach(System.out::println);
//this outputs average
System.out.println(asd.stream().mapToDouble(val -> val).sum()/asd.size());
//this outputs sum
System.out.println(asd.stream().mapToInt(val -> val).sum());
//another way to achieve this thanks to commenter
System.out.println(IntStream.of(asd).summaryStatistics());

Increaing Randomly Generated Numbers

I want to generate random integers such that the next generated number is always greater than the previous one.
Assume I start with 3, I want the next to be always greater than 3. And say I generated 5, I want the next to be greater than 5 and so on..
This should get you a number that is consistently larger than the previous value. The range is the maximum distance from the previous value that you want the number to be.
public getLargerRandom(int previousValue){
int range = 100; //set to whatever range you want numbers to have
return random.nextInt(range) + previousValue;
}
int rnd = 0;
while (true) {
rnd = ThreadLocalRandom.current().nextInt(rnd +1, Integer.MAX_INT);
System.out.println("Next random: "+rnd);
}
You would store the randomly generated number as a variable, then use that as a minimum value for the next generation of numbers.
int x = 0;
x = new Random.nextInt(aNumber) + x;
The following example generates a set of random numbers between a start value and a max value without going over the desired maximum number.
import java.util.Random;
public class RandomNumbers {
public static void main(String[] args) {
GetIncreasingInts(20, 3, 101);
}
public static void GetIncreasingInts(int numIntsToGet, int start, int max) {
if (numIntsToGet > 0 && start >= 0 && max > 0) {
Random random = new Random();
int nextStart = start;
int num = -1;
for (int index = 0; index < numIntsToGet; index++) {
if ((max - 1) <= nextStart)
break;
else {
num = nextStart + random.nextInt(max - nextStart);
nextStart = num;
System.out.println("Number: " + num);
}
}
}
}
}

How can I divide a range into n equal bins?

I have a range [min-max]. min and max are of type double. I want to divide this interval into n equal intervals.(n is an integer). How can I achieve this in Java?
For example :
say I have a range [10-50]. and n=4 .
output should be a list of ranges like [10-20] [20-30][30-40] [40-50]
So what you need here is a formula for the limits of the smaller ranges. First lets start off by computing the length of each small range:
// let range be [start, end]
// let the number of smaller ranges be n
double total_length = end - start;
double subrange_length = total_length/n;
After that do a simple cycle for the smaller ranges moving the left end of the current range with the value computed above on each step:
double current_start = start;
for (int i = 0; i < n; ++i) {
System.out.printl("Smaller range: [" + current_start + ", " + (current_start + subrange_length) + "]");
current_start += subrange_length;
}
If have the Range given in the form of an array with two elements (min and max)
double[] range = new double[] {min, max};
int n = 4;
you could try it this way. What you get from divideRange is a two-dimensional array with subranges of the given range, with each of them having the wanted length.
public double[][] divideRange(double[] range, n) {
double[][] ranges = new double[n][2];
double length = (range[1] - range[0])/n;
ranges[0][0] = range[0];
ranges[0][1] = range[0]+length;
for(int i = 1; i < n; i++) {
ranges[i][0] = ranges[i-1][1];
ranges[i][1] = ranges[i-1][1]+length;
}
return ranges;
}
What you can do is use what #Achintya used, double dist = (double)(max-min)/n; Then starting from the min, add dist to it and that is the max of your first interval.
So it'd be something like:
[min, min + dist], [min + dist, min + 2*dist]... until min + n*dist >= max.
int counter = 0;
while(true) {
CreateInterval(min + counter*dist, min + (counter+1)*dist);
if (min+(counter+1)*dist >= max) {
//if we have reached the max, we are done
break;
}
}

Categories