How to add or subtract within a certain range - java

I am trying to add numbers but keep it within a range. If it oversteps or understeps the boundary it will circle back to the other boundary.
Examples:
Min: 10
Max: 50
20 + 10 = 30
20 + 30 = 50 (or 0 idrk)
20 + 31 = 1
40 + 20 = 10
40 + 70 = 10
40 - 10 = 30
10 - 30 = 30
10 - 20 = 40
10 - 70 = 40
I am looking for two functions, one to add, one to subtract. I don't really care which language but python or java is preferred. Thanks for any help!

# define the range
start = 0
end = 93
# this function accepts positive and negative numbers in x
def mover(current_place, x):
locate = current_place + x
locate = locate % (end-start) # if x > the range
if locate > end:
locate = locate - end
if locate < start:
locate = locate + end
return locate
if __name__ == "__main__":
current_place = 50
print(current_place) #50
current_place = mover(current_place, 10)
print(current_place) #60
current_place = mover(current_place, -20)
print(current_place) #40
current_place = mover(current_place, -50)
print(current_place) #83
current_place = mover(current_place, 220)
print(current_place) #24

I'm afraid we have to add more specific information to your question:
is the boundary inclusive or exclusive?
are we talking abount only interger numbers or floating numbers?
If you want to use your routine as library function for many purposes, it's maybe a good idea to define one end as inclusive and the other as exclusive.
The following (incomplete) Java program shows the direction of solution as well as the problem with boundaries: whenever the boundary is hit, it flips to other end of your value frame:
public class FramedAddSub {
int min;
int max;
int value;
public FramedAddSub(int min, int max, int value) {
this.min = min;
this.max = max;
this.value = value;
}
public FramedAddSub add(int toAdd) {
final int diff = max - min;
if (toAdd >= 0) {
// step 1: norm to zero
value -= min;
// step 2: rest of division
value = (value + toAdd) % diff;
// step 3: re-norm to old offset
value += min;
} else {
// step 1: norm to zero from other end
value -= max;
// step 2:
value = (value + toAdd) % diff;
// step 3: re-norm back
value += max;
}
return this;
}
public static void main(String[] args) {
FramedAddSub test = new FramedAddSub(20, 50, 20);
System.out.println("start: " + test.value);
test.add(10);
System.out.println("+10: " + test.value);
test.add(20);
System.out.println("+20: " + test.value);
test.add(1);
System.out.println("+1: " + test.value);
test.add(30);
System.out.println("+30 should just turn around circle: " + test.value);
test.add(-1);
System.out.println("-1: " + test.value);
test.add(-1);
System.out.println("-1: " + test.value);
test.add(-30);
System.out.println("-30 should just turn around circle: " + test.value);
}
}

Try this in python:
ans = abs(a + b) % 50
You need to pass a and b as negative numbers, if you want to do a substraction.

I had the same problem and I use this solution for integers.
( ( (X ± Y) - MaximumValue ) % ( MaximumValue - MinimumValue ) ) + MinimumValue
% : modulo/reminder operator
Update:
The expression above works perfectly on Excel, but according to Microsoft it calculates the modulo like this
MOD(n, d) = n - d*INT(n/d)
Combine this two we got
((X+Y)-Mx)-(Mx-Mn)*Math.floor(((X+Y)-Mx)/(Mx-Mn))+Mn
Mx: MaximumValue
Mn: MinimumValue

Related

I want to make arithmetic mean for first half and then for the second half of array

