Cannot print out the right sum - java

I have assigned a letter grade to each student based on his/her grade. And I want to count the total number of students for each letter grade. But for some reasons, the result turns total wrong. Can anyone tell me what parts I did wrong? Thank you!
String letter ="A";
int letterA=0;
int letterB=0;
int letterC=0;
int letterD=0;
int letterF=0;
int a=0;
int b=0;
int c=0;
int d=0;
int f=0;
for (int row=0;row<100;row++){ //the outer loop, have 100 rows to go through
for ( int column=0;column<words.length;column++) {
if(words[column].equals(table[row][column])){ // compare two arrays
count++; }// add the score for each student if he/she is right
}
if (count >=18)
letter=("A");
if(count>=16 && count<18)
letter=("B");
if(count>=14 && count<16)
letter=("C");
if(count>=12 && count<14)
letter=("D");
if(count<12)
letter=("F");
System.out.println("Student Grade: "+letter+"\t");
count=0; // make sure the count will go back to 0, and run the loop again
if (letter.equals("A"))
letterA++;
a+=letterA;}
if (letter.equals("B"))
letterB++;
b+=letterB;
if (letter.equals("C"))
letterC++;
c+=letterC;
if (letter.equals("D"))
letterD++;
d+=letterD;
if (letter.equals("F"))
letterF++;
f+=letterF;
System.out.print("Question A "+a);
System.out.print("Question B "+b);
System.out.print("Question C "+c);
System.out.print("Question D "+d);
System.out.print("Question F "+f);
}

