Problema N Rainhas - Haskell

2
Trabalho usando a linguagem de programação Haskell Aluno: Alessandro Pereira Rezende 1- Definição do problema N Rainhas: O problema consiste em determinar as possíveis posições em que podem ser colocadas n rainhas em um tabuleiro de xadrez (n x n), de maneira que nenhuma rainha seja atacada pelas demais (uma rainha ataca outra se as duas estiverem na mesma linha, ou na mesma coluna, ou na mesma diagonal). Considere que uma posição no tabuleiro de xadrez é representada por um par de valores inteiros que indicam a linha e a coluna no tabuleiro. 2- Estratégia para a resolução do problema: A solução do problema de colocar n rainhas pode ser obtida, a partir da solução para o problema de colocar (n-1) rainhas, acrescentando a essa solução as posições em que podem ser colocadas a última rainha, de maneira que ela não ataque nenhuma das outras já colocadas no tabuleiro. A i-ésima rainha deve ser colocada na i-ésima linha do tabuleiro, para i = 1..n. Uma solução para o problema pode ser então representada por uma lista contendo as posições das n rainhas. As possíveis soluções para o problema consistem, portanto, de uma lista de listas de n posições: type Pos = (Int,Int) rainhas :: Int -> [[Pos]] Para obter um script que determina a solução do problema, temos que criar 3 funções: 1. Defina a função atacar :: Pos -> Pos -> Bool que determina se as rainhas colocadas nas posições passadas como argumentos atacam uma à outra. 2. Defina a função posAtaque :: [Pos] -> Pos -> Bool que retorna True se a rainha colocada na posição passada como argumento não ataca nenhuma das demais rainhas colocadas anteriormente, nas posições contidas na lista passada como argumento; e retorna False em caso contrário. 3. Defina a função rainhas :: Int -> [[Pos]] que, dado o número de rainhas a serem colocadas no tabuleiro, retorna a lista das possíveis soluções para o problema. 3- O código da implementação em Haskell das funções propostas: type Pos = (Int,Int) -- verifica se uma posicao ataca outra no tabuleiro: atacar :: Pos -> Pos -> Bool atacar (row1,col1) (row2,col2) = (col1==col2) || (row1+col1 == row2+col2) || (row1-col1 == row2-col2) -- verifica se a posicao pos ataca alguma das posicoes da lista: posAtaque:: [Pos] -> Pos -> Bool posAtaque [] pos = True posAtaque (p:xp) pos = not(atacar p pos) && posAtaque xp pos -- demonstra as possibilidades de posicionamento das rainhas: rainhas :: Int -> [[Pos]] rainhas n = rainha n where rainha 0 = [] rainha 1 = [[(1,c)] | c <- [1..n]] rainha x = [ (x,c) : gx | c <- [1..n], gx <- rainha (x-1), posAtaque gx (x,c) ]

description

Problema N Rainhas - Haskell

Transcript of Problema N Rainhas - Haskell

  • Trabalho usando a linguagem de programao Haskell Aluno: Alessandro Pereira Rezende 1- Definio do problema N Rainhas:

    O problema consiste em determinar as possveis posies em que podem ser colocadas n

    rainhas em um tabuleiro de xadrez (n x n), de maneira que nenhuma rainha seja atacada pelas demais

    (uma rainha ataca outra se as duas estiverem na mesma linha, ou na mesma coluna, ou na mesma

    diagonal). Considere que uma posio no tabuleiro de xadrez representada por um par de valores

    inteiros que indicam a linha e a coluna no tabuleiro.

    2- Estratgia para a resoluo do problema:

    A soluo do problema de colocar n rainhas pode ser obtida, a partir da soluo para o

    problema de colocar (n-1) rainhas, acrescentando a essa soluo as posies em que podem ser

    colocadas a ltima rainha, de maneira que ela no ataque nenhuma das outras j colocadas no

    tabuleiro. A i-sima rainha deve ser colocada na i-sima linha do tabuleiro, para i = 1..n. Uma soluo

    para o problema pode ser ento representada por uma lista contendo as posies das n rainhas. As

    possveis solues para o problema consistem, portanto, de uma lista de listas de n posies:

    type Pos = (Int,Int)

    rainhas :: Int -> [[Pos]]

    Para obter um script que determina a soluo do problema, temos que criar 3 funes:

    1. Defina a funo atacar :: Pos -> Pos -> Bool que determina se as rainhas colocadas nas posies passadas como argumentos atacam uma outra.

    2. Defina a funo posAtaque :: [Pos] -> Pos -> Bool que retorna True se a rainha colocada na posio passada como argumento no ataca nenhuma das demais rainhas colocadas anteriormente, nas

    posies contidas na lista passada como argumento; e retorna False em caso contrrio.

    3. Defina a funo rainhas :: Int -> [[Pos]] que, dado o nmero de rainhas a serem colocadas no tabuleiro, retorna a lista das possveis solues para o problema.

    3- O cdigo da implementao em Haskell das funes propostas:

    type Pos = (Int,Int) -- verifica se uma posicao ataca outra no tabuleiro: atacar :: Pos -> Pos -> Bool atacar (row1,col1) (row2,col2) = (col1==col2) || (row1+col1 == row2+col2) || (row1-col1 == row2-col2) -- verifica se a posicao pos ataca alguma das posicoes da lista: posAtaque:: [Pos] -> Pos -> Bool posAtaque [] pos = True posAtaque (p:xp) pos = not(atacar p pos) && posAtaque xp pos -- demonstra as possibilidades de posicionamento das rainhas: rainhas :: Int -> [[Pos]] rainhas n = rainha n where rainha 0 = [] rainha 1 = [[(1,c)] | c

  • Exemplo de utilizao das funes no WinHugs:

    Main> atacar (1,2) (3,2)

    True

    Satisfaz c1 = c2

    Q

    Q

    Main> posAtaque [(1,2)] (3,2) False

    not(atacar p pos) && posAtaque xp pos

    not(atacar (1,2)(3,2)) && not(atacar (1,2)(3,2))

    not(True) && not(True)

    False && False

    False

    Logo, a posio passada ataca a outra.

    Main> rainhas 4

    [[(4,2),(3,4),(2,1),(1,3)],[(4,3),(3,1),(2,4),(1,2)]]

    1 POSSIBILIDADE 2 POSSIBILIDADE

    Q

    Q

    Q

    Q

    Q

    Q

    Q

    Q

    Q

    Q

    POSIO PASSADA