I made the arithmetic mean for whole the sorted array, but now i want to make the arithmetic mean for first sorted half and second sorted half of array.
Ex: My array is: 77, 99, 44, 55, 22, 88, 11, 00, 66, 33.
My code make in first place the sort.
The outcome of program is: 00 11 22 33 44 55 66 77 88 99.
Now i want to make the mean for first half:
00 11 22 33 44 and print it.
Then i want to make the mean for the second half:
55 66 77 88 99 and print it.
public class Array {
private double[] a;
private int NrElmts;
public Array(int max)
{ a = new double[max];
NrElmts = 0;
}
public void elements(double value)
{ a[NrElmts] = value;
NrElmts++;
}
public void print()
{ for(int j=0; j<NrElmts; j++)
System.out.print(a[j] + " ");
System.out.println("");
}
public void selectionSort()
{
int out, in, min;
for(out=0; out< NrElmts -1; out++)
{ min = out;
for(in=out+1; in< NrElmts; in++)
if(a[in] < a[min] )
min = in;
invertPositions(out, min); }
}
private void invertPositions(int one, int two)
{ double temp = a[one];
a[one] = a[two];
a[two] = temp;
}
public void mean()
{
int i;
double sum = 0;
for(i = 0; i < NrElmts; i++) {
sum+=a[i];}
double medie = sum/NrElmts;
System.out.format("Mean is: %.1f", mean);
System.out.println("");
}
}
Try this
public void firstHalfMean(){
int i;
double sum = 0;
int numberOFElements = NrElmts/2;
for (i = 0; i < NrElmts/2; i++) { // take sum only till half.
sum += a[i];
}
double mean = sum / numberOFElements; // sum/half the elements
System.out.format("Mean is: %.1f", mean);
System.out.println("");
}
public void secondHalfMean(){
int i;
double sum = 0;
int numberOFElements = NrElmts % 2 == 0 ? NrElmts/2 : NrElmts/2 + 1; // If odd, this second array will contain one more element.
for (i = NrElmts/2; i < NrElmts; i++) { // take sum for the next half
sum += a[i];
}
double mean = sum / numberOFElements; // sum/half elements (half + 1) in case of odd length.
System.out.format("Mean is: %.1f", mean);
System.out.println("");
}
To calculate the mean for 9, 2 and 7 you have to firstly add them all up, which equals 18 and then divide by how many there are - so 18 / 3 which is 6.
Although, you will have to account for the possibility of an odd list - if there's an odd amount of elements, say for example 1, 2, 3 the middle point of 3 - is 1.5 - and if you're iterating through indexes the iterative variable will count the middle point as 1. So it's a bit tricky, not sure what you'd want to do.Consider the following code though - it does exactly what you want, but with odd list sizes, it will just divide by a decimal value
LinkedList<Integer> numbers = new LinkedList<>();
numbers.add(10);
numbers.add(20);
numbers.add(30);
numbers.add(40);
int size = numbers.size();
int iterativeHalf = size / 2;
float meanHalf = (float) size / 2;
float lowerMean = 0;
float upperMean = 0;
for (int i = 0; i < size; i++) {
int realRef = i + 1;
Integer value = numbers.get(i);
if (realRef > iterativeHalf) { //Should be calculating upper mean
if (upperMean == 0) { //if lowerMean is just a running total, not divided yet to get the mean
System.out.println("the lower mean for numbers is " + lowerMean + " / " + meanHalf);
lowerMean = (lowerMean) / meanHalf; //add last value + divide to set it to the mean
}
System.out.println("upper mean = " + upperMean + " + " + value + " = " + (upperMean + value));
upperMean = upperMean + value; //keep the upper values up total going
} else {
System.out.println("lower mean = " + lowerMean + " + " + value + " = " + (lowerMean + value));
lowerMean = lowerMean + value; //keep adding the lower halfs values up
}
}
//When it breaks, must divide upperMean by size to get mean
System.out.println("the upper mean for numbers is " + upperMean + " / " + meanHalf);
upperMean = (upperMean) / meanHalf;
System.out.println(" ");
System.out.println("FINAL lower mean = " + lowerMean);
System.out.println("FINAL upper mean = " + upperMean);
Output is:
lower mean = 0.0 + 10 = 10.0
lower mean = 10.0 + 20 = 30.0
the lower mean for numbers is 30.0 / 2.0
upper mean = 0.0 + 30 = 30.0
upper mean = 30.0 + 40 = 70.0
the upper mean for numbers is 70.0 / 2.0
FINAL upper mean = 35.0
FINAL lower mean = 15.0
This, for a [10, 20, 30, 40] will yield the output shown above but essentially (10+20)/2 as the lower mean and (30+40)/2 for the upper mean.
For [10, 20, 30, 40, 50] will yield (10 + 20) / 2.5 the lower mean and (30+40+50)/2.5 for the upper mean
Only take sum of half the array. Give one more element to your second or first half in case if your array size is odd.
public void firstHalfMean(){
int i;
double sum = 0;
int numberOFElements = NrElmts/2;
for (i = 0; i < NrElmts/2; i++) { // take sum only till half.
sum += a[i];
}
double mean = sum / numberOFElements; // sum/half the elements
System.out.format("Mean is: %.1f", mean);
System.out.println("");
}
public void secondHalfMean(){
int i;
double sum = 0;
int numberOFElements = NrElmts % 2 == 0 ? NrElmts/2 : NrElmts/2 + 1; // If odd, this second array will contain one more element.
for (i = NrElmts/2; i < NrElmts; i++) { // take sum for the next half
sum += a[i];
}
double mean = sum / numberOFElements; // sum/half elements (half + 1) in case of odd length.
System.out.format("Mean is: %.1f", mean);
System.out.println("");
}
Since you already have way to make mean for entire array, all you need to do is find mid position of array and then run from and to that point.
In your example: NrElmts is 10, so divide your NrElmnts by 2, so you can get mean for 1 to 5, and then 6 to 10 both 5 each.
Think about situation where you have odd number of elements in array, how do u want to do it, whether in first array or second. let me know if this need help as well.
Steps:
1) create a new variable say a1 to NrElmts/2, and go with your mean function from 1 to a1
2) go from a1+1 to NrElmnts
Let me know if you need any help.

