ajout des fichiers originaux présentés dans l'atelier
This commit is contained in:
commit
74bfdbfb44
6 changed files with 355 additions and 0 deletions
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
.idea/
|
||||
project/target/
|
||||
target/
|
9
build.sbt
Normal file
9
build.sbt
Normal file
|
@ -0,0 +1,9 @@
|
|||
name := "puzzles_libre"
|
||||
|
||||
version := "0.1"
|
||||
|
||||
scalaVersion := "2.11.12"
|
||||
|
||||
resolvers += "Artifactory" at "http://artifactory.info.ucl.ac.be/artifactory/libs-release/"
|
||||
|
||||
libraryDependencies += "oscar" % "oscar-cp_2.11" % "3.1.0"
|
1
project/build.properties
Normal file
1
project/build.properties
Normal file
|
@ -0,0 +1 @@
|
|||
sbt.version = 1.1.1
|
185
src/main/scala/CrossWord.scala
Normal file
185
src/main/scala/CrossWord.scala
Normal file
|
@ -0,0 +1,185 @@
|
|||
/*******************************************************************************
|
||||
* OscaR is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* OscaR is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with OscaR.
|
||||
* If not, see http://www.gnu.org/licenses/lgpl-3.0.en.html
|
||||
******************************************************************************/
|
||||
import oscar.cp._
|
||||
import oscar.cp.core.CPPropagStrength
|
||||
|
||||
/**
|
||||
|
||||
Crosswords in OscaR.
|
||||
|
||||
This is a standard example for constraint logic programming. See e.g.
|
||||
|
||||
http://www.cis.temple.edu/~ingargio/cis587/readings/constraints.html
|
||||
|
||||
We are to complete the puzzle
|
||||
|
||||
1 2 3 4 5
|
||||
+---+---+---+---+---+ Given the list of words:
|
||||
1 | 1 | | 2 | | 3 | AFT LASER
|
||||
+---+---+---+---+---+ ALE LEE
|
||||
2 | # | # | | # | | EEL LINE
|
||||
+---+---+---+---+---+ HEEL SAILS
|
||||
3 | # | 4 | | 5 | | HIKE SHEET
|
||||
+---+---+---+---+---+ HOSES STEER
|
||||
4 | 6 | # | 7 | | | KEEL TIE
|
||||
+---+---+---+---+---+ KNOT
|
||||
5 | 8 | | | | |
|
||||
+---+---+---+---+---+
|
||||
6 | | # | # | | # | The numbers 1,2,3,4,5,6,7,8 in the crossword
|
||||
+---+---+---+---+---+ puzzle correspond to the words
|
||||
that will start at those locations.
|
||||
|
||||
|
||||
The model was inspired by Sebastian Brand's Array Constraint cross word example
|
||||
http://www.cs.mu.oz.au/~sbrand/project/ac/
|
||||
http://www.cs.mu.oz.au/~sbrand/project/ac/examples.pl
|
||||
|
||||
|
||||
|
||||
@author Hakan Kjellerstrand hakank@gmail.com
|
||||
http://www.hakank.org/oscar/
|
||||
|
||||
*/
|
||||
object CrossWord extends CPModel with App {
|
||||
|
||||
//
|
||||
// data
|
||||
//
|
||||
|
||||
val alpha = Array(" ", "a", "b", "c", "d", "e", "f",
|
||||
"g", "h", "i", "j", "k", "l", "m",
|
||||
"n", "o", "p", "q", "r", "s", "t",
|
||||
"u", "v", "w", "x", "y", "z")
|
||||
|
||||
val a = 1
|
||||
val b = 2
|
||||
val c = 3
|
||||
val d = 4
|
||||
val e = 5
|
||||
val f = 6
|
||||
val g = 7
|
||||
val h = 8
|
||||
val i = 9
|
||||
val j = 10
|
||||
val k = 11
|
||||
val l = 12
|
||||
val m = 13
|
||||
val n = 14
|
||||
val o = 15
|
||||
val p = 16
|
||||
val q = 17
|
||||
val r = 18
|
||||
val s = 19
|
||||
val t = 20
|
||||
val u = 21
|
||||
val v = 22
|
||||
val w = 23
|
||||
val x = 24
|
||||
val y = 25
|
||||
val z = 26
|
||||
|
||||
val num_words = 15
|
||||
val word_len = 5
|
||||
|
||||
val AA = Array(Array(h, o, s, e, s), // HOSES
|
||||
Array(l, a, s, e, r), // LASER
|
||||
Array(s, a, i, l, s), // SAILS
|
||||
Array(s, h, e, e, t), // SHEET
|
||||
Array(s, t, e, e, r), // STEER
|
||||
Array(h, e, e, l, 0), // HEEL
|
||||
Array(h, i, k, e, 0), // HIKE
|
||||
Array(k, e, e, l, 0), // KEEL
|
||||
Array(k, n, o, t, 0), // KNOT
|
||||
Array(l, i, n, e, 0), // LINE
|
||||
Array(a, f, t, 0, 0), // AFT
|
||||
Array(a, l, e, 0, 0), // ALE
|
||||
Array(e, e, l, 0, 0), // EEL
|
||||
Array(l, e, e, 0, 0), // LEE
|
||||
Array(t, i, e, 0, 0)) // TIE
|
||||
|
||||
val num_overlapping = 12
|
||||
val overlapping = Array(Array(0, 2, 1, 0), // s
|
||||
Array(0, 4, 2, 0), // s
|
||||
|
||||
Array(3, 1, 1, 2), // i
|
||||
Array(3, 2, 4, 0), // k
|
||||
Array(3, 3, 2, 2), // e
|
||||
|
||||
Array(6, 0, 1, 3), // l
|
||||
Array(6, 1, 4, 1), // e
|
||||
Array(6, 2, 2, 3), // e
|
||||
|
||||
Array(7, 0, 5, 1), // l
|
||||
Array(7, 2, 1, 4), // s
|
||||
Array(7, 3, 4, 2), // e
|
||||
Array(7, 4, 2, 4)) // r
|
||||
|
||||
val N = 8
|
||||
|
||||
//
|
||||
// variables
|
||||
//
|
||||
val A = Array.fill(num_words, word_len)(CPIntVar(0 to 26))
|
||||
val A_flatten = A.flatten
|
||||
|
||||
val E = Array.fill(N)(CPIntVar(0 to num_words))
|
||||
|
||||
//
|
||||
// constraints
|
||||
//
|
||||
|
||||
|
||||
add(allDifferent(E))
|
||||
|
||||
for (i <- 0 until num_words;j <- 0 until word_len){
|
||||
add(A(i)(j) == AA(i)(j))
|
||||
}
|
||||
|
||||
|
||||
// Handle the overlappings.
|
||||
//
|
||||
// It's coded in MiniZinc as:
|
||||
// forall(i in 1..num_overlapping) (
|
||||
// A[E[overlapping[i,1]], overlapping[i,2]] =
|
||||
// A[E[overlapping[i,3]], overlapping[i,4]]
|
||||
// )
|
||||
//
|
||||
for (i <- 0 until num_overlapping) {
|
||||
add(
|
||||
A_flatten(E(overlapping(i)(0)) * word_len + overlapping(i)(1))
|
||||
==
|
||||
A_flatten(E(overlapping(i)(2)) * word_len + overlapping(i)(3)),
|
||||
CPPropagStrength.Strong
|
||||
)
|
||||
}
|
||||
|
||||
search(binaryStatic(E))
|
||||
|
||||
onSolution {
|
||||
println("E: " + E.mkString(" "))
|
||||
for (ee <- 0 until N) {
|
||||
print(ee + ": (" + "%2d".format(E(ee).value) + ") ")
|
||||
for (ii <- 0 until word_len) {
|
||||
print(alpha(A(ee)(ii).value))
|
||||
}
|
||||
println()
|
||||
}
|
||||
println()
|
||||
}
|
||||
|
||||
val stats = start()
|
||||
println(stats)
|
||||
|
||||
}
|
23
src/main/scala/Queens.scala
Normal file
23
src/main/scala/Queens.scala
Normal file
|
@ -0,0 +1,23 @@
|
|||
import oscar.cp._
|
||||
object Queens extends CPModel with App {
|
||||
val nQueens = 12 // Number of queens
|
||||
val Queens = 0 until nQueens
|
||||
// Variables
|
||||
val queens = Array.fill(nQueens)(CPIntVar.sparse(0, nQueens - 1))
|
||||
// Constraints
|
||||
add(allDifferent(queens))
|
||||
add(allDifferent(Queens.map(i => queens(i) + i)))
|
||||
add(allDifferent(Queens.map(i => queens(i) - i)))
|
||||
// Search heuristic
|
||||
search(binaryFirstFail(queens))
|
||||
onSolution{
|
||||
print("Solution potentielle\n")
|
||||
println(queens.mkString(" "))
|
||||
}
|
||||
// Execution
|
||||
val stats = start()
|
||||
println(stats)
|
||||
|
||||
|
||||
|
||||
}
|
134
src/main/scala/Sudoku2.scala
Normal file
134
src/main/scala/Sudoku2.scala
Normal file
|
@ -0,0 +1,134 @@
|
|||
/*******************************************************************************
|
||||
* OscaR is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* OscaR is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with OscaR.
|
||||
* If not, see http://www.gnu.org/licenses/lgpl-3.0.en.html
|
||||
******************************************************************************/
|
||||
import oscar.cp._
|
||||
import scala.io.Source._
|
||||
import scala.math._
|
||||
|
||||
/**
|
||||
*
|
||||
* Sudoku solver in Oscar.
|
||||
*
|
||||
* See http://en.wikipedia.org/wiki/Sudoku
|
||||
*
|
||||
* This version can also read a problem instance from a file.
|
||||
*
|
||||
* A collection of problem instances (from Gecode) can be found
|
||||
* in the ./data directory.
|
||||
*
|
||||
*
|
||||
* @author Hakan Kjellerstrand hakank@gmail.com
|
||||
* http://www.hakank.org/oscar/
|
||||
*
|
||||
*/
|
||||
object Sudoku2 extends CPModel with App {
|
||||
|
||||
// data
|
||||
var n = 9
|
||||
var reg = 3
|
||||
val X = 0
|
||||
|
||||
//
|
||||
// data
|
||||
//
|
||||
// This problem is problem 0 from
|
||||
// Gecode's sudoku.cpp
|
||||
// http://www.gecode.org/gecode-doc-latest/sudoku_8cpp-source.html
|
||||
//
|
||||
var problem = Array(
|
||||
Array(X, X, X, 2, X, 5, X, X, X),
|
||||
Array(X, 9, X, X, X, X, 7, 3, X),
|
||||
Array(X, X, 2, X, X, 9, X, 6, X),
|
||||
Array(2, X, X, X, X, X, 4, X, 9),
|
||||
Array(X, X, X, X, 7, X, X, X, X),
|
||||
Array(6, X, 9, X, X, X, X, X, 1),
|
||||
Array(X, 8, X, 4, X, X, 1, X, X),
|
||||
Array(X, 6, 3, 1, X, X, X, 8, X),
|
||||
Array(X, X, X, 6, X, 8, X, X, X))
|
||||
|
||||
val alpha = ('0' to'9') ++ ('A' to 'Z')
|
||||
|
||||
// read problem instance from file
|
||||
if (args.length > 0) {
|
||||
val fileName = args(0)
|
||||
println("\nReading from file: " + fileName)
|
||||
|
||||
val lines = fromFile(fileName).getLines.filter(!_.startsWith("#")).toArray
|
||||
n = lines(0).toInt
|
||||
reg = sqrt(n).toInt
|
||||
println("Size:" + n)
|
||||
val this_problem = lines.tail.map(_.split("\\s+").
|
||||
filter(_.length>0).map(i=>if (i == ".") X else i.toInt))
|
||||
println(this_problem.map(row=>row.
|
||||
map(e=>if (e==0) " ." else "%3s".format(alpha(e))).mkString("")).
|
||||
mkString("\n"))
|
||||
|
||||
println()
|
||||
|
||||
problem = this_problem
|
||||
|
||||
}
|
||||
|
||||
val NRANGE = 0 until n
|
||||
val RRANGE = 0 until reg
|
||||
|
||||
// variables
|
||||
val x = Array.fill(n,n)(CPIntVar(1 to n))
|
||||
val x_t = x.transpose
|
||||
|
||||
//
|
||||
// constraints
|
||||
//
|
||||
var numSols = 0
|
||||
|
||||
search {
|
||||
|
||||
binaryFirstFail(x.flatten.toSeq)
|
||||
|
||||
}
|
||||
|
||||
onSolution {
|
||||
|
||||
println("\nSolution:")
|
||||
for(i <- NRANGE) {
|
||||
println(x(i).map(j=>alpha(j.value)).mkString(" "))
|
||||
}
|
||||
println()
|
||||
|
||||
numSols += 1
|
||||
|
||||
}
|
||||
|
||||
|
||||
// fill with the hints
|
||||
for(i <- NRANGE;
|
||||
j <- NRANGE if problem(i)(j) > 0) {
|
||||
add(x(i)(j) == problem(i)(j))
|
||||
}
|
||||
|
||||
// rows and columns
|
||||
for(i <- NRANGE) {
|
||||
add(allDifferent(x(i)), Strong)
|
||||
add(allDifferent(x_t(i)), Strong)
|
||||
}
|
||||
|
||||
// blocks
|
||||
for(i <- RRANGE; j <- RRANGE) {
|
||||
add(allDifferent((for{ r <- i*reg until i*reg+reg;
|
||||
c <- j*reg until j*reg+reg
|
||||
} yield x(r)(c))), Strong)
|
||||
}
|
||||
val stats = start()
|
||||
println(stats)
|
||||
}
|
Loading…
Reference in a new issue