How to the "decision/path" during recursion? - java

I want to calculate the minimal costs in production by choosing lot sizes with recursion. The value I get is correct, but I also want to save the correct decisions/path(how much to produce in each period n). I don't know how to save it correctly. This way I just overwrite it everytime.
n = period, i = inventory, pcap = production capacity, demand[n] = how much i sell in period n,
Thanks!
public double getMinC(int n, int i) {
if(demand[n]-i > pcap) return Double.MAX_VALUE;
if(this.n == n) {
if(demand[n] < i) { //not sure if i need this
decision[n] = 0;
return storagecost * i-demand[n];
}
decision[n] = demand[n]-i;
return varc * demand[n]-i + fixc;
}
double min = Double.MAX_VALUE;
double cost = min;
int xmin = Math.max(0, demand[n] - i);
int xmax = Math.min(storagecap-i+demand[n], pcap);
int bestx = -1;
for(int x=xmin; x<=xmax; x++) {
cost = getMinC(n+1, i+x-demand[n]) + storagecost * (i+x-demand[n]);
if(x!=0) cost += fixc + varc * x;
if(cost< min) {
min = cost;
bestx = x;
}
}
decision[n] = bestx;
return min;
}

Your function should return both the value of the best decision along with the set of values that lead to that best solution. Something like:
struct solution {
double min;
int *decision;
}
This code:
cost = getMinC(n+1, i+x-demand[n]) + storagecost * (i+x-demand[n]);
if(x!=0) cost += fixc + varc * x;
if(cost< min) {
min = cost;
bestx = x;
}
should be changed to:
sol = getMinC(n+1, i+x-demand[n]) + storagecost * (i+x-demand[n]);
if(x!=0) cost += fixc + varc * x;
if ( sol.min< minsol.min) {
minsol.min = sol.min;
minsol.decision=malloc (n, sizeof (int));
minsol.decision [0]=x;
// Copy content of sol.decision into minsol.decision starting at index 1
}
...
...
return minsol;
Note that you need to take care of deallocating the returned solution structure and take care of allocating a new solution structure to be returned. A more efficient way would be to return a linked list instead of the array within the solution struct and append minx to the returned linked list of decisions.
This is in no way complete but I hope you got the idea.

Related

StackOverFlowError while calculating cos(x) using recursive McLaurin series approximation

I have to write simple code to calculate cos(x) value with McLaurin series approximation. I have to do it recursively. Problem is that with too big angle (param in radians) or too high precision (loop has to stop while last term is smaller or equal than given ε) I get StackOverFlowError. At first I did it non-recursively and it worked perfectly, but it's not fully correct according to assignment. I tried to decrease number of calls for term, but I couldn't fix this. Is there any way to improve this code?
public int factorial(int n) {
int result = 1;
for (int i = 1; i <= n; i++) {
result = result * i;
}
return result;
}
public double term(double x, int n) {
return Math.pow(-1, n) * (Math.pow(x, 2*n) / factorial(2*n));
}
public double laurin(String param, String epsilon) {
double x, eps;
double result = 1;
int n = 0;
x = Double.parseDouble(param);
eps = Double.parseDouble(epsilon);
while(Math.abs(term(x, n)) > eps) {
result += term(x, n) * (term(x, n+1) / term(x, n));
n++;
}
return result;
}
Changing factorial(int n) to non-recursive hasn't changed much, I still get an error real quick.

how to remove : java.lang.OutOfMemoryError