Always use braces, even for single statements:
if (letter.equals("A"))
letterA++;
a+=letterA;}
if (letter.equals("B"))
letterB++;
b+=letterB;
if (letter.equals("C"))
letterC++;
c+=letterC;
if (letter.equals("D"))
letterD++;
d+=letterD;
if (letter.equals("F"))
letterF++;
f+=letterF;
Should always be:
if ("A".equals(letter)) { letterA++; }
else if ("B".equals(letter)) { letterB++; }
else if ("C".equals(letter)) { letterC++; }
else if ("D".equals(letter)) { letterD++; }
else if ("F".equals(letter)) { letterF++; }
else { throw new RuntimeException("Invalid Letter " + letter); }
Use single line statements if you want them visually compact, but
still use the braces as they guarantee the intent of what is to be
done in a given block, they also act as documentation of that intent
for people in the future ( people includes you ) to know what is going
on.
I see no valid reason for the single letter variables they are never used and I do not understand why they are there?
General Critique:
Always use braces:
Leaving out braces means only the first statement after the if is executed when the if matches, the next line(s) are always executed.
if (letter.equals("A"))
letterA++;
a+=letterA;
is actually
if (letter.equals("A")) { letterA++; }
a+=letterA;
Which means that line outside the braces will always get executed no matter what the expression inside the if test evaluates to. The indention of the second line is conflating that statement as part of the if block and it is not.
There is absolutely nothing to gain by leaving out braces and
everything to lose.
Neat code is easy to read and maintain and shows you care:
Always format your code consistently and not so densely so you can tell what is going on and what was wrong with the braces missing version.
Look at the best advertising it has plenty of white space, clean formatted code should have plenty of consistent white space as well so that our brains can quickly pattern match and scan for relevant things like matching pairs of braces.
Clean formatted code is just a keystroke away in all IDEs worth using.
Clean code shows you care about what you are doing and makes your question more appealing, which means others will care about their answer just as much.
Clean code earns you respect from your peers that know what they are looking at and sets you apart from those that do not care or know what they are looking at.
Most Importantly Clean Code is easier to reason about and has less
bugs, no subtle bugs and is orders of magnitude easier to maintain.
Always cover all the conditions:
Always use if/else if/else with mutually exclusive tests.
If all the if clauses are mutually exclusive and you match the first one, all the rest are still evaluated for no reason with the if/if/if/if structure. if/else if/else if/else if/else only evaluates until something matches or nothing matches.
Without else you do not cover all possible cases that do not match, which is usually and error that will just occur silently without the else.
Do not just cover the happy path, cover the exceptional path, but do it in the least defensive manner possible.
Explicit is always better than Implicit!
Avoid == null checks; avoid null completely:
Always compare literals to variables with .equals() to avoid possible NullPointerExceptions.
Avoid using null references completely, it is possible in every case, even the cases that it seems like a legitimate reason.
If Tony Hoare, the inventor of them thinks it is a mistake
who is to argue.
Always Name your variables descriptively!
I am not sure what letterA is supposed to represent anymore than what a is supposed to represent. So no one can tell you if these are correct because no one knows for sure what they represent semantically.
No Unnamed Numerical Constants ( Magic Numbers ):
final int A_GRADE = 18;
final int B_GRADE = 16;
final int C_GRADE = 14;
final int D_GRADE = 12;
Given the way they are used the names arguably could be even better
like MINIMUM_A_GRADE, but that is opinion based, the lesson is avoid
magic numbers.
Do range checks in the same direction:
Do range checks in the same direction so that the variable is visually in the middle of the comparison.
This makes it harder to break the logic later on and is self documenting that it is a range check.
if (count >= A_GRADE) { /* omitted */ }
else if (B_GRADE <= count && count < A_GRADE) { /* omitted */ }
else if (C_GRADE <= count && count < B_GRADE) { /* omitted */ }
else if (D_GRADE <= count && count < C_GRADE) { /* omitted */ }
else /* isF */ { /* omitted */ }
Which one is easier to reason about and maintain?
Do not hesitate to have many small methods if they make the code more self documenting:
private static boolean isA(final int count) { return count >= A_GRADE; }
private static boolean isB(final int count) { return B_GRADE <= count && count < A_GRADE; }
private static boolean isC(final int count) { return C_GRADE <= count && count < B_GRADE; }
private static boolean isD(final int count) { return D_GRADE <= count && count < C_GRADE; }
then you will have the following:
if (isA(count)) { /* omitted */ }
else if (isB(count)) { /* omitted */ }
else if (isC(count)) { /* omitted */ }
else if (isD(count)) { /* omitted */ }
else /* isF */ { /* omitted */ }
Which one is more obvious and self documenting, thus more
maintainable?
DRY - Don't Repeat Yourself:
Logically if (count >= A_GRADE) { letter = "A";} is exactly the same as if ("A".equals(letter)) { /* do stuff */ } so this is duplicated logic.
Instead of assigning a letter than checking that again, just put the logic in the original check.
if (count >= A_GRADE) { /* do stuff */ }
else if (B_GRADE <= count && count < A_GRADE) { /* do stuff */ }
else if (C_GRADE <= count && count < B_GRADE) { /* do stuff */ }
else if (D_GRADE <= count && count < C_GRADE) { /* do stuff */ }
else { /* omitted */ }
I see no valid reason for the single letter variables they are never used and I do not understand why they are there?
Duplicate logic means multiple places to have errors and multiple
places to edit to fix bugs, save yourself time and effort and follow
the DRY principle.
Move large logic blocks to method calls:
When do stuff is more than a few lines, refactor it to a method call.
if (count >= A_GRADE) { recordMarkA(); }
else if (B_GRADE <= count && count < A_GRADE) { recordMarkB(); }
else if (C_GRADE <= count && count < B_GRADE) { recordMarkC(); }
else if (D_GRADE <= count && count < C_GRADE) { recordMarkD(); }
else { recordMarkF(); }
More small methods with descriptive names is always better than large
monolithic blocks of inline code.
This question shows substantial effort and a genuine desire to learn:
So I crafted up what I would want a complete solution ( provided the partial/incomplete code ) to look like.
Q34081279.java
public class Q34081279
{
final static int A_GRADE = 18;
final static int B_GRADE = 16;
final static int C_GRADE = 14;
final static int D_GRADE = 12;
public static void main(final String[] args)
{
final String[] words = new String[]{}; /* this is just a placeholer, not provided in question */
final String[][] table = new String[][]{}; /* this is just a placehoder, not provided in question */
int markA = 0;
int markB = 0;
int markC = 0;
int markD = 0;
int markF = 0;
for (int row = 0; row < 100; row++)
{
int count = 0;
for (int column = 0; column < words.length; column++)
{
if (words[column].equals(table[row][column])) { count++; }
}
if (count >= A_GRADE) { System.out.format("%d = A", count); }
else if (B_GRADE <= count && count < A_GRADE) { System.out.format("%d = B", count); }
else if (C_GRADE <= count && count < B_GRADE) { System.out.format("%d = C", count); }
else if (D_GRADE <= count && count < C_GRADE) { System.out.format("%d = D", count); }
else { System.out.format("%d = F", count); }
System.out.println();
}
System.out.println(String.format("Question A %d", markA));
System.out.println(String.format("Question B %d", markB));
System.out.println(String.format("Question C %d", markC));
System.out.println(String.format("Question D %d", markD));
System.out.println(String.format("Question F %d", markF));
}
}

