Representing Minesweeper Constraints in Sat4J/CNF - java

I'm trying to implement a minesweeper solver using a SAT solver (sat4j) and I have a simple understanding of how they work. But one thing I can't figure out is how to represent the x+y+Z+....=2 for mines, since SAT solvers use Boolean input. Something such as in the table below:
| a | b | c | d | e |
| f | 2 | g | 3 | h |
| i | j | k | l | m |
You could write a+b+c+f+g+i+j+k = 2 and c+d+e+g+h+k+l+m= 3.

if by a+b+c+f+g+i+j+k = 2 you mean that the surrounding cells contain exactly two mines, then your letters really are Boolean variables, and that constraint is called a cardinality constraint.
This is supported out of the box by Sat4j.
You may find some hints here:
https://sat4j.gitbooks.io/case-studies/content/

Related

Java find “stain” in multidimensional - recursive

I am trying to solve this Recursive Exercise:
In a multidimensional board (M x N), which everyone of his elements can be empty or full.
"stain" size is the number of elements who are next to each other and has the value 'x'.
for example this is a multidimensional array (the numbers are the row/column number)
| 0 | 1 | 2 | 3 | 4 |
0 | | x | | | x |
1 | x | | | x | x |
2 | | | x | x | |
3 | x | | | | |
4 | x | x | x | | |
There are 3 stains:
Rows (0,1), (1,0) - Size of 2
Rows (0 ,4) ,(1 ,3) ,(1 ,4) ,(2 ,2) ,(2 ,3) - Size 5
Rows (3 ,0) ,(4 ,0) ,(4 ,1) ,(4 ,2) - Size 4
We need to write a recursive method who has a signature of:
public static int stain (char [][] mat, int row, int col)
the method will get a row and a column and calculate the stain size from that place, if there is no stain it will return 0.
I tried to write the method to solve it but looks like I was doing it kinda messy... can you direct me to the right direction? I'm not looking for a straight answer.
Thanks.
I can't do loops!

Given a Dataset<Row> is there an API function that takes a Row to add a column?

I'm looking for an API which would allow me to add a column based on a functions output that has access to the whole Row. This would be similar to the ability to call Dataset#filter(FilterFunction)
As an example, suppose I have the following DF
+----+----+----+
| c0 | c1 | c2 |
+----+----+----+
| 1 | 2 | 3 |
+----+----+----+
I would like to be able to create a new column
df.withColumn("c3", row ->
row.getInt(0) + row.getInt(1) + row.getInt(2));
And result in
+----+----+----+----+
| c0 | c1 | c2 | c3 |
+----+----+----+----+
| 1 | 2 | 3 | 6 |
+----+----+----+----+
This is an over simplified example, the functions in question are much more complex and built at run-time.
You can either use map:
map(MapFunction<T,U> func, Encoder<U> encoder)
and rebuild a whole Row, or combine all columns you need with struct and use udf:
import static org.apache.spark.sql.functions.*;
UserDefinedFunction f = udf(
(Row row) -> row.getInt(0) + row.getInt(1) + row.getInt(2),
DataTypes.IntegerType
);
df.withColumn("c3", f(struct(col("c1"), col("c2"), col("c3"))));
but both methods will significantly less efficient than using standard SQL expressions.

How to count values in different column of table in sql using java

This is database table named attendance _table and i want to count total no. of absent in all subjects i.e total no. absent in MATHS+CA+CN+SP+OOPS. Please help!!!
you can use case to find above sum. Take an idea from this query.
select sum(case when maths = 'ABSENT' then 1 else 0 end) +
sum(case when ca = 'ABSENT' then 1 else 0 end) +
sum(case when cn = 'ABSENT' then 1 else 0 end)
from attendance_table;
Note that this answer is not a direct answer to the question...
You have a problem with your data modelling. You don't respect normal form, which make simple operations harder to execute. You should split your table and store Students, Courses and Attendance in separate tables. :
+-----------+------+
| StudentID | Name |
+-----------+------+
| 1 | Max |
| 2 | Luke |
+-----------+------+
+-----------+-------+
| CourseId | Title |
+-----------+-------+
| 1 | Math |
| 2 | CA |
+-----------+-------+
+--------------+-----------+---------+------------+
| attendenceId | StudentId | CourseId| Attendance |
+--------------+-----------+---------+------------+
| 1 | 1 | 1 | present |
| 2 | 1 | 2 | absent |
| 3 | 2 | 1 | present |
| 4 | 2 | 2 | present |
+--------------+-----------+---------+------------+
The query now is much simpler and does not need to be changed if you add new courses:
select count(*) from attendance where Attendance = 'absent'
If you want the number of absence for a specific user, it again quite easy. Or the number of absence for a specific course, again, easy.

What's wrong with this recursion for checkers move generation?

