print "$_->[-1][VAL]\n" for @pile; #### #!/usr/bin/perl use strict; use warnings; use List::Util 'shuffle'; use constant VAL => 0; use constant PREV => 1; my @list = shuffle(1..20); print "@list\n"; print join " ", Long_Inc_Sub(@list); sub Long_Inc_Sub { my @list = @_; my (@pile, @seq); # Partial patience sort (w/o bin search) to get LIS NUM: for my $num (@list) { for (0 .. $#pile) { if ($num < $pile[$_][-1][VAL]) { my $prev = $_ ? $#{$pile[$_ - 1]} : undef; push @{$pile[$_]}, [$num, $prev]; next NUM; } } my $prev = @pile ? $#{$pile[-1]} : undef; push @pile, [[$num, $prev]]; } # Obtain LIS for return my ($prev, $len) = ($#{$pile[-1]}, scalar @pile); while ($len--) { $seq[$len] = $pile[$len][$prev][VAL]; $prev = $pile[$len][$prev][PREV]; } # Finish patience sorting via a mergesort my @order; while (@pile) { my ($low, $idx) = (undef, undef); for (0 .. $#pile) { my $val = $pile[$_][-1][VAL]; ($low, $idx) = ($val, $_) if ! defined $low || $val < $low; } push @order, $low; pop @{$pile[$idx]}; splice(@pile, $idx, 1) if ! @{$pile[$idx]}; } # print "$_\n" for @order; return @seq; }