#Buddy is on the right rack but it's more than that. All of the if statements with more than one line need to have braces.
Otherwise only the first line is read by the compiler. According to Oracle:
Deciding when to omit the braces is a matter of personal taste. Omitting them can make the code more brittle. If a second statement is later added to the "then" clause, a common mistake would be forgetting to add the newly required braces. The compiler cannot catch this sort of error; you'll just get the wrong results.
eg:
if (letter.equals("A")) {
letterA++;
a+=letterA;
}
if (letter.equals("B")) {
letterB++;
b+=letterB;
}

Related

Program constantly says missing return statement

My program is supposed to be passed 2 array-lists, arrivals and duration, and should return the number of events that can basically take place without overlap. The last thing I did was add the final else if statement to count the last arrival as an event that could take place. However, my code constantly gives a no return statement error although there is a return statement.
class Results {
public static int maxEvents(List<Integer> arrival,List<Integer> duration) {
int counter = 0;
for (int i = 0; i < arrival.size(); i++) {
if (arrival.get(i) + duration.get(i) <= arrival.get(i+1)) {
counter++;
} else if (arrival.get(i)==arrival.get(i+1)) {
counter++;
i++;
} else if (i == arrival.size()-1) {
counter++;
}
return counter;
}
}
}
The return statement which you have written lies within for loop that is incorrect.
please follow below code
class Results {
public static int maxEvents(List<Integer> arrival,List<Integer> duration) {
int counter = 0;
for (int i = 0; i < arrival.size(); i++) {
if (arrival.get(i) + duration.get(i) <= arrival.get(i+1)) {
counter++;
} else if (arrival.get(i)==arrival.get(i+1)) {
counter++;
i++;
} else if (i == arrival.size()-1) {
counter++;
}
}
return counter;
}
}
The Java compiler requires that all methods with a non-void return type either:
Return a value (or throw) on all paths
Definitely don't return a value (e.g. if they contain an infinite loop).
It determines this by looking at the statements in your method to see if they "complete normally". This is a bit of a funny term, but it basically means that execution would move onto the next statement (or the method would finish executing if it is the last statement in the method).
In this case, it looks at the loop:
for (int i = 0; i < arrival.size(); i++) {
// ...
return counter;
}
And it finds that:
The for loop body completes abruptly (it always returns a value)
The for loop might be able to complete normally, because i < arrival.size() isn't a constant (*).
As such, it looks after the for loop to make sure that all following paths return a value (or throw). But this cannot be the case, because there are no statements after the for loop. As such, a compile-time error results.
The easiest way to satisfy the compiler is to put another return after the for loop:
for (int i = 0; i < arrival.size(); i++) {
// ...
return counter;
}
return /* some int */;
Or make the guard expression constant true (or omit it):
for (int i = 0; true; i++) {
// ...
return counter;
}
However, your loop body always returns if entered; so it is basically if (0 < arrival.size()) rather than a loop. And it would only ever return 0 or 1, because counter is incremented at most once.
This is presumably a logical error: the return shouldn't be inside the loop, allowing you to count the number of items in the list which meet the condition:
for (int i = 0; i < arrival.size(); i++) {
// ...
}
return counter;
(*) The compiler doesn't look any deeper than the fact it's not a constant equal to true. For example, i <= Integer.MAX_VALUE isn't constant, and thus is considered to allow normal completion, but it is clearly always true.

