Declaratieve Talen/Oplossing haskell nqueens: verschil tussen versies
Naar navigatie springen
Naar zoeken springen
Geen bewerkingssamenvatting |
|||
(8 tussenliggende versies door 4 gebruikers niet weergegeven) | |||
Regel 1: | Regel 1: | ||
====Mogelijke oplossing==== | ====Mogelijke oplossing==== | ||
<pre> | |||
nqueens::Int->[Int] | nqueens::Int->[Int] | ||
------------------- | ------------------- | ||
nqueens n = let | nqueens n = let | ||
list = [1..n] | |||
permlist = perms list | |||
in | |||
getoklist permlist | |||
Regel 14: | Regel 15: | ||
getoklist [] = error "geen oplossing" | getoklist [] = error "geen oplossing" | ||
getoklist (x:xs) | listok x = x | getoklist (x:xs) | listok x = x | ||
| otherwise = getoklist xs | |||
Regel 21: | Regel 22: | ||
listok [] = True | listok [] = True | ||
listok (a:as) = if (listok2 a as 1) == False then False | listok (a:as) = if (listok2 a as 1) == False then False | ||
else listok as | |||
listok2::Int->[Int]->Int->Bool | listok2::Int->[Int]->Int->Bool | ||
Regel 27: | Regel 28: | ||
listok2 _ [] _ = True | listok2 _ [] _ = True | ||
listok2 a (b:bs) kol | a == (b+kol) = False | listok2 a (b:bs) kol | a == (b+kol) = False | ||
| a == (b-kol) = False | |||
| otherwise = listok2 a bs (kol+1) | |||
Regel 39: | Regel 40: | ||
tussen e [] = [[e]] | tussen e [] = [[e]] | ||
tussen e (y:ys) = (e:y:ys) : map (y:) (tussen e ys) | tussen e (y:ys) = (e:y:ys) : map (y:) (tussen e ys) | ||
</pre> | |||
====Een alternatief==== | |||
<pre> | |||
nqueens::Int->[Int] | |||
nqueens n = | |||
let | |||
permutaties = permuteer [1..n] | |||
oplossingen = [p | p<-permutaties, (mog_oplossing p) == True] | |||
in head oplossingen | |||
permuteer::[Int]->[[Int]] | |||
permuteer [] = [[]] | |||
permuteer rij = [x:xs | x<-rij, xs<-permuteer (filter (/=x) rij)] | |||
mog_oplossing::[Int]->Bool | |||
mog_oplossing rij = | |||
let | |||
indexen = get_indexen rij 1 | |||
in voldoet indexen [] | |||
-- nog af te gaan, reeds afgegaan | |||
voldoet::[Int]->[Int]->Bool | |||
voldoet [] _ = True | |||
voldoet (x:xs) rij = | |||
if (elem x rij) then False | |||
else if ((check_diagonaal (x-2) rij) == False) then False | |||
else voldoet xs ([x]++rij) | |||
get_indexen::[Int]->Int->[Int] | |||
get_indexen [] _ = [] | |||
get_indexen (x:xs) w = | |||
let | |||
n_x = x + w | |||
in [n_x] ++ (get_indexen xs (w+1)) | |||
check_diagonaal::Int->[Int]->Bool | |||
check_diagonaal _ [] = True | |||
check_diagonaal n (x:xs) = | |||
if n == x then False | |||
else check_diagonaal (n-2) xs | |||
</pre> | |||
====nog een alternatief==== | |||
(alle oplossingen) | |||
<pre> | |||
nqueens::Int->[[Int]] | |||
nqueens n = [opl | opl<-(permuteer [1..n]), (safe opl) == True] | |||
permuteer::[Int]->[[Int]] | |||
permuteer [] = [[]] | |||
permuteer rij = [x:xs | x<-rij, xs<-permuteer (filter (/=x) rij)] | |||
safe [] = True | |||
safe (x:xs) = (no_attack x xs 1) && (safe xs) | |||
no_attack _ [] _ = True | |||
no_attack x (l:ls) n = not (x == n + l) && not (l==x+n) && not (x==l) && no_attack x ls (n+1) | |||
</pre> | |||
====Ik heb nog iets korters gevonden==== | |||
<pre> | |||
--Eerste argument is het aantal queens, het tweede de grootte van het bord | |||
queens 0 _ = [[]] | |||
queens n b = [x:y | y <- queens (n-1) b, x <- [1..b], safe x y 1] | |||
where safe x [] n = True | |||
safe x (c:y) n = and [x/=c,x/=c+n,x/=c-n,safe x y (n+1)] | |||
</pre> |
Huidige versie van 31 aug 2008 20:31
Mogelijke oplossing
nqueens::Int->[Int] ------------------- nqueens n = let list = [1..n] permlist = perms list in getoklist permlist getoklist::[[Int]]->[Int] ------------------------ getoklist [] = error "geen oplossing" getoklist (x:xs) | listok x = x | otherwise = getoklist xs listok::[Int]->Bool ------------------- listok [] = True listok (a:as) = if (listok2 a as 1) == False then False else listok as listok2::Int->[Int]->Int->Bool ------------------------------ listok2 _ [] _ = True listok2 a (b:bs) kol | a == (b+kol) = False | a == (b-kol) = False | otherwise = listok2 a bs (kol+1) --Permuteer de lijst perms :: [k] -> [[k]] --------------------- perms [] = [[]] perms (x:xs) = concat (map (tussen x) (perms xs)) where tussen e [] = [[e]] tussen e (y:ys) = (e:y:ys) : map (y:) (tussen e ys)
Een alternatief
nqueens::Int->[Int] nqueens n = let permutaties = permuteer [1..n] oplossingen = [p | p<-permutaties, (mog_oplossing p) == True] in head oplossingen permuteer::[Int]->[[Int]] permuteer [] = [[]] permuteer rij = [x:xs | x<-rij, xs<-permuteer (filter (/=x) rij)] mog_oplossing::[Int]->Bool mog_oplossing rij = let indexen = get_indexen rij 1 in voldoet indexen [] -- nog af te gaan, reeds afgegaan voldoet::[Int]->[Int]->Bool voldoet [] _ = True voldoet (x:xs) rij = if (elem x rij) then False else if ((check_diagonaal (x-2) rij) == False) then False else voldoet xs ([x]++rij) get_indexen::[Int]->Int->[Int] get_indexen [] _ = [] get_indexen (x:xs) w = let n_x = x + w in [n_x] ++ (get_indexen xs (w+1)) check_diagonaal::Int->[Int]->Bool check_diagonaal _ [] = True check_diagonaal n (x:xs) = if n == x then False else check_diagonaal (n-2) xs
nog een alternatief
(alle oplossingen)
nqueens::Int->[[Int]] nqueens n = [opl | opl<-(permuteer [1..n]), (safe opl) == True] permuteer::[Int]->[[Int]] permuteer [] = [[]] permuteer rij = [x:xs | x<-rij, xs<-permuteer (filter (/=x) rij)] safe [] = True safe (x:xs) = (no_attack x xs 1) && (safe xs) no_attack _ [] _ = True no_attack x (l:ls) n = not (x == n + l) && not (l==x+n) && not (x==l) && no_attack x ls (n+1)
Ik heb nog iets korters gevonden
--Eerste argument is het aantal queens, het tweede de grootte van het bord queens 0 _ = [[]] queens n b = [x:y | y <- queens (n-1) b, x <- [1..b], safe x y 1] where safe x [] n = True safe x (c:y) n = and [x/=c,x/=c+n,x/=c-n,safe x y (n+1)]