how would I find the nth term in a loop? java

Here is a quick look at the program that I made to give a better example of my question.
Loop code
public void scheme1(int d) {
// first modification
if (mark<=20){
System.out.print("\nBecause mark under 20 mark stays as its original value. mark="+mark);
return;
}
int total = mark;
int finalMark=20;
System.out.print("Scheme 1"+"\n");
// Loop
for(int loopParameter = START_CONDITION;
loopParameter <= d;loopParameter++){
System.out.print("(" + loopParameter + ") " + total + " ");
total = total + constantDiffSch1;
// second modification
if (total < 40){
System.out.print("\nThis work can be up to " + loopParameter);
return;
}
// third modification
if (total<=20){
System.out.print("\nBecause mark drops below 20, mark stays as 20. final mark="+ finalMark);
return;
}
} // End
System.out.print("\n\n");
}
This is what my program outputs
Please input mark: 64
Please input number of days to display: 10
Scheme 1
(0) 64 (1) 59 (2) 54 (3) 49 (4) 44
This work can be up to 4 days late before failing.
This is what the output is supposed to be
Please input mark: 64
Please input number of days to display: 10
Scheme 1
(0) 64 (1) 59 (2) 54 (3) 49 (4) 44 (5) 39 (6) 34 (7) 29 (8) 24
This work can be up to 4 days late before failing.
I have to display how many days late the assignment is and calculate the late penaltie (mark -5) I also have to display the number of days needed needed to fail the assigment ( number of days until failure might be larger than the number (d) of days that the user input ) . the failing mark is less than 40.
2nd example (output)
Please input mark: 64
Please input number of days to display: 2
Scheme 1
(0) 64 (1) 59 (2) 54
This work can be up to 4 days late before failing.
I have almost complete my code but this problem is slowing me down.
P.S. I am new at java
here is my full program
LatePenalties calss
public class LatePenalties {
// attributes
private int mark;
private static final int constantDiffSch1 = -5;
private static final double constantDiffSch2 = 0.9;
private static final int START_CONDITION = 0;
// constructors
public LatePenalties(int m) {
mark = m;
}
// methods
public void scheme1(int d) {
// first modification
if (mark<=20){
System.out.print("\nBecause mark under 20 mark stays as its original value. mark="+mark);
return;
}
int total = mark;
int finalMark=20;
System.out.print("Scheme 1"+"\n");
// Loop
for(int loopParameter = START_CONDITION;
loopParameter <= d;loopParameter++){
System.out.print("(" + loopParameter + ") " + total + " ");
total = total + constantDiffSch1;
// second modification
if (total < 40){
System.out.print("\nThis work can be up to " + loopParameter);
return;
}
// third modification
if (total<=20){
System.out.print("\nBecause mark drops below 20, mark stays as 20. final mark="+ finalMark);
return;
}
} // End
System.out.print("\n\n");
}
public void scheme2(int d) {
double total = mark;
System.out.print("\n\nScheme 2"+"\n");
// Loop
for(int loopParameter = START_CONDITION;
loopParameter <= d;loopParameter++){
System.out.print( "(" + loopParameter + ") " );
System.out.printf("%.02f",total);
System.out.print(" ");
total = total * constantDiffSch2;
} // End
System.out.print("\n");
}
}
Main class
import java.util.Scanner;
public class LatePenaltiesUser {
public static void main(String [] args) {
// local variables
Scanner input = new Scanner(System.in);
LatePenalties latePen;
int mark;
int days;
// input
do{
System.out.print("Please input mark (between 0 and 100) --> ");
mark = input.nextInt();
if (( mark < 0 ) | (mark > 100 )){System.out.print("\n" + "Input value outside the range!!!" + "\n");}
}while(( mark < 0 ) | (mark > 100 ));
do{
System.out.print("Please input number of days to display (between 0 and 20) --> ");
days = input.nextInt();
System.out.print("\n");
if (( days < 0 ) | (days > 20 )){System.out.print("Input value outside the range!!!"+ "\n");}
}while(( days < 0 ) | (days > 20 ));
// computation
latePen = new LatePenalties(mark);
latePen.scheme1(days);
latePen.scheme2(days);
}
}
I have to show when the faling mark occurs(at less than 40), but I have to stop the loop at 20 or when the number of days is reached, as I show in the example on what it is expected.
You can use break to come out of the loop as soon as total is less than 40. You can update your scheme1 method as below
public void scheme1(int d) {
int total = mark;
System.out.print("Scheme 1" + "\n");
int days = 0;
// Loop
for (int loopParameter = START_CONDITION; loopParameter <= d; loopParameter++) {
System.out.print("(" + loopParameter + ") " + total + " ");
total = total + constantDiffSch1;
if(total < 40)
break;
days++;
} // End
if (total <= 40) {
System.out.print("\nThis work can be up to " + days +" days late before failing.");
}
System.out.print("\n\n");
}
Please input mark (between 0 and 100) --> 82
Please input number of days to display (between 0 and 20) --> 10
Scheme 1 (0) 82 (1) 77 (2) 72 (3) 67 (4) 62 (5) 57 (6) 52
(7) 47 (8) 42
This work can be up to 8 days late before failing.
You don't need to know your loopParameter to calculate the number of days. You can calculate it like so:
int days = (d - 40) / -constantDiffSch1;
You can use break when you want to quit loop. So:
if (total < 20) break;
And off topic. Don't call loopParameter like that. It is good practice to call it in one symbol (or short word) like i or day. It makes code easier to read and understand.

