diff options
| author | Mohammad S Anwar <Mohammad.Anwar@yahoo.com> | 2020-07-02 18:57:00 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-07-02 18:57:00 +0100 |
| commit | ff28d260554a8b78ab0eb0b0ecbdf798c14d305a (patch) | |
| tree | 4e1b142d00a5c0bffb9de8114387997119d70bfc | |
| parent | 25d45b91610eeff9abb5807696f40012428d4151 (diff) | |
| parent | c6a0d772a861b1cbf7d1f6e64aec46b4ea6f9b99 (diff) | |
| download | perlweeklychallenge-club-ff28d260554a8b78ab0eb0b0ecbdf798c14d305a.tar.gz perlweeklychallenge-club-ff28d260554a8b78ab0eb0b0ecbdf798c14d305a.tar.bz2 perlweeklychallenge-club-ff28d260554a8b78ab0eb0b0ecbdf798c14d305a.zip | |
Merge pull request #1896 from jo-37/contrib
rework 058-2
| -rw-r--r-- | challenge-058/jo-37/perl/ch-2.pl | 35 |
1 files changed, 10 insertions, 25 deletions
diff --git a/challenge-058/jo-37/perl/ch-2.pl b/challenge-058/jo-37/perl/ch-2.pl index 13ca638146..9bb110a537 100644 --- a/challenge-058/jo-37/perl/ch-2.pl +++ b/challenge-058/jo-37/perl/ch-2.pl @@ -1,18 +1,16 @@ #!/usr/bin/perl use Test2::V0; +use List::MoreUtils qw(pairwise firstidx reduce_1); # exchange item at position $pos and next taller item. # return position of found next item. sub exchange { my ($items, $pos) = @_; - my $next; - for ($next = $pos; $next < @$items; $next++) { - last if $items->[$next]{height} > $items->[$pos]{height}; - } - my $tmp = $items->[$pos]; - $items->[$pos] = $items->[$next]; - $items->[$next] = $tmp; + my $pos_height = $items->[$pos]{height}; + my $next = $pos + firstidx {$_->{height} > $pos_height} + @$items[$pos..$#$items]; + @$items[$pos, $next] = @$items[$next, $pos]; return $next; } @@ -21,23 +19,13 @@ sub lineup { die "hights and talls have different sizes" if @$heights != @$talls; # collect hights and talls into single array. - my @items; - while (defined (my $height = shift @$heights)) { - my $taller = shift @$talls; - push @items, {height => $height, taller => $taller}; - } - - # sort array by height - @items = sort {$a->{height} <=> $b->{height}} @items; + my @items = sort {$a->{height} <=> $b->{height}} + pairwise { {height => $a, taller => $b} } @$heights, @$talls; # check solvability: the required number of taller predecessors must # not exceed the number of taller items. - for (my $i = 0; $i < @items; $i++) { - my $item = $items[$i]; - die "height: $item->{height}, " . - "requested: $item->{taller}, available: " . ($#items - $i) - if $item->{taller} > $#items - $i; - } + reduce_1 {$a && $b->{taller} <= $#items - $_} @items + or die "no solution"; # create an index to locate items in the array. my @index = (0 .. $#items); @@ -47,15 +35,12 @@ sub lineup { my $pos = $index[$i]; my $item = $items[$pos]; - # move item to the right for the desired number of taller # predecessors. foreach my $offs (1 .. $item->{taller}) { - my $taller = exchange \@items, $pos; - # store new position of moved item $index[$i + $offs] = $pos; - $pos = $taller; + $pos = exchange \@items, $pos; } } return [map $_->{height}, @items]; |
