In Int§

See primary documentation in context for method polymod

method polymod(Int:D: +@mods)

Returns a sequence of mod results corresponding to the divisors in @mods in the same order as they appear there. For the best effect, the divisors should be given from the smallest "unit" to the largest (e.g. 60 seconds per minute, 60 minutes per hour) and the results are returned in the same way: from smallest to the largest (5 seconds, 4 minutes). The last non-zero value will be the last remainder.

say 120.polymod(10);    # OUTPUT: «(0 12)␤»
say 120.polymod(10,10); # OUTPUT: «(0 2 1)␤»

In the first case, 120 is divided by 10 giving as a remainder 12, which is the last element. In the second, 120 is divided by 10, giving 12, whose remainder once divided by 10 is 2; the result of the integer division of 12 div 10 is the last remainder. The number of remainders will be always one more item than the number of given divisors. If the divisors are given as a lazy list, runs until the remainder is 0 or the list of divisors is exhausted.

my $seconds = 1 * 60*60*24 # days
            + 3 * 60*60    # hours
            + 4 * 60       # minutes
            + 5;           # seconds

say $seconds.polymod(60, 60);                # OUTPUT: «(5 4 27)␤»
say $seconds.polymod(60, 60, 24);            # OUTPUT: «(5 4 3 1)␤»

say 120.polymod:      1, 10, 10², 10³, 10⁴;  # OUTPUT: «(0 0 12 0 0 0)␤»
say 120.polymod: lazy 1, 10, 10², 10³, 10⁴;  # OUTPUT: «(0 0 12)␤»
say 120.polymod:      1, 10, 10²  ∞;        # OUTPUT: «(0 0 12)␤»
my @digits-in-base37 = 9123607.polymod(37 xx *); # Base conversion
say @digits-in-base37.reverse                    # OUTPUT: «[4 32 4 15 36]␤»

All divisors must be Ints when called on an Int.

say 120.polymod(⅓);                            # ERROR

To illustrate how the Int, non-lazy version of polymod works, consider this code that implements it:

my $seconds = 2 * 60*60*24 # days
            + 3 * 60*60    # hours
            + 4 * 60       # minutes
            + 5;           # seconds

my @pieces;
for 60, 60, 24 -> $divisor {
    @pieces.push: $seconds mod $divisor;
    $seconds div= $divisor
}
@pieces.push: $seconds;

say @pieces; # OUTPUT: «[5 4 3 2]␤»

For a more detailed discussion, see this blog post.

We can use lazy lists in polymod, as long as they are finite:

my $some-numbers = lazy gather { take 3*$_ for 1..3 };
say 600.polymod( $some-numbers ); # OUTPUT: «(0 2 6 3)␤»

In role Real§

See primary documentation in context for method polymod

method polymod(Real:D: +@mods)

Returns the remainders after applying sequentially all divisors in the @mods argument; the last element of the array will be the last remainder.

say (1e8+1).polymod(10 xx 8);  # OUTPUT: «(1 0 0 0 0 0 0 0 1)␤»

10 xx 8 is simply an array with eight number 10s; the first division by 10 will return 1 as a remainder, while the rest, up to the last, will return 0. With 8 divisors, as above, the result will have one more elements, in this case for the last remainder.

say ⅔.polymod(⅓);                            # OUTPUT: «(0 2)␤»
say 5.Rat.polymod(.3, .2);                   # OUTPUT: «(0.2 0 80)␤»