#!/usr/bin/perl -w
##################
# oct9.pl
#
# In class example of a perl program with good form:
# header comments, implementation comments, tests,
# and POD - plain old documentation, data structures, ..
#
# Oh yeah, the program actually looks for "perfect" numbers like these:
#
# 6 has factors 1,2,3 and is 1+2+3.
# 28 has factors 1,2,4,7,14 and is 1+2+4+7+14
#
# See the POD at the end of the file for more details.
#
# To do:
# - tests for find_factors;
# - finish implementing find_factors odd cases like 1 and 0 correctly.
# - tests for is_perfect
# - implement is_perfect
# - define sub for appending data to $perfect
# - flesh out the main loop
# - decide what to print out
#
##################################################
use strict;
# == file "global" variables ==============================
# For each perfect number found,
# I'm going to remember the number and the list of factors here, eg
# $perfect[$n] = { number => $n, factors => [ $f1, $f2, $f3, ... ] };
my $perfects = ();
# == main =================================================
run_tests();
exit;
# (only pseudo code in "main" right now...)
# Loop over possible perfect numbers.
# If number $n is perfect,
# append $n and its @factors to $perfect data structure.
# Print out some kind of summary report.
# Let the user ask about a given integer,
# and give some information about it.
# == subs =================================================
#-----------------------------
# ... add comments here ...
sub is_perfect {
}
# ------------------------------------------------------
# Return a list of factors of a given integer $n,
# not including 1 or $n.
# Usage: @list = find_factors($n);
sub find_factors {
my ($n) = @_;
my $factor = 2; # first possible factor to test.
my $last = int(sqrt($n)); # don't need to look higher than this.
my @answer = ();
while (1){
return @answer if ($factor > $last);
push @answer, $factor if is_factor($factor, $n);
}
}
# --------------------------------------------------------
# Return true if $factor is a factor of number, else false.
# Usage: if (is_factor($factor,$number)){ ... }
sub is_factor {
my ($factor, $number) = @_;
return 0 if $factor == 0;
if ( $number % $factor == 0 ){
return 1;
}
else {
return 0;
}
}
# ---------------------------------
# Tests... Tests for sale... Get your tests here...
# (It's particularly good to put weird cases here.)
sub run_tests {
ok( is_factor(2,10));
ok( ! is_factor(2,7));
ok( is_factor(12.0, 144) , "is_factor(12.0,144) is true" );
ok( ! is_factor(0,1) , "is_factor(0,1) is false (no 0 divide)" );
ok( is_factor(1,0) , "is_factor(1,0) is true");
ok( ! is_factor(4,2) , "is_factor(4,2) is false : 4's bigger");
ok( find_factors(0) == () , "0 has no factors");
ok( find_factors(0) == () , "0 has no factors");
}
# -----------------------------------------------------------
# Print "ok" or "not ok" for each test,
# where each test is an expression which should evaluat to true.
# Second argument is an optional comment describing the test.
# Usage: ok( 1 == is_prime(7), "is_prime(7) is true" );
our $test_number; # initialized to 1 on first test.
sub ok {
my ($boolean, $comment) = @_;
# -- debugging --
# print " boolean = '$boolean' \n";
# print " comment = '$boolean' \n";
$test_number = 0 unless defined $test_number;
$test_number++;
if ($boolean) {
print "ok ";
}
else {
print "not ok ";
}
print $test_number;
if ($comment){
print " "x10, $comment;
}
print "\n";
}
__END__
=head1 NAME
oct9.pl
=head1 SYNOPSIS
From the command line,
$ ./oct9.pl
=head1 DESCRIPTION
This is where you should describe what your program
does when it runs - in other words, what a user
needs to know. What inputs does it take? What output
does it produce? And so on.
First let's talk about POD - plain old documentation.
See perdoc.com on perlpod for more details.
To create the .html file with the documentation, you
type "pod2html filename.pl > filename.html" at the
command line.
Here's a bullet list.
=over
=item One
So here's item one.
=item Two
And here's item two.
=back
=head2 Text formatting.
You can also put I or B stuff in.
And this is a "head2" section.
indenting stuff
keeps the white space
as you . . . type it.
=head1 HISTORY
* version 0.1 before class on Oct 9.
=head1 SEE ALSO
The class notes are accessible through
the http://cs.marlboro.edu/ website.
=head1 AUTHOR
Jim Mahoney, Emahoney@marlboro.eduE
=head1 COPYRIGHT AND LICENSE
Copyright 2003 by Jim Mahoney
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
=cut