Structure Lab

This lab explores the  definition of record-based structures as well as the self-referential structure most commonly known as a list

Structure Problems

Before we tackle lists, we'll get used to simply building and and manipulating structured data. Remember to follow the Design Recipe for structures.

  1. Provide a datatype definition for a structure called a pit, representing points in time since midnight. A point in time consists of three numbers: hours, minutes, and seconds.

    Now develop the function time-diff. It consumes two pits, t1 and t2, and returns the number of seconds from t1 to t2. 

    For example:
    (time-diff (make-pit 1 2 3) (make-pit 4 5 6)) 

    should yield 10983. If you would like, I have written up a complete solution, which may give you a sense for what I think a full solution looks like.

  2. Provide a structure definition and a data definition for a game-score. A game-score is characterized by two pieces of information: a symbol representing the name of the team and a number representing the points-scored by that team.

  3. Develop a function that consumes two game-scores from a particular game and returns the name of the team that won or 'tie if the scores were equal. 

  4. Develop a datatype definition for a position in two-dimensional space called a posn. A posn should have an x and a y coordinate. 

  5. Provide a datatype definition for shapes. There are three kinds of shapes:
    1. A circle has a center (center isa posn?) and a radius (radius isa number?)
    2. A square has an upper-left corner (corner isa posn?) and a length (length isa number?)
    3. A rectangle has an upper-left corner (corner isa posn?), width (width isa number?), and height (height isa number?

    In each case, remember to provide a clear comment regarding the structure along with its definition.

  6. Develop the function area that consumes a shape and computes its area.

  7. Develop the function in-shape? that consumes a shape and a posn, and returns true if that posn is within the shape, false otherwise.

List Problems

Remember, lists are structures too. Follow the Design Recipe for lists, and your code will be much easier to read (as it follows a common, well-defined style), and it will be easier to write (because it follows the structure naturally found in the data).

You will find that Chapter 9 in HtDP is an excellent resource. I would encourage you to work as many problems from that section as you feel necessary to become comfortable with lists in Scheme.

We will be working with list-like data all through the course. We will have one more week of practice on lists, but there will be a twist. See if you can't tackle these problems and write high-quality code from the start. 

Remember our mantra: your code should follow the structure of the data.

  1. Develop a function that computes the length of a list.

  2. Develop the function between?, which consumes three numbers and produces true if the last is between the first two, otherwise it returns false.

    Use between? to develop the function three-between?, which consumes two numbers and a list of three numbers and determines if all three numbers in the list are between the first two.

  3. Develop a function contains-true? that consumes a list of booleans and determines whether one of them is true. Consider whether empty contains a true element. 

  4. Develop a function in-the-balance that consumes a list of numbers and computes the difference between the number of positive numbers in the list and the number of negative numbers in the list. 

    E.g. The list '(1 4 -3 7 -2) would yield 1, because there are three positive numbers and two negative numbers. (NOTE: Don't worry about the sign of the result.)

  5. Develop a function sum-nums that consumes a list of numbers and computes the sum of all of those numbers.

  6. Develop a function sum-num-acc that consumes a list of numbers and an accumulator. The accumulator is a variable that accumulates the value of the ongoing computation. How is this different from your solution to the previous problem? Which do you think requires more RAM? Why?

  7. Develop a function avg-nums that consumes a list of numbers and computes the average of those numbers.

  8. Develop a function that consumes a list of posn structures, and computes the average of all of the positions. It should return the average position of the points given.

    E.g. (average-posn (list (make-posn 1 1) (make-posn -1 -1))) 
    should return 
    (make-posn 0 0)

    HINT: Your solution might make good use of the syntax "local", as well as previous functions you've written.

  9. Develop a function that consumes a string and returns the number of vowels present in that string. Your solution might involve the use of the built-in function string->list.

    HINT: Consider the use of member to find out if a given character is a vowel. Either way, definitely create a helper function called vowel? that consumes a character and returns a boolean.

  10. Develop a function that consumes a list of strings and returns an onion. For example, the list '("red" "yellow") should become a (make-onion "red" (make-onion "yellow" (make-onion-core))).
     
  11. Develop a function that consumes a list of animals and returns the total weight of all the animals in the list. If you are lacking inspiration, implement structures for an elephant, a wombat, and the emu. The structure definition for animal becomes:

    ;; An animal is either
    ;;  - An elephant
    ;;  - A wombat
    ;;  - An emu
    

    As part of your solution, first develop animals->weights that consumes a list of animals, and returns a list of weights.

  12. Develop a function that consumes a list of numbers, and returns the largest number in the list.

    HINT: I often write functions like this as a pair of functions: one that accepts one argument (a list), and a helper function that accepts two arguments: the list and an element that we will compare to (and possibly change) throughout the process.  That helper is, again, an accumulator, but this time it will hold the largest value in the list. Note that negative infinity is -inf.0. (That's a zero.)

  13. Develop a function that consumes a list of numbers and returns a list of the squares of each of those numbers.

  14. Develop a function that consumes a list of strings, and returns a list of the lengths of those strings. (Lookup string-length.)

  15. Develop a function that consumes a list of lists of numbers. It should return a list of numbers where each number is the largest number in the list.

    For example, an input to your function might be '((1 2 3) (2 4 3) (9 3 6)). The return value would be '(3 4 9). Your solution should make good use of the predicate list? and your solution to the previous problem. (In short, there is no reason this should be substantially more difficult than any other problem.)

  16. Develop a function that consumes a list of arbitrary data, and returns the number of symbols in the list. For example, given the list '(3 false "hello" 'dolly 42), the returned value should be 1. 

  17. Develop a function that consumes a list of lists, and returns the sum of the lengths of the lists. For example, the input '((42) (hello goodbye) (867 5309)) should return 5. (The first list has length 1, the second list has length two, and the third list has length two.) You might reuse code you have already written as part of your solution. In fact, your solution might be very simple, given the functions you have written previously. 

Regarding Looping

Edsger W. Dijkstra

1930 - 2002

Edsger Dijkestra is a founder of our discipline. By "a founder," I mean he wrote some of the first languages, compilers, and algorithms we know and use daily.

One of his most cited pieces is the manuscript A Case against the GO-TO Statement. It was published by the ACM in 1968 under the title Go-to Statement Considered Harmful. Many of the citations simply reference the title, and not the content of the paper. If you wish to read more of his writings, you will find the Dijkestra Archive at UT Austin invaluable.




Consider Dijkestra's (original) manuscript in light of program and language design. Is his message still relevant to us in 2009? In what way? Why?

Feedback

I had 2 goals in assigning this first laboratory.

  1. Provide you with the opportunity to practice defining and manipulating structured data.
  2. Support you (through practice) in understanding of the structural definition of a list by writing (many) list-based functions that follow the HtDP Design Recipe.

If you would please rate this laboratory based on these goals, and provide whatever feedback you feel is necessary to improve this lab in the future, that would be excellent.