Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
126
Task/Stream-merge/Perl/stream-merge.pl
Normal file
126
Task/Stream-merge/Perl/stream-merge.pl
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
use strict;
|
||||
use warnings;
|
||||
use English;
|
||||
use String::Tokenizer;
|
||||
use Heap::Simple;
|
||||
|
||||
my $stream1 = <<"END_STREAM_1";
|
||||
Integer vel neque ligula. Etiam a ipsum a leo eleifend viverra sit amet ac
|
||||
arcu. Suspendisse odio libero, ullamcorper eu sem vitae, gravida dignissim
|
||||
ipsum. Aenean tincidunt commodo feugiat. Nunc viverra dolor a tincidunt porta.
|
||||
Ut malesuada quis mauris eget vestibulum. Fusce sit amet libero id augue mattis
|
||||
auctor et sit amet ligula.
|
||||
END_STREAM_1
|
||||
|
||||
my $stream2 = <<"END_STREAM_2";
|
||||
In luctus odio nulla, ut finibus elit aliquet in. In auctor vitae purus quis
|
||||
tristique. Mauris sed erat pulvinar, venenatis lectus auctor, malesuada neque.
|
||||
Integer a hendrerit tortor. Suspendisse aliquet pellentesque lorem, nec tincidunt
|
||||
arcu aliquet non. Phasellus eu diam massa. Integer vitae volutpat augue. Nulla
|
||||
condimentum consectetur ante, ut consequat lectus suscipit eget.
|
||||
END_STREAM_2
|
||||
|
||||
my $stream3 = <<"END_STREAM_3";
|
||||
In hendrerit eleifend mi nec ultricies. Vestibulum euismod, tellus sit amet
|
||||
eleifend ultrices, velit nisi dignissim lectus, non vestibulum sem nisi sed mi.
|
||||
Nulla scelerisque ut purus sed ultricies. Donec pulvinar eleifend malesuada. In
|
||||
viverra faucibus enim a luctus. Vivamus tellus erat, congue quis quam in, lobortis
|
||||
varius mi. Nulla ante orci, porttitor id dui ac, iaculis consequat ligula.
|
||||
END_STREAM_3
|
||||
|
||||
my $stream4 = <<"END_STREAM_4";
|
||||
Suspendisse elementum nunc ex, ac pulvinar mauris finibus sed. Ut non ex sed tortor
|
||||
ultricies feugiat non at eros. Donec et scelerisque est. In vestibulum fringilla
|
||||
metus eget varius. Aenean fringilla pellentesque massa, non ullamcorper mi commodo
|
||||
non. Sed aliquam molestie congue. Nunc lobortis turpis at nunc lacinia, id laoreet
|
||||
ipsum bibendum.
|
||||
END_STREAM_4
|
||||
|
||||
my $stream5 = <<"END_STREAM_5";
|
||||
Donec sit amet urna nulla. Duis nec consectetur lacus, et viverra ex. Aliquam
|
||||
lobortis tristique hendrerit. Suspendisse viverra vehicula lorem id gravida.
|
||||
Pellentesque at ligula lorem. Cras gravida accumsan lacus sit amet tincidunt.
|
||||
Curabitur quam nisi, viverra vel nulla vel, rhoncus facilisis massa. Aliquam
|
||||
erat volutpat.
|
||||
END_STREAM_5
|
||||
|
||||
my $stream6 = <<"END_STREAM_6";
|
||||
Curabitur nec enim eu nisi maximus suscipit rutrum non sem. Donec lobortis nulla
|
||||
et rutrum bibendum. Duis varius, tellus in commodo gravida, lorem neque finibus
|
||||
quam, sagittis elementum leo mauris sit amet justo. Sed vestibulum velit eget
|
||||
sapien bibendum, sit amet porta lorem fringilla. Morbi bibendum in turpis ac
|
||||
blandit. Mauris semper nibh nec dignissim dapibus. Proin sagittis lacus est.
|
||||
END_STREAM_6
|
||||
|
||||
merge_two_streams(map {String::Tokenizer->new($ARG)->iterator()}
|
||||
($stream1, $stream2));
|
||||
merge_N_streams(6, map {String::Tokenizer->new($ARG)->iterator()}
|
||||
($stream1, $stream2, $stream3,
|
||||
$stream4, $stream5, $stream6));
|
||||
exit 0;
|
||||
|
||||
sub merge_two_streams {
|
||||
my ($iter1, $iter2) = @ARG;
|
||||
print "Merge of 2 streams:\n";
|
||||
while (1) {
|
||||
if (!$iter1->hasNextToken() && !$iter2->hasNextToken()) {
|
||||
print "\n\n";
|
||||
last;
|
||||
}
|
||||
elsif (!$iter1->hasNextToken()) {
|
||||
print $iter2->nextToken(), q{ };
|
||||
}
|
||||
elsif (!$iter2->hasNextToken()) {
|
||||
print $iter1->nextToken(), q{ };
|
||||
}
|
||||
elsif ($iter1->lookAheadToken() lt $iter2->lookAheadToken()) {
|
||||
print $iter1->nextToken(), q{ };
|
||||
}
|
||||
else {
|
||||
print $iter2->nextToken(), q{ };
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
sub merge_N_streams {
|
||||
my $N = shift;
|
||||
print "Merge of $N streams:\n";
|
||||
my @iters = @ARG;
|
||||
my $heap = Heap::Simple->new(order => 'lt', elements => 'Array');
|
||||
for (my $i=0; $i<$N; $i++) {
|
||||
my $iter = $iters[$i];
|
||||
$iter->hasNextToken() or die "Each stream must have >= 1 element";
|
||||
$heap->insert([$iter->nextToken() . q{ }, $i]);
|
||||
}
|
||||
$heap->count == $N or die "Problem with initial population of heap";
|
||||
while (1) {
|
||||
my ($token, $iter_idx) = @{ $heap->extract_top };
|
||||
print $token;
|
||||
# Attempt to read the next element from the same iterator where we
|
||||
# obtained the element we just extracted.
|
||||
my $to_insert = _fetch_next_element($iter_idx, $N, @iters);
|
||||
if (! $to_insert) {
|
||||
print join('', map {$ARG->[0]} $heap->extract_all);
|
||||
last;
|
||||
}
|
||||
$heap->insert($to_insert);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
sub _fetch_next_element {
|
||||
my $starting_idx = shift; my $N = shift; my @iters = @ARG;
|
||||
# Go round robin through every iterator exactly once, returning the first
|
||||
# element on offer.
|
||||
my @round_robin_idxs =
|
||||
map {$ARG % $N} ($starting_idx .. $starting_idx + $N - 1);
|
||||
foreach my $iter_idx (@round_robin_idxs) {
|
||||
my $iter = $iters[$iter_idx];
|
||||
if ($iter->hasNextToken()) {
|
||||
return [$iter->nextToken() . q{ }, $iter_idx];
|
||||
}
|
||||
}
|
||||
# At this point every iterator has been exhausted.
|
||||
return;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue