sub gen_iterator {
my @initial_info = @_;
my ($current_state, $done);
return sub {
# code to calculate $next_state or $done;
return undef if $done;
return $current_state = $next_state;
};
}
####
my $next = gen_iterator( 42 );
while ( my $item = $next->() ) {
print "$item\n";
}
##
##
my @DNA = qw/A C T G/;
my $seq = gen_permutate(14, @DNA);
while ( my $strand = $seq->() ) {
print "$strand\n";
}
sub gen_permutate {
my ($max, @list) = @_;
my @curr;
return sub {
if ( (join '', map { $list[ $_ ] } @curr) eq $list[ -1 ] x @curr ) {
@curr = (0) x (@curr + 1);
}
else {
my $pos = @curr;
while ( --$pos > -1 ) {
++$curr[ $pos ], last if $curr[ $pos ] < $#list;
$curr[ $pos ] = 0;
}
}
return undef if @curr > $max;
return join '', map { $list[ $_ ] } @curr;
};
}
##
##
my $start = $ARGV[0] || 999999;
my $next_id = gen_id( $start );
print $next_id->(), "\n" for 1 .. 10; # Next 10 IDs
sub gen_id {
my $curr = shift;
return sub {
0 while ! is_valid( ++$curr );
return $curr;
};
}
sub is_valid {
my ($num, $chk) = (shift, '');
my $tot;
for ( 0 .. length($num) - 1 ) {
my $dig = substr($num, $_, 1);
$_ % 2 ? ($chk .= $dig * 2) : ($tot += $dig);
}
$tot += $_ for split //, $chk;
return $tot % 10 == 0 ? 1 : 0;
}
##
##
my $next_file = rotate( qw/FileA FileB FileC/ );
print $next_file->(), "\n" for 1 .. 10;
sub rotate {
my @list = @_;
my $index = -1;
return sub {
$index++;
$index = 0 if $index > $#list;
return $list[ $index ];
};
}
##
##
while ( my $pass = $next_pw->() ) {
if ( unlock( $pass ) ) {
print "$pass\n";
last;
}
}
sub fix_size_perm {
my ($size, @list) = @_;
my @curr = (0) x ($size - 1);
push @curr, -1;
return sub {
if ( (join '', map { $list[ $_ ] } @curr) eq $list[ -1 ] x @curr ) {
@curr = (0) x (@curr + 1);
}
else {
my $pos = @curr;
while ( --$pos > -1 ) {
++$curr[ $pos ], last if $curr[ $pos ] < $#list;
$curr[ $pos ] = 0;
}
}
return undef if @curr > $size;
return join '', map { $list[ $_ ] } @curr;
};
}
sub unlock { $_[0] eq 'john' }
##
##
my @list = map { my @lines = <$_>; \@lines } @f_handles;
# becomes
my $next = gen_fh_iterator( \@f_handles );
while ( my $lines = $next->() ) {
print @$lines, "\n";
}
sub gen_fh_iterator {
my $f_handle = shift;
my $index = -1;
return sub {
$index++;
return undef if $index > $#f_handle;
my @lines = <$f_handle->[$index]>;
return \@lines;
};
}
##
##
sub infinite_evens {
my $curr = shift;
$curr++ if $curr % 2;
my $next;
return sub {
if ( ! defined $next ) { return $next = $curr }
return $next += 2;
};
}
my $next_even = infinite_evens( 41 );
print $next_even->(), "\n" while 1;