Make things a lot quicker
authorMart Lubbers <mart@martlubbers.net>
Wed, 13 Feb 2019 13:51:42 +0000 (14:51 +0100)
committerMart Lubbers <mart@martlubbers.net>
Wed, 13 Feb 2019 13:51:58 +0000 (14:51 +0100)
Makefile
README.md
peg.icl

index ee49bc5..a6869ee 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,14 +2,9 @@ BINARIES:=peg
 
 CLEAN_HOME?=/opt/clean
 
-CLMLIBS:=$(addprefix -I $(CLEAN_HOME)/lib/,Platform Generics Dynamics StdEnv)
+CLMLIBS:=-IL Platform
 CLM:=clm
 
-override CLMFLAGS+=-nt
-ifeq "$(shell expr `gcc -dumpversion | cut -f1 -d.` \>= 6)" "1"
-       override CLMFLAGS+=-l -no-pie
-endif
-
 all: $(BINARIES)
 
 %: %.icl $(wildcard *.[id]cl)
index 0c2847b..faabf38 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1,9 +1,10 @@
 # Peg solitaire solver
 
-Solves it in a minute.
+Solves it in a couple of seconds.
 
 ## Todo
 - iTasks interface
+- unique arrays
 
 ## Author
 Mart Lubbers
diff --git a/peg.icl b/peg.icl
index 8efcd4b..07129a0 100644 (file)
--- a/peg.icl
+++ b/peg.icl
@@ -2,13 +2,12 @@ module peg
 
 import StdEnv
 
-from Text import class Text, instance Text String
-import qualified Text
-from Data.Func import $
+import Text
+import Data.Func
 import Data.Tuple
 import Data.List
 import Data.Monoid
-import Control.Monad
+import Control.Monad => qualified join
 import Control.Monad.RWST
 import Control.Applicative
 import Data.Maybe
@@ -25,14 +24,12 @@ E :== 1
 S :== 2
 W :== 3
 
