PROGRAM ASSIGNMENT #4

CS171 - Dr. Harris
DUE: 1:00 p.m., Monday, March 12, 2001
VALUE: 80 pts.

Program #4 illustrates how to write a rather lengthy program, but a program which is relatively easy to write in stages or sections. We are aiming towards writing program code using modular construction (much like designing a manufactured home where various sub-sections such as roof, flooring, wall joists, wiring, etc. are constructed separately and then joined together to make a finished, complete structure.)

Program #4 produces an output report about characteristics of integers found in an input file. The structure of the input file is as follows:

{Input data file for Program #4 - positive integers each not greater than 500}
12
600
-12
0
23
52
121
360
Assume that the name of the input file is NUMS_PG4.DAT and that the integers in the file are each on their own line. There is a single comment line at the top of the file indicating the purpose of the file. The program produces a report similar to the following output, sent to the output file PROG004.OUT. Put these file names in the Const section of your program, e.g.,
     Const
       Input_file_name = 'NUMS_PG4.DAT';
       Output_file_name = 'PROG004.OUT';
Deviate from the report format shown here as little as possible.

SAMPLE OUTPUT PRODUCED BY PROGRAM #4:

Programmed by <your name here>, Section <your section here>
Program #4
Due: March 12, 2001
Value = 80 pts.

====================
Test value is: 12
====================

The 12th Fibonacci number is: 144

The nontrivial factorizations of 12 are:
2*6 3*4 
12 has 2 nontrivial factorizations.

12! = 479001600

The multiples of 12 less than 500 are: 
  24  36  48  60  72  84  96 108 120 132 144 156 168 180 192
 204 216 228 240 252 264 276 288 300 312 324 336 348 360 372
 384 396 408 420 432 444 456 468 480 492

The perfect squares less than or equal to 12 are: 
   1,   4,   9 


====================
Test value is: 600
====================

Test value is greater than 500 - test aborted.


====================
Test value is: -12
====================

Test value is less than 1 - test aborted


====================
Test value is: 0
====================

Test value is less than 1 - test aborted.


====================
Test value is: 23
====================

The 23rd Fibonacci number is: 28657

The nontrivial factorizations of 23 are:
23 has no nontrivial factorizations.  It is prime.

23! = 25852016738884978200000

The multiples of 23 less than 500 are: 
  46  69  92 115 138 161 184 207 230 253 276 299 322 345 368
 391 414 437 460 483

The perfect squares less than or equal to 23 are: 
   1,   4,   9,  16 


====================
Test value is: 52
====================

The 52nd Fibonacci number is too large to compute
using type LONGINT (over 2 billion)

The nontrivial factorizations of 52 are:
2*26 4*13 
52 has 2 nontrivial factorizations.

52! is too large to compute accurately (over 8 x 10^36)

The multiples of 52 less than 500 are: 
 104 156 208 260 312 364 416 468

The perfect squares less than or equal to 52 are: 
   1,   4,   9,  16,  25,  36,  49 


====================
Test value is: 121
====================

The 121st Fibonacci number is too large to compute
using type LONGINT (over 2 billion)

The nontrivial factorizations of 121 are:
11*11 
121 has 1 nontrivial factorization.

121! is too large to compute accurately (over 8 x 10^36)

The multiples of 121 less than 500 are: 
 242 363 484

The perfect squares less than or equal to 121 are: 
   1,   4,   9,  16,  25,  36,  49,  64,  81,  100, 
 121 


====================
Test value is: 360
====================

The 360th Fibonacci number is too large to compute
using type LONGINT (over 2 billion)

The nontrivial factorizations of 360 are:
2*180 3*120 4*90 5*72 6*60 8*45 9*40 10*36 12*30 15*24 18*20 
360 has 11 nontrivial factorizations.

360! is too large to compute accurately (over 8 x 10^36)

360 has no multiples less than 500

The perfect squares less than or equal to 360 are: 
   1,   4,   9,  16,  25,  36,  49,  64,  81, 100, 
 121, 144, 169, 196, 225, 256, 289, 324 


=================================================================
END OF REPORT.
The first line of the output file is an identifier of the programmer and the program number. The integer being analyzed is identified at the top of each section of the report in the output file. For each integer n in the input file, the program computes and prints (when possible) the following characteristics determined by the integer (in this order): The output file ends with the sign-off message "END OF REPORT."

Include the following features into your program code:

Certain calculations are subject to size restrictions because the results grow very rapidly. Use the limitations described here for now; we will revise these limitations later after a more careful analysis. Variables used to compute the Fibonacci numbers should be declared to be of type LONGINT, since these grow very fast for even "modest" values of n (recall that LONGINT variables can store integers essentially in the range +/-2,147,483,648). Even so, Fibonacci numbers cannot be computed by this program for n > 46. Declare variables calculating factorials to be Double (real). Even so, such factorials cannot be computed by this program for n > 32 with any degree of accuracy. Messages to this effect should appear in the reports for these integers.

Your program MUST use the following loop structures:

Use whatever structures you feel appropriate for the remaining tasks. Be sure to include these particular features:

  1. Catch the cases where the number, n, from the file is too big to compute either the nth Fibonacci number or n!; print appropriate messages to that effect in the report file.
  2. When there are no non-trivial factorizations of n, print an appropriate message. Remember that 1 is not considered prime and has no nontrivial factorizations. However, the prime integers 2, 3, 5, etc. are the only integers bigger than 1 with no nontrivial factorizations.
  3. Don't repeat factorizations (i.e, don't give both 3 * 4 and 4 * 3 as factorizations of 12).
  4. Be sure to respond in the singular when n has exactly one non-trivial factorization (like n=35).
  5. Catch the case where there are no multiples of n less than 500 (500 is not less than 500) and print an appropriate message. Be sure to print 15 multiples per line, neatly aligned under each other when appropriate.
  6. Be sure NOT to print a comma after the last perfect square in the list of perfect squares, but make sure to include a space after every comma. Also, be sure to print ten multiples per line, neatly aligned under each other when appropriate.
  7. Be sure to use the requested loop control structures listed above!
  8. Separate the various sections of each report with two blank lines (do not run all information together).
  9. Put all appropriate cut-off values in the Const section of the program; e.g.,
         Const
           Max_factorial = 32; { Last computable factorial }
         etc.
    Avoid all hard-coded constants in your program code!
  10. One of the "sticky" points in this program is printing the proper ordinal ending in each section of the report. A CASE statement may best be used for this task, as indicated in the algorithms below.