I am solving this question (Stated below with solution (including dp)) , I am getting java.lang.OutOfMemoryError error . I have learned that dp removes unnecessary calculations so i have applied dp also , but then why i am getting this error can we optimize better than dp also ? or i am doing something wrong as the solution runs for small input?
Problem Statement
Your algorithms have become so good at predicting the market that you now know what the share price of Wooden Orange Toothpicks Inc. (WOT) will be for the next N days.
Each day, you can either buy one share of WOT, sell any number of shares of WOT that you own, or not make any transaction at all. What is the maximum profit you can obtain with an optimum trading strategy?
Input
The first line contains the number of test cases T. T test cases follow:
The first line of each test case contains a number N. The next line contains N integers, denoting the predicted price of WOT shares for the next N days.
Output
Output T lines, containing the maximum profit which can be obtained for the corresponding test case.
Constraints
1 <= T <= 10
1 <= N <= 50000
All share prices are between 1 and 100000
MY solution
import java.util.Arrays;
import java.util.Scanner;
public class Stock_Maximize {
private static int days;
private static long[] a;
private static int t;
private static long[][] dp;
// private static int max;
public static void main(String args[]) {
Scanner e = new Scanner(System.in);
t = e.nextInt();
while (t > 0) {
days = e.nextInt();
int m = days;
// System.out.println(days);
int i = 1;
a = new long[days + 1];
while (m > 0) {
a[i] = e.nextInt();
i++;
m--;
}
dp = new long[days + 1][days + 1];
for (int k = 0; k < days + 1; k++) {
Arrays.fill(dp[k], -1);
}
System.out.println(solve(1, 0));
t--;
}
}
private static long solve(int daynumber, int stocks) {
// TODO Auto-generated method stub
// System.out.println("vefvvv");
long x;
int i = 1;
if (daynumber == (days + 1)) {
// System.out.println("daynumber= " + daynumber);
return 0;
}
if (stocks < 0) {
// System.out.println("***********");
return 0;
}
if (dp[daynumber][stocks] != -1) {
return dp[daynumber][stocks];
}
long z = solve(daynumber + 1, stocks + 1) - a[daynumber];
// System.out.println("z= " + z);
long m = solve(daynumber + 1, stocks);
int d = stocks;
long max = Long.MIN_VALUE;
while (d > 0) {
d = stocks - i;
x = solve(daynumber + 1, d) + i * a[daynumber];
i++;
// System.out.println("x= " + x + "z= " + z + "m= " + m);
if (max < getmax(x, z, m)) {
max = getmax(x, z, m);
}
}
dp[daynumber][stocks] = Math.max(max, Math.max(z, m));
return dp[daynumber][stocks];
}
private static long getmax(long x, long z, long m) {
// TODO Auto-generated method stub
return Math.max(Math.max(x, z), m);
}
}
As mention in the comment, for your dp table, you are using 50000*50000*64 bit memory (long[][]dp), which is around 20 GB, and it is too large for any personal computer.
The problem can be solved in a much easier manner.
For set of n days, assume that in day i, we have the largest price for WOT, so, to make the largest profit, we need to buy WOT from day 0 to day i - 1, and sell all of them in day i. From day i + 1 onward, we can follow the same strategy, which we will result us the maximum profit.
Space complexity for this solution is O(n), and time complexity is O(n log n) if implemented properly.
Pseudo-code:
class WOT{
int day;
int price;
}
WOT[]data = new WOT[n];
//Initialize data here
long[]cost = new long[n];
for(int i = 0; i < n; i++)
cost[i] = data[i].price + (i > 0 ? cost[i - 1] : 0);
sort data based on price
int startDate = 0;
long result = 0;
for(int i = n - 1; i >= 0; i--){
if(data[i].day > startDate){
int numberOfDays = data[i].day - startDate;
result += numberOfDays*data[i].price - (cost[data[i].day - 1] - cost[startDate - 1])
startDate = data[i].day + 1;
}
}
print result;

Riemann Zeta Function in Java - Infinite Recursion with Functional Form

