Homework 2 - COMP 364

Homework 2 - COMP 364

Assigned in class on Jan 28, 2008

Due by class time Feb 6, 2008

Late turn in by class time Feb 8, 2008 (10% penalty)

Turn in on by email only to perkins@mcb.mcgill.ca

For the programming questions below, please include the code of your programs, at least one and up to a few sample runs, and any other comments you would like to make.

1. Madlib (10 points)

Write a program that takes as input two names, which we'll denote by [Name1] and [Name2], two nouns, which we'll denote by [Noun1] and [Noun2], and a gerund (an "-ing" word), which we'll denote by [Gerund]. The program should output the following poem, with the words filled in as appropriate.
[Name1] and [Name2] went up the hill,
to fetch a pail of [Noun1],
[Name1] fell down and broke his [Noun2],
and [Name2] came [Gerund] after.
An example run of your program might look like:

[perkins][lab2-2][~/HW2] Perl Madlib.pl
Enter Name1: Sam
Enter Name2: Bill
Enter Noun1: fleas
Enter Noun2: knees
Enter a gerund: whimpering

Here's a lovely poem:
Sam and Bill went up the hill,
to fetch a pail of fleas,
Sam fell down and broke his knees,
and Bill came whimpering after.
[perkins][lab2-2][~/HW2]

2. Alphabetic ordering (10 points)

Write a program that takes two strings as input. You may assume that these strings contain upper case and lower case letters, but no numbers, symbols or other strange characters. Your program should tell which of the strings comes first alphabetically, or, if the strings are the same alphabetically, your program should report that. For example, sample runs of your program might look like:

[perkins][lab2-2][~/HW2] perl Alpha.pl
Enter string one: apple
Enter string two: Banana
"apple" comes before "Banana" alphabetically. 
[perkins][lab2-2][~/HW2] perl Alpha.pl
Enter string one: apple
Enter string two: ApPlE
"apple" and "ApPlE" are the same alphabetically.
[perkins][lab2-2][~/HW2] perl Alpha.pl
Enter string one: Grapefruit
Enter string two: grape
"grape" comes before "Grapefruit" alphabetically.
[perkins][lab2-2][~/HW2]

3. Divisors (10 points)

(A) Write a program that prompts the user for a positive integer, and outputs all the positive integers that divide it evenly. For example, sample runs of your program might look like:

[perkins][lab2-2][~/HW2] perl Divisors.pl
Enter a positive integer: 12
12 is divisible by: 1 2 3 4 6 
[perkins][lab2-2][~/HW2] perl Divisors.pl
Enter a positive integer: 7
7 is divisible by: 1
[perkins][lab2-2][~/HW2] perl Divisors.pl
Enter a positive integer: 64
64 is divisible by: 1 2 4 8 16 32
(B) Modify your program from part (A) so that it keeps running until the user enters the string "quit". If the user enters a positive number, print out the numbers by which it is divisible. If the user enters anything else (a negative number, for example, or any other string), just prompt the user for input again. For example, a sample run of your program might look like:
[perkins][lab2-2][~/HW2] perl Divisors2.pl
Enter a positive integer or "quit": 12
12 is divisible by: 1 2 3 4 6
Enter a positive integer or "quit": applesauce
Enter a positive integer or "quit": 0
Enter a positive integer or "quit": 9
9 is divisible by: 1 3
Enter a positive integer or "quit": quit
[perkins][lab2-2][~/HW2]

4. Print your own character table / the "for" loop (10 points)

(A) In class, I handed out a table of the ASCII characters, which showed the characters associated with each number between 0 and 127. For part (A), write a program that prints out a characters associated with each number, by making use of the chr() function. Use a while loop to count through the numbers from 0 to 127. Don't worry about formatting your output in any special way -- you could put each character on its own line, or just run them together on one line. A sample run of your program might look like this:
[perkins][lab2-2][~/HW2] perl Chars.pl
0  1  2  3  4  5  6  7  8 9      10 
 11 
     12 
 14  15  16  17  18  19  20  21  22  23  24  25  26  27 8  29  30  31  32   33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127  
