Re: [QUIZ] Perl 'Easy' Quiz of the Week #2006-04-02 - Rounded Fractions

"Sven Hergenhahn" <[email protected]> Wed, 5 Apr 2006 09:05:43 +0200
Newsgroups gmane.comp.lang.perl.qotw.discuss
Message-ID <[email protected]>
Hi All,

Here's my suggestion.

Cheers,
Sven

#!/usr/bin/perl -w
#
# Name:         quiz_fractions.pl
#
# Description:   Your task: create a script that prompts for a ratio of =
two integers and a quantity=20
#                given as a whole number and/or a fraction (e.g. "1 =
3/5", "12", "3/7") and print out=20
#                a rounded result of multiplying the quantity by the =
ratio in the same format.
#
#                The result should be rounded to the nearest half, =
third, or fourth, whichever is most=20
#                accurate (in cases exactly between two quantities, =
using the lowest denominator).  You=20
#                may assume none of the integers are overly large.
#
# Author:       Sven Hergenhahn
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

use strict;

# set a lookup hash for the remainder
my %fractions =3D (0 =3D> '0', 1/4 =3D> '1/4', 1/3 =3D> '1/3', 1/2 =3D> =
'1/2', 2/3 =3D> '2/3', 3/4 =3D> '3/4', 1 =3D> '1');

# Get input (not checked here!)
print 'Please enter a fraction: ';
my $frac_in =3D <STDIN>; chomp $frac_in;
$frac_in =3D~ s/\s/+/;
print 'By what do you want to multiply? ';
my $mult_in =3D <STDIN>; chomp $mult_in;
$mult_in =3D~ s/\s/+/;

# calculate floats for both values
my $res  =3D eval $frac_in;
my $mult =3D eval $mult_in;

# calculate int part and remainder
my $int_res =3D int($res * $mult);
my $mod_res =3D $res * $mult - $int_res;

my $result   =3D 0;
my $old_frac =3D 0;

# go through the hash=20
# check reaminder against mean of two possible fractions
# set a result
foreach my $frac (sort {$a <=3D> $b} keys %fractions) {
  my $mean =3D ($frac + $old_frac)/2;
  if ($mod_res <=3D $mean) {
    if ($frac =3D=3D 0) {
      $result =3D $int_res;
      last;
    }
    else {
      $result =3D $int_res =3D=3D 0 ? $fractions{$old_frac} :  $int_res =
. ' ' . $fractions{$old_frac};
      last;
    }
  }
  elsif ($frac =3D=3D 1 && $mod_res > $mean) {
      $result =3D $int_res +1;
      last;
  }
  $old_frac =3D $frac;
}

print 'Result: ' . "$result \n";