CSC 533: Organization of Programming Languages
Spring 2022

HW5: Scheme Programming I


For this assignment, you are to define a collection of Scheme functions. For simplicity, place all of your function definitions in a single file named LASTNAME-hw5.scm, where LASTNAME is your last name. Be careful to name your functions exactly as defined in the exercises, and be sure to comment each function as to its behavior.

Fun with Geometry

    Recall the following formulas from your high school geometry class:

  1. Define a function named area-rectangle that takes two inputs, the height and width of a rectangle, and returns the area of that triangle. For example, (area-rectangle 4 7) should evaluate to 28.
  2. Define a function named area-square that takes one input, the length of the side of a square, and returns the area of that square. Since a square IS_A rectangle, your area-square function should call area-rectangle as opposed to duplicating the multiplication. For example, (area-square 6) should evaluate to 36.
  3. Define a function named area-circle that takes one input, the radius of a circle, and returns the area of that circle. Note that the constant pi is predefined in Scheme, so you do not need to provide your own approximation. For example, (area-circle 10) should evaluate to 314.1592653589793.
  4. Define a function named area-triangle that takes two inputs, the base and height of a triangle, and returns the area of that triangle. For example, (area-triangle 4 10) should evaluate to 20.
  5. Define a function named distance that takes two inputs, lists representing points, and returns the distance between those points. For example, (distance '(0 0) '(3 4)) should evaluate to 5.
  6. Define a function named slope that takes one input, a pair of points representing a line, and returns the slope of that line. For example, (slope '((0 0) (2 4))) should evaluate to 2.
  7. Define a predicate function named parallel? that takes two inputs, each a pair of points representing a line, and returns whether those lines are parallel (i.e., have the same slope). For example, (parallel? '((0 0) (2 4)) '((1 1) (3 5))) should evaluate to #t.
  8. Define a predicate function named perpendicular? that takes two inputs, each a pair of points representing a line, and returns whether those lines are perpendicular (i.e., their slopes are negative inverses). For example, (perpendicular? '((0 0) (2 4)) '((1 1) (-1 2))) should evaluate to #t.

List Processing

    Consider the following recursive function, which counts how any times a particular number appears in a list of numbers.

        (define (count-occur num numlist)
          (cond ((null? numlist) 0)
                ((= num (car numlist)) (+ 1 (count-occur num (cdr numlist))))
                (else (count-occur num (cdr numlist)))))
    
  1. Define a similar function named count-between that takes three inputs, the low and high numbers of a range and a list of numbers, and returns a count of numbers from the list that fall within the specified range. For example, (count-between 5 10 '(1 4 7 12 5 10 9)) should evaluate to 4.
  2. Define a similar function named remove-between that returns a copy of the list with all numbers from the specified range removed. For example, (remove-between 5 10 '(1 4 7 12 5 10 9)) should evaluate to (1 4 12).

  3. Define a function named roman->num that takes one input, a list of characters representing a roman numeral, and returns the number value represented by that roman numeral. For example, (roman->num '(X V I)) should evaluate to 16. The following is a list of the roman letters and numbers they represent (M = 1000, D = 500, C = 100, L = 50, X = 10, V = 5, I = 1). You may assume the ancient roman style of writing letters, where 4 is represented IIII and 90 is represented LXXXX. A harder problem, which you may attempt if you like, is to use the modern roman style where 4 is IV and 90 is XC.
  4. Define a function named num->roman that performs the reverse conversion, from a number to a list of characters representing a roman numeral. For example, (roman->num 66) should evaluate to (L X V I). Again, you may assume the ancient roman style of writing letters.

Simulations

  1. Define a function named dice-roll that takes one input, the number of sides of a die, a returns the sum of two random die rolls. For example, the call (dice-roll 6) should simulate rolling two 6-sided dice and return an integer from the range 2 through 12 (following the appropriate probability distribution). Likewise, (dice-roll 8) should simulate rolling two 8-sided dice and return an integer from the range 2 through 16 (following the appropriate probability distribution). Hint: The built-in random function generates a pseudo-random integer from 0 up to its input (exclusive). For example, the call (random 4) would return either 0, 1, 2, or 3.
  2. Define a function named average-rolls that takes two inputs, the number of die sides and the number of rolls to simulate. The function should simulate rolling a pair of dice the specified number of times and return the average of all those rolls. For example, the call (average-rolls 6 1000) should simulate 1000 rolls of two 6-sided dice and return the average (as an inexact value). Since the number of rolls could be large, your function should utilize tail-recursion.
  3. Define a function named count-dice that has an additional input identifying a particular roll total. The function should simulate the specified number of rolls and return the number of times that total was obtained. For example, the call (count-dice 6 1000 7) should simulate 1000 dice rolls (of 6-sided dice) and return the number of times 7 was rolled. Since the number of rolls could be large, your function should utilize tail-recursion.