Convert given number to power in Java

I have a main function that calls another function and passes the given number as a parameter. In the other function, I want to break up the given number into sums of power. How can this be done?
My code looks like:
public static void main()
{
String hello=raisetopower(in.nextInt());
}
public String raisetopower(int n)
{
// do the logic
}
Explanation :
say if the number is 25: the function should return 5^2 + 0^2
and if it is 26: 5^2+1^2
I agree with Richard's comment that this more Mathematics than Java
The question needs more information to be able to provide code to assist, such as whether or not you consider a maximum base like 10 and whether or not all bases should be in the output even if they are to the power of 0 as your example is confusing:
"say if the number is 25: the function should return 5^2 + 0^2 and if
it is 26: 5^2+1^2"
However with that in mind, hopefully this example will be able to assist
Assuming you do have a maximum base being considered, you could start from the highest base to the lowest and use logs
If the result of the log is greater than or equal to 1, then this value should be in the output, so subtract that value and continue on to the next base
Keep continuing until you hit a value of exactly 1 and that should be your end condition
E.g assuming a maximum base of 5 for this example with an input of 27
log5 27 = 2.04781858346
so we will have 5^2 in the output and subtract this from the input, you could use floor to extract the '2'
log4 2 = 0.5
less than one so not an integer power
log3 2 = 0.630929753571
less than one so not an integer power
log2 2 = 1
add to output as greater than or equal to 1 and terminate as it is exactly 1
If you're only displaying bases with powers greater than or equal to one (this was unclear), your output at this point would be:
27 = 25^2 + 2^1
You could use a StringBuilder or an ordered collection of custom objects holding your bases and powers to make it easier to generate the output
Here's an SSCCE for my above algorithm:
import java.util.Scanner;
public class NumberToPowerConversion {
public static void main(String[] args) {
int maxBaseToConsider = 5;
System.out.println("Input number to convert: ");
Scanner input = new Scanner(System.in);
int number = input.nextInt();
StringBuilder output = new StringBuilder("Represented as powers: " + number + " = ");
for(int base = maxBaseToConsider; base >= 1; base--){
//Prevent division by 0 (log 1)
double logResult = base > 1 ? Math.log(number) / Math.log(base) : 1;
int floorResult = (int)Math.floor(logResult);
if(number == 1 || logResult == 1.0){
output.append(base + "^" + floorResult);
number -= Math.pow(base, floorResult);
if(number != 0){
//If the number couldn't be broken down completely, add the remainder to the output
output.append(" + " + number + "^1"); //To keep format consistent
}
break; //end condition reached
}
else if(floorResult >= 1){
output.append(base + "^" + floorResult);
number -= Math.pow(base, floorResult);
if(number == 0){ break; }
else{ output.append(" + "); }
}
}
System.out.println(output.toString());
}
}
Example output:
Represented as powers: 27 = 5^2 + 2^1
Represented as powers: 77 = 5^2 + 4^2 + 3^3 + 2^3 + 1^1
Represented as powers: 234 = 5^3 + 4^3 + 3^3 + 2^4 + 1^1 + 1^1
Represented as powers: 99 = 5^2 + 4^3 + 3^2 + 2^0
Represented as powers: 1 = 5^0
I have actually found the solution of this problem over here : https://github.com/Widea/Interview-Questions/blob/master/Hard/Random/PowerNumbers.java
/* Algorithm :
i <- square root of n
while n<1
n <- n-square of i
r <- r concatenate with i^2
if n=0 r concatenate with i^0
if n=1 r concatenate with i^1
i <- square root of n
return r
*/
public static String raisetopower(int n){
String raised="";
int i=(int)Math.sqrt(n);
while(n>1){
n=n-(int)Math.pow(i,2);
raised+=String.valueOf(i)+"^2+";
if(n==0)
raised+="0^2";
if(n==1)
raised+="1^2";
i=(int)Math.sqrt(n);
}
return raised;
}

