История изменений
Исправление Jini, (текущая версия) :
Быстрее, экономичнее, элегантнее будет не экономить на пробелах, а завернуть это в простую функцию. Почитай про bottom-up программирование. Вот первое что пришло в голову, возможно, есть ещё проще варианты:
use Data::Dumper;
sub make_intervals {
my ($m, $c) = @_;
my @result;
my $i = 0;
while ($m > 0) {
push @result, [ $i, $i + $c - 1 ];
$i += $c;
$m -= $c;
};
$result[$#result][1] += $m if @result;
\@result;
};
print Dumper make_intervals 90, 15;
Касательно предыдущей части, попробуй использовать итераторы. На CPANе мне попадались подходящие модули, но вообще их можно на коленке делать. Вот пример:
use v5.22;
my $eos = \1; # end of stream designator for igenerate
sub done { $eos };
sub igenerate(&) {
my ($generator) = @_;
sub {
my ($yield) = @_;
my $value = $generator->();
return if $value == $eos;
$yield->($value);
__SUB__;
};
};
sub imap(&@) {
my ($function, $iterator) = @_;
sub {
my ($yield) = @_;
$iterator = $iterator->(sub { $yield->($function->(@_)) });
__SUB__ if $iterator;
};
};
sub igather(&@) {
my ($gatherer, $iterator) = @_;
$iterator = $iterator->($gatherer) while $iterator;
};
sub iarray {
my ($array) = @_;
my $i = 0;
igenerate { $i < @$array ? $array->[$i++] : done };
};
sub isplice {
my ($n, $iterator) = @_;
my @args;
sub {
my ($yield) = @_;
my $i = 0;
while ($iterator && $i < $n) {
$iterator = $iterator->(sub { $args[$i++] = $_[0] });
};
$#args = $i - 1;
$yield->(@args) if @args;
__SUB__ if $iterator;
};
};
igather { say "@_" } imap { map { $_ * 2 } @_ } isplice 5, iarray [ 1..20 ];
Исходная версия Jini, :
Быстрее, экономичнее, элегантнее будет не экономить на пробелах, а завернуть это в простую функцию. Почитай про bottom-up программирование. Вот первое что пришло в голову, возможно, есть ещё проще варианты:
use Data::Dumper;
sub make_intervals {
my ($m, $c) = @_;
my @result;
my $i = 0;
while ($m > 0) {
push @result, [ $i, $i + $c - 1 ];
$i += $c;
$m -= $c;
};
$result[$#result][1] += $m if @result;
\@result;
};
print Dumper make_intervals 90, 15;
Касательно предыдущей части, попробуй использовать итераторы. На CPANе мне попадались подходящие модули, но вообще их можно на коленке делать. Вот пример:
use v5.22;
my $eos = \1; # end of stream designator for igenerate
sub done { $eos };
sub igenerate(&) {
my ($generator) = @_;
sub {
my ($yield) = @_;
my $value = $generator->();
return if $value == $eos;
$yield->($value);
__SUB__;
};
};
sub imap(&@) {
my ($function, $iterator) = @_;
sub {
my ($yield) = @_;
$iterator = $iterator->(sub { $yield->($function->(@_)) });
__SUB__ if $iterator;
};
};
sub igather(&@) {
my ($gatherer, $iterator) = @_;
$iterator = $iterator->($gatherer) while $iterator;
};
sub iarray {
my ($array) = @_;
my $i = 0;
igenerate { $i < @$array ? $array->[$i++] : done };
};
sub isplice($@) {
my ($n, $iterator) = @_;
my @args;
sub {
my ($yield) = @_;
my $i = 0;
while ($iterator && $i < $n) {
$iterator = $iterator->(sub { $args[$i++] = $_[0] });
};
$#args = $i - 1;
$yield->(@args) if @args;
__SUB__ if $iterator;
};
};
igather { say "@_" } imap { map { $_ * 2 } @_ } isplice 5, iarray [ 1..20 ];