Algorithm that shows n numbers whose sum is 100 with regression - java

I need an algorithm that accepts the total numbers count and the first number as input, where the sum of these numbers must be 100.
Examples:
Input:
count = 5,
first = 50
Output must be something LIKE that:
50, 30, 15, 3.5, 1.5
Input:
count = 7,
first = 30
Output must be something LIKE that:
30, 25, 20, 10, 7.5, 5, 2.5
it is not very important for me that the output is as I indicated it in the examples, it's all about
I just do this code, and I can't figure out how to integrate the "first" variable to it:
public class Main {
public static void main(String[] args) {
var count = 5;
var first = 50;
System.out.println(calc(first, count)); // [6.7, 13.3, 20.0, 26.7, 33.3]
}
private static List<BigDecimal> calc(double first, double count) {
double total = 100;
int multiplier = 0;
for (int i = 1; i <= count; i++) {
multiplier+=i;
}
BigDecimal a = BigDecimal.valueOf(total / multiplier);
List<BigDecimal> list = new ArrayList<>();
BigDecimal b = BigDecimal.ZERO;
for (int i = 0; i < count; i++) {
b = b.add(a);
list.add(b.setScale(1, RoundingMode.HALF_UP));
}
return list;
}
}

Why can't you subtract the first number from the total, and decrease count by 1?
import java.util.*;
import java.math.*;
public class Main {
public static void main(String[] args) {
var count = 5;
var first = 50;
System.out.println(calc(first, count)); // [6.7, 13.3, 20.0, 26.7, 33.3]
}
private static List<BigDecimal> calc(double first, double count) {
double total = 100 - first; // Decrease total by first
count--; // Decrement
int multiplier = 0;
for (int i = 1; i <= count; i++) {
multiplier+=i;
}
BigDecimal a = BigDecimal.valueOf(total / multiplier);
List<BigDecimal> list = new ArrayList<>();
list.add(BigDecimal.valueOf(first)); // Add first to list
BigDecimal b = BigDecimal.ZERO;
for (int i = 0; i < count; i++) {
b = b.add(a);
list.add(b.setScale(1, RoundingMode.HALF_UP));
}
return list;
}
}

Related

I want to find the average in a given array, and find the closest number to that average in java

I want to calculate the number closest to the average of the array, I have finished calculating the average but I have no idea how to find the closest number to that average.
public class ClosestToTheArray {
int array [] = new int[]{1, 2, 3 ,4 ,5, 6 ,7 ,8};
int sum;
int sum2;
public void findAverage(){
double avg;
double lol = 0;
double smthelse;
for(int i =0; i < array.length; i++){
sum += array[i];
}
avg = sum/array.length;
}
public static void main(String [] args){
ClosestToTheArray test = new ClosestToTheArray();
test.findAverage();
}
}
To find the average in the given array and find the number which is closest to the average,
public static void main(String[] args)
{
int array[] = new int[]
{ 1, 2, 3, 4, 5, 6, 7, 8 };
int sum=0;
double avg;
for (int i = 0; i < array.length; i++)
{
sum += array[i];
}
avg = sum / array.length;
System.out.println(avg);
double difference = Math.abs(array[1] - avg);
Integer closest = array[1];
for (int i = 0; i < array.length; i++)
{
double diff = Math.abs(array[i] - avg);
if(difference > diff)
{
difference = diff;
closest = array[i];
}
}
System.out.println(closest);
}

Sum of an arrayList

