CS 536 Homework 3: Programming in Haskell

Due: September 27, hardcopy in class and electronic via turnin (asgmt name hwk3)


The Haskell Notes page provides pointers to haskell software downloads, tutorials, and a mapping from common Scheme functions to their Haskell equivalents.

Problem 1: Prime Numbers

  1. Write isPrime :: Integer -> Bool, which determines whether a given integer is prime.
  2. Define primes :: [Integer], the list of all primes.
  3. Revise isPrime so that it only tests divisibility by prime factors. Just turn in the revised version.

Problem 2: Longest Common Subsequence

  1. Write buildList :: Int -> (Int -> a) -> [a], where ((buildList n f) !! i) == (f i) (for all i in [0 .. n-1]).
  2. Write buildTable :: Int -> Int -> (Int -> Int -> a) -> [[a]], where (((buildTable n m f) !! i) !! j) == (f i j) (for all i in [0 .. n-1], j in [0 .. m-1]).
  3. Write lcs :: String -> String -> String, which computes the longest common subsequence of two strings s1 and s2.

    A good solution to this will exploit laziness. In particular, your submitted solution should not simply generate all possible subsequences from all pairs of indices then look for the longest (though if writing the code this way first helps you get a feel for the problem, feel free). Your code should only generate instances of the lcs problem that are necessary to compute the longest subsequence.

    As a hint, you could try computing lcs (take i s1) (take j s2) from

    lcs (take (i-1) s1) (take   j   s2),
    lcs (take   i   s1) (take (j-1) s2), and 
    lcs (take (i-1) s1) (take (j-1) s2).
    
  4. and the knowledge of whether (s1 !! (i-1)) == (s2 !! (j-1)).

Problem 3: Minimax Search

In this exercise, you will implement a strategy to play a simple game. The game is called Mancala, but you don't need to understand the rules because we have implemented that part for you. Your job is to build a tree of possible move sequences and choose the move that appears best.

Download the support code, which provides the following set of data types and functions:

  1. Define a datatype GameTree to represent the game state after any sequence of moves. Each node should have its current configuration and a list of trees, where each tree corresponds to containing the configurations obtainable following a specific single move.
  2. Define the tree of all legal board configurations (those obtainable by repeated application of nextStates to the initialState).
  3. Define prune :: Int -> GameTree -> GameTree, which prunes a tree to a given height.
  4. Define minimax :: Player -> GameTree -> Int, which consumes a (pruned) tree and evaluates the configuration by looking ahead and applying the following minimax algorithm. If a node has no children, it receives its own immediate score. If it corresponds to Player's turn, it receives the maximum of the recursively-computed child scores, otherwise it receives the minimum.

You do not need to understand the support code to do this assignment. The API given above is sufficient for solving these problems.

To use the support code, put the following two lines at the top of your file, where your file is called Filename.hs and Game.hs (the support code) is in the same directory as your file.

  module Filename where
  import Game 

Back to the Assignments page