Csc 4330/6330, Programming Language Concepts (Spring 2022)

Homework 5 (Due: 7 April (Thursday))

  1. (Single Digit) Complete the definition of the following function:
    singleDigit :: Int -> Int
    
    singleDigit takes a positive integer, num, as input and returns a digit between 0 and 9 as the output. The output is computed as follows: sum all the digits in num to obtain a result; if this result is less than 10 then result is the answer; otherwise take the result and apply the same procedure (i.e. sum its digits and compute a result, and so on). Here is a sample run:
    *Main> singleDigit 37425
    3
    *Main> singleDigit 9876543
    6
    
    Here is how the above answers are computed by hand:
    singleDigit 37425 => 3+7+4+2+5 = 21 => 2+1 = 3
    singleDigit 9876543 => 9+8+7+6+5+4+3 = 42 => 4+2 = 6
    

  2. (Word Value) Complete the definition of the following function:
    wordValue :: String -> Int
    
    wordValue takes a word as input and generates a value (number) as output. The word's value is computed by adding the ordinal values of the individual letters in the word, with 'a' having an ordinal value of 1, 'b' having a value of 2, etc. Lower and upper case of the same letter have the same ordinal value. Here is a sample run:
    *Main> wordValue "Attitude"
    100
    *Main> wordValue "Sunderraman"
    128
    
    You may use the following import:
    import Data.Char
    
    to use some built-in functions to solve this problem.

  3. (Bulls and Cows) Complete the definitions of the following related functions:
    extractDigits :: Int -> [Int]
    noRepeatingDigits :: Int -> Bool
    numBulls :: Int -> Int -> Int
    numCows :: Int -> Int -> Int
    

    extractDigits takes as input a positive integer and returns a list of digits in the integer. Sample run is shown below:

    *Main> extractDigits 12345
    [1,2,3,4,5]
    *Main> extractDigits 210067
    [2,1,0,0,6,7]
    

    noRepeatingDigits takes as input a positive integer and returns True if the integer has no repeating digits and False otherwise. Sample run is shown below:

    *Main> noRepeatingDigits 12345
    True
    *Main> noRepeatingDigits 123436
    False
    

    numBulls takes as input two positive integers as input and returns -1 if either the two integers have different number of digits or either of them have repeating digits. However, if the two integers have the same number of digits and also do not have any repeating digits, the function returns the number of digits that match in the exact same positions in the integers. For example,

    *Main> numBulls 1234 1235
    3
    *Main> numBulls 1234 12356
    -1
    *Main> numBulls 12349 1235
    -1
    *Main> numBulls 12349 12355
    -1
    *Main> numBulls 12349 21349
    3
    *Main> numBulls 1234 1234
    4
    

    numCows takes as input two positive integers as input and returns -1 if either the two integers have different number of digits or either of them have repeating digits. However, if the two integers have the same number of digits and also do not have any repeating digits, the function returns the number of digits that match but NOT in the same positions in the integers. For example,

    *Main> numCows 1234 1234
    0
    *Main> numCows 1234 12345
    -1
    *Main> numCows 12345 1234
    -1
    *Main> numCows 12345 12344
    -1
    *Main> numCows 1234 3124
    3
    *Main> numCows 12478 78901
    3
    

  4. (Decimal to Binary) Complete the definitions of the following two functions:
    convertNum2Binary :: Int -> String
    convertFraction2Binary :: Float -> String
    

    convertNum2Binary takes as input a number greater or equal to 0 and returns the binary representation of the number as a String.

    convertFraction2Binary takes as input a fractional number between 0 and 1 and returns the binary representation of the number as a String. In case of repeating patterns, stop at length 23.

    Here is a sample run:

    *Main> convertNum2Binary 100
    "1100100"
    *Main> convertFraction2Binary 0.375
    ".011"
    *Main> convertFraction2Binary 0.8
    ".11001100110011001100110"
    

  5. (Matrices) In this problem, you will write functions to perform the following matrix operations: Transpose, Matrix Multiplication, and Determinant. For this assignment, we shall assume that the input matrices are of the proper dimensions so that the corresponding operation can be computed (i.e. we do not have to handle invalid matrices in the inputs).

    Matrices are represented as a list of list of integers in row major form. For example,

    [[1,2,3,4],[2,3,5,6],[7,1,2,4]]
    
    represents the matrix:
    1 2 3 4
    2 3 5 6 
    7 1 2 4
    
    We can use the following type definitions in Haskell:
    type Matrix = [[Int]]
    type Column = [Int]
    type Row = [Int]
    
    Here are the types for the three functions:
    transpose :: Matrix -> Matrix
    matrixMultiply :: Matrix -> Matrix -> Matrix
    determinant :: Matrix -> Int
    
    I found the following helper functions useful:
    extractColumn :: Matrix -> Int -> Column
    removeColumn :: Matrix -> Int -> Matrix
    scalarProduct :: Row -> Row -> Int
    rowMul :: Row -> Matrix -> Row
    mmul :: Matrix -> Matrix -> Matrix
    
    You may choose to implement the helper functions, but if you come up with other ways to solve transpose, matrixMultiply, and determinant, then you may not implement the helper functions.

    Sample run is shown below:

    *Main> m1 = [[1,2,3],[4,5,6]]
    *Main> transpose m1
    [[1,4],[2,5],[3,6]]
    *Main> transpose []
    []
    *Main> m2 = [[1,2],[3,4]]
    *Main> m3 = [[5,6],[7,8]]
    *Main> matrixMultiply m2 m3
    [[19,22],[43,50]]
    *Main> m4 = [[2,3,4],[5,6,7]]
    *Main> m5 = [[1,2,3,4],[2,3,5,6],[7,1,2,4]]
    *Main> matrixMultiply m4 m5
    [[36,17,29,42],[66,35,59,84]]
    *Main> m6 = [[4,6],[3,8]]
    *Main> m7 = [[99]]
    *Main> m8 = []
    *Main> m9 = [[6,1,1],[4,-2,5],[2,8,7]]
    *Main> determinant m6
    14
    *Main> determinant m7
    99
    *Main> determinant m8
    0
    *Main> determinant m9
    -306
    *Main> extractColumn m1 1
    [1,4]
    *Main> extractColumn m1 2
    [2,5]
    *Main> extractColumn m1 3
    [3,6]
    *Main> removeColumn m1 1
    [[2,3],[5,6]]
    *Main> removeColumn m1 2
    [[1,3],[4,6]]
    *Main> removeColumn m1 3
    [[1,2],[4,5]]
    *Main> scalarProduct [1,2] [5,6]
    17
    *Main> rowMul [2,3,4] m1
    [20,47]
    *Main> rowMul [3,3,3] [[6,1,1],[4,-2,5],[2,8,7]]
    [24,21,51]
    *Main> transpose m5
    [[1,2,7],[2,3,1],[3,5,2],[4,6,4]]
    *Main> mmul [[2,3,4],[5,6,7]] [[1,2,7],[2,3,1],[3,5,2],[4,6,4]]
    [[36,17,29,42],[66,35,59,84]]
    

What to Submit?

  • single.hs
  • word.hs
  • bulls.hs
  • convert.hs
  • matrix.hs