[pure-lang-svn] SF.net SVN: pure-lang: [191] pure/trunk/examples/myutils.pure
Status: Beta
Brought to you by:
agraef
|
From: <ag...@us...> - 2008-06-07 06:36:30
|
Revision: 191
http://pure-lang.svn.sourceforge.net/pure-lang/?rev=191&view=rev
Author: agraef
Date: 2008-06-06 23:36:38 -0700 (Fri, 06 Jun 2008)
Log Message:
-----------
Update examples.
Modified Paths:
--------------
pure/trunk/examples/myutils.pure
Modified: pure/trunk/examples/myutils.pure
===================================================================
--- pure/trunk/examples/myutils.pure 2008-06-06 21:08:17 UTC (rev 190)
+++ pure/trunk/examples/myutils.pure 2008-06-07 06:36:38 UTC (rev 191)
@@ -1,13 +1,13 @@
// Dr Libor Spacek, 21th May 2008
-//General mathematical iterators over one and two indices and examples of their use
+//General mathematical iterators over one and two indices
MathIter1 op i1 i2 f = foldl1 op (map f (i1..i2));
-MathIter2 op i1 i2 j1 j2 f = foldl1 op (map (uncurry f) [x,y; x = i1..i2; y = j1..j2]);
-
+MathIter2 op i1 i2 j1 j2 f =
+ foldl1 op (map (uncurry f) [x,y; x = i1..i2; y = j1..j2]);
+//Examples on how to use the mathematical iterators
Sigma i1 i2 f = MathIter1 (+) i1 i2 f;
Pi i1 i2 f = MathIter1 (*) i1 i2 f;
Factorial n = Pi 1L n id;
-
//Binomial using (k, n-k) symmetry and bignum division
Binomial n k = (Pi (k+1L) n id) div (Pi 2L (n-k) id) if n-k < k;
= (Pi (n-k+1L) n id) div (Pi 2L k id);
@@ -26,27 +26,28 @@
// rotate n items, generalisation of "rotate the bits instruction"
// example: head (nrotate (-33) (0..23));
-// what time is 33 hrs before midnight? 15 hrs. The clock was moved -9 = -33 mod 24
+// what time is 33 hrs before midnight? 15 hrs.
+// The clock was moved -33 mod 24 = -9 hours from midnight (0)
nrotate n::int l = protate nm l when ll = #l; nm = ll + (n mod ll) end if n<0;
- = protate nm l when nm = n mod #l end;
+ = protate nm l when nm = n mod #l end;
// interpret any nonzero result as true: prevents errors in conditions
nonzero 0 = 0;
nonzero x = 1;
// The Queens problem:
-// the solution is only the rows permutation, without the ordered columns (1..n).
+// the solution is only the rows permutation, without the ordered columns (1..n)
// full 2D board coordinates can be produced with: zip (1..n) (queens n);
safe _ _ [] = 1;
-safe id::int j::int (j2::int:l) = if (j==j2) || (id==j2-j) || (id==j-j2) then 0
- else safe (id+1) j l;
+safe id::int j::int (j2::int:l) =
+ if (j==j2) || (id==j2-j) || (id==j-j2) then 0 else safe (id+1) j l;
queens n::int = list (search n n n [])
with
- search _ 0 _ _ = (); // last i, solved
+ search _ 0 _ p = (); // last i, solved
search _ _ 0 _ = 0; // fail, run out of alternative js
search n::int i::int j::int p =
- if nonzero solution then j,solution // new i led to a solution
+ if nonzero solution then j,solution // new i led to a solution
else search n i (j-1) p // or it failed, try another j
when solution = search n (i-1) n (j:p); end if safe 1 j p;
= search n i (j-1) p // also try another j when unsafe
@@ -55,34 +56,38 @@
// this concise backtracking tailqueens throw a single solution
tailqueens n::int = catch id (srch n n n [])
with srch _ 0 _ p = throw p; srch _ _ 0 _ = 0;
- srch n::int i::int j::int p = () if safe 1 j p && nonzero (srch n (i-1) n (j:p));
- = srch n i (j-1) p end;
+ srch n::int i::int j::int p = if safe 1 j p then
+ ( if nonzero (srch n (i-1) n (j:p)) then 1 else srch n i (j-1) p )
+ else srch n i (j-1) p
+ end;
// thequeens encodes my no search solution which is my original discovery,
// to my knowledge the simplest known algorithm for this kind of a problem.
// there always exists one fundamental centre-symmetrical solution of this form,
// representing an orbit of just four solutions, instead of the usual eight.
// these few lines of code are self-contained (not calling any square checking).
+// has been tested exhaustively from 0 to 5000 and individually for 50000.
thequeens 1 = [0]; thequeens n::int = no solution if n<4;
-thequeens n::int = map (\x-> newsquare n x) (0..(n-1))
+thequeens n::int = map (newsquare n) (0..(n-1))
with newsquare n::int x::int = (start+2*x) mod n if x < halfn;
= (start2+2*(x-halfn)) mod n end //reflections
when halfn = n div 2;
start = if (n mod 3) then (halfn-1) else 1; // (n mod 3) == 0 is special
- start2 = n-((start + 2*(halfn-1)) mod n)-1 end if (n mod 2)==0; // all even boards
- = 0:(map (\x->1+x)(thequeens (n-1))); // corner start solves odd size boards
+ start2 = n-((start + 2*(halfn-1)) mod n)-1 end if (n mod 2)==0; // even
+ = 0:(map (\x->1+x)(thequeens (n-1))); // corner start solves odd size boards!
// row numbering in thequeens was changed to the "C style" e.g. 0..7.
// full board coordinates, e.g. (1..8) x (1..8) can be reconstructed with:
fullboard simple = zip (1..(#simple)) (map (\x->1+x) simple);
// checks one queens solution either in 0..7 encoding or in 1..8 encoding.
-// returns 1 for a valid solution, 0 otherwise
+// returns 1 for a correct result, including "no solution" for sizes 2 and 3.
+// returns 0 if a queen attack exists anywhere in the presented solution
checkqs [] = 1;
checkqs (s::int:l) = if safe 1 s l then checkqs l else 0;
+checkqs (no solution) = 1;
-// conducts an exhaustive test of boards of all sizes from min to max, e.g. >queenstest (4..1000);
-// test _ min::int max::int = second argument must be greater than the first if min>=max;
+// conducts an exhaustive test of boards of all listed sizes.
+// examples of use: >queenstest (1..1000); >queenstest (5000,4999..4990);
queenstest [] = 1;
queenstest (h:l) = if checkqs (thequeens h) then queenstest l else 0;
-
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|