I'm trying to make an average (moy) of an arrayList's column but I need to sum it first, I don't know how to do it
int sumX = 0;
val = new ArrayList<>();
float moy[] = new float[3];
if (i < 100) {
val.add(sensorEvent.values);
i++;
} else {
for (; i > 0; i--);
{
sumX = ?
moy[0] = sumX/100;
}
val.clear();
i = 0;
}
Using DoubleStream:
Variants:
The input is an array of double
double[] values = new double[] {1.1D, 2.33D, 4D};
double average = DoubleStream.of(values).average().getAsDouble();
The input is an ArrayList of Integer
ArrayList<Integer> values = new ArrayList<>();
values.add(1);
values.add(42);
values.add(-1);
double average = values.stream().mapToDouble(value -> (double) value).average().getAsDouble();
You can use this code snippet: (Written in kotlin)
fun main() {
val s: List<Float> = listOf(1.2F, 1.4F, 5.6F)
// populate it with your custom list data
var sum = 0F
s.forEach { it ->
sum+=it
}
println("Sum = $sum and avg = ${sum/(s.size)}")
}
Well here is the java solution:
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
List<Float> s = new ArrayList(Arrays.asList(1.2F, 1.3F, 5.4F, 6.5F));
Float sum = 0F;
for (int i=0; i< s.size(); i++) {
sum+=s.get(i);
}
System.out.println("Sum: "+sum+" and Avg: "+sum/(s.size()));
}
}
Here is how to sum all values in an ArrayList
ArrayList<Integer> nums = new ArrayList<>();
// Populate ArrayList
int sum = 0;
for (int num : nums) {
sum += num;
}
// Do whatever you want with sum after
Just use averaging collector in streams and you don't have to calculate SUM and NUMBER of elements:
ArrayList<Double> numbers = new ArrayList<>() {{
add(1d);
add(2.45d);
add(100d);
}};
final double average = numbers.stream()
.collect(Collectors.averagingDouble(d -> d));
moy[0] = average;

How to calculate a unique "mode" from an array?