How to create the FizzBuzz using loops in JAVA

I'm writing this problem for school and I have some issues with it. I can't get "printFizzBuzz" to actually go up and calculate the wrapper function "FizzBuzz". I am required to use loops and was attempting to use a FOR loop. Beginner programmer here so no, I haven't used loops much at all. Any tips or pointers? ;)
The instructions are as follows.
public static String FizzBuzz(int number)
{
if( (number%3==0) && (number%5==0)) {
return "FizzBuzz";
}
else if( number%3 == 0 ) {
return "Fizz";
} else if( number%5 == 0 ) {
return "Buzz";
} else {
return ""+number;
}
}
/*
* use a for loop to print the appropriate FizzBuzz values (feel free to
* call the provided FizzBuzz function) for values from from to to,
* including both of those values. Each value should be printed in a separate line.
*/
public static void printFizzBuzz(int from, int to, PrintStream out)
{
for (int i = 1; i <= to; ++i){
FizzBuzz(++i);
}
}
Take a look at the FizzBuzz function:
public static String FizzBuzz(int number)
public static STRING tells you that this function returns a string.
Each time you write
FizzBuzz(++i);
imagine this to be a string like "Fizz"
So in your program what you really wrote is
for (int i = 1; i <= to; ++i){
"Fizz";
}
That doesn't look good right? You actually need to assign this string to something, or do some stuff with it. For example:
for (int i = 1; i <= to; ++i){
String a = "Fizz";
System.out.println(a);
}
Better, this is printing it to the standard output! However your function has already one PrintStream out parameter that you can use to print!
for (int i = 1; i <= to; ++i){
String a = FizzBuzz(i++);
out.println(a);
}
Now let's take a look at the for loop: it creates a variable i that starts from 1 (int i = 1), checks the condition ( i <= to) and if the condition is satisfied it executes the body of the loop. After that it increments i by 1 (++i).
So the first 3 rounds of the loop will be unrolled like this:
int i = 1;
if(i<=to){
String a = FizzBuzz(i++);
out.println(a);
}
++i; //i = 3;
if(i<=to){
String a = FizzBuzz(i++);
out.println(a);
}
++i; //i = 5;
if(i<=to){
String a = FizzBuzz(i++);
out.println(a);
}
++i; //i = 7;
Looks like we still have a problem here. Why is i 3, then 5 and then 7? What happened to 2,4,6? The problem is that you are also incrementing i by 1 when calling FizzBuzz (FizzBuzz(i++)).
This is wrong, the loop is already incrementing i for you by 1, if you increment i by 1 more, it will be incremented by 2 each round.
I'll leave the final fix to you.

largest product of 30 consecutive digits

