- See Also
- Author, Copyright, and License
Algorithm::Odometer::Tiny - Generate "base-N odometer" permutations (Cartesian product / product set)
use Algorithm::Odometer::Tiny; my $odometer = Algorithm::Odometer::Tiny->new( [qw/a b c/], [qw/1 2/] ); print $odometer->(), "\n"; # prints "a1" my $val = <$odometer>; # $val is "a2" my @val = $odometer->(); # @val is ("b", "1") my @rest = <$odometer>; # only in Perl 5.18+: get remaining values
This class implements the permutation algorithm described in  as an iterator. An "odometer" has a number of "wheels", each of which can have a different number of positions. On each step, the rightmost wheel is advanced to the next position, and if it wraps around, the next higher wheel is incremented by one, and so on - it is the same basic algorithm that we use to count from 0 to 100 and onwards, except with different "digits".
The constructor of this class takes a list of array references, each of which represents a wheel in the odometer. The constructor returns an object of this class, which can be called as a code reference (
$odometer->()), or the
<> I/O operator can be used to read the next item. Calling the code reference or
<> operator in scalar context returns the current state of the wheels joined together as a string, while calling the code reference in list context returns the current state of the wheels as a list of individual values. In Perl 5.18 and above, calling the
<> operator in list context will return all of the (remaining) values in the sequence as strings. In scalar context, the iterator will return
undef once, and then start the sequence from the beginning.
This class is named
::Tiny because the code for the odometer fits on a single page, and if you look at the source, you'll see a
sub odometer that you can copy out of the source code if you wish (if you're not using Carp, just replace
The following wheels:
["Hello","Hi"], ["World","this is"], ["a test.","cool!"]
produce this sequence:
("Hello", "World", "a test.") ("Hello", "World", "cool!") ("Hello", "this is", "a test.") ("Hello", "this is", "cool!") ("Hi", "World", "a test.") ("Hi", "World", "cool!") ("Hi", "this is", "a test.") ("Hi", "this is", "cool!")
Here are some other implementations of the Cartesian product, although they may not produce items in the same order as this module. Note that if you want speed, XS-based implementations such as Math::Prime::Util or Set::Product::XS are probably going to be fastest.
Perl's glob can produce a Cartesian product, if non-empty braces are the only wildcard characters used in the pattern.
The motivation to release this module kindly provided by: Some Kiwi Novice @ PerlMonks
Dominus, M. (2005). Higher-Order Perl: Transforming Programs with Programs. Burlington: Elsevier. http://hop.perl.plover.com/. Chapter 4 "Iterators", Section 4.3.1 "Permutations".
Copyright (c) 2019 Hauke Daempfling (email@example.com).
This library is free software; you can redistribute it and/or modify it under the same terms as Perl 5 itself.