I'm writing a simple checkers game in Java. The hard part so far is to generate a list of possible jumps for a piece, especially when there are several paths to jump. I have this recursion to find all possible paths to do a series of jumps. Here's some code:
/*
* possibleJumps(Square pos, Board b, Move jump, ArrayList<Move> moves)
* Add all possible jumps from the position b on board b to movelist moves.
*/
void possibleJumps(Square pos, Board b, Move jump, ArrayList<Move> moves) {
ArrayList<Move> simpleJ = this.simpleJumps(pos, b);
//jump.addJumpSquare(pos);
//System.out.println("check jump " + pos + " so far:" + jump);
if (simpleJ.isEmpty()) {
// no more jumps -> end this jump and add it to the list
jump.endJump(pos);
moves.add(jump);
System.out.println("found jump" + jump);
return;
}
for(Move j:simpleJ) {
jump.addJumpSquare(j.jumped.get(0)); // add the jumped square to the jump path
possibleJumps(j.to, b.doMove(j), new Move(jump), moves);
}
}
Just to explain: simpleJumps generates a list of possible jumps over one square (so basically all attack moves). That works fine.
Here's the test board:
A B C D E F G H
---------------------------------
1 | | o | | | | | | | 1 (0)
---------------------------------
2 | | | | | | | | | 2 (1)
---------------------------------
3 | | o | | o | | o | | o | 3 (2)
---------------------------------
4 | | | | | | | | | 4 (3)
---------------------------------
5 | | o | | o | | o | | o | 5 (4)
---------------------------------
6 | | | | | | | | | 6 (5)
---------------------------------
7 | | o | | O | | o | | | 7 (6)
---------------------------------
8 | x | | | | | | | | 8 (7)
---------------------------------
Here's the output I get:
found jumpa8c2 via b7-b5-b3-
found jumpa8c2 via b7-b5-d5-d3-
found jumpa8g2 via b7-b5-d5-d3-f3-
What it should be is:
found jumpa8c2 via b7-b5-b3-
found jumpa8c2 via b7-d5-d3-
found jumpa8g2 via b7-d5-f3-
This is, in principle, very similar to:
Print all paths from root to leaf in a Binary tree
which I read and used to get as far as I have gotten, but I'm missing something probably very simple...
Any ideas?
In this loop
for(Move j:simpleJ) {
jump.addJumpSquare(j.jumped.get(0)); // add the jumped square to the jump path
possibleJumps(j.to, b.doMove(j), new Move(jump), moves);
}
you are reusing the same jump for all possible moves - if you got 3 possible moves x,y,z you will end up with x, y and z added to the jump path.
So you either have to
create a new jump-object (with appropriate state) at each iteration or
remove the added square at the end of the iteration

iterating list with x blocks and pick out y elements out of each block

I do not have a smart or at least working idea how to solve following challenge:
I have 198 assignments and let each assignment solved by 10 persons, then I wrote everything in a PostgreSQL database by using Java hibernate & persistence API. That worked fine so far.
Sometimes I do have 10 different/distinct answers for an assignment - for other assignments I do have only 2 or 3 different/distinct answers (e.g. for the assignment "what is 5 + 5", 8 persons told "10" and 2 persons told "25")
Now I run a SQL statement to get a list with my assignments and the distinct answers:
SELECT DISTINCT question, answer FROM survey INNER JOIN results ON results.survey_id=results.id;
what I get now is a result list that looks more or less like this:
+---------+----------+--------+
| ID | Question | Answer |
+---------+----------+--------+
| 1 | Q1 | 20 |
| 2 | Q1 | 22 |
| 3 | Q1 | 25 |
| 4 | Q1 | 21 |
| 5 | Q1 | 22 |
| 6 | Q1 | 10 |
| 7 | Q1 | 20.5 |
| 8 | Q1 | 22.3 |
| 9 | Q1 | 28 |
| 10 | Q1 | 26 |
| 11 | Q2 | 52 |
| 12 | Q2 | 51 |
| 13 | Q3 | 78 |
| 14 | Q3 | 80 |
| ... | ... | ... |
| ... | ... | ... |
| ... | ... | ... |
+---------+---------+---------+
now the challening part:
I want now randomly pick out 4 distinct answers (if possible) from each assignment (Q1, Q2, Q3, ...) and create a new assignment where people have to vote on the best answer.
But as shown, sometimes I do have less then 4 distinct answers for an assignment. In this case I want to take everything that's available.
How could I iterate through my list and perform this kind of "picking"?
P.S. it's not very important to pick the answers randomly - would also be okay to pick the first 4 answers.
appreciate your help
regards
if the resultset is that small i would just
// if random is needed [see here][1] to adapt the criteria
var answers = session.createCriteria(Answer.class)
.setFetchMode("Question", FetchMode.eager)
.list<Answer>();
// map of orginal question to voting question
Map<Question, Question> questions = new Hashmap<Question, Question>();
for (Answer answer : answers)
{
if (questions.ContainsKey(answer.getQuestion()))
{
Question votingQuestion = questions.get(answer.getQuestion());
if (votingQuestion.getPossibleAnswers().Count() < 4)
votingQuestion.getPossibleAnswers().add(answer.Text);
}
else
{
Question votingQuestion = createVotingQuestion(answer.getQuestion());
votingQuestion.getPossibleAnswers().add(answer.Text);
questions.add(answer.getQuestion(), votingQuestion);
}
}

Categories