-:: Coord = {x::Int, y::Int}
-:: Move = {c::Coord, d::Direction}
+:: Coord     =  {x :: !Int  , y :: !Int}
+:: Move      =  {c :: !Coord, d :: !Direction}
 :: PegBoard :== {#{#Position}}
 
-:: Solver a :== RWST () [PegBoard] PegBoard Maybe a
-
-english :: PegBoard
-english = 
+english :: *PegBoard
+english =
        {{Inv, Inv, Peg, Peg, Peg, Inv, Inv}
        ,{Inv, Inv, Peg, Peg, Peg, Inv, Inv}
        ,{Peg, Peg, Peg, Peg, Peg, Peg, Peg}
@@ -42,8 +39,8 @@ english =
        ,{Inv, Inv, Peg, Peg, Peg, Inv, Inv}
        }
 
-french :: PegBoard
-french = 
+french :: *PegBoard
+french =
        {{Inv, Inv, Peg, Peg, Peg, Inv, Inv}
        ,{Inv, Peg, Peg, Peg, Peg, Peg, Inv}
        ,{Peg, Peg, Peg, Emp, Peg, Peg, Peg}
@@ -53,8 +50,8 @@ french =
        ,{Inv, Inv, Peg, Peg, Peg, Inv, Inv}
        }
 
-german :: PegBoard
-german = 
+german :: *PegBoard
+german =
        {{Inv, Inv, Inv, Peg, Peg, Peg, Inv, Inv, Inv}
        ,{Inv, Inv, Inv, Peg, Peg, Peg, Inv, Inv, Inv}
        ,{Inv, Inv, Inv, Peg, Peg, Peg, Inv, Inv, Inv}
@@ -91,45 +88,42 @@ diamond =
        ,{Inv, Inv, Inv, Inv, Peg, Inv, Inv, Inv, Inv}
        }
 
-empty = RWST \_ _->Nothing
-(<|>) (RWST fa) (RWST fb) = RWST \r s->maybe (fb r s) Just (fa r s)
-
-transform :: Coord Direction -> Coord
-transform c=:{x,y} d = case d of
-       N = {c&y=y+1}; S = {c&y=y-1}; W = {c&x=x+1}; E = {c&x=x-1}
-
-getPos :: Coord -> Solver Position
-getPos {x,y} = get >>= \b->if (valid b) empty (pure b.[y].[x])
+getPos :: !Coord !.PegBoard -> Maybe Position
+getPos {x,y} b = if (valid b) Nothing (Just (b.[y].[x]))
 where 
        valid b = y<0 || x<0 || y >= size b || x >= size b.[0] || b.[y].[x] == Inv
 
-move :: Move -> Solver ()
-move {c=c=:{x=tx,y=ty}, d}
-# sc=:{x=sx,y=sy} = transform c d
+move :: !PegBoard !Move -> Maybe PegBoard
+move b {c=cc=:{x=tx,y=ty}, d}
+# sc=:{x=sx,y=sy} = transform cc d
 # fc=:{x=fx,y=fy} = transform sc d
-= get >>= \b->liftM3 tuple3 (getPos fc) (getPos sc) (getPos c) >>= \f->case f of
-       (Peg, Peg, Emp)
-               # b = {{{c\\c<-:r}\\r<-:b} & [fy,fx]=Emp, [sy,sx]=Emp, [ty,tx]=Peg}
-               = tell [b] >>| put b
-       _ = empty
-
-getCoords :: (Char -> Bool) PegBoard -> [Coord]
+= case getPos fc b of
+       Just Peg = case getPos sc b of
+               Just Peg = case getPos cc b of
+                       Just Emp = Just {{{c\\c<-:r}\\r<-:b} & [fy,fx]=Emp, [sy,sx]=Emp, [ty,tx]=Peg}
+                       _ = Nothing
+               _ = Nothing
+       _ = Nothing
+where
+       transform :: !Coord !Direction -> Coord
+       transform c=:{x,y} d = case d of
+               N = {c & y=y+1}
+               S = {c & y=y-1}
+               W = {c & x=x+1}
+               E = {c & x=x-1}
+
+getCoords :: (Char -> Bool) !PegBoard -> [Coord]
 getCoords f b = [{x=x,y=y}\\r<-:b & y<-[0..] , c<-:r & x<-[0..] | f c]
 
-win :: (PegBoard -> Bool)
-win = (==) 1 o length o getCoords ((==)Peg)
-
-printPegBoard :: PegBoard -> String
-printPegBoard b = 'Text'.join "\n" $ ["\n":[r\\r <-: b]] ++ ["\n"]
-
-moves :: Solver [Move]
-moves = gets $ \b->[{c=c,d=d}\\c<-getCoords ((==)Emp) b, d<-[N,E,S,W]]
+printPegBoard :: !PegBoard -> String
+printPegBoard b = join "\n" (["\n":[r\\r <-: b]] ++ ["\n"])
 
-solve :: PegBoard -> Maybe [PegBoard]
-solve b = snd <$> evalRWST (tell [b] >>| solver) () b
+solve :: !PegBoard -> Maybe [PegBoard]
+solve b
+       | 1 == length (getCoords ((==)Peg) b) = pure [b]
+       = (\xs->[b:xs]) <$> foldr (<|>) empty [move b m >>= solve\\m<-moves]
 where
-       solver = get >>= \board->if (win board)
-               (get >>= tell o pure)
-               (moves >>= foldr (<|>) empty o map (\m->move m >>| solver))
+       moves = [{c=c,d=d}\\c<-getCoords ((==)Emp) b, d<-[N,E,S,W]]
 
-Start = [map printPegBoard <$> solve b\\b<-[english,german,french,bell, diamond]]
+//Start = [map printPegBoard <$> solve b\\b<-[english,german,french,bell, diamond]]
+Start = map printPegBoard <$> solve english