I just begin to learn java (today),
To exercise me, I would like to translate the following "8 Queens" algorithm written in python into Java :
BOARD_SIZE = 8
def under_attack(col, queens):
left = right = col
for r, c in reversed(queens):
left, right = left-1, right+1
if c in (left, col, right):
return True
return False
def solve(n):
if n == 0: return [[]]
print n
smaller_solutions = solve(n-1)
return [solution+[(n,i+1)] for i in range(BOARD_SIZE) for solution in smaller_solutions if not under_attack(i+1, solution)]
sols = solve(BOARD_SIZE)
for answer in sols:
print answer
For translation, I want to use exactly the same algorithm : recursive and use of "lists of lists of tuple" like in python (I know I should think "java", but for now, it's just for fun)
I wrote this :
import java.util.ArrayList;
class Queens {
public static boolean under_attack(int col, ArrayList<Integer[]> queens) {
int left = col, right = col;
for(int i=queens.size()-1;i>=0;i--) {
int r = queens.get(i)[0];
int c = queens.get(i)[1];
left--;
right++;
if ( c==left || c==col || c==right) {
return true;
}
}
return false;
}
public static ArrayList<ArrayList<Integer[]>> solve(int n){
ArrayList<ArrayList<Integer[]>> new_solutions = new ArrayList<ArrayList<Integer[]>>();
if ( n==0 ) {
return new_solutions;
}
ArrayList<ArrayList<Integer[]>> smaller_solutions = solve(n-1);
for (int i=0;i<8;i++) {
for (ArrayList<Integer[]> solution : smaller_solutions) {
if ( ! under_attack(i+1,solution) ) {
ArrayList<Integer[]> bigger_solution = (ArrayList<Integer[]>) solution.clone();
Integer [] tuple = new Integer [2];
tuple[0] = n;
tuple[1] = i+1;
bigger_solution.add(tuple);
new_solutions.add(bigger_solution);
}
}
}
return new_solutions;
}
public static void main(String[] args) {
System.out.println("Résolution du problème des 8 reines");
ArrayList<ArrayList<Integer[]>> solutions;
solutions = solve(8);
System.out.format("Nb solutions : %d%n",solutions.size());
for (ArrayList<Integer[]> solution : solutions) {
System.out.print("(");
for(Integer[] i:solution) {
System.out.format("[%d,%d],",i[0],i[1]);
}
System.out.println(")");
System.out.println("==============================");
}
}
}
But this does not work : no answers is found
Do you have an idea why ?
The correction needed to your code to run identicaly to the python program is the following. At the begining of the solve() function instead of:
if ( n==0 ) {
return new_solutions;
}
you should write:
if ( n==0 ) {
ArrayList<Integer[]> empty = new ArrayList<Integer[]>();
new_solutions.add(empty);
return new_solutions;
}
The reason is that the artifact [[]] in python is not an empty list, right? It is a list containing as it's only element the empty list. This is exactly the correction in the java code! Otherwise the recursion doesn't work and the under_attack() function is never called (as you can verify adding a diagnostic message at its first line)
Happy coding...and java learning
Related
I am trying to return two values from an Netlogo extension separability. In the extension code below :
package distribution;
import java.util.Random;
import org.nlogo.api.*;
public class V2G extends DefaultReporter {
public Syntax getSyntax() {
return Syntax.reporterSyntax(new int[] {Syntax.ListType(), Syntax.NumberType(), Syntax.NumberType(), Syntax.NumberType(), Syntax.NumberType()}, Syntax.ListType());
}
public Object report(Argument args[], Context context) throws ExtensionException {
LogoList coalizao;
double gamma;
double amdc;
double op;
int constante;
double mep=0;
double sum = 0;
try {
coalizao = args[0].getList();
gamma = args[1].getDoubleValue();
amdc = args[2].getDoubleValue();
constante = args[3].getIntValue();
op = args[4].getDoubleValue();
}
catch(LogoException e) {
throw new ExtensionException( e.getMessage() ) ;
}
if (coalizao.size() < 2 || coalizao.size() > gamma) return 0;
for (int i = 0; i < coalizao.size(); i++) {
int agente = (int)((Double)coalizao.get(i)).doubleValue();
int min = 0;
int max = 30;
Random r = new Random(agente*constante);
mep += r.nextInt(max - min + 1) + min;
return mep;
}
sum = amdc + mep - op ;
return sum;
}
}
In the code above there are two values to be return mep and sum .
I am using the following code in Netlogo to import the values
to-report getCoalitionValue [coalition]
report distribution:V2G coalition gamma amdc constante op
end
Now, my problem is how can i import the values of mep and sum separately in Netlogo.
Please can anyone help me with this ?
Thanks in advance.
NetLogo doesn't really have a concept of returning multiple values from a primitive. The most NetLogo-ish way of accomplishing this is to return a list of values in a standard order.
Here is some Scala code to accomplish this. Users of this primitive in NetLogo would have to know to do item 0 sample-scala:two-values to get "apples" and item 1 sample-scala:two-values to get 0.
object TwoValues extends api.Reporter {
override def getSyntax = reporterSyntax(ret = ListType)
def report(args: Array[api.Argument], context: api.Context): AnyRef = {
import org.nlogo.api.ScalaConversions.toLogoList
Seq( "apples", 0 ).toLogoList // returns the NetLogo list ["apples", 0]
}
}
I see you're writing Java code, so a good reference for building a NetLogo list using a LogoListBuilder would be in the Java extension sample code:
public Object report(Argument args[], Context context)
throws ExtensionException {
// create a NetLogo list for the result
LogoListBuilder list = new LogoListBuilder();
int n;
// use typesafe helper method from
// org.nlogo.api.Argument to access argument
try {
n = args[0].getIntValue();
} catch (LogoException e) {
throw new ExtensionException(e.getMessage());
}
if (n < 0) {
// signals a NetLogo runtime error to the modeler
throw new ExtensionException
("input must be positive");
}
// populate the list
// note that we use Double objects; NetLogo numbers
// are always doubles
for (int i = 0; i < n; i++) {
list.add(Double.valueOf(i));
}
return list.toLogoList();
}
I implemented an experimental OOP language and now benchmark garbage collection using a Storage benchmark. Now I want to check/print the following benchmark for small depths (n=2, 3, 4,..).
The tree (forest with 4 subnode) is generated by the buildTreeDepth method. The code is as follows:
import java.util.Arrays;
public final class StorageSimple {
private int count;
private int seed = 74755;
public int randomNext() {
seed = ((seed * 1309) + 13849) & 65535;
return seed;
}
private Object buildTreeDepth(final int depth) {
count++;
if (depth == 1) {
return new Object[randomNext() % 10 + 1];
} else {
Object[] arr = new Object[4];
Arrays.setAll(arr, v -> buildTreeDepth(depth - 1));
return arr;
}
}
public Object benchmark() {
count = 0;
buildTreeDepth(7);
return count;
}
public boolean verifyResult(final Object result) {
return 5461 == (int) result;
}
public static void main(String[] args) {
StorageSimple store = new StorageSimple();
System.out.println("Result: " + store.verifyResult(store.benchmark()));
}
}
Is there a somewhat simple/straight forward way to print the tree generated by buildTreeDepth? Just the short trees of n=3, 4, 5.
As other has already suggested, you may choose some lib to do so. But if you just want a simple algo to test in command line, you may do the following, which I always use when printing tree in command line (write by handle, may have some bug. Believe you can get what this BFS algo works):
queue.add(root);
queue.add(empty);
int count = 1;
while (queue.size() != 1) {
Node poll = queue.poll();
if (poll == empty) {
count = 1;
queue.add(empty);
}
for (Node n : poll.getChildNodes()) {
n.setNodeName(poll.getNodeName(), count++);
queue.add(n);
}
System.out.println(poll.getNodeName());
}
Sample output:
1
1-1 1-2 1-3 1-4
1-1-1 1-1-2 1-1-3 1-2-1 1-2-2 1-3-1 1-3-2 1-4-1
...
And in your case you use array, which seems even easier to print.
Instead of using object arrays, use a List implementation like ArrayList. For an improved better result subclass ArrayList to also hold a 'level' value and add indentation to the toString() method.
I am aware there are multiple threads like my assignment below, but I just can't figure it out. I can't exactly figure out the mistake. Help would be appreciated.
I am trying to do this program:
Everything works fine unless I input the same chains or similar (for example ACTG and ACTG or ACTG and ACTGCCCC), when it tells me
string index out of range
This is that part of my code:
int tries=0;
int pos=-1;
int k;
for (int i=0; i<longDNA.length(); i++) {
tries=0;
k=i;
for (int j=0; j<shortDNA.length(); j++) {
char s=shortDNA.charAt(j);
char l=longDNA.charAt(k);
if (canConnect(s,l)) {
tries+=1;
k+=1;
}
}
if (tries==shortDNA.length()-1) {
pos=i-1;
break;
}
}
Let's call the two DNA strings longer and shorter. In order for shorter to attach somewhere on longer, a sequence of bases complementary to shorter must be found somewhere in longer, e.g. if there is ACGT in shorter, then you need to find TGCA somewhere in longer.
So, if you take shorter and flip all of its bases to their complements:
char[] cs = shorter.toCharArray();
for (int i = 0; i < cs.length; ++i) {
// getComplement changes A->T, C->G, G->C, T->A,
// and throws an exception in all other cases
cs[i] = getComplement(cs[i]);
}
String shorterComplement = new String(cs);
For the examples given in your question, the complement of TTGCC is AACGG, and the complement of TGC is ACG.
Then all you have to do is to find shorterComplement within longer. You can do this trivially using indexOf:
return longer.indexOf(shorterComplement);
Of course, if the point of the exercise is to learn how to do string matching, you can look at well-known algorithms for doing the equivalent of indexOf. For instance, Wikipedia has a category for String matching algorithms.
I tried to replicate your full code as fast as I could, I'm not sure if I fixed the problem but you don't get any errors.
Please try it and see if it works.
I hope you get this in time and good luck!
import java.util.Arrays;
public class DNA {
public static void main(String[] args) {
System.out.println(findFirstMatchingPosition("ACTG", "ACTG"));
}
public static int findFirstMatchingPosition(String shortDNA, String longDNA) {
int positionInLong = 0;
int positionInShort;
while (positionInLong < longDNA.length()) {
positionInShort = 0;
while(positionInShort < shortDNA.length()) {
String s = shortDNA.substring(positionInShort, positionInShort + 1);
if(positionInShort + positionInLong + 1 > longDNA.length()) {
break;
}
String l = longDNA.substring(positionInShort + positionInLong, positionInShort + positionInLong + 1);
if(canConnect(s, l)) {
positionInShort++;
if(positionInShort == shortDNA.length()) {
return positionInLong;
}
} else {
break;
}
}
positionInLong++;
if(positionInLong == longDNA.length()) {
return -1;
}
}
return -1;
}
private static String[] connections = {
"AT",
"TA",
"GC",
"CG"
};
private static boolean canConnect(String s, String l) {
if(Arrays.asList(connections).contains((s+l).toUpperCase())) {
return true;
} else {
return false;
}
}
}
I finally changed something with the k as Faraz had mentioned above to make sure the charAt does not get used when k overrides the length of the string and the program worked marvelously!
The code was changed to the following:
int tries=0;
int pos=-1;
int k;
for (int i=0; i<longDNA.length(); i++) {
tries=0;
k=i;
for (int j=0; j<shortDNA.length(); j++) {
if (k<longDNA.length()) {
char s=shortDNA.charAt(j);
char l=longDNA.charAt(k);
if ((s=='A' && l=='T') || (s=='T' && l=='A') || (s=='G' && l=='C') || (s=='C' && l=='G')) {
tries+=1;
k+=1;
}
}
}
if (tries==shortDNA.length()) {
pos=i;
break;
}
}
I am not sure how aesthetically pleasing or correct this excerpt is but - it completely solved my problem, and just 2 minutes before the deadline! :)
A huge thanks to all of you for spending some time to help me!!
I want to display an error if more than one of the four variables is set...
In Java..this is what I came up with..
if( (isAset() && isBset()) || (isBset() && isCset()) || (isCset() && isDset()) || (isDset() && isAset()) )
attri.greedySelectionException(..);
I wanted to check if there is a better way of doing this..?
How about you use a counter and then compare it to 1?
Something like...
int i = 0;
if (isAset()) i++;
if (isBset()) i++;
if (isCset()) i++;
if (isDset()) i++;
if (i > 1)
...
Alternatively, if you are checking properties of a certain object, you could use some reflection to iterate through the relevant properties instead of having one if statement per property.
Edit: Take a look at Marius Žilėnas's varargs static method below for some tidier code, i.e. using (changed the oldschool for to a for-each and the ternary expression for an if):
static int trueCount(boolean... booleans) {
int sum = 0;
for (boolean b : booleans) {
if (b) {
sum++;
}
}
return sum;
}
instead of several if statements.
You can simplify this expression with :
if((isAset() || isCset()) && (isBset() || isDset()))
attri.greedySelectionException(..);
Wolfram alpha made the work for you :
Original expression
You can verify with the truth tables :
Original
Final
In Java 8 you can solve this problem with Streams in an elegant way (assuming your values are null if they are not set):
if (Stream.of(valueA, valueB, valueC, valueD).filter(Objects::nonNull).count() != 1) {
/* throw error */
}
If you have control on the implementation of isAset(), isBSet, isCSet, & isDset methods, you can achieve this with much more clarity if you return 1 or 0 instead of true or fales from this functions. These functions are to be created as below...
public int isAset()
{
return (A != null) ? 1 : 0;
}
To verify if more than one variable is set use use something like below...
if( isASet() + isBSet() + isCSet() + isDSet() > 1)
ThrowMoreAreSetException()
If you don't have control on this here is another way of doing it...
int count = isASet() ? 1 : 0;
count+= isBSet() ? 1 : 0;
count+= isCSet() ? 1 : 0;
count+= isDSet() ? 1 : 0;
if(count > 1)
ThrowMoreAreSetException()
By following either of these approches, code will be less clumsy and more readable than doing somany comparision combinations.
I suggest using varargs ... (see Java tutorial) and make a function that calculates how many trues was given. The following code to demonstrates it:
public class Values
{
public static boolean isASet()
{
return false;
}
public static boolean isBSet()
{
return true;
}
public static boolean isCSet()
{
return true;
}
public static boolean isDSet()
{
return true;
}
public static int booleans(boolean... booleans)
{
int sum = 0;
for (int i = 0; i < booleans.length; i++)
{
sum += booleans[i] ? 1 : 0;
}
return sum;
}
public static void main(String[] args)
{
System.out.println(
booleans(isASet(), isBSet(), isCSet(), isDSet()));
if (1 < booleans(isASet(), isBSet(), isCSet(), isDSet()))
{
System.out.println("Condition met.");
}
}
}
Try this:
if (!(isAset ^ isBset ^ isCset ^ isDset))
This will true only is any one is true or else false.
Right now I have my array sorting (which is better than getting an error) except it is sorting in the reverse than what I want it to sort in.
public static void sortDatabase(int numRecords, String[] sDeptArr,
int[] iCourseNumArr, int[] iEnrollmentArr)
{
System.out.println("\nSort the database. \n");
String sTemp = null;
int iTemp = 0;
int eTemp = 0;
String a, b = null;
for(int i=0; i<numRecords; i++)
{
int iPosMin = i+1;
for(int j=iPosMin; j<numRecords; j++)
{
a = sDeptArr[i];
b = sDeptArr[iPosMin];
if(a.compareTo(b) > 0)
{
sTemp= sDeptArr[j];
sDeptArr[j] = sDeptArr[iPosMin];
sDeptArr[iPosMin] = sTemp;
iTemp = iCourseNumArr[j];
iCourseNumArr[j] = iCourseNumArr[iPosMin];
iCourseNumArr[iPosMin] = iTemp;
eTemp = iEnrollmentArr[j];
iEnrollmentArr[j] = iEnrollmentArr[iPosMin];
iEnrollmentArr[iPosMin] = eTemp;
}
else if(sDeptArr[j].equals(sDeptArr[iPosMin]) && !(iCourseNumArr[j] < iCourseNumArr[iPosMin]))
{
sTemp= sDeptArr[i];
sDeptArr[i] = sDeptArr[iPosMin];
sDeptArr[iPosMin] = sTemp;
iTemp = iCourseNumArr[i];
iCourseNumArr[i] = iCourseNumArr[iPosMin];
iCourseNumArr[iPosMin] = iTemp;
eTemp = iEnrollmentArr[i];
iEnrollmentArr[i] = iEnrollmentArr[iPosMin];
iEnrollmentArr[iPosMin] = eTemp;
}
else continue;
}
}
}
Again, no array lists or array.sorts. I need just to reverse how this is sorting but I have no idea how.
just do a.compareTo(b) < 0 instead of the > 0
EDIT: I've figured out the problem. But since this is homework (thanks for being honest), I won't post my solution, but here are a few tips:
You are doing selection sort. The algorithm isn't as complicated as you made it. You only have to swap if the two elements you are checking are in the wrong order. I see you have 3 branches there, no need.
Take a look at when you are assigning a and b. Through the inner loop, where j is changing, a and b never change, because i and iPosMin stay the same. I hope that helps.
It's always good to break your algorithm down to discreet parts that you know works by extracting methods. You repeat the same swap code twice, but with different arguments for indices. Take that out and just make a:
-
// swaps the object at position i with position j in all arrays
private static void swap(String[] sDeptArr, int[] iCourseNumArr, int[] iEnrollmentArr, int i, int j)
Then you'll see you're code get a lot cleaner.
First I'd say you need to build a data structure to encapsulate the information in your program. So let's call it Course.
public class Course {
public String department;
public Integer courseNumber;
public Integer enrollment;
}
Why not use the built in sort capabilities of Java?
List<Course> someArray = new ArrayList<Course>();
...
Collections.sort( someArray, new Comparator<Course>() {
public int compare( Course c1, Course c2 ) {
int r = c1.compareTo( c2 );
if( r == 0 ) { /* the strings are the same sort by something else */
/* using Integer instead of int allows us
* to compare the two numbers as objects since Integer implement Comparable
*/
r = c1.courseNumber.compareTo( c2.courseNumber );
}
return r;
}
});
Hope that gets you an A on your homework. Oh and ditch the static Jr. Maybe one day your prof can go over why statics are poor form.
Hmm... I wonder what would happen of you altered the line that reads if(a.compareTo(b) > 0)?