[perkins][lab2-2][~/HW2] 
(B) For part (B), you will write a program that creates the same output, but using a different control flow construct that we have not discussed before -- the for loop. Let us discuss the for loop. The general appearance of a for loop as as follows:
for ( [Command1] ; [Cond] ; [Command2] ) {
  [Commands3]
}
When a Perl program is running and reaches a for loop, the first thing Perl does is execute the command [Commands1]. Usually, this is used to initialize the value of a variable for the loop. Next, Perl tests the condition [Cond]. If it is true, then Perl runs the commands [Commands3] and then the command [Command2], which is often used to update a loop variable. Then it tests the condition [Cond] again, and if it is true, runs the commands [Commands3] and [Command2] again, and so on. If ever the condition [Cond] is false, the for loop is said to end, and Perl continues running any commands after the "}" of the for loop. For example, a simple program that counts from 1 to 10, printing the numbers on a single line, is below:
for ( $Count=1; $Count<=10; $Count++) {
  print "$Count ";
}
print "\n";
This program sets $Count to 1. Then it tests if $Count<=10. It is, so it prints $Count, and then adds one to $Count, making it 2. Then it tests again if $Count<=10. It is, so the program prints $Count and adds one to it, making it 3. This continues until $Count is 10. The condition $Count<=10 is true, so the program prints $Count and then adds one to it, making it 11. Now, the condition $Count<=10 is false, so the loop ends. The output of the program looks like this:
[perkins][lab2-2][~/HW2] perl CountTo10.pl
1 2 3 4 5 6 7 8 9 10 
[perkins][lab2-2][~/HW2] 
A for loop is often used to count through a range of numbers, though it can be used for other things as well. You can updateAnything that can be done with a for loop can also be done with a while loop. The general description of the for loop above is equivalent to the following code employing a while loop:
[Commands1]
while ( [Cond] ) {
  [Commands3]
  [Commands2]
}
However, the for loop is sometimes preferred, because it allows one to write the initialization, condition, and updating of a loop variable all on one line. Sometimes this makes it easier to read a program and understand what it is doing. In any case, to complete part (B) of this question, write a program that outputs a character table just as in part (A), but using a for loop to count from 0 to 127.

Optional exploration (No points): If you're interested, you don't need to stop your program at 127. Try printing out characters with higher numbers, and see what you get.

5. How computers represent numbers (10 points)

Strings in Perl can be arbitrarily long, but numbers cannot be arbitrarily large. This is because (unless you are using special software) computers generally use a hard-ware based representation for numbers. This hardware representation allows for very fast computations on numbers, but it only accommodates a limited number of significant digits. (Just like on a calculator, you usually only have about 10 digits.) More precisely, the computer allocates a limited number of bits (0 or 1) to represent each number, and so the size and/or precision of the numbers it can represent are limited.

Modern computers support two different representations for numbers -- as an integer (like 0, 1, -10, 220, etc.) or as a floating-point or scientific format number (like 0*100, -1.2*104, 3.1415*10-7, 6.022*1023, etc.). In Perl, an integer will always print as you would expect. For example, the integer 124 prints out like:

124
Floating point numbers can print out in a couple of ways. One is in standard deci mal notation. For example, 11.25 prints out as:
11.25
Whereas a very large number, like 6.022*1023, prints out like:
6.022e+23
The "e+23" part is how the computer expresses the "times ten to the 23rd power". You can also enter numbers this way in Perl. For example, to enter this number in Perl, you could simply write:
$Num = 6.022e+23;
To enter a number like 3.1*10-4 you could write:
$Num = 3.1e-4;
In the floating point numbers, the part before the "e" is called the "mantissa" and the part after the "e" is called the exponent. The floating-point representation can hold much larger numbers than the integer representation by taking advantage of the exponent.

Your task in this question is to find, as accurately as possible and without simply looking up the answer, the largest integer and the largest floating-point numbers that your computer can represent. One way to do this is to simply enter or to compute successively larger integers and print them out. When an integer gets too large for the computer to handle, it will automatically switch over to the floating-point representation and will print out as such. This will help you identify the largest possible integer. Similarly, to find the largest floating-point number, you can enter or compute successively larger numbers until one prints out as "inf". This "inf" is short for infinity, and indicates that the computer simply couldn't handle a number that big. In you answer to this question, tell the largest integer and floating point numbers you found, and the method you used to find them. You may include the code you used as part of your explanation.

6. Feedback (No points)

Estimate how long this homework took for you to complete. Was it easy/medium/hard? Was it boring/interesting/fun?