I was tasked to find the mode of a given array (unspecified length). The mode is defined as the number that occurs the most uniquely. So, for example, the mode of an array [1.0, 2.0, 3.0, 2.0] is 2.0. However, if there is not a unique number of that value, for example, [1.0, 2.0, 2.0, 3.0, 3.0], the program returns "no mode" or "Double.NaN" in my program.
I have written code that works for 3/4 test cases, but always messes up on catching the case where there are two modes that are the same.
public double mode() {
double modeOne = data[0];
double modeTwo = 0;
int count = 0;
int countOne = 0;
int countTwo = 0;
if(data.length == 1) { // special case: if array length is 1 the mode will always just be that value
modeOne = data[0];
return modeOne;
} // end if
for(int i = 0; i < data.length; i++) { // pulling out first value
double value = data[i];
for(int n = 0; n < data.length; n++) { // comparing first value to all other values
if (data[n] == value) {
count ++; // adding onto a count of how many of the same number there are
}
}
if(modeOne == value || modeTwo == value) { // move on if the modes already have that value
continue;
}
if(count > countOne) { // setting the max count
countTwo = countOne;
countOne = count;
modeTwo = modeOne;
modeOne = value;
}
else if(count > countTwo) { // setting second highest count
countTwo = count;
modeTwo = value;
}
} // end for
if(countOne == 1) { // if all the modes are just one
return Double.NaN;
}
if(countOne == countTwo) { // if there are two of the same modes
return Double.NaN;
}
else {
return modeOne;
}
} //end MODE
For this test case:
double[] data = {1,2,2,3,3,4};
Stat stat1 = new Stat(data);
System.out.println("stat1 mode = " + stat1.mode());
I expect "NaN" but it returns 4. However, it works for the case below:
double[] data = {-5.3, 2.5, 88.9, 0, 0.0, 28, 16.5, 88.9, 109.5, -90, 88.9};
Stat stat1 = new Stat(data);
System.out.println("stat1 mode = " + stat1.mode());
The expected output is 88.9, which the program does correctly output.
Here is an approaching using Streaming API. However, I took the definition of modes which is a set rather than a single number.
import org.junit.Test;
import java.util.Arrays;
import java.util.Map;
import java.util.OptionalLong;
import java.util.Set;
import java.util.concurrent.ThreadLocalRandom;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
public class ModeTest {
private <T extends Number> Set<T> modes(T... input) {
return modes(Arrays.stream(input));
}
/**
* Calculate the modes of a numeric stream. The modes are the values that occurs most often. If no number in the
* stream is repeated, then all the numbers in the stream are modes.
*
* #param input stream of numbers
* #param <T> number type
* #return modes.
*/
private <T extends Number> Set<T> modes(Stream<T> input) {
// transform the input to a map containing the counted entries
final Set<Map.Entry<T, Long>> countedEntries = input
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.entrySet();
// Figure out the max value
final OptionalLong max = countedEntries
.parallelStream()
.mapToLong(Map.Entry::getValue)
.max();
// Handle the case where the stream was empty
if (max.isEmpty()) {
return Set.of();
}
return countedEntries
.parallelStream()
.filter(e -> e.getValue() == max.getAsLong())
.map(Map.Entry::getKey)
.collect(Collectors.toSet());
}
#Test
public void oneMode() {
final Double[] input = new Double[]{1.0, 1.1, 1.2, 2.0, 2.0, 3.0};
assertEquals(modes(input), Set.of(2.0));
}
#Test
public void multipleModes() {
final Stream<Double> input = Stream.of(1.0, 1.1, 1.2, 2.0, 2.0, 3.0, 3.0);
assertEquals(modes(input), Set.of(2.0, 3.0));
}
#Test
public void allSingles() {
final Stream<Double> input = Stream.of(1.0, 1.1, 1.2, 2.0, 3.0);
assertEquals(modes(input), Set.of(1.0, 1.1, 1.2, 2.0, 3.0));
}
#Test
public void largeRandomSet() {
Integer[] randoms = new Integer[204800];
for (int i = randoms.length - 1; i >= 0; --i) {
randoms[i] = ThreadLocalRandom.current().nextInt(200);
}
assertFalse(modes(randoms).isEmpty());
}
#Test
public void emptyStream() {
final Stream<Double> input = Stream.of();
assertEquals(modes(input), Set.of());
}
}
There you go no Collection etc... pure hard programming :)
public double mode(double[] data)
{
if(data.length==1)
return data[0];
double temp;
double [] fr = new double [data.length]; //store frequency
int visited = -1;
for(int i = 0; i < data.length; i++)
{
int count = 1;
for(int j = i+1; j < data.length; j++)
{
if(data[i] == data[j])
{
count++;
fr[j] = visited;
}
}
if(fr[i] != visited)
fr[i] = count;
}
for (int i = 0; i < fr.length; i++) // sort array in decreasing order
{
for (int j = i + 1; j < fr.length; j++)
{
if (fr[i] < fr[j])
{
temp = data[i];
data[i] = data[j];
data[j] = temp;
temp = fr[i];
fr[i] = fr[j];
fr[j] = temp;
}
}
}
if(fr[0] == fr[1])
return Double.NaN;
else
return data[0];
}
Since I was in the mood for a small challenge, I did write my own solution using a Map to count the individual values.
Then you retrieve the highest count available and iterate over the map again to determine if multiple entries have the same highest count, if so, you'll return NaN.
public static double calculateMode(double[] numbers) {
Map<Double, Integer> lookupMap = new TreeMap<>();
for (double number : numbers) {
if (lookupMap.get(number) != null) {
lookupMap.put(number, lookupMap.get(number) + 1);
} else {
lookupMap.put(number, 1);
}
}
int max = -1;
double maxKey = Double.NaN;
for (Entry<Double, Integer> entry : lookupMap.entrySet()) {
if (entry.getValue() > max) {
max = entry.getValue();
maxKey = entry.getKey();
}
}
int foundMax = 0;
for (Entry<Double, Integer> entry : lookupMap.entrySet()) {
if (entry.getValue() == max) {
foundMax++;
}
}
if (foundMax > 1) {
return Double.NaN;
}
return maxKey;
}
Method call:
public static void main(String[] args) {
double[] data = {1, 2, 2, 3, 3, 4};
double[] data2 = {-5.3, 2.5, 88.9, 0, 0.0, 28, 16.5, 88.9, 109.5, -90, 88.9};
System.out.println("Expected NaN - and was: " + calculateMode(data));
System.out.println("Expected 88.90 - and was: " + calculateMode(data2));
}
Outputs:
Expected NaN - and was: NaN
Expected 88.90 - and was: 88.9
So I felt challenged as well and got a solution without the use of Collections.
Not a really nice solution but it seems to work:
public class TestMode
{
private static class NumberFrequency
{
double number;
int frequency;
}
public static double calculateMode(double[] numbers)
{
// Maybe array empty
if ((numbers == null) || (numbers.length == 0))
return Double.NaN;
// Initialize array with frequencies
NumberFrequency[] array;
int size = 0;
array = new NumberFrequency[numbers.length];
// Loop over numbers determining frequencies
for (double number : numbers)
{
// Maybe encountered before
int index;
for (index = 0; index < size; index++)
{
if (array[index].number == number)
break;
}
// Update array
NumberFrequency elm;
if (index == size)
{
elm = new NumberFrequency();
elm.number = number;
elm.frequency = 0;
array[index] = elm;
size++;
}
else
elm = array[index];
elm.frequency += 1;
} // for all numbers
// Initialize element with highest frequency
int index_highest;
int highest_freq;
int nr_occurs;
index_highest = 0;
highest_freq = array[0].frequency;
nr_occurs = 1;
// Search 'better' element
int counter;
for (counter = 1; counter < size; counter++)
{
if (array[counter].frequency > highest_freq)
{
index_highest = counter;
highest_freq = array[counter].frequency;
nr_occurs = 1;
}
else if (array[counter].frequency == highest_freq)
nr_occurs++;
}
// Return result
if (nr_occurs == 1)
return array[index_highest].number;
else
return Double.NaN;
} // calculateMode
public static void main(String[] args)
{
double[] data = {1, 2, 2, 3, 3, 4};
double[] data2 = {-5.3, 2.5, 88.9, 0, 0.0, 28, 16.5, 88.9, 109.5, -90, 88.9};
System.out.println("Expected NaN - and was: " + calculateMode(data));
System.out.println("Expected 88.90 - and was: " + calculateMode(data2)); }
} // class TestMode
To add one more alternative and because I also felt challenged as well:
The general idea is to generate a frequency array, fore the given example above
[1.0, 2.0, 2.0, 3.0, 3.0]
[1, 2, 2, 2, 2]
which indicates how many times the element at the same index is in the input, then find the max value in the frequency array, and finally check if all values with the same frequency are equal.
public static double mode(double [] data) {
if(data == null || data.length < 1){
return Double.NaN;
}
int [] freq = new int [data.length];
for(int i = 0; i<data.length; i++){
for(int j = 0; j<data.length; j++){
if(data[i]==data[j]){
freq[i]++;
}
}
}
int max = 0;
double mode = data[0];
for(int i = 0; i<freq.length; i++){
if(freq[i]>max){
max = freq[i];
mode = data[i];
}
}
for(int i = 0; i<freq.length; i++){
if(freq[i] == max){
if(mode != data[i]){
return Double.NaN;
}
}
}
return mode;
}