Note: Updated on 06/17/2015. Of course this is possible. See the solution below.
Even if anyone copies and pastes this code, you still have a lot of cleanup to do. Also note that you will have problems inside the critical strip from Re(s) = 0 to Re(s) = 1 :). But this is a good start.
import java.util.Scanner;
public class NewTest{
public static void main(String[] args) {
RiemannZetaMain func = new RiemannZetaMain();
double s = 0;
double start, stop, totalTime;
Scanner scan = new Scanner(System.in);
System.out.print("Enter the value of s inside the Riemann Zeta Function: ");
try {
s = scan.nextDouble();
}
catch (Exception e) {
System.out.println("You must enter a positive integer greater than 1.");
}
start = System.currentTimeMillis();
if (s <= 0)
System.out.println("Value for the Zeta Function = " + riemannFuncForm(s));
else if (s == 1)
System.out.println("The zeta funxtion is undefined for Re(s) = 1.");
else if(s >= 2)
System.out.println("Value for the Zeta Function = " + getStandardSum(s));
else
System.out.println("Value for the Zeta Function = " + getNewSum(s));
stop = System.currentTimeMillis();
totalTime = (double) (stop-start) / 1000.0;
System.out.println("Total time taken is " + totalTime + " seconds.");
}
// Standard form the the Zeta function.
public static double standardZeta(double s) {
int n = 1;
double currentSum = 0;
double relativeError = 1;
double error = 0.000001;
double remainder;
while (relativeError > error) {
currentSum = Math.pow(n, -s) + currentSum;
remainder = 1 / ((s-1)* Math.pow(n, (s-1)));
relativeError = remainder / currentSum;
n++;
}
System.out.println("The number of terms summed was " + n + ".");
return currentSum;
}
public static double getStandardSum(double s){
return standardZeta(s);
}
//New Form
// zeta(s) = 2^(-1+2 s)/((-2+2^s) Gamma(1+s)) integral_0^infinity t^s sech^2(t) dt for Re(s)>-1
public static double Integrate(double start, double end) {
double currentIntegralValue = 0;
double dx = 0.0001d; // The size of delta x in the approximation
double x = start; // A = starting point of integration, B = ending point of integration.
// Ending conditions for the while loop
// Condition #1: The value of b - x(i) is less than delta(x).
// This would throw an out of bounds exception.
// Condition #2: The value of b - x(i) is greater than 0 (Since you start at A and split the integral
// up into "infinitesimally small" chunks up until you reach delta(x)*n.
while (Math.abs(end - x) >= dx && (end - x) > 0) {
currentIntegralValue += function(x) * dx; // Use the (Riemann) rectangle sums at xi to compute width * height
x += dx; // Add these sums together
}
return currentIntegralValue;
}
private static double function(double s) {
double sech = 1 / Math.cosh(s); // Hyperbolic cosecant
double squared = Math.pow(sech, 2);
return ((Math.pow(s, 0.5)) * squared);
}
public static double getNewSum(double s){
double constant = Math.pow(2, (2*s)-1) / (((Math.pow(2, s)) -2)*(gamma(1+s)));
return constant*Integrate(0, 1000);
}
// Gamma Function - Lanczos approximation
public static double gamma(double s){
double[] p = {0.99999999999980993, 676.5203681218851, -1259.1392167224028,
771.32342877765313, -176.61502916214059, 12.507343278686905,
-0.13857109526572012, 9.9843695780195716e-6, 1.5056327351493116e-7};
int g = 7;
if(s < 0.5) return Math.PI / (Math.sin(Math.PI * s)*gamma(1-s));
s -= 1;
double a = p[0];
double t = s+g+0.5;
for(int i = 1; i < p.length; i++){
a += p[i]/(s+i);
}
return Math.sqrt(2*Math.PI)*Math.pow(t, s+0.5)*Math.exp(-t)*a;
}
//Binomial Co-efficient - NOT CURRENTLY USING
/*
public static double binomial(int n, int k)
{
if (k>n-k)
k=n-k;
long b=1;
for (int i=1, m=n; i<=k; i++, m--)
b=b*m/i;
return b;
} */
// Riemann's Functional Equation
// Tried this initially and utterly failed.
public static double riemannFuncForm(double s) {
double term = Math.pow(2, s)*Math.pow(Math.PI, s-1)*(Math.sin((Math.PI*s)/2))*gamma(1-s);
double nextTerm = Math.pow(2, (1-s))*Math.pow(Math.PI, (1-s)-1)*(Math.sin((Math.PI*(1-s))/2))*gamma(1-(1-s));
double error = Math.abs(term - nextTerm);
if(s == 1.0)
return 0;
else
return Math.pow(2, s)*Math.pow(Math.PI, s-1)*(Math.sin((Math.PI*s)/2))*gamma(1-s)*standardZeta(1-s);
}
}
Ok well we've figured out that for this particular function, since this form of it isn't actually a infinite series, we cannot approximate using recursion. However the infinite sum of the Riemann Zeta series (1\(n^s) where n = 1 to infinity) could be solved through this method.
Additionally this method could be used to find any infinite series' sum, product, or limit.
If you execute the code your currently have, you'll get infinite recursion as 1-(1-s) = s (e.g. 1-s = t, 1-t = s so you'll just switch back and forth between two values of s infinitely).
Below I talk about the sum of series. It appears you are calculating the product of the series instead. The concepts below should work for either.
Besides this, the Riemann Zeta Function is an infinite series. This means that it only has a limit, and will never reach a true sum (in finite time) and so you cannot get an exact answer through recursion.
However, if you introduce a "threshold" factor, you can get an approximation that is as good as you like. The sum will increase/decrease as each term is added. Once the sum stabilizes, you can quit out of recursion and return your approximate sum. "Stabilized" is defined using your threshold factor. Once the sum varies by an amount less than this threshold factor (which you have defined), your sum has stabilized.
A smaller threshold leads to a better approximation, but also longer computation time.
(Note: this method only works if your series converges, if it has a chance of not converging, you might also want to build in a maxSteps variable to cease execution if the series hasn't converged to your satisfaction after maxSteps steps of recursion.)
Here's an example implementation, note that you'll have to play with threshold and maxSteps to determine appropriate values:
/* Riemann's Functional Equation
* threshold - if two terms differ by less than this absolute amount, return
* currSteps/maxSteps - if currSteps becomes maxSteps, give up on convergence and return
* currVal - the current product, used to determine threshold case (start at 1)
*/
public static double riemannFuncForm(double s, double threshold, int currSteps, int maxSteps, double currVal) {
double nextVal = currVal*(Math.pow(2, s)*Math.pow(Math.PI, s-1)*(Math.sin((Math.PI*s)/2))*gamma(1-s)); //currVal*term
if( s == 1.0)
return 0;
else if ( s == 0.0)
return -0.5;
else if (Math.abs(currVal-nextVal) < threshold) //When a term will change the current answer by less than threshold
return nextVal; //Could also do currVal here (shouldn't matter much as they differ by < threshold)
else if (currSteps == maxSteps)//When you've taken the max allowed steps
return nextVal; //You might want to print something here so you know you didn't converge
else //Otherwise just keep recursing
return riemannFuncForm(1-s, threshold, ++currSteps, maxSteps, nextVal);
}
}
This is not possible.
The functional form of the Riemann Zeta Function is --
zeta(s) = 2^s pi^(-1+s) Gamma(1-s) sin((pi s)/2) zeta(1-s)
This is different from the standard equation in which an infinite sum is measured from 1/k^s for all k = 1 to k = infinity. It is possible to write this as something similar to --
// Standard form the the Zeta function.
public static double standardZeta(double s) {
int n = 1;
double currentSum = 0;
double relativeError = 1;
double error = 0.000001;
double remainder;
while (relativeError > error) {
currentSum = Math.pow(n, -s) + currentSum;
remainder = 1 / ((s-1)* Math.pow(n, (s-1)));
relativeError = remainder / currentSum;
n++;
}
System.out.println("The number of terms summed was " + n + ".");
return currentSum;
}
The same logic doesn't apply to the functional equation (it isn't a direct sum, it is a mathematical relationship). This would require a rather clever way of designing a program to calculate negative values of Zeta(s)!
The literal interpretation of this Java code is ---
// Riemann's Functional Equation
public static double riemannFuncForm(double s) {
double currentVal = (Math.pow(2, s)*Math.pow(Math.PI, s-1)*(Math.sin((Math.PI*s)/2))*gamma(1-s));
if( s == 1.0)
return 0;
else if ( s == 0.0)
return -0.5;
else
System.out.println("Value of next value is " + nextVal(1-s));
return currentVal;//*nextVal(1-s);
}
public static double nextVal(double s)
{
return (Math.pow(2, s)*Math.pow(Math.PI, s-1)*(Math.sin((Math.PI*s)/2))*gamma(1-s));
}
public static double getRiemannSum(double s) {
return riemannFuncForm(s);
}
Testing on three or four values shows that this doesn't work. If you write something similar to --
// Riemann's Functional Equation
public static double riemannFuncForm(double s) {
double currentVal = Math.pow(2, s)*Math.pow(Math.PI, s-1)*(Math.sin((Math.PI*s)/2))*gamma(1-s); //currVal*term
if( s == 1.0)
return 0;
else if ( s == 0.0)
return -0.5;
else //Otherwise just keep recursing
return currentVal * nextVal(1-s);
}
public static double nextVal(double s)
{
return (Math.pow(2, s)*Math.pow(Math.PI, s-1)*(Math.sin((Math.PI*s)/2))*gamma(1-s));
}
I was misinterpretation how to do this through mathematics. I will have to use a different approximation of the zeta function for values less than 2.
I think I need to use a different form of the zeta function. When I run the entire program ---
import java.util.Scanner;
public class Test4{
public static void main(String[] args) {
RiemannZetaMain func = new RiemannZetaMain();
double s = 0;
double start, stop, totalTime;
Scanner scan = new Scanner(System.in);
System.out.print("Enter the value of s inside the Riemann Zeta Function: ");
try {
s = scan.nextDouble();
}
catch (Exception e) {
System.out.println("You must enter a positive integer greater than 1.");
}
start = System.currentTimeMillis();
if(s >= 2)
System.out.println("Value for the Zeta Function = " + getStandardSum(s));
else
System.out.println("Value for the Zeta Function = " + getRiemannSum(s));
stop = System.currentTimeMillis();
totalTime = (double) (stop-start) / 1000.0;
System.out.println("Total time taken is " + totalTime + " seconds.");
}
// Standard form the the Zeta function.
public static double standardZeta(double s) {
int n = 1;
double currentSum = 0;
double relativeError = 1;
double error = 0.000001;
double remainder;
while (relativeError > error) {
currentSum = Math.pow(n, -s) + currentSum;
remainder = 1 / ((s-1)* Math.pow(n, (s-1)));
relativeError = remainder / currentSum;
n++;
}
System.out.println("The number of terms summed was " + n + ".");
return currentSum;
}
public static double getStandardSum(double s){
return standardZeta(s);
}
// Riemann's Functional Equation
public static double riemannFuncForm(double s, double threshold, double currSteps, int maxSteps) {
double term = Math.pow(2, s)*Math.pow(Math.PI, s-1)*(Math.sin((Math.PI*s)/2))*gamma(1-s);
//double nextTerm = Math.pow(2, (1-s))*Math.pow(Math.PI, (1-s)-1)*(Math.sin((Math.PI*(1-s))/2))*gamma(1-(1-s));
//double error = Math.abs(term - nextTerm);
if(s == 1.0)
return 0;
else if (s == 0.0)
return -0.5;
else if (term < threshold) {//The recursion will stop once the term is less than the threshold
System.out.println("The number of steps is " + currSteps);
return term;
}
else if (currSteps == maxSteps) {//The recursion will stop if you meet the max steps
System.out.println("The series did not converge.");
return term;
}
else //Otherwise just keep recursing
return term*riemannFuncForm(1-s, threshold, ++currSteps, maxSteps);
}
public static double getRiemannSum(double s) {
double threshold = 0.00001;
double currSteps = 1;
int maxSteps = 1000;
return riemannFuncForm(s, threshold, currSteps, maxSteps);
}
// Gamma Function - Lanczos approximation
public static double gamma(double s){
double[] p = {0.99999999999980993, 676.5203681218851, -1259.1392167224028,
771.32342877765313, -176.61502916214059, 12.507343278686905,
-0.13857109526572012, 9.9843695780195716e-6, 1.5056327351493116e-7};
int g = 7;
if(s < 0.5) return Math.PI / (Math.sin(Math.PI * s)*gamma(1-s));
s -= 1;
double a = p[0];
double t = s+g+0.5;
for(int i = 1; i < p.length; i++){
a += p[i]/(s+i);
}
return Math.sqrt(2*Math.PI)*Math.pow(t, s+0.5)*Math.exp(-t)*a;
}
//Binomial Co-efficient
public static double binomial(int n, int k)
{
if (k>n-k)
k=n-k;
long b=1;
for (int i=1, m=n; i<=k; i++, m--)
b=b*m/i;
return b;
}
}
I notice that plugging in zeta(-1) returns -
Enter the value of s inside the Riemann Zeta Function: -1
The number of steps is 1.0
Value for the Zeta Function = -0.0506605918211689
Total time taken is 0.0 seconds.
I knew that this value was -1/12. I checked some other values with wolfram alpha and observed that --
double term = Math.pow(2, s)*Math.pow(Math.PI, s-1)*(Math.sin((Math.PI*s)/2))*gamma(1-s);
Returns the correct value. It is just that I am multiplying this value every time by zeta(1-s). In the case of Zeta(1/2), this will always multiply the result by 0.99999999.
Enter the value of s inside the Riemann Zeta Function: 0.5
The series did not converge.
Value for the Zeta Function = 0.999999999999889
Total time taken is 0.006 seconds.
I am going to see if I can replace the part for --
else if (term < threshold) {//The recursion will stop once the term is less than the threshold
System.out.println("The number of steps is " + currSteps);
return term;
}
This difference is the error between two terms in the summation. I may not be thinking about this correctly, it is 1:16am right now. Let me see if I can think better tomorrow ....

