summaryrefslogtreecommitdiff
path: root/squeen.icl
diff options
context:
space:
mode:
Diffstat (limited to 'squeen.icl')
-rw-r--r--squeen.icl58
1 files changed, 58 insertions, 0 deletions
diff --git a/squeen.icl b/squeen.icl
new file mode 100644
index 0000000..cd67c16
--- /dev/null
+++ b/squeen.icl
@@ -0,0 +1,58 @@
+module squeen
+
+/*
+The Queens Problem.
+
+Or: How to put n queens on a n*n chessboard in such a way that they
+cannot attack each other.
+
+The result of this program is the number of possible solutions for
+the queens problem for a certain boardsize together with one solution.
+When BoardSize is 8 the result will be: (92,[4,2,7,3,6,8,5,1]),
+which means the queens are on a4, b2, c7, d3, e6, f8, g5 and h1.
+
+Strictness annotations are used at certain points, because that makes
+this program more than twice as fast (the strictness analyzer is not
+able to deduce this strictness information). However, other Clean programs
+for the Queens problem exist without strictness annotations added by the
+programmer that are only 40% slower than this solution (lqueen.icl).
+
+*/
+
+import StdEnv
+
+BoardSize :== 8 // The size of the chessboard.
+
+// Finding all solutions for the queens problem.
+
+Queens::Int [Int] [[Int]] -> [[Int]]
+Queens row board boards
+ | row>BoardSize = [board : boards]
+ | otherwise = TryCols BoardSize row board boards
+
+TryCols::Int Int [Int] [[Int]] -> [[Int]]
+TryCols 0 row board boards = boards
+TryCols col row board boards
+ | Save col 1 board = TryCols (col-1) row board queens
+ | otherwise = TryCols (col-1) row board boards
+where queens = Queens (row+1) [col : board] boards
+
+/* The strictness analyzer can't derive strictness for the first and second
+ argument of Save, because they are not used in the first alternative
+ of that function. However, Save is strict in these arguments (in the
+ context of this program) and adding the strictness annotations speeds
+ up this program considerably. */
+
+Save::!Int !Int [Int] -> Bool
+Save c1 rdiff [] = True
+Save c1 rdiff [c2:cols]
+ | cdiff==0 || cdiff==rdiff || cdiff==0-rdiff = False
+ | otherwise = Save c1 (rdiff+1) cols
+where cdiff = c1 - c2
+
+/* The Start Rule: Calculate the list of solutions, show the first
+ solution and the length of that list. */
+
+Start::(Int,[Int])
+Start = (length solutions, hd solutions)
+where solutions = Queens 1 [] []