CSC 533: Organization of Programming Languages
Spring 2021

HW5: Scheme Functions


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

Numerical Functions

  1. Define functions for converting between inches and centimeters, and between pounds and kilograms (and vice versa for each). Recall that 1 inch = 2.54 centimeters and 1 pound = 0.45359237 kilograms. For example, (in->cm 10) should evaluate to 25.4, (cm->in 100) should evaluate to approximately 39.37, (kg->lb 10) should evaluate to approximately 22.05, and (lb->kg 100) should evaluate to approximately 45.36.

  2. Body Mass Index (BMI) is often used by doctors and dieticians in assessing the overall health of a patient. The formula is as follows:

        BMI = (weight in kilograms) / (height in meters)2
    

    Define a function named BMI-Metric that takes two inputs, a person's height (in centimeters) and weight (in kilograms), and returns their BMI. For example, (BMI-Metric 170.0 70.0) should evaluate to approximately 24.22.

    Similarly, define a function named BMI-US that takes two inputs, a person's height (in inches) and weight (in pounds), and returns their BMI. For example, (BMI-US 65.0 170.0) should evaluate to approximately 28.29. Note: you should be able to make use of the BMI-Metric function here.

  3. According to the Center for Disease Control, body mass index correlates to the following weight categories:

    BMI < 18.5underweight
    18.5 ≤ BMI < 25.0normal
    25.0 ≤ BMI < 30.0overweight
    30.0 ≤ BMI obese

    Define functions classify-Metric and classify-US that each take two inputs, the person's height (in cm or inches, respectively) and weight (in kg or lb, respectively). These functions should calculate the person's BMI and return the corresponding CDC classification. For example, (classify-Metric 170.0 70.0) should evaluate to normal, while (classify-US 65.0 170.0) should evaluate to overweight. Note: you should be able to make use of the BMI-Metric and/or BMI-US functions here.

List Functions

  1. Define a function named num-pos which takes a list of numbers as input and returns a count of how many of those numbers are positive (i.e., greater than 0). For example, (num-pos '(0 -3.2 6 88 -0.11 3.2)) would return 3.

  2. Define a function named num-between which takes a list of numbers and two numbers (defining a range) as input. The function returns a count of how many of those numbers are in the specified range. For example, (num-between '(0 -3.2 6 88 -0.11 3.2) 0 10) would return 3. Assume the boundaries of the range are inclusive, so 0 is considered to be in the range from 0 to 10. To simplify this task, you may assume that the range values are specified in non-decreasing order (i.e., the first number is the lower bound and the second is the upper bound).

  3. Define a function named remove-between which takes a list of numbers and two numbers (defining a range) as input. The function returns a copy of the list with any numbers from that range removed. For example, (remove-between '(0 -3.2 6 88 -0.11 3.2) 0 10) would return (-3.2 88 -0.11) . As with the previous function, you may assume the boundaries of the range are inclusive and the range values are specified in non-decreasing order.

  4. 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.

  5. 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 has no inputs and simulates the roll of two six-sided dice. That is, the call (dice-roll) should return an integer from the range 2 through 12, following the appropriate probability distribution (e.g., 7 is the most likely roll, 2 and 12 are the least likely). 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 count-rolls that takes two inputs, both positive integers, representing a number of rolls and the desired total. The function should simulate the specified number of rolls and return the number of times the desired total was obtained. For example, the call (count-rolls 1000 7) should simulate 1000 dice rolls and return the number of times 7 was rolled. Since the number of rolls could be large, your function should utilize tail-recursion.

  3. Define a function named incr that takes two inputs, a list of numbers and a non-negative integer representing an index. The function should return the list with the number at that index incremented. For example, the call (incr '(0 0 0) 1) should return (0 1 0). Since the size of the number lists will likely be fairly small, your solution may utilize full-recursion.

  4. Define a function named count-all-rolls that takes one input, a positive integer, representing a number of rolls. The function should simulate that many rolls and return a list with the counts for each dice total. For example, the call (count-all-rolls 10000) might return (288 526 824 1093 1388 1708 1413 1115 811 563 271), signifying that 288 rolls totaled 2, 526 rolls totaled 3, 824 rolls totaled 4, etc. Since the number of rolls could be large, your function should utilize tail-recursion. Note: you should be able to make use of the incr function here.