How can I use an array variable to IF statement?

I am developing a simple Taxi Meter Calculator system. I have no idea what to use to implement it. I have written a code but got stuck at IF statement where I had to insert an array variable. I am not sure whether this is the correct way to implement it.
This is the logic.
The first Km is 50/-.
Then the next 10Km will be charged 45/- per Km. eg : if 2km were gone
, charges would be 50/- + 45/- = 95/-, if 3km were gone 140/-.
The next 10km will be charged 35/- per km
25/- per km will be charged no matter how many kms gone after the above 10km exceed.
This is the code I have coded so far
private void btn_calActionPerformed(java.awt.event.ActionEvent evt) {
int kms1 = 50;
int kms2 = 45;
int kms3 = 35;
int kms4 = 25;
String[] firstkm={"3,4,5,6,7,8,9,10,11"};
if(txt_km.getText().equals("1")){
lblout.setText(""+kms1);
}
if(txt_km.getText().equals("2")){
lblout.setText(""+(kms1+kms2));
}if(txt_km.getText().equals(firstkm)){
int get = Integer.parseInt(txt_km.getText());
int rate = get+kms2;
lblout.setText(""+rate);
}
}
if there is any other method to solve this problem please mention it.
int fare = 0;
int distance = 0;
if (distance > 21) {
fare += (distance - 21) * 25;
distance = 21;
}
if (distance > 11) {
fare += (distance - 11) * 35;
distance = 11;
}
if (distance > 1) {
fare += (distance - 1) * 45;
distance = 1;
}
if (distance > 0) {
fare += distance * 50;
}
Then refactor by putting the magic numbers into arrays and loop through the arrays (4 times).
Here's a hint: Implement this method
/**
This method returns the amount a passenger must pay for this kilometer of their trip
*/
public int chargeForKilometer(int kilometerNumberInTrip) {
//...
}
try
String[] firstkm={3,4,5,6,7,8,9,10,11};
if(txt_km.getText().equals(firstkm[1])){
lblout.setText(""+kms1);
}
....
In case your conditions change and you want to avoid adding if conditions in your code, I wrote a configurable code.
public int calculateRate(int kmCount){
int baseRate = 50;
int[] stepRate = {45,35};
int step = 10;
int fare = 0;
int threshold = 21;
int beyondThresholdRate = 25;
if(kmCount>0){
fare = baseRate;
fare += (kmCount - threshold)<0?0:(kmCount - threshold)*beyondThresholdRate;
kmCount = kmCount - 1;
for(int i=0;i<=((kmCount/step) + (kmCount%step>0?1:0));i++){
fare += (kmCount/step)==0?(kmCount%step)*stepRate[i]:step*stepRate[i];
kmCount -=step;
if(i==stepRate.length-1) break;
}
}
return fare;
}
It is slightly complex, however, flexible.

