File Coverage

blib/lib/Math/SNAFU.pm
Criterion Covered Total %
statement 33 33 100.0
branch 6 6 100.0
condition 1 3 33.3
subroutine 7 7 100.0
pod 2 2 100.0
total 49 51 96.0


line stmt bran cond sub pod time code
1 3     3   678470 use 5.012;
  3         31  
2 3     3   16 use strict;
  3         6  
  3         57  
3 3     3   14 use warnings;
  3         5  
  3         190  
4              
5             package Math::SNAFU;
6              
7             our $AUTHORITY = 'cpan:TOBYINK';
8             our $VERSION = '0.001';
9              
10 3         219 use Carp qw(
11             croak
12 3     3   21 );
  3         6  
13              
14 3         15 use Exporter::Shiny 1.006000 qw(
15             decimal_to_snafu
16             snafu_to_decimal
17 3     3   1295 );
  3         15893  
18              
19             sub decimal_to_snafu ($) {
20 30     30 1 83462 my ( $n ) = @_;
21 30 100       97 return '0' if $n == 0;
22              
23 29         42 my @chars;
24 29         67 while ( $n > 0 ) {
25 111         154 my $mod = $n % 5;
26 111         155 $n = int( $n / 5 );
27 111 100       198 if ( $mod == 3 ) {
    100          
28 13         28 push @chars, '=';
29 13         36 ++$n;
30             }
31             elsif ( $mod == 4 ) {
32 16         30 push @chars, '-';
33 16         46 ++$n;
34             }
35             else {
36 82         167 push @chars, $mod;
37             }
38             }
39              
40 29         191 return join '', reverse @chars;
41             }
42              
43             sub snafu_to_decimal ($) {
44 30     30 1 19804 my ( $snafu ) = @_;
45              
46 30         57 state $digits = {
47             '=' => -2,
48             '-' => -1,
49             '0' => +0,
50             '1' => +1,
51             '2' => +2,
52             };
53              
54 30         117 my @input = reverse split //, $snafu;
55 30         54 my ( $sum, $slot ) = ( 0, 0 );
56             $sum += ( 5 ** $slot++ ) * ( $digits->{$_} // croak "Bad SNAFU digit: $_" )
57 30   33     202 for @input;
58              
59 30         154 return $sum;
60             }
61              
62             1;
63              
64             __END__