File Coverage

blib/lib/Math/TotalBuilder.pm
Criterion Covered Total %
statement 37 37 100.0
branch 12 12 100.0
condition 2 2 100.0
subroutine 7 7 100.0
pod 3 3 100.0
total 61 61 100.0


line stmt bran cond sub pod time code
1 2     2   1713 use strict;
  2         3  
  2         80  
2 2     2   9 use warnings;
  2         5  
  2         119  
3             package Math::TotalBuilder;
4             {
5             $Math::TotalBuilder::VERSION = '1.102';
6             }
7             # ABSTRACT: build a whole total out of valued pieces
8              
9             # aka, solve the bin packing problem lol
10              
11              
12 2     2   10 use Carp ();
  2         2  
  2         41  
13              
14 2     2   11 use Exporter 5.57 'import';
  2         67  
  2         855  
15             our @EXPORT = qw(build total); ## no critic Export
16              
17              
18             sub build {
19 12   100 12 1 4775 $_[2] ||= \&build_basic;
20 12 100       42 if (ref $_[2] eq 'ARRAY') {
    100          
21 1         2 %{(
22 5         17 sort { $a->{_remainder} <=> $b->{_remainder} }
  4         21  
23 1         1 map { { $_->($_[0], $_[1]) } } @{$_[2]}
  1         3  
24             )[0]};
25             } elsif (ref $_[2] eq 'CODE') {
26 10         27 return $_[2]->($_[0], $_[1]);
27             } else {
28 1         148 Carp::croak "bad third parameter to build";
29             }
30             }
31              
32              
33             sub build_basic {
34 9     9 1 11 my ($pieces, $total) = @_;
35              
36 9 100       26 return unless $total;
37              
38 7         10 my %result;
39              
40 7         32 for (sort { $pieces->{$b} <=> $pieces->{$a} } keys %$pieces) {
  142         175  
41 61 100       109 next unless $pieces->{$_} <= $total;
42 20         43 $result{$_} = int( $total / $pieces->{$_} );
43 20         36 $total -= $result{$_} * $pieces->{$_};
44             }
45              
46 7 100       19 $result{_remainder} = $total if $total;
47              
48 7         57 return %result;
49             }
50              
51              
52             sub total {
53 2     2 1 652 my ($pieces, $set) = @_; ## no critic Ambiguous
54 2         3 my $total;
55 2         62 for (keys %$set) {
56 10 100       190 Carp::croak "invalid unit type: $_" unless exists $pieces->{$_};
57 9         22 $total += $set->{$_} * $pieces->{$_};
58             }
59 1         8 $total;
60             }
61              
62              
63             "Here's your change.";
64              
65             __END__