Split Temporary Variable Refactoring Example

I'm preparing for my exams and I stumbled across a weird previous year actual exam question:
Perform Split Temporary Variable Refactoring on this piece of code:
public int createUniqueCasenumber (GregorianCalendar date, int departmentID) {
int temp = 0;
temp = date.get(GregorianCalendar.DAY_OF_MONTH);
temp = temp * 100;
temp = temp + date.get(GregorianCalendar.MONTH);
temp = temp * 100;
temp = temp + date.get(GregorianCalendar.YEAR);
temp = temp * 100;
temp = temp + (date.get(GregorianCalendar.HOUR_OF_DAY) * departmentID);
return temp;
}
Now I understand the Split Temporary Variable Refactoring as a case when a temp variable is used for different purposes and we simply "rename" it into two different making-sense-names.
But in this situation I can't really thinks of smart names, the function of this temp variable is rather similar to a loop collecting variable.
The only thing remotely close to the required refactoring would be:
public int createUniqueCasenumber (GregorianCalendar date, int departmentID) {
int result= 0;
int firstStep = 100 * date.get(GregorianCalendar.DAY_OF_MONTH);
int secondStep = 100 * (firstStep + date.get(GregorianCalendar.MONTH));
int thirdStep = 100 * (secondStep + date.get(GregorianCalendar.YEAR));
result = thirdStep + (date.get(GregorianCalendar.HOUR_OF_DAY) * departmentID);
return result;
}
But why would you do it "in real life" ? Or is there some deep meaning I don't see?
Any thoughts?
Thank you in advance :)
Your refactoring is incorrect; each -step variable does not depend on any of the others (note that each assignment to temp from a date.get overwrites what was there before). Also makes it clear that all of the assignments except the last, and all of the multiplications by 100, are useless.
This refactoring makes it clear that these values are independent, and could be assigned in any order (even in parallel, if that were allowed).
You can refactor this code in 2 steps
If you look closely, you may notice, that day multyplied by 100 three times, month - twice and year - once
So you can rewrite code in this manner:
public int createUniqueCasenumber(GregorianCalendar date, int departmentID) {
int temp = date.get(GregorianCalendar.DAY_OF_MONTH) * 100 * 100 * 100;
temp += date.get(GregorianCalendar.MONTH) * 100 * 100;
temp += date.get(GregorianCalendar.YEAR) * 100;
temp += date.get(GregorianCalendar.HOUR_OF_DAY) * departmentID;
return temp;
}
After that it's much easier to split temp variable:
public int createUniqueCasenumber(GregorianCalendar date, int departmentID) {
int magnifiedDay = date.get(GregorianCalendar.DAY_OF_MONTH) * 100 * 100 * 100;
int magnifiedMonth = date.get(GregorianCalendar.MONTH) * 100 * 100;
int magnifiedYear = date.get(GregorianCalendar.YEAR) * 100;
int magnifiedHour = date.get(GregorianCalendar.HOUR_OF_DAY) * departmentID;
return magnifiedDay + magnifiedMonth + magnifiedYear + magnifiedHour;
}

Categories