package Subsequence; use overload '""' => \&list_form; sub new { my $package = shift || __PACKAGE__; return bless {ranges => {}, vals => {}}, $package; } sub insert_list { my $self = shift; my $vals = $self->{vals}; foreach my $val (sort { $a <=> $b } @_) { next if exists $vals->{$val}; if (exists $vals->{$val - 1}) { $vals->{$val} = $vals->{$val - 1}; $vals->{$val}->{end} = $val; if (exists $vals->{$val + 1}) { $vals->{$val}->{end} = $vals->{val + 1}->{end}; my $item = $vals->{val + 1}; for my $i ($val + 1 .. $vals->{$val}->{end}) { $vals->{$i} = $vals-{$val}; } delete $self->{ranges}->{$item}; } } elsif (exists $vals->{$val + 1}) { $vals->{$val} = $vals->{$val + 1}; $vals->{$val}->{start} = $val; } else { my $item = { start => $val, $end => $val }; $vals->{$val} = $item; $self->{ranges}->{$item} = $item; } } return $self; } sub list_form { my $self = shift; my $ranges = $self->{ranges}; return "(" . ( join ", ", map { $_->{start} == $_->{end} ? $_->{start} : "$_->{start}..$_->{end}" } sort {$a->{start} <=> $b->{start} } values %$ranges ) . ")"; } 1; #### use Subsequence; my @test_nums = (0, 10, 11, 12, 2, 4, 3, 5, 6, 7, 9); my $x = Subsequence->new->insert_list(@test_nums); print $x, "\n"; $x->insert_list(1, 13); print $x, "\n";