Efficient solution for my task needed

I just solve this but want know more efficient way to do matrix multiplication
M = | 1 0 3 |
| 1 0 2 |
| 0 5 0 |
f[n] = M^n
I have implemented using Exponentiation_by_squaring
Is there more efficient then this ?
I guess, this is actually more suitable for math as there's a closed form solution. It's system of Linear homogeneous recurrence relations with constant coefficients.
Another posibility: You could speed up the program twice by deriving a formula for two steps, i.e., express RR(i) etc. via RR(i-2), etc.
And this can be repeated, so you can jump much faster.
One problem is that your calculations are overflowing. If you run it for K=1 and J=9, you get -334328541#510576792#-817751931.
The easiest fix for that is to do % 1000000006 in calculateProduction.
About efficiency, I would look at this problem as performing matrix multiplications.
You start with the vector (i.e. 1*3 matrix):
3 1 0
And at each step you multiply it (mod 1000000006) with the matrix:
1 1 0
0 0 5
3 2 0
Let's call the vector V and the matrix M. Basically you need to calculate V*MN. Since matrix multiplication is associative, you can calculate MN first, and do that recursively:
MN = (MN/2)2 if N is even, or
MN = M*(M[N/2])2 if N is odd
You don't need to calculate MM. This is why:
PP[i] = 5*MM[i-1] = 5*(RR[i-2] + 2*PP[i-2])
RR[i] = RR[i-1] + 3*PP[i-1] = (RR[i-2] + 3*PP[i-2]) + 3*PP[i-1]
See? You don't need to calculate MM at each step. This should be the algorithm:
public class RecurrenceMachine {
private static final int max = 1000000006;
public String calculate(int k, int j) {
long n = k * j;
if (n < 1)
return "error";
long RRi2 = 3;
long PPi2 = 0;
long RRi1 = 3 + 3 * PPi2;
long PPi1 = 5 * 1;
if (n == 1)
return RRi1 + "##" + (RRi2 + 2 * PPi2) + "##" + PPi1;
Long PPi = (long) 0, RRi = (long) 0, temp;
int i;
for (i = 2; i <= n; i++) {
temp = RRi2 + 2 * PPi2;
PPi = 5 * temp;
if (PPi >= max)
PPi %= max;
RRi = temp + PPi2 + 3 * PPi1;
if (RRi >= max)
RRi %= max;
RRi2 = RRi1;
PPi2 = PPi1;
RRi1 = RRi;
PPi1 = PPi;
}
return RRi + "##" + (RRi2 + 2 * PPi2) % max + "##" + PPi1;
}
}
I tried only with small values and it seems to work.