I was given a programming question by a friend where I was given a 1000 character string of numbers. The task is to find the largest product of 30 consecutive digits.
Although my code looks right, the answer seems to come out really low, why is this?
The relevant code for this problem has been provided below.
static String s = "2389748943892"; //... This number is actually 1000 characters.
public static void main(String[] args) {
// TODO Auto-generated method stub
int largest = 0;
for(int i = 0; i < 970; i ) {
String cur = s.substring(i, i 30);
int cur_val = 0;
for(int x = 0; x < 30; x ) {
if(x == 0) {
System.out.println(Integer.parseInt(cur.substring(0, 1)));
cur_val = Integer.parseInt(cur.substring(x, 1));
} else {
cur_val = cur_val * Integer.parseInt(cur.substring(x, x 1));
}
}
if(cur_val > largest) {
largest = cur_val;
}
System.out.println("Largest: " largest);
// should be 8876473335152640000 but is 2013265920
}
}
Edit: Arrgh, I read 'slow' instead of 'low'...
OK, forget about the performance issues, I thought you were speaking of.
Howver, long won't help you either: calculate ln(9^30)/ln(2), and you get little more than 95, thus you need 96 digits. Try Math.BigInteger then!
This is due to the excessive usage of substring (resulting in constructing and destroying new String objects all the time). As you are only interested in single characters, better use s.charAt(n). Parsing is then easy, too: Just subtract '0' from the char you got this way. So you get:
for(int i = 0; i < 970; ++i)
{
int cur_val = 0;
for(int x = i; x < i + 30; ++x)
{
cur_val *= s.charAt(x) - '0';
}
}
/* rest as you had already */
(OK, I left out printing the substring).
Additionally, in the code you posted, there are some syntax errors (substring i, i 30, apparently there is missing a '+') and you did not increment the counter variables (if this happened in your code, too, you would have ended in endless loops - but then you would not have gotten a slow result, you would not have gotten any at all).
You might include some short cuts (e. g. if you find a '0' in the outer loop, you know that the result for the next 30 iterations will be 0 and you could skip these), giving you another speedup.

Is there a neater way to do this? Java IF

public void moveRowItemToBottomIfAllowed(int r, int f) {
int i = rows[r].peek().getType();
int j = 0;
if (bottom[f].isEmpty()) {
for (int k = 0; k < 4; k++) {
if ((k == f) || (bottom[k].isEmpty()) || (bottom[k].peek().getType() != i)) {
continue;
}
j = 1;
}
if (j == 0) {
bottom[f].push(rows[r].pop());
}
} else if ((!bottom[f].isEmpty()) && (rankTrueFalse(rows[r].peek(), bottom[f].peek())) && (rows[r].peek().getType() == bottom[f].peek().getType())) {
bottom[f].push(rows[r].pop());
}
}
As I'm still learning java I've been putting together some rules for a game, I went through how to do it logically and came up with the above code which works correctly but it looks like a bit of a mess - is there any neater way or a more efficient way of writing this code? any pointers are much appreciated.
I would extract methods to make the code more readable. At first sight I would extract
the for loop, or probably the whole contents of the if block,
the expression from the 2nd long else if
Use descriptive names for your new methods (and for your variables too, for that matter). This makes a huge difference in readability.
I would recommend that you use more descriptive names for your variables. What is r? What is f? I'm guessing that f is some sort of numeric representation of the suit, since you compare it to k, which iterates over four values.
There might be more to say about the code overall, but the first step is to write the code in a self documenting manner.
There are bits of expressions which could be extracted into local variables: rows[r].peek() and bottom[f].peek() being the most obvious ones.
It looks like you are using j as a flag. Booleans are better for that, but you can return early instead of setting the condition that guards the rest of the processing, getting rid of j entirely.
You're double checking that bottom[f].isEmpty()) is false, and can use the already looked up i instead of repeating rows[r].peek().getType()
Both sides of your first condition, if they end up doing the processing, do the same processing, which you can write once:
public void moveRowItemToBottomIfAllowed(int r, int f) {
int i = rows[r].peek().getType();
if (bottom[f].isEmpty()) {
for (int k = 0; k < 4; k++) {
if (k == f) continue;
if (bottom[k].isEmpty()) continue;
if (bottom[k].peek().getType() == i) return;
}
} else {
if (!rankTrueFalse(rows[r].peek(), bottom[f].peek())) return;
if (bottom[f].peek().getType() != i) return;
}
bottom[f].push(rows[r].pop());
}
This code is then structured as a bunch of guards with early exits, followed by the processing.
The guards could then be extracted into their own method, leaving:
public void moveRowItemToBottomIfAllowed(int r, int f) {
if (moveIsAllowed(r,f)) bottom[f].push(rows[r].pop());
}