===========================================
TURN IN !!!
===========================================

A listing of your program together with a printout of your output file PROG004.OUT. Also include a diskette containing your program file (named PRG4_S01.PAS) and both input and output data files. You will run your program against a data file I provide on or before 3/7/2001. Run the usual drill: sign all output listings, remove tear strips, and do not physically remove printer header pages from your listings.

ALGORITHMS APPROPRIATE FOR THIS PROJECT:


FIBONACCI ROUTINE

{ The number to be tested is n }
{ Fib_cutoff defined in constant section }
If n > Fib_cutoff Then 
  print an appropriate message
Else
  If n = 1 or 2 Then 
    New_Fib <-- 1
  Else
    Temp_Fib_1 <-- 1
    Temp_Fib_2 <-- 1
    Count <-- 2
    Repeat
      New_Fib <-- Temp_Fib_1 + Temp_Fib_2
      Increment Count
      Temp_Fib_1 <-- Temp_Fib_2
      Temp_Fib_2 <-- New_Fib
    Until (Count >= n)
  End Else
  Print value of New_Fib
End Else


ORDINAL ENDING ROUTINE

Const
  Low_teen = 11;
  High_teen = 19;
  Decimal_base = 10;
  Endings_base = 100;
  First_ending = 'st';
  Second_ending = 'nd';
  Third_ending = 'rd';
  General_ending = 'th';