Incompatible types: double[][] can not be converted to double

I am trying to resolve an issue for this assignment I was given for Homework. I am currently stuck and would appreciate any help that could guide me in correcting the program.
The original assignment is as follows:
Write a program that uses a two-dimensional array to store the highest and lowest temperatures for each month of the year. Write two methods : one to calculate and return the average high and one to calculate and return the average low of the year. Your program should output all the values in the array and then output the average high and the average low.
This is the code I have assembled so far and have an error that I am not able to resolve. It is " incompatible types: converting double[][] cannot be converted to double. The lines in question are Line 8, and Line 110 ( the last return in the program).
import java.util.*;
public class Weather
{
public static void main(String[] args)
{
double[][] tempData = getData();
printTempData(tempData);
double avgHigh = averageHigh(tempData);
double avgLow = averageLow(tempData);
int indexHigh = indexHighTemp(tempData);
int indexLow= indexLowTemp(tempData);
System.out.format("The average high temperature is %4.1f%n", avgHigh);
System.out.format("The average low temperature is %4.1f%n", avgLow);
System.out.format("The index of high temperature is %2d%n", indexHigh);
System.out.format("The index of low temperature is %2d%n", indexLow);
}
private static void printTempData(double[][] tempData)
{
System.out.format("%6s:%4s%4s%4s%4s%4s%4s%4s%4s%4s%4s%4s%4s%n","Month","Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec");
System.out.format("%6s:","Low");
for (int i = 0; i < tempData[0].length;i++)
{
System.out.format("%4.1s", tempData[0][i]);
}
System.out.format("%n");
System.out.format("%6s: ","High");
for (int i = 0; i < tempData[1].length; i++)
{
System.out.format("%4.1f", tempData[1][i]);
}
System.out.format("%n");
}
private static int indexLowTemp(double[][] tempData)
{
int index = 0;
double temp = tempData[0][0];
for (int i = 0; i < tempData[0].length; i++)
{
if (temp > tempData[0][i])
{
temp = tempData[0][i];
index = i;
}
}
return index +1;
}
private static int indexHighTemp(double[][] tempData)
{
int index = 0;
double temp = tempData[1][0];
for(int i = 0; i< tempData[1].length; i++)
{
if ( temp < tempData[1][i])
{
temp = tempData[1][i];
index = i;
}
}
return index + 1;
}
private static double averageHigh(double[][] tempData)
{
double avg = 0.0;
for(int i=0; i < tempData[0].length; i++)
{
avg += tempData[0][i];
}
avg /= tempData[0].length;
return avg;
}
private static double averageLow(double[][] tempData)
{
double avg = 0.0;
for(int i=0; i > tempData[1].length; i++)
{
avg += tempData[0][i];
}
avg /= tempData[0].length;
return avg;
}
private static double getData()
{
double[][] tempData = new double[2][12];
Random r = new Random();
for (int j = 0; j < tempData[0].length; j++)
{
tempData[0][j] = 30 + Math.sqrt(j) - r.nextDouble();
tempData[1][j] = 30 + Math.sqrt(j) + r.nextDouble();
}
return tempData;
}
}
Your method private static double getData() should be private static double[][] getData()
You already declared an array
double[][] tempData = getData();
but you are trying to call
private static double getData()
thus the error "converting double[][] cannot be converted to double."
Hence change to
private static double[][] getData()
The method should be private static double[][] getData()

