I am converting a some C++ to java and have a small bit that I am unsure about
first question is what is tested for in the line
if (ampconst[i][0] || ampconst[i][1])
this in an example to the data in the array.
static short ampconst[NUT_SERIES][2] = {
{0,0},
{0,0},
{46,-24}
};
and my second question is that the ampsecul array is far shorter than NUT_SERIES
so I am getting array out of bounds exceptions, the array terminates like so
static long ampsecul[][5] = {
{0 ,-171996 ,-1742 ,92025 ,89},
{1 ,2062 ,2 ,-895 ,5},
{8 ,-13187 ,-16 ,5736 ,-31},
{9 ,1426 ,-34 ,54 ,-1},
{10 ,-517 ,12 ,224 ,-6},
{11 ,217 ,-5 ,-95 ,3},
{12 ,129 ,1 ,-70 ,0},
{15 ,17 ,-1 ,0 ,0},
{17 ,-16 ,1 ,7 ,0},
{30 ,-2274 ,-2 ,977 ,-5},
{31 ,712 ,1 ,-7 ,0},
{32 ,-386 ,-4 ,200 ,0},
{33 ,-301 ,0 ,129 ,-1},
{37 ,63 ,1 ,-33 ,0},
{38 ,-58 ,-1 ,32 ,0},
/* termination */ { -1, }
};
so how could this be handled in java and what would the values be at these lines
when the array is out of bounds or how would C++ handle this.
ampsin = ampsecul[isecul][1] + ampsecul[isecul][2] * T10;
ampcos = ampsecul[isecul][3] + ampsecul[isecul][4] * T10;
thanks in advance for any advice.
This is the whole for loop too see the code in context.
for (i = isecul = 0; i < NUT_SERIES ; ++i) {
double arg = 0., ampsin, ampcos;
short j;
if (ampconst[i][0] || ampconst[i][1]) {
/* take non-secular terms from simple array */
ampsin = ampconst[i][0];
ampcos = ampconst[i][1];
} else {
/* secular terms from different array */
ampsin = ampsecul[isecul][1] + ampsecul[isecul][2] * T10;
ampcos = ampsecul[isecul][3] + ampsecul[isecul][4] * T10;
++isecul;
}
for (j = 0; j < 5; ++j)
arg += delcache[j][NUT_MAXMUL + multarg[i][j]];
if (fabs(ampsin) >= prec)
lastdpsi += ampsin * sin(arg);
if (fabs(ampcos) >= prec)
lastdeps += ampcos * cos(arg);
}
if (ampconst[i][0] || ampconst[i][1])
tests whether the first/second column in ampconst[i] contain non-zero (it is an early-out optimization: if both the constants are 0 then the calculation can be skipped)
Edit I just found (google!) that this is a nutation calculation that has been adopted in quite a few places, but seems to be originally from a libastro.
hg clone https://bitbucket.org/brandon/pyephem
As far as the isecul index is concerned: apparently isecul should never grow to >= 15 (note that i is the loop variable, not isecul, isecul is incremented conditionally).
However, seeing the 'terminator' (-1) value, I'd really expect a check some like
if (ampsecul[isecul][0] == -1)
isecul = 0; // ? just guessing :)
or
if (ampsecul[isecul][0] == -1)
break;
Also, I get the impression that the first column of ampsecul is a range-based division, so somehow, there would be a binarysearch for the matching slot into ampsecul, not direct indexing (i.e. isecul=4 would select index 2 (2..8) not 4)
Are you sure you are getting the source code correctly? I looks very much like there are some custom indexers (operators[](...)) that you misssed out on? This would probably be about the same class/function that contains the terminator check like shown above.
Edit from the linked source I get the impression that the code is very much intended as is, and hence isecul should simply not be growing >= 15
That first if statement is testing the array entries for zero/non-zero. In C/C++ a boolean is simply an int that is used in a special way such that zero is false and non-zero is true.
As for your second array question I haven't grocked it yet. But understand that C/C++ does no array bounds checking (other than what may accidentally occur if you touch an undefined storage page), so unless there's an egregious error in the C++ code there must be something that limits references to the valid bounds of the array.
Related
I'm trying to write a Java program to calculate the square root of an integer x, without using in-built functions like Math.pow() . This is the approach I tried -
class Solution {
public int mySqrt(int x) {
if(x==0 || x==1)
return x;
// if(x>=2147395600)
// return 46340;
int i;
for(i=1 ; i*i<=x ; i++) {}
return i-1;
}
}
Without the commented part, I start getting errors if x is in the range 2147395600 <= x <= 2^31-1 (which is the upper limit of an int's value range in Java). For instance, for the input x=2147395600, the expected output is 46340 but the actual output is 289398. Why is this happening? Thanks to all in advance.
PS - I am aware there are other (better) methods to solve this problem, but I'd really like to know why this code behaves this way.
Since 46340 * 46340 = 2147395600, when i=46340, x=2147395600 and you reach the condition i*i<=x it evaluates to true since 2147395600 = 2147395600. So the loop counter will incremnet by 1 and in the next iteration we will get i=46341 and i * i will cause an overflow - 46341*46341 = -2147479015.
The loop condition will still be true, since -2147479015 <= 2147395600, and the loop will not stop.
You can replace the <= with =, and check for edge cases that may occur now.
In my software, I need to decide the version of a feature based on 2 parameters. Eg.
Render version 1 -> if (param1 && param2) == true;
Render version 2 -> if (!param1 && !param2) == true;
Render version 3 -> if only param1 == true;
Render version 4 -> if only param2 == true;
So, to meet this requirement, I wrote a code which looks like this -
if(param1 && param2) //both are true {
version = 1;
}
else if(!param1 && !param2) //both are false {
version = 2;
}
else if(!param2) //Means param1 is true {
version = 3;
}
else { //Means param2 is true
version = 4;
}
There are definitely multiple ways to code this but I finalised this approach after trying out different approaches because this is the most readable code I could come up with.
But this piece of code is definitely not scalable because -
Let say tomorrow we want to introduce new param called param3. Then
the no. of checks will increase because of multiple possible
combinations.
For this software, I am pretty much sure that we
will have to accommodate new parameters in future.
Can there be any scalable & readable way to code these requirements?
EDIT:
For a scalable solution define the versions for each parameter combination through a Map:
Map<List<Boolean>, Integer> paramsToVersion = Map.of(
List.of(true, true), 1,
List.of(false, false), 2,
List.of(true, false), 3,
List.of(false, true), 4);
Now finding the right version is a simple map lookup:
version = paramsToVersion.get(List.of(param1, param2));
The way I initialized the map works since Java 9. In older Java versions it’s a little more wordy, but probably still worth doing. Even in Java 9 you need to use Map.ofEntries if you have 4 or more parameters (for 16 combinations), which is a little more wordy too.
Original answer:
My taste would be for nested if/else statements and only testing each parameter once:
if (param1) {
if (param2) {
version = 1;
} else {
version = 3;
}
} else {
if (param2) {
version = 4;
} else {
version = 2;
}
}
But it scales poorly to many parameters.
If you have to enumerate all the possible combinations of Booleans, it's often simplest to convert them into a number:
// param1: F T F T
// param2; F F T T
static final int[] VERSIONS = new int[]{2, 3, 4, 1};
...
version = VERSIONS[(param1 ? 1:0) + (param2 ? 2:0)];
I doubt that there is a way that would be more compact, readable and scalable at the same time.
You express the conditions as minimized expressions, which are compact and may have meaning (in particular, the irrelevant variables don't clutter them). But there is no systematism that you could exploit.
A quite systematic alternative could be truth tables, i.e. the explicit expansion of all combinations and the associated truth value (or version number), which can be very efficient in terms of running-time. But these have a size exponential in the number of variables and are not especially readable.
I am afraid there is no free lunch. Your current solution is excellent.
If you are after efficiency (i.e. avoiding the need to evaluate all expressions sequentially), then you can think of the truth table approach, but in the following way:
declare an array of version numbers, with 2^n entries;
use the code just like you wrote to initialize all table entries; to achieve that, enumerate all integers in [0, 2^n) and use their binary representation;
now for a query, form an integer index from the n input booleans and lookup the array.
Using the answer by Olevv, the table would be [2, 4, 3, 1]. A lookup would be like (false, true) => T[01b] = 4.
What matters is that the original set of expressions is still there in the code, for human reading. You can use it in an initialization function that will fill the array at run-time, and you can also use it to hard-code the table (and leave the code in comments; even better, leave the code that generates the hard-coded table).
Your combinations of parameters is nothing more than a binary number (like 01100) where the 0 indicates a false and the 1 a true.
So your version can be easily calculated by using all the combinations of ones and zeroes. Possible combinations with 2 input parameters are:
11 -> both are true
10 -> first is true, second is false
01 -> first is false, second is true
00 -> both are false
So with this knowledge I've come up with a quite scalable solution using a "bit mask" (nothing more than a number) and "bit operations":
public static int getVersion(boolean... params) {
int length = params.length;
int mask = (1 << length) - 1;
for(int i = 0; i < length; i++) {
if(!params[i]) {
mask &= ~(1 << length - i - 1);
}
}
return mask + 1;
}
The most interesting line is probably this:
mask &= ~(1 << length - i - 1);
It does many things at once, I split it up. The part length - i - 1 calculates the position of the "bit" inside the bit mask from the right (0 based, like in arrays).
The next part: 1 << (length - i - 1) shifts the number 1 the amount of positions to the left. So lets say we have a position of 3, then the result of the operation 1 << 2 (2 is the third position) would be a binary number of the value 100.
The ~ sign is a binary inverse, so all the bits are inverted, all 0 are turned to 1 and all 1 are turned to 0. With the previous example the inverse of 100 would be 011.
The last part: mask &= n is the same as mask = mask & n where n is the previously computed value 011. This is nothing more than a binary AND, so all the same bits which are in mask and in n are kept, where as all others are discarded.
All in all, does this single line nothing more than remove the "bit" at a given position of the mask if the input parameter is false.
If the version numbers are not sequential from 1 to 4 then a version lookup table, like this one may help you.
The whole code would need just a single adjustment in the last line:
return VERSIONS[mask];
Where your VERSIONS array consists of all the versions in order, but reversed. (index 0 of VERSIONS is where both parameters are false)
I would have just gone with:
if (param1) {
if (param2) {
} else {
}
} else {
if (param2) {
} else {
}
}
Kind of repetitive, but each condition is evaluated only once, and you can easily find the code that executes for any particular combination. Adding a 3rd parameter will, of course, double the code. But if there are any invalid combinations, you can leave those out which shortens the code. Or, if you want to throw an exception for them, it becomes fairly easy to see which combination you have missed. When the IF's become too long, you can bring the actual code out in methods:
if (param1) {
if (param2) {
method_12();
} else {
method_1();
}
} else {
if (param2) {
method_2();
} else {
method_none();
}
}
Thus your whole switching logic takes up a function of itself and the actual code for any combination is in another method. When you need to work with the code for a particular combination, you just look up the appropriate method. The big IF maze is then rarely looked at, and when it is, it contains only the IFs themselves and nothing else potentially distracting.
I'm fairly new to Python so please bear with me.
This is the Java code:
public static int countDeafRats(final String town) {
String t = town.replaceAll(" ","");
int count = 0;
for (int i = 0 ; i < t.length() ; i+=2)
if (t.charAt(i) == 'O') count++;
return count;
}
This is my attempt to translate it to Python:
def count_deaf_rats(town):
count = 0
increment = 0
newTown = town.replace(" ", "")
while increment <= len(newTown):
if newTown[increment]=='O':
count +=1
increment +=2
return count
I didn't use for loop in Python since I don't how to increment by 2, so as the title says, would this be an acceptable translation?
Edit, sample input: ~O~O~O~OP~O~OO~
It appears that you are trying to find the number of zeroes in the string that occur at indices incremented by 2. You can use regex and list comprehensions in Python:
import re
new_town = re.sub("\s+", '', town)
count = sum(i == "0" for i in new_town[::2])
I don't know too much Java, but I believe this is a more direct translation of your code into python:
def countDeafRats(town):
count = 0
new_town = town.replace(' ','')
#format for range: start, end (exclusive), increment
for i in range(0, len(new_town), 2):
if new_town[i] == '0':
count += 1
return count
I agree with #Ajax1234 's answer, but I thought you might like an example that looks closer to your code, with the use of a for loop that demonstrates use of an increment of 2. Hope this helps!
Okay I will recommend that you must follow the answer provided by #Ajax1234 but since you mentioned that you are fairly new(probably not familiar much about regex) to python so I would suggest for the current instance you should stick to your code which you are trying to convert to. It is fairly correct just you need to make some amendments to your code(although very small related to indentation). Your amended code would look something like:
def count_deaf_rats(town):
count = 0
increment = 0
newTown = town.replace(" ", "")
while increment <= len(newTown):
if newTown[increment]=='O':
count +=1
increment +=2
return count
#print count_deaf_rats("~O~O~O~OP~O~OO~")
This yields the same result as your corresponding java code. Also since while loops are not considered much handy(but at some instances much useful also) in python therefore I will insist to use for loop as:
#Same as above
for increment in range(0,len(newTown),2):
if newTown[increment] == 'O':
count +=1
return count
Read more about range function here
This question already has answers here:
"Code too large" compilation error in Java
(14 answers)
Closed 6 years ago.
I have this code and when I try to compile it, it returns:
E:\temp\JavaApplication12\src\javaapplication12\JavaApplication12.java:15: error: code too large
public static void main(String[] args) {
1 error
My code is a sudoku solver. First I need to load all the numbers, and then process which numbers that are already present on rows and columns, to decide what I can solve. But it doesn't compile the code! I have spent weeks working on this.
The approach of my sudoku solver solve the problem in constant time. So, I am not using cycles or arrays because it will make the problem O(n). I want O(k) where k is the constant.
Even if the code compiled, it wouldn't solve a game of Sudoku. Actually, all it does is to set the 9 variables bN to true if any of the 81 variables aPQ are equal to N.
And it doesn't even do this efficiently. There are 1458 (=18*81) conditions setting each of the bN variables to true. (Simple check: each of the conditions is 3 lines; 1458 checks for each of 9 variables: 3 * 1458 * 9 = 39366, the approximate length of the file).
All of the setters of bN are independent, and are idempotent, so they can be arbitrarily rearranged and the 17 repeated checks of the conditions can be removed.
An equivalent (and adequately efficient) version of this code - using arrays - is:
// Using 10 as array size, as OP's code is one-based;
// first element is unused.
int a[][] = new int[10][10];
// Initialize the elements of a.
boolean b[] = new boolean[10];
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= 9; j++) {
if (a[i][j] >= 1 && a[i][j] <= 9) {
b[a[i][j]] = true;
}
}
}
which should fit inside the maximum size of a method quite easily.
You should focus on writing correct, maintainable code, before considering how to make it efficient - this code doesn't work for its stated purpose, and I would not want to be the one working out where the bug in 40k lines of code is. The only reason I was able to analyse this much code is that it appears to be generated, as it is very uniform in its pattern.
I did the analysis above using a (very hacky) Python script.
Run using:
curl http://pastebin.com/raw/NbyTTAdX | python script.py
script.py:
import sys
import re
with open('/dev/stdin') as fh:
lines = fh.readlines()
bequals = re.compile(r'^b\d\s*= true;$')
i = 0
bvariablesetters = {}
while i < len(lines):
if lines[i].strip().startswith('if (') and lines[i].strip().endswith('{'):
# Match the conditionals setting one of the b variables.
if lines[i+2].strip() == '}' and bequals.search(lines[i+1].strip()):
newline = ' '.join(map(str.strip, lines[i:i+3]))
spl = newline.split()
# This is the "b=" variable
bvar = spl[5]
bvariablesetters.setdefault(bvar, []).append(' '.join(newline))
i += 3
continue
else:
# Print out lines which don't match the conditional-set-b pattern, so you
# can see that there's nothing else going on.
sys.stdout.write(lines[i])
i += 1
# Print the number of conditionals setting each of the b variables.
print {(k, len(v)) for k, v in bvariablesetters.iteritems()}
# Print the number of unique conditionals setting each of the b variables.
print {(k, len(set(v))) for k, v in bvariablesetters.iteritems()}
# Print one of the lists of conditions to set a b variable.
print bvariablesetters['b1=']
# Print one of the sets of conditions to set a b variable.
print sorted(set(bvariablesetters['b1=']))
I am working on a Mancala game project. In case you are interested in the GUI, here it is:
https://s32.postimg.org/hxzmhxt1x/mancala.png
I am working on a method that will cause the computer player to select the pit closest to their store that will allow it to capture stones from the human player. A capture is made when the last stone lands in an empty pit directly across from a pit with stones on the other side. I am including the relevant method below. The parameter "theBoard" is an int array to represent all of the pits including the stores and how many stones are contained in each pit of the array. Here is the code I have for the method:
public int selectPit(int[] theBoard) {
int pitChoice = theBoard.length - 2;
while (pitChoice >= theBoard.length / 2) {
int destinationPit = theBoard[pitChoice] + pitChoice;
int opposite = (theBoard.length - 2) - destinationPit;
if (theBoard[destinationPit] == 0 && theBoard[opposite] > 0 && destinationPit <= (theBoard.length - 2) && destinationPit > (theBoard.length / 2)) {
return pitChoice;
} else {
pitChoice--;
}
}
return this.selectClosestPitWithStones(theBoard);
}
The last line that calls the selectClosestPitWithStones is a call to a backup method just in case there are no options that would allow a capture. The functionality of this backup method works as intended. However, my selectPit method keeps returning incorrect results or "ArrayIndexOutOfBoundsException: -1".
I am using JUnit tests that are correctly written to test this method. Here is one such test:
#Test
public void testCapturePit0() {
this.setUp();
int[] theBoard = {6, 0, 0, 0, 2, 0, 0, 0};
assertEquals(4, this.strategy.selectPit(theBoard));
}
Any ideas on what could be causing incorrect results?
Debug it and verify that variables have the values you expect.
The problem at the moment is one of the variables going out of the bounds of the array. Remember that array indexes go from 0 to length minus one. Both int destinationPit = theBoard[pitChoice] + pitChoice; and int destinationPit = theBoard[pitChoice] + pitChoice; could go out of bounds depending on the input or the state of the array.