Strange: Cant get '1' from Math.random

I am using the following code, it generates numbers randomly but the problem is, I am not able to figure out why does not it generate the number 1
int ran, g, d, col, ran2;
double y = 1000 * (Double.parseDouble(t2.getText()));
int x = (int) y;
d = Integer.parseInt(anum.getText());
double c = 10;
int prevrandom = Integer.parseInt(lnum.getText());
lnum.setText("");
lnum.setVisible(true);
for (g = 0; g==0;) {
d = Integer.parseInt(anum.getText());
ran = (int) (Math.random() * (c)); // Random Number Creation Starts
if (ran > (c / 10)) {
g = 1;
ran2 = ((int) (Math.random() * 10)) % 2;
if (ran2 == 1) {
ran = ran * (-1);
}
d = d + ran;
if (d < 0) {
ran = ran * (-1);
d = d + (2 * ran);
}
int a = d - ran;
if(prevrandom==ran){
g=0;
}
if(g==1){
lnum.setText("" + ran);
}
}
}
I call this function(button) from somewhere. The problem comes when the sum ('a') becomes 4, according to my conditions it shouldn't allow any number other than 'one' and thus it goes into infinite loop.
I am talking about ran variable. Which I get after multiplying Math.random with 10^x where x is a positive integer.
Here ran2 is a number with value 1 or 0. As I multiply Math.Random with 10 which gives a 1 digit number and I mod it with 2.
THis is a 14 year old boy new to java. it would be greatful of people out here to help rather than discourage.
Look at the Javadoc:
Returns a double value with a positive sign, greater than or equal to
0.0 and less than 1.0. Returned values are chosen pseudorandomly with (approximately) uniform distribution from that range.
If you need integer random numbers, you might be better off with java.util.Random. To generate a random integer in the range a..b (inclusively), you can use
Random random=new Random();
int rnd=a+random.nextInt(b-a+1);
The problem lies in the code
if (ran > (c / 10)) {
The random number gets created which is even equal to one; but here due to the sign '>' it gets rejected.
Use '>=' instead.
ran = (int) (Math.random() * (c)); where c is from 10 to 10^x
This can be 1 as follows.
int c = 1000;
for (int i = 0; i < 1000; i++) {
int count = 0;
int ran;
do {
ran = (int) (Math.random() * (c)); // where c is from 10 to 10^x
count++;
} while (ran != 1);
System.out.println("count: " + count);
}
prints sometime like
count: 1756
count: 86
count: 839
count: 542
count: 365
....
count: 37
count: 2100
count: 825
count: 728
count: 1444
count: 1943
It returns 1 a thousand time in less than a second.

Categories

Resources