Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import Data.List
- import Data.Function
- ----- predefined types and inputs
- type Matrix a = [[a]]
- type WList = [[Char]]
- type Coordinate = (Int, Int)
- type Site = [Coordinate] -- from start to end
- test = [0,0,1,0,1,1,1,0,1,1,0]
- test2 = ([[(6,3),(7,3),(8,3)],[(4,4),(5,4),(6,4)],[(1,5),(2,5),(3,5)],
- [(4,2),(4,3),(4,4)],[(5,0),(5,1),(5,2)],[(6,2),(6,3),(6,4)]]
- ,["MAC","SQL","WEB","GNU","NFS","XML"])
- test3 = [[[([(4,2),(4,3),(4,4),(4,5)],"ARES")]]
- ,[[([(0,2),(1,2),(2,2),(3,2),(4,2)],"ALPHA"),([(2,0),(2,1),(2,2),(2,3),(2,4)],"POPPY")]
- ,[([(0,2),(1,2),(2,2),(3,2),(4,2)],"POPPY"),([(2,0),(2,1),(2,2),(2,3),(2,4)],"ALPHA")]]]
- test4 = [([(4,2),(4,3),(4,4),(4,5)],"ARES")
- ,([(0,2),(1,2),(2,2),(3,2),(4,2)],"ALPHA")
- ,([(2,0),(2,1),(2,2),(2,3),(2,4)],"POPPY")]
- teststatz1 :: [(Site, [Char])]
- teststatz1 = [([(4,2),(4,3),(4,4),(4,5)],"ARES")]
- wlist1 = ["ALPHA","ARES","POPPY"]
- frame1 :: Matrix Int
- frame1 = [[0,0,1,0,0]
- ,[0,0,1,0,0]
- ,[1,1,1,1,1]
- ,[0,0,1,0,1]
- ,[0,0,1,0,1]
- ,[0,0,0,0,1]]
- wlist2 = ["PROLOG","LINUX","MAC","SQL","WEB","PERL","ONLINE","GNU","NFS","XML","EMACS"]
- frame2 :: Matrix Int
- frame2 = [[1,1,1,1,1,1,0,0,1]
- ,[1,0,1,0,0,1,0,0,1]
- ,[1,0,1,1,1,1,1,0,1]
- ,[1,0,1,0,1,0,1,1,1]
- ,[0,0,1,0,1,1,1,0,1]
- ,[0,1,1,1,0,0,0,0,0]]
- wlist3 = ["AAL","DER","TAL","TAT","ISEL","TELL","ZANK","ZEUS","ALSEN","BLASE","EOSIN","ETTAL","KARRE","LIANE","NEEFS","NONNE","OSTEN"
- ,"STUHL","TIARA","ANKARA","EGERIA","GRANAT","HIRTEN","MISERE","SAMPAN","TILSIT","WAGGON","FORTUNA","ITALIEN","MADONNA","MELASSE"
- ,"REAUMUR","RIVIERA","SEKUNDE","SERBIEN","SKELETT","SKRUPEL","STETTIN","STOIKER","HANNIBAL","REGISTER","RELIGION","STANNIOL"
- ,"TRUEFFEL","UNTERTAN","USAMBARA","VENDETTA","TUEBINGEN","TURKMENEN","ALLENSTEIN","ATTRAKTION","BRIEFTAUBE","TATTERSALL"
- ,"PROTEKTORAT","TEMPERAMENT","KRANKENKASSE","CHRONOGRAPHIE","TRAUBENZUCKER","WALZER"]
- frame3 :: Matrix Int
- frame3 = [[1,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1]
- ,[1,0,1,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1]
- ,[1,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,0,1]
- ,[1,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,1]
- ,[1,1,1,1,1,1,0,1,1,1,1,0,1,0,1,1,1,1,1,1,0,0,1,0,1]
- ,[1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,1,0,1]
- ,[1,0,1,0,1,1,1,1,1,1,0,0,1,1,1,1,1,0,1,1,1,1,1,1,1]
- ,[1,0,1,0,1,0,0,1,0,0,1,1,1,0,1,0,0,0,1,0,0,0,1,0,0]
- ,[1,1,1,1,1,1,1,1,0,0,1,0,0,0,1,0,0,0,1,0,1,1,1,1,1]
- ,[1,0,1,0,1,0,0,1,0,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0]
- ,[1,0,0,0,1,0,0,0,0,0,1,0,1,1,1,1,1,1,1,0,1,0,1,0,0]
- ,[0,1,1,1,1,1,1,0,0,0,1,0,0,0,1,0,1,0,0,1,1,1,1,1,0]
- ,[0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,1]
- ,[0,0,1,0,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1]
- ,[0,0,1,0,1,0,1,0,1,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,1]
- ,[0,1,1,1,1,0,1,0,1,0,0,1,0,1,1,1,1,1,1,1,0,0,1,0,1]
- ,[1,0,1,0,1,0,1,0,1,0,0,1,0,0,0,1,0,0,0,0,1,1,1,0,1]
- ,[1,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,1]
- ,[1,1,1,1,1,0,1,0,1,0,0,1,0,0,0,1,0,0,0,0,1,0,1,0,1]
- ,[1,0,0,0,0,0,1,0,0,0,0,1,0,1,1,1,0,1,0,0,1,0,1,0,1]
- ,[1,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,1,0,1]
- ,[1,0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,1,0,0,1,0,1,0,1]
- ,[1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1]
- ,[0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,1]
- ,[1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1]]
- wlist4 = ["BANI","HAUS","NETZ","LENA","ANKER","ARIEL","GASSE","INNEN","ORADE","SESAM","SIGEL","ANGOLA","AZETAT","EKARTE","NATTER"
- ,"NENNER","NESSEL","RITTER","SOMMER","TAUNUS","TRANIG","AGENTUR","ERRATEN","ERREGER","GELEISE","HAENDEL","KAROSSE","MANAGER"
- ,"OSTEREI","SIDERIT","TERRIER","ANATOMIE","ANPASSEN","BARKASSE","BEDANKEN","DEKADENT","EINLADEN","ERLASSEN","FRAGMENT"
- ,"GARANTIE","KRAWATTE","MEISTERN","REAKTION","TENTAKEL","TRIANGEL","UEBERALL","VERGEBEN","AFRIKANER","BESTELLEN","BULLAUGEN"
- ,"SANTANDER","VERBERGEN","ALLENSTEIN","AUSTRALIEN","BETEILIGEN","NATALITAET","OBERHAUSEN","UNTERSTAND","LEUMUND"]
- frame4 :: Matrix Int
- frame4 = [[1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1]
- ,[1,0,0,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,1,0,1,0,0,0,1]
- ,[1,0,1,0,1,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,1,0,0,0,1]
- ,[1,1,1,1,1,1,1,0,0,1,0,0,0,1,0,1,0,1,1,1,1,1,1,1,1]
- ,[1,0,1,0,1,0,1,0,0,1,0,1,0,1,0,1,0,0,1,0,1,0,1,0,1]
- ,[1,0,1,0,1,0,1,0,1,1,1,1,1,1,0,1,0,0,0,0,1,0,1,0,1]
- ,[1,0,1,0,1,0,1,0,0,0,0,1,0,1,1,1,1,1,1,1,1,0,1,0,0]
- ,[1,0,1,0,1,1,1,1,1,1,0,1,0,1,0,1,0,1,0,0,1,0,1,0,1]
- ,[1,0,1,0,0,1,0,0,1,0,0,1,0,0,0,1,0,1,0,0,0,0,1,0,1]
- ,[1,1,1,1,1,1,0,0,1,1,1,1,1,1,0,1,0,1,0,1,1,1,1,1,1]
- ,[0,0,0,0,0,1,0,0,1,0,0,1,0,1,0,1,0,1,0,1,0,0,1,0,1]
- ,[1,1,1,1,1,1,1,0,1,0,0,1,0,1,0,1,1,1,1,1,1,1,0,0,1]
- ,[1,0,0,0,0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,1]
- ,[1,0,1,0,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,0,0,1]
- ,[1,0,1,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1]
- ,[1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1]
- ,[1,0,1,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1]
- ,[1,0,1,0,1,1,1,1,1,1,1,1,1,0,0,0,1,0,1,0,1,0,0,0,0]
- ,[1,0,1,0,0,0,0,1,0,1,0,0,1,0,0,0,1,0,1,0,1,1,1,1,1]
- ,[0,0,1,0,0,0,0,1,0,0,1,1,1,1,1,1,1,0,1,0,1,0,0,0,1]
- ,[1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,0,1,0,0,0,0,1,0,0,1]
- ,[1,0,1,0,0,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,0,0,1]
- ,[1,0,0,1,1,1,1,1,1,1,1,1,0,1,0,0,1,0,0,0,0,1,0,0,1]
- ,[1,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,1,0,0,1]
- ,[1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1]]
- ----- imported from problem 28
- -- sortlength
- sortlength :: Ord a => [[a]] -> [[a]]
- sortlength [] = []
- sortlength (x:xs) = sortlength small ++ (x : sortlength large)
- where small = [ y | y <- xs, length y <= length x]
- large = [ y | y <- xs, length y > length x]
- -- sortfreq
- lenfreq :: [[a]] -> [a] -> Int
- lenfreq [] x = 0
- lenfreq (y:ys) x = (if length x == length y then 1 else 0) + lenfreq ys x
- sortfreq :: [[a]] -> [[a]]
- sortfreq [] = []
- sortfreq (x:xs) = sortfreq small ++ (x : sortfreq large)
- where small = [ y | y <- xs, lenfreq (x:xs) y < lenfreq (x:xs) x]
- large = [ y | y <- xs, lenfreq (x:xs) y >= lenfreq (x:xs) x]
- ----- crossword validation
- lenlist :: [[a]] -> [Int]
- lenlist wlist = map length wlist
- siteCnt :: [Int] -> [Int]
- siteCnt [] = []
- siteCnt row = filter ( > 1) $ map length (filter (\x -> (head x == 1)) (group row))
- allSeq :: Matrix Int -> [Int]
- allSeq frame = (concatMap siteCnt frame) ++ (concatMap siteCnt $transpose frame)
- validCross :: [[a]] -> Matrix Int -> Bool
- validCross wlist frame = (sort $lenlist wlist) == (sort $allSeq frame)
- ----- convert obtain block lists from frame into co-ordinate format
- sitescanRow :: [Int] -> [(Int, Int)]
- sitescanRow row = sitescanRow' 0 (group row)
- where sitescanRow' :: Int -> [[Int]] -> [(Int, Int)]
- sitescanRow' _ [] = []
- sitescanRow' x (r:rs) = if ((head r == 1) && (length r > 1)) then (x, length r) : (sitescanRow' (x + length r) rs)
- else sitescanRow' (x + length r) rs
- sitescanFrame :: Matrix Int -> Int -> [Site]
- sitescanFrame frame direction = concat (siteform 0 (map sitescanRow frame))
- where siteform _ [] = []
- siteform x (r:rs) = (map siteform' r) : (siteform (x+1) rs)
- where siteform' (a, b)
- | direction == 0 = [ (hori, x) | hori <- [a..a+b-1] ]
- | direction == 1 = [ (x, verti) |verti <- [a..a+b-1] ]
- sitescanFull :: Matrix Int -> [Site]
- sitescanFull frame = sortfreq $ (sitescanFrame frame 0) ++ (sitescanFrame (transpose frame) 1)
- ----- states properties
- noDup :: Eq a => [a] -> Bool
- noDup [] = True
- noDup (x:xs) = (x `notElem` xs) && (noDup xs)
- failSol :: [(Site, [Char])] -> Bool
- failSol statz = not (noDup [ fst x | x <- statz' ])
- where statz' = nub $ concatMap (\x -> zip (fst x) (snd x)) statz
- validSol :: [Coordinate] -> [(Site, [Char])] -> Bool
- validSol plist statz = (all (`elem` [ fst x | x <- statz' ]) plist) && (noDup [ fst x | x <- statz'])
- where statz' = nub $ concatMap (\x -> zip (fst x) (snd x)) statz
- waytoSol :: [Coordinate] -> [(Site, [Char])] -> Bool
- waytoSol plist statz = (any (`notElem` [ fst x | x <- statz' ]) plist) && (noDup [ fst x | x <- statz'])
- where statz' = nub $ concatMap (\x -> zip (fst x) (snd x)) statz
- ----- solution permutation
- pairbyLen :: Matrix Int -> WList -> [([Site], WList)]
- pairbyLen frame wlist = zip (gbLen $ sitescanFull frame) (gbLen $ sortfreq wlist)
- where gbLen = groupBy (\x y -> length x == length y)
- fullPermu :: [([Site], WList)] -> [[(Site, [Char])]]
- fullPermu swpbl = map concat $ cartProd (map permuinLen swpbl)
- where permuinLen swp = [ zip (fst swp) temp | temp <- permutations (snd swp) ]
- cartProd :: [[a]] -> [[a]]
- cartProd [] = [[]]
- cartProd (ls:lss) = [ x:xs | x <- ls, xs <- cartProd lss ]
- permuSolver :: Matrix Int -> WList -> [[(Site, [Char])]]
- permuSolver frame wlist = filter (validSol plist) $ fullPermu (pairbyLen frame wlist)
- where plist = nub (concat $ sitescanFull frame)
- ----- deterministic guess according to number of possible choices.
- conjuComp :: Site -> [Char] -> [(Site, [Char])] -> Bool
- conjuComp site word statz = and (map f (zip site word))
- where f x = (fst x `notElem` plist) || (x `elem` statz')
- statz' = nub $ concatMap (\x -> zip (fst x) (snd x)) statz
- plist = [ fst x | x <- statz' ]
- sortedBranch :: Matrix Int -> WList -> [(Site, [Char])] -> [(Site, [[Char]])]
- sortedBranch frame wlist statz = sortBy (compare `on` (length . snd)) [ (site, (possible site)) | site <- remainsites ]
- where remainsites = (sitescanFull frame) \\ [ fst x | x <- statz ]
- remainwords = wlist \\ [ snd x | x <- statz ]
- possible site = filter (\word -> (length word == length site) && (conjuComp site word statz)) remainwords
- detGuess :: Matrix Int -> WList -> [(Site, [Char])] -> [[(Site, [Char])]]
- detGuess frame wlist statz = [ statz ++ [s] | s <- pickup (sortedBranch frame wlist statz) ]
- where pickup [] = []
- pickup templist = extract (head templist)
- where extract x = [ (fst x, b) | b <- snd x ]
- cwSolver :: Matrix Int -> WList -> [(Site, [Char])] -> [[(Site, [Char])]]
- cwSolver frame wlist statz
- | failSol statz = []
- | validSol plist statz = [statz]
- | waytoSol plist statz = concatMap (cwSolver frame wlist) (detGuess frame wlist statz)
- where plist = nub (concat $ sitescanFull frame)
- cwSolve :: Matrix Int -> WList -> [[(Coordinate, Char)]]
- cwSolve frame wlist = map transform (cwSolver frame wlist [])
- where transform solution = nub $ concatMap (\x -> zip (fst x) (snd x)) solution
Advertisement
Add Comment
Please, Sign In to add comment