Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Re: In need of a sequence iterator.

by !1 (Hermit)
on Dec 02, 2004 at 07:26 UTC ( #411674=note: print w/replies, xml ) Need Help??


in reply to In need of a sequence iterator.

How about:

sub genIterator { my ($len,$count) = @_; my @list = (); return sub { if (@list == 0 || @list < $len) { push @list, 0; } else { $list[-1]++; while (@list && $list[-1] >= $count) { pop @list; $list[-1]++ if @list; } } return @list ? join("", @list) : undef; } }

Note that the code to iterate should be:

my $iter = genIterator(4,3); print while defined($_ = $iter->());

since 0 evaluates as false.

Replies are listed 'Best First'.
Re^2: In need of a sequence iterator.
by BrowserUk (Pope) on Dec 02, 2004 at 08:04 UTC

    That works perfectly. Thankyou.

    Looks so easy ... when someone else does it:)


    Examine what is said, not who speaks.
    "But you should never overestimate the ingenuity of the sceptics to come up with a counter-argument." -Myles Allen
    "Think for yourself!" - Abigail        "Time is a poor substitute for thought"--theorbtwo         "Efficiency is intelligent laziness." -David Dunham
    "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon

      Now that I've had a chance to sleep, here's a solution that accepts either a count or an arrayref.

      sub genIterator { my ($len,$array) = @_; $array = [0..$array-1] if $array =~ /^\d+$/; die "Don't know what to do with $array" unless ref $array eq "ARRA +Y"; my @list = (); return sub { return undef unless @$array; if (@list < $len) { push @list, 0; } else { $list[-1]++; while (@list && $list[-1] >= @$array) { pop @list; $list[-1]++ if @list; } } return @list ? join("", @$array[@list]) : undef; } }
Re^2: In need of a sequence iterator.
by hv (Parson) on Dec 02, 2004 at 13:27 UTC

    As far as I can see this is just counting in base $count, in which case I'd probably use a string instead:

    sub genIterator { my($len, $count) = @_; my $cur = ''; my $lastdig = $count - 1; return sub { if (length($cur) < $len) { $cur .= '0'; } else { $cur =~ s/([^$lastdig])$lastdig*\z/$1 + 1/e or $cur = undef; } $cur; } }

    Of course this assumes $count doesn't exceed 10; this approach gets a bit more complex if you need to deal with larger bases.

    Hugo

      The $count can get upto 255 (and theoretically beyond with unicode). The numbers are eventually packed to form a binary string of codepoints that increment, magic string auto-increment style, but starting at chr(0) and modulo alphabet size.

      I'm currently limiting my thinking to 8-bit ascii bytes, but notionally the alphabet could be larger with unicode.

      The actual keys involved (made up from an arbitrary alphabet) are translated to chr(0) ... chr(alphabet max).


      Examine what is said, not who speaks.
      "But you should never overestimate the ingenuity of the sceptics to come up with a counter-argument." -Myles Allen
      "Think for yourself!" - Abigail        "Time is a poor substitute for thought"--theorbtwo         "Efficiency is intelligent laziness." -David Dunham
      "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon

        Ah ok, well you could use the string approach directly on the packed strings by changing the replace to /chr(ord($1)+1)/e or use a hash to describe successorship in the arbitrary alphabet:

        my $alphabet = "0123456789ABCDEF"; my %successor = $alphabet =~ /(.)(?=(.))/g; my $zero = substr($alphabet, 0, 1); ... sub genIterator { my($len, $count) = @_; my $cur = ''; my $lastdig = substr($alphabet, $count - 1, 1); return sub { if (length($cur) < $len) { $cur .= $zero; } else { $cur =~ s/([^$lastdig])$lastdig*\z/$successor{$1}/ or $cur = undef; } $cur; } }

        Hugo

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://411674]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (2)
As of 2021-07-23 22:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?