I'm trying to put this formula into a loop
The function to put inside the loop
I've used if statements to give me a specific result if the input is zero, but if the input is one or higher, the for loop should run.
I was given a question regards recursion and supposed to execute it 3 different ways one of them using a loop that I've already made and runs but gives unexpected results.
public class Assignment5Recursion {
public static int puzzleLoop(int n) {
int v=0;
if(n>=1) {
for(int i=1; i<=n+1; i++) {
v = (2*i-1);
}
return ((2*n+1)+2*v);
}
else {
return 1;
}}}
if n is 1, the result should be 5, if n is 2, the result should be 13, if n is 3, the result should be 25, if n is 7, the result should be 113, but for some reason, I'm getting different outputs, so I'm assuming that I've set the loop wrong.
You need to make 2 changes.
1)The loop will run from i=1 to i=n+1 whereas you only require it to run till i=n.
So the for loop exit condition should either be i<n+1 or i<=n
2)The variable v is going to be replaced every run of the loop as it is getting assigned a new value every time.
So the value for v will always be v=2*(n+1)-1 according to your code.
You need to make this v += (2*i-1) so that the new value of v gets added to the old value to get sigma(sum).
Replacing your for loop as below will solve your problem.
for(int i=1; i<n+1; i++) {
v += (2*i-1);
}
or
for(int i=1; i<=n; i++) {
v = v+(2*i-1);
}
You have made two mistake, instead of adding to v you are updating on every iteration, so total values doesn't get summed up. And since you are using <= you don't need to iterate upto n+1. So here is a revised puzzleLoop method for you
public static int puzzleLoop(int n) {
int v = 0;
if (n >= 1) {
for (int i = 1; i <= n; i++) {
v += (2 * i - 1);
}
return ((2 * n + 1) + 2 * v);
}
return 1;
}
You also don't need the else part statement since if it is not in the if block you can always safely return 1.
Σ(2*i-1), sum should be carried over the loop
change the statement in loop to v = v+(2*i-1) and condition to i<=n
Related
Here is my solution:
public static int minimumAbsoluteDifference(List<Integer> arr) {
int absValues = 0;
int maxNum = Integer.MAX_VALUE;
Collections.sort(arr);
for (int i = 0; i < arr.size() - 1; i++){
absValues = Math.abs(arr.get(i) - arr.get(i + 1));
}
int absValuesDiff = Math.min(absValues, maxNum);
return absValuesDiff;
}
I pass small test cases, but not ones with a larger data set.
As L_Cleo suggested, you indeed check the minimum value only once.
Instead, you should check it on every iteration of the loop:
public static int minimumAbsoluteDifference(List<Integer> arr) {
int absValue = Integer.MAX_VALUE;
Collections.sort(arr);
for (int i = 0; i < arr.size() - 1; i++) {
absValue = Math.min(absValue, Math.abs(arr.get(i) - arr.get(i + 1)));
}
return absValue;
}
I added the minimum check on every iteration. The checking is done between the absValue and the absolute difference of the current loop iteration.
By the end of the loop, absValue will contain the minimum value, because you have compared it to every other possibility.
The longer explanation why this works is this:
The reason why updating the absValue in each loop iteration is enough is this: absValue's first value is Integer.MAX_VALUE. This means that any other value will be smaller than absValue. In the first loop iteration, absValue is updated with the first absolute difference. In all other iterations, the code will always update absValue with the smaller value between the current absValue and the absolute difference you calculate on each iteration.
This guarantees that, for all iterations, the smallest value will be stored in absValue at some point, and in the further iterations, absValue value will not change.
The problem in your solution is that you're not checking all possible couples within the array of numbers.
With this for loop, for example:
for (int i = 0; i < arr.size() - 1; i++) {
absValues = Math.abs(arr.get(i) - arr.get(i + 1));
}
And iterating over the simple array 1, 4, 6, 7, you would be checking the couples [1,4], [4,6] and [6,7], but you're still missing 1,7 and 4,7.
So step number one would be to iterate over the array per every number of the array (knowing that the order of the pairs doesn't matter [1,6] == [6,1] in this case, you will have to check 1 less number every iteration of the outer loop... here is an example of a correct for loop:
public static int minimumAbsoluteDifference(List<Integer> arr) {
Collections.sort(arr);
int minAbsoluteValue = Integer.MAX_VALUE;
for(int i=0; i < arr.size() - 1; i++) {
for(int j=i+1; j < arr.size(); j++)
minAbsoluteValue = Math.min(Math.abs(arr.get(i) - arr.get(j)), minAbsoluteValue);
}
return minAbsoluteValue;
}
As you can see, another missing part in your solution is the tracking of the minimum value. You're checking the minimum value between the last iterated couple and the maxInteger value only once, while you have to that for every couple.
This might not be the most efficient solution...
How to resolve timeout error in my java code:
This code first finds reverse of the element and then find out the difference between the actual and reverse value if that difference is divisible by k then increase the counter
Please find below code :
//all header files are included
public class Solution {
// Complete the beautifulDays function below.
static int beautifulDays(int i, int j, int k) {
int count=0;
for(int a=i;a<=j;a++)
{
int p=a;
int t=0,r=0;
while(a>0)
{
r=a%10;
t=t*10+r;
a=a/10;
}
if((t-p)%k==0)
count++;
}
return count;
}
// all other code of input and calling methods
You have an infinite loop in this section:
for (int a = i; a <= j; a++) {
int p = a;
int t = 0, r = 0;
while (a > 0) {
r = a % 10;
t = t * 10 + r;
a = a / 10; //OUCH!
}
}
Lets analyze this.
The outer loop increases the loop variable a by 1 from i to j
The inner loop decreases the same loop variable a until it reaches zero.
Guess which one wins? (Can't guess? Try a pencil and paper and "hand execute" these loops. It is a useful exercise.)
That means .... that the outer loop will never terminate.
Solution: use a different loop variable in the inner loop.
I'm taking an online Java programming class (I'm a beginner) and I cannot figure how to correctly complete the code. I've already written what I think is to be included, however I'm missing something that would make the code work completely.
Directions:
Double any element's value that is less than minVal. Ex: If minVal = 10, then dataPoints = {2, 12, 9, 20} becomes {4, 12, 18, 20}.
public class StudentScores {
public static void main (String [] args) {
final int NUM_POINTS = 4;
int[] dataPoints = new int[NUM_POINTS];
int minVal = 0;
int i = 0;
dataPoints[0] = 2;
dataPoints[1] = 12;
dataPoints[2] = 9;
dataPoints[3] = 20;
minVal = 10;
// DO NOT EDIT ANYTHING ABOVE THIS COMMENT. ABOVE IS THE DEFAULT CODE OF ASSIGNMENT
for (i = 0; dataPoints[i] < minVal; ++i) {
dataPoints[i] = dataPoints[i] * 2;
}
// DO NOT EDIT ANYTHING BELOW THIS COMMENT. BELOW IS DEFAULT CODE OF ASSIGNMENT
for (i = 0; i < NUM_POINTS; ++i) {
System.out.print(dataPoints[i] + " ");
}
System.out.println();
return;
}
}
I made comments of what isn't to be messed with, as I am using an online interactive book and cannot edit or change the default code. Additionally, we are working with arrays in this chapter.
I'm new to this site in the sense that I don't know the unwritten ways of stackoverflow, but I've search multiple times online to see how to double the values for an array in java but I do not get the search results I need to help me.
The error messages I get are:
Testing minVal = 10 and dataPoints = {2, 12, 9, 20}
Expected output: 4 12 18 20
Your output: 4 12 9 20
I thought that the compiler should be able to read the lines fully to register that 9 is also less than 10 and thus should be doubled to 18, but it doesn't. What am I missing to make 9 be read as well?
In your code, 12 < 10 evaluates to be false and so, it goes out of loop and hence, it gives Wrong Output. Check the below code:
for (i = 0; dataPoints[i] < NUM_POINTS ; ++i) {
if(dataPoints[i] < minVal) {
dataPoints[i] = dataPoints[i] * 2;
}
}
I looped through all elements of array and if an element is < minVal, I multiplied it by 2.
The second section of the for statement is the termination condition: once it evaluates to false, your loop will stop executing.
In this particular problem, you're trying to look at each value in your dataPoints array, and double it. This calls for the use of an index variable.
Your index variable will keep track of your position within the array as you move from left to right. Starting on the left, at index 0, you will move right until you're at the end of the array.
++i takes care of incrementing your index variable each time the loop runs. This is what moves you through the array.
Your termination condition should check whether you have looked at all values in the array. Once you've gone past all the values in your array your index variable is pointing all the way at the end. And remember, as soon as the termination condition is false your loop will stop executing. So you want to run your code while i (your index variable) is less than the size of the array (dataPoints.length).
Once you've figured out the for loop bounds, simply check your conditional with an if-then statement before updating the values:
for (i = 0; i < dataPoints.length; ++i) {
if (dataPoints[i] < minVal) {
dataPoints[i] = dataPoints[i] * 2;
}
}
for (i = 0; i < NUM_POINTS; ++i) {
if (dataPoints[i] < minVal) {
dataPoints[i] = (dataPoints[i] * 2);
}
}
I'm writing a program for a class at school, and when the independents couldn't help, I turn to you...
I encounter my issue when I attempt to find the average - the variables either don't add correctly or they don't divide correctly. For example, an input of [4], [2], [4], [2], will give me 7.0, when it should be 3.0. Similarly, [2], [2], [4], [4], will give 2.0.
As far as I'm aware, the rest of the code functions exactly as it should. I'm including only what should effect it, but I can post the rest if required.
public class ArrayFunctions
{
String elementNumber =
JOptionPane.showInputDialog("How many elements do you want?");
int number = Integer.parseInt(elementNumber);
//assigns how many elements are in the array, based on user input
int[] min_array = new int[number];
int recalculate = 0;
public void arrayValues()
{
for (int i = 1; i < (number + 1); i++)
{
String elementInfo =
JOptionPane.showInputDialog("Input value for element " + i);
int element = Integer.parseInt(elementInfo);
//assigns values for elements, based on user input
min_array[(i - 1)] = element;
}
System.out.println('\u000C'); /*using BlueJ, this clears the console*/
for (int i = 1; i < (number + 1); i++)
{
System.out.println(min_array[(i - 1)]);
}
//prints the values of the elements in the array
}
...
public double avg()
{
for (int i = 1; i < (min_array.length); i++)
{
recalculate = (recalculate + min_array[(i - 1)]);
}
//should add together the values of all the elements
//this may be where it stops working as intended
double array_avg = (recalculate / min_array.length);
return array_avg;
//should divide the sum of all the elements by how many elements there are
//this is the other place where it might stop working.
}
Again, I can post more code if required. Sorry about bad/lacking comments and poor structure at times, I need to get this written, because I've a due date for this. :/
for (int i = 1; i < (min_array.length); i++)
{
recalculate = (recalculate + min_array[(i - 1)]);
}
This loop is going between index 0 (1 - 1) and index min_array.length - 2 due to your boolean condition in the for loop, stating that it should go while i is LESS than the array's length, and then also subtracting it by 1 in the code.
A possible solution would be to simply go until it's less than OR equal to the size, or simply start your loop at 0 and stop the (i - 1) stuff in the average calculation.
for (int i = 0; i < min_array.length; i++)
{
recalculate += min_array[i];
}
Also, on a side note, you're basically making that same mistake in the GUI stuff as well above; I've corrected it (as well as kept your methodology of using 1-based indexing for asking the user to fill in values, rather than 0-based indexing)
for (int i = 0; i < number; i++){
String elementInfo =
JOptionPane.showInputDialog("Input value for element " + (i + 1));
int element = Integer.parseInt(elementInfo);
min_array[i] = element;
}
System.out.println('\u000C'); /*using BlueJ, this clears the console*/
for (int i = 0; i < number; i++){
System.out.println(min_array[i]);
}
I see that you're going from index 0 to index array.length - 2, instead of -1. That's the problem. I hope this helps
public double avg()
{
for (int i = 0; i < (min_array.length); i++)
{
recalculate = (recalculate + min_array[i]);
}
//should add together the values of all the elements
//this may be where it stops working as intended
double array_avg = (recalculate / min_array.length);
return array_avg;
//should divide the sum of all the elements by how many elements there are
//this is the other place where it might stop working.
}
Also always start a for loop with i=0 for counting purposes
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