Arrays, Statistics, and calculating mean, median, mode, average and sqrt

I need to implement four static methods in a class named ArrayStatistics. Each of the four methods will calculate the mean, median, mode, and population standard deviation, respectively, of the values in the array.
This is my first time working with Java, and cannot figure out what should I do next. I was given some test values for, you guessed it, test out my program.
public class ArrayStatistics {
public static void main(String[] args) {
final int[] arr;
int[] testValues = new int[] { 10, 20, 30, 40 };
meanValue = a;
meadianValue = b;
modeValue = c;
sqrtDevValue = d;
average = (sum / count);
System.out.println("Average is " );
}
static double[] mean(int[] data) {
for(int x = 1; x <=counter; x++) {
input = NumScanner.nextInt();
sum = sum + inputNum;
System.out.println();
}
return a;
}
static double[] median(int[] data) {
// ...
}
public double getMedian(double[] numberList) {
int factor = numberList.length - 1;
double[] first = new double[(double) factor / 2];
double[] last = new double[first.length];
double[] middleNumbers = new double[1];
for (int i = 0; i < first.length; i++) {
first[i] = numbersList[i];
}
for (int i = numberList.length; i > last.length; i--) {
last[i] = numbersList[i];
}
for (int i = 0; i <= numberList.length; i++) {
if (numberList[i] != first[i] || numberList[i] != last[i]) middleNumbers[i] = numberList[i];
}
if (numberList.length % 2 == 0) {
double total = middleNumbers[0] + middleNumbers[1];
return total / 2;
} else {
return b;
}
}
static double[] mode(int[] data) {
public double getMode(double[] numberList) {
HashMap<Double,Double> freqs = new HashMap<Double,Double>();
for (double d: numberList) {
Double freq = freqs.get(d);
freqs.put(d, (freq == null ? 1 : freq + 1));
}
double mode = 0;
double maxFreq = 0;
for (Map.Entry<Double,Doubler> entry : freqs.entrySet()) {
double freq = entry.getValue();
if (freq > maxFreq) {
maxFreq = freq;
mode = entry.getKey();
}
}
return c;
}
static double[] sqrt(int[] sqrtDev) {
return d;
}
}
This is pretty easy.
public double mean(ArrayList list) {
double ans=0;
for(int i=0; i<list.size(); i++) {
ans+=list.get(i); }
return ans/list.size()
}
`
Median:
public void median(ArrayList list) {
if(list.size()%==2) return (list.get(list.size()/2)+list.get(list.size()+1))/2;
else return list.get((list.size()/2)+1)
}
For Mode, just a keep a tally on the frequency of each number occurrence, extremely easy.
For standard deviation find the mean and just use the formula given here: https://www.mathsisfun.com/data/standard-deviation-formulas.html

Categories