{ n is the number whose ordinal ending we seek; for example, if
  n = 23, we would want to print 23rd }

Begin
  Last_digits <-- n MOD Endings_base { extract last digits from numbers > 100 }
  If (Last_digits <= High_teen) and (Last_digits >= Low_teen) Then 
    Ordinal_ending := ???
  Else
    Case Last_digits MOD Decimal_base Of
      1: Ordinal_ending := ???;
      2: Ordinal_ending := ???;
      3: Ordinal_ending := ???;
      Else Ordinal_ending := ???
    End; {Case}
  End Else
  Write(n, Ordinal_ending);


FACTORIZATION ROUTINE

{ The number to be tested is n }
If n = 1 Then
  Report n " has no nontrivial factorizations."
If n = 2 Then
  Report n " has no nontrivial factorizations; it is prime."
If n > 2 Then
  Last <-- Integer part of the square root of  n
  Number_of_factorizations <-- 0
  For Count <-- 2 to Last Do
    If n MOD Count = 0 Then
      Print Count, n DIV Count
      Increment Number_of_factorizations
    End If 
  End For
  If Number_of_factorizations = 0 Then 
    print n is prime
  Else 
    print n has Number_of_factorizations nontrivial factorizations
End If n > 2
  

FACTORIAL ROUTINE

{ The number to be tested is n }
{ Factorial_cutoff defined in constant section }
Factorial <-- 1.0
If n > Factorial_cutoff Then
  print n is too large to compute n! (n! would be over 8x10^36)
Else
  For Count <-- 2 to n 
    Factorial <-- Factorial * Count
  print value of n!
End Else


MULTIPLE ROUTINE

{ The number to be tested is n }
{ Multiple_cutoff declared in constant section }
{ Number_per_line declared in constant section }
Count <-- 2
Number_printed <-- 0
Multiple <-- Count * n
If Multiple >= Multiple_Cutoff Then
  Print n has no multiples less than Multiple_cutoff
Else
  While Multiple < Multiple_Cutoff Do
    Print value of Multiple
    Increment Count
    Increment Number_printed
    If Number_printed MOD Number_per_line = 0 Then
      advance to next line of output file
    Find new value of Multiple
  End While


PERFECT SQUARES ROUTINE

{ The number to be tested is n }
Square <-- 1
Count <-- 1
Repeat
  Write a comma and space to the output file if appropriate
  Advance to a new line when ten multiples have been written on the current line
  Print value of Square
  Increment Count
  Find new value of Square
Until Square > n

Advice for Developing Program #4
I will very likely make the following comments in class, but I wanted you to have them in a more permanent form:
  1. Develop the input data file. Put only 2 numbers in it to start (like 4 and 5).

  2. Get the major outline of the program designed and coded. This will include just the bare bones of opening the input and output files, reading the value of n from the input file, writing the header to the output file, and closing all files properly when the input file is completely read. Do not proceed until this step is completed! So, you should see only the following when running your program at this stage:
         Programmed by ....
         etc.
    
         ====================
         Test value is  4
         ====================
    
         ====================
         Test value is  5
         ====================
         
         =========================
         END OF REPORT

  3. Add in the appropriate tests to "filter out" the invalid numbers (like -12 or 600).

  4. When you are confident that your program in Step 3 is thoroughly tested, add one module (e.g., the factors routine). Test your module with the current values in the input data file. Clean up your code until the output for these values is correct. Then add more numbers to the input file. Thoroughly test your program before proceeding!

  5. Add another module to your code (e.g., the Fibonacci routine). Proceed as in Step 4. Thoroughly test your program with sufficient input data before proceeding.

  6. Repeat Step 5 until done.

Return to
CS-171
Home Page
    Return to
UW-W
Home Page
   
This page last updated
22 February 2001