java recursion on array

I have to create a program that finds all the possible ways of filling a square of size x by y. You place a block which takes up 2 spaces to completely fill.
The problem is I don't know how to code it to the point where you can remember the placements of each square. I can get it to where it fills the board completely once and maybe twice, but nothing past that. I also know that I'm supposed to use recursion to figure this out . Here is the code I started on so far. There is also a main method and I have the initial even/odd check working fine. This is the part I have no idea on.
public void recurDomino(int row, int column) {
if (Board[2][x - 1] != false) {
} else if(Board[1][x-1]!=false)
{
}
else {
for (int n=0; n < x - 1; n++) {
Board[row][column] = true;
Board[row][column+1] = true;
column++;
counter++;
}
recurDomino(1, 0);
recurDomino(2, 0);
}
}
Thank you for any help you guys can give me.
******************* EDIT ****************************************
I am a little confused still. I came up with this algorithm but I always get 2 for any value greater or equal to 2.
public boolean tryHorizontal(int row , int col){
if( row < 0 || row >= array[0].length-1)
return false;
else
return true;
}
public boolean tryVertical(int row, int col){
if( col < 0 || col >= 2 )
return false;
else
return true;
}
public boolean tryRowCol(int row, int col){
if(this.tryHorizontal(row, col) && this.tryVertical(row, col)){
return true;
}
else
return false;
}
public int findWays(int row, int col){
int n = 0;
if( !this.tryRowCol(row, col))
return 0;
else
n =+ 1 + this.findWays(row+1, col+1);
return n;
}
This recursive solution actually generates all the possible tiling of a general MxN board. It's more general than what your program requires, and therefore not optimized to just count the number of tiling of a 3xN board.
If you just want to count how many there are, you can use dynamic programming techniques and do this much faster. Also, having the number of rows fixed at 3 actually makes the problem considerably easier. Nonetheless, this general generative solution should be instructive.
public class Domino {
final int N;
final int M;
final char[][] board;
int count;
static final char EMPTY = 0;
Domino(int M, int N) {
this.M = M;
this.N = N;
board = new char[M][N]; // all EMPTY
this.count = 0;
generate(0, 0);
System.out.println(count);
}
void printBoard() {
String result = "";
for (char[] row : board) {
result += new String(row) + "\n";
}
System.out.println(result);
}
void generate(int r, int c) {
//... see next code block
}
public static void main(String[] args) {
new Domino(6, 6);
}
}
So here's the meat and potatoes:
void generate(int r, int c) {
// find next empty spot in column-major order
while (c < N && board[r][c] != EMPTY) {
if (++r == M) {
r = 0;
c++;
}
}
if (c == N) { // we're done!
count++;
printBoard();
return;
}
if (c < N - 1) {
board[r][c] = '<';
board[r][c+1] = '>';
generate(r, c);
board[r][c] = EMPTY;
board[r][c+1] = EMPTY;
}
if (r < M - 1 && board[r+1][c] == EMPTY) {
board[r][c] = 'A';
board[r+1][c] = 'V';
generate(r, c);
board[r][c] = EMPTY;
board[r+1][c] = EMPTY;
}
}
This excerpt from the last few lines of the output gives an example of a generated board, and the final count.
//... omitted
AA<><>
VVAA<>
AAVV<>
VVAA<>
<>VVAA
<><>VV
//... omitted
6728
Note that 6728 checks out with OEIS A004003.
A few things that you need to learn from this solutions are:
Clean-up after yourself! This is a very common pattern in recursive solution that modifies a mutable shared data. Feel free to do your thing, but then leave things as you found them, so others can do their thing.
Figure out a systematic way to explore the search space. In this case, dominoes are placed in column-major order, with its top-left corner as the reference point.
So hopefully you can learn something from this and adapt the techniques for your homework. Good luck!
Tip: if you comment out the printBoard line, you can generate all ~13 million boards for 8x8 in reasonable time. It'll definitely be much faster to just compute the number without having to generate and count them one by one, though.
Update!
Here's a recursive generator for 3xN boards. It doesn't use a shared mutable array, it just uses immutable strings instead. It makes the logic simpler (no clean up since you didn't make a mess!) and the code more readable (where and how the pieces are placed is visible!).
Since we're fixed at 3 rows, the logic is more explicit if we just have 3 mutually recursive functions.
public class Domino3xN {
static int count = 0;
public static void main(String[] args) {
addRow1(8, "", "", "");
System.out.println(count);
}
static void addRow1(int N, String row1, String row2, String row3) {
if (row1.length() == N && row2.length() == N && row3.length() == N) {
count++; // found one!
System.out.format("%s%n%s%n%s%n%n", row1, row2, row3);
return;
}
if (row1.length() > row2.length()) { // not my turn!
addRow2(N, row1, row2, row3);
return;
}
if (row1.length() < N - 1)
addRow2(N, row1 + "<>",
row2,
row3);
if (row2.length() == row1.length())
addRow3(N, row1 + "A",
row2 + "V",
row3);
}
static void addRow2(int N, String row1, String row2, String row3) {
if (row2.length() > row3.length()) { // not my turn!
addRow3(N, row1, row2, row3);
return;
}
if (row2.length() < N - 1)
addRow3(N, row1,
row2 + "<>",
row3);
if (row3.length() == row2.length())
addRow1(N, row1,
row2 + "A",
row3 + "V");
}
static void addRow3(int N, String row1, String row2, String row3) {
if (row3.length() == row2.length()) { // not my turn!
addRow1(N, row1, row2, row3);
return;
}
if (row3.length() < N - 1)
addRow1(N, row1,
row2,
row3 + "<>");
}
}
You don't often see 3 mutually recursive functions like this, so this should be educational.
One way of doing it is with the CSP (Constraint Satisfaction Problem) approach:
Consider every cell in the grid to be a variable, with 4 possible values (indicating the part of the domino it takes). Some assignments are obviously illegal. Legal assignments assign values to a "neighboring variable" as well. Your goal is to assign all the 3xN variables with legal values.
The recursion here can help you cover the state space easily. On each invocation, you try to assign a value to the next unasigned cell, by trying all the 4 options. After each successfull assignment, you can call the same method recursively, and then undo your last assignment (this way you don't have to clone anything - one copy of the grid data is enough).
--EDIT--
If you want to do it efficiently so that it works for large values on N in reasonable time, you will also have to think about optimizations, in order to discard some assignment attempts.
Here are some hints:
With a fixed-size board you can precompute the exact number of steps that each solution takes, so the termination criterion is trivial: you just check the nesting level.
Starting from one corner is a good idea, because it means that you can always find a field that can only be covered in two different ways (vertically or horizontally).
That means that you have a branching factor of only 2, and a recursion depth of 3*N/2, which is probably small enough that you can just clone the sstate of the board for each call (ordinarily you would construct new states incrementally from existing states to save space, but that is a bit harder to program).
In many states here will be more than one field that allows only two possibilities; with a clever strategy for choosing the next field, you can ensure that you will never find the same solution via two different paths, so you don't even have to check the solutions for duplicates.
The state of the board must record which fields are free and which fields are occupied, but also which fields are occupied by the same domino, so an array of int could do the trick.

Categories

Resources