Prohledávání a prořezávání

Problém n dam

Postupné rozšiřování šachovnice

Pomocná funkce

hrozba :: [Int] -> [Int]
hrozba p = p ++ zipWith (+) p [1..] ++ zipWith (-) p [1..]

Řešení

type Reseni = [Int]

damy :: Int -> [Reseni]
damy n = da n n

da :: Int -> Int -> [Reseni]
da 0 _ = [[]]
da m n = [ k:p | p <- da (m-1) n, k <- [1..n], nh k p] -- nh = neni hrozba
	 where nh k p = k `notElem` ( p
				      ++ zipWith (+) p [1..]
				      ++ zipWith (-) p [1..]

Backtracking, prořezávání

Pole

Typový konstruktor Array

array (1,4) [(1,'a'),(2,'b'),(3,'a'),(4,'b')] :: (Num i, Ix i) => Array i Char

Indexace

class (Ord) => Ix a where
    range :: (a,a) -> [a]
    index :: (a,a) -> a -> Int
    inRange :: (a,a) -> a -> Bool

Přístup k prvkům pole

(!) :: Ix i => Array i e -> i -> e

array (5,6) [(5,"ANO!"),(6,"NE1")] ! 5 ~>* "ANO!"

Aktualizace hodnot v poli

(//) :: Ix i => Array i e -> [(i,e)] -> Array i e
array (1,2) [(1,1),(2,2)] // [(1,3),(2,3)] ~>* array (1,2) [(1,3),(2,3)]

Operace s poli

-- Meze pole
bounds :: Ix i => Array i e -> (i,i)

-- Seznam indeců pole
indices :: Ix i => Array i e -> [i]

-- Převody mezi poli a seznamy
elems :: Ix i => Array i e -> [e]
listArray :: Ix i => (i,) -> [e] -> Array i e

-- Převody mezi poli a seznamy dvojic
assocs :: Ix i => Array i e -> [(i,e)]
array :: Ix i => (i,i) -> [(i,e)] -> Array i e

accumArray

accumArray :: Ix i => (e -> a -> e) -> e
		       -> (i, i) -> [(i, a)] -> Array i e
accumArray (+) 0 (1,2) [(1,1),(1,1),(1,1)]
	~>* (1,2) [(1,3),(2,0)]

Lineární řazení čísel z omezeného rozsahu

max = 1000

countlist :: [Int] -> Array Int Int
countlist s = accumArray (+) 0 (0,max) (zip s (repeat 1))

sortBoundedList s = concant [ replicate k x | (x,k) <- assocs (countlist s) ]