CSc 352, Fall 2002: Programming Assignment 8: Shell Scripts

Out: Thu Oct 31

Due: 12:00 Noon Thu Nov 7


You are to create a number of files, as directed below, and then submit them electronically on host lectura.cs.arizona.edu using the command

turnin cs352_hw8 files

Please follow the directions below carefully: submissions that don't follow directions will be penalized heavily.


The Problems

  1. Write a shell-script named count_first_names that takes a single file-name as argument, and behaves as follows. The file specified contains a list of names, one per line, in the form

    first-name [ optional initials ] last-name

    Your shell-script is to print out the number of times each first name occurs in the file specified. The output format is to be as follows: for each first name in the file, print the count for that name at the beginning of the line (no leading whitespace), then a single space character, then the first name, with each first name printed exactly once. The order in which the different names are printed is immaterial.

    Example: Given an input file sht.names with the following contents:

    Greg Andrews
    Richard Schlichting
    Marcella J. A. Slatin
    Marcella J. A. Diaz
    Richard A. Hiltunen
    Richard T. Homer
    Rich Saunders

    the execution of the command "count_first_names sht.names" should produce the following output (on stdout):

    1 Greg
    2 Marcella
    3 Richard
    1 Rich

    Note in this case that one of the names in this file, Rich, is a prefix of another name, Richard. Make sure that your script does not get confused by such situations and is able to maintain the distinction between such names. Another (larger) input is given in the file /home/cs352/FALL02/hw8_stuff/NAMES, with the expected output (except possibly for the order of names) given in the file /home/cs352/FALL02/hw8_stuff/count.NAMES.

    Hint: Read the man pages for sort to see the effect of the -u option, and see what happens when you execute the command "sort -u /home/cs352/FALL02/hw8_stuff/fst_names". How might this help you?

  2. If we time different runs of an executable program on some particular input, we often see slight differences in the running time, arising due to a variety of reasons such as clock granularity, system interrupts, etc. For this reason, when measuring the speed of a program, people usually run the program several times and compute some sort of summary from the results of these runs.

    Your task in this assignment is to write a shell-script named get_range that takes as argument a single file name, where the file so named contains a set of timing data for multiple runs for each of several different programs. Each line of the input file contains timing data for one run of a program, in the following form:

    progName executionTime

    Your script should behave as follows: for each program that is mentioned in the input file, compute the smallest and largest execution time, and print out this information in the following form, one program per line, where each pair of adjacent fields is separated by a single space character:

    progName minExecTime maxExecTime

    where minExecTime and maxExecTime represent the smallest and largest execution times, respectively, for that program.

    Example: Given an input file data.in with the following contents:

    x.out 10.9
    y.out 9.3
    z.out 8.0
    x.out 11.2
    y.out 9.7
    z.out 7.8
    x.out 10.2
    y.out 9.8
    z.out 7.9
    x.out 10.5

    the execution of the command "get_range data.in" should produce the following output (on stdout):

    x.out 10.2 11.2
    y.out 9.3 9.8
    z.out 7.8 8.0

  3. Write a C program mycircle.c that behaves as follows.

    Invocation:

    The program is invoked with two positive integer arguments, N and M, respectively (M, N > 0). If the number of arguments provided is different from this, the program gives a descriptive error message and exits with status -1.
    Behavior:
    Suppose that the program is invoked as mycircle M N. Consider the integers 1 through N arranged clockwise in a circle, as shown:

    Starting from 1, we count clockwise around the circle M integers (where M is any positive integer) and eliminate the Mth. integer from the circle to form a new circle with N-1 integers. Then, starting from the integer after the one just eliminated, we count clockwise around the circle M integer and eliminate that integer to form a new circle with M-2 integers. This process is repeated until only one integer remains. Our goal is to determine the single remaining integer.

    Given any pair of positive integers M and N, your program is to carry out the computation as described above and print out (only!) the last integer so obtained.

    Example:

    Executing the program "mycircle 4 3" (i.e., N = 4, M = 3) results in the following sequence, where the integer to be eliminated is shown circled:

    The output printed in this case is therefore the value 1.

    Restrictions:

    There should not be any fixed hard limits on the input. Moreover, the amount of memory used by your program should be proportional to the size of the input. Please do not use realloc for dynamic memory allocation: I would like you to use malloc.