Centenary Sequences with Raku
Part 5

by Arne Sommer

# Centenary Sequences with Raku - Part 5: Divisors and Factors

[100.5] Published 4. November 2020.

#### Divisors vs Factors

Divisors: All the numbers that we can divide the number with. E.g. the divisors of 20 are: 1, 2, 4, 5, 10 and 20.

Factors: All the prime numbers that we can divide the number into. E.g. the factors of 20 are: 2, 2 and 5.

## Divisors

Divisors are whole numbers that are multiplied together to produce another number. E.g 20 has the following pair of divisors: (1,20), (2,20) and (4,5). Thus the divisors are: 1, 2, 4, 5, 10 and 20.

Note that `1` and the number itself are included in the divisors. There are situations where we do not want them, so the following program supports all combinations:

File: divisors ```unit sub MAIN (Int \$number); say "[]: ", divisors(\$number); say "[>: ", divisors(\$number, :not-self); say "<>: ", divisors(\$number, :not-self, :not-one); say "<]: ", divisors(\$number, :not-one); sub divisors (\$number, :\$not-self, :\$not-one) { my @divisors; for (\$not-one ?? 2 !! 1) .. \$number/2 -> \$candidate { @divisors.push: \$candidate if \$number %% \$candidate; } @divisors.push: \$number unless \$not-self; return @divisors; } ```

Running it:

```\$ ./divisors 100 []: [1 2 4 5 10 20 25 50 100] # 1 and the number itself included [>: [1 2 4 5 10 20 25 50] # 1 included, but not the number itself <>: [2 4 5 10 20 25 50] # Neither included <]: [2 4 5 10 20 25 50 100] # 1 not included, but the number itself is ```

We can use this procedure to set up some sequences, where we include 1 and the number itself. (The next 3 sequences are all computed by the «divisors-applied» program, available in the zip file.)

##### 057. Number of Divisors
We can count the number of divisors:

```(1..Inf).map({ divisors(\$_).elems }); # 057 ``` ```> say (1..Inf).map({ divisors(\$_).elems })[^20]; (1 2 2 3 2 4 2 4 3 4 2 6 2 4 4 5 2 6 2 6) ```

## Perfect Divisors

As Divisors, but excluding the number itself. (The `[>` line from the «divisors» program.)

##### 058. Multipled Divisors
We can multiply the divisors:

```(1..Inf).map({ [*] divisors(\$_, :not-self) }); # 058 ``` ```> say (1..Inf).map({ divisors(\$_, :not-self).elems })[^20]; (1 1 1 2 1 6 1 8 3 10 1 144 1 14 15 64 1 324 1 400) ```

##### 059. Summed Divisors

```(1..Inf).map({ divisors(\$_, :not-self).sum }); # 059 ``` ```> say (1..Inf).map({ divisors(\$_, :not-self).sum })[^20]; (0 1 1 3 1 6 1 7 4 8 1 16 1 10 9 15 1 21 1 22) ```

##### 060. Deficient Numbers
A Deficient Number is a number that is larger than the sum of its perfect divisors.

```(1..Inf).grep({ \$_ > divisors(\$_, :not-self).sum }) # 060 ``` ```> say (1..Inf).grep({ \$_ > divisors(\$_, :not-self).sum })[^20]; (1 2 3 4 5 7 8 9 10 11 13 14 15 16 17 19 21 22 23 25) ```

I have included the program «deficient-numbers» in the zip file.

##### 061. Abundant Numbers
An Abundant Number is a number that is smaller than the sum of its divisors (excluding itself).

```(1..Inf).grep({ \$_ < divisors(\$_, :not-self).sum }) # 061 ``` ```> say (1..Inf).grep({ \$_ < divisors(\$_, :not-self).sum })[^20]; (12 18 20 24 30 36 40 42 48 54 56 60 66 70 72 78 80 84 88 90) ```

I have included the program «abundant-numbers» in the zip file.

##### 062. Perfect Numbers
A perfect number is a number that is equal to the sum of its perfect divisors. For example, 28=1+2+4+7+14 is a perfect number.

```(1..Inf).grep({ \$_ eq divisors(\$_, :not-self).sum }); # 062 ``` ```> say (1..Inf).grep({ \$_ eq divisors(\$_, :not-self).sum })[^3]; (6 28 496) > say (1..Inf).grep({ \$_ eq divisors(\$_, :not-self).sum })[^4]; (6 28 496 8128) ```

The first one is fast, but the second one took about 16 seconds. I wisely stopped there...

I have included the program «perfect-numbers» in the zip file.

##### 063. Almost Perfect Numbers

An Almost Perfect Number (sometimes also called Slightly Defective or Least Deficiente Number) is a natural number `n` such that the sum of all divisors of `n` is equal to `2n − 1`.

```(1..Inf).grep({ divisors(\$_).sum == 2 * \$_ - 1 }); # 063 ``` ```> say (1..Inf).grep({ divisors(\$_).sum == 2 * \$_ - 1 })[^12]; (1 2 4 8 16 32 64 128 256 512 1024 2048) ```

Note that this is a more time consuming way of generating the «Double the Value» sequence from Part 2: Arithmetic and Geometric Sequences.

I have included the program «almost-perfect-numbers» in the zip file.

##### 064. Arithmetic Number

An Arithmetic Number is an integer for which the average of its positive divisors is also an integer:

```(1..Inf).grep({ my @d = divisors(\$_); @d.sum %% @d.elems }) # 064 ``` ```> say (1..Inf).grep({ my @d = divisors(\$_); @d.sum %% @d.elems })[^25]; (1 3 5 6 7 11 13 14 15 17 19 20 21 22 23 27 29 30 31 33 35 37 38 39 41) ```

I have included the program «arithemetic-numbers» in the zip file.

##### 065. Sublime Numbers

A Sublime Number has a Perfect Number of Positive Divisors, and those Positive Divisors add up to another Perfect number.

There are only two numbers in this sequence, so we can cheat and state them directly:

```(12, # 065 6086555670238378989670371734243169622657830773351885970528324860512791691264) ```

## Factors

The Factors of a number is a list of prime number we multiply together to get the number. The number itself is the only factor for prime numbers, and the number 1.

File: factors ```unit sub MAIN (Int \$number where \$number > 0, :u(:\$upto)); \$upto ?? ( say "\$_: " ~ factors(\$_) for 1..\$number ) !! say factors(\$number); sub factors (\$number is copy) { return (1) if \$number == 1; return (\$number) if \$number.is-prime; my @factors; for (2 .. \$number div 2).grep( *.is-prime) -> \$candidate { while \$number %% \$candidate { @factors.push: \$candidate; \$number /= \$candidate; } } return @factors; } ```

Running it:

```\$ ./factors 10 [2 5] ```

With «upto» mode:

```\$ ./factors -u 20 1: 1 2: 2 3: 3 4: 2 2 5: 5 6: 2 3 7: 7 8: 2 2 2 9: 3 3 10: 2 5 11: 11 12: 2 2 3 13: 13 14: 2 7 15: 3 5 16: 2 2 2 2 17: 17 18: 2 3 3 19: 19 20: 2 2 5 ```

##### 066. Summed Factors
We can add the factors of the numbers (indices):

```(1..Inf).map({ factors(\$_).sum }); # 066 ``` ```> say (1..Inf).map({ factors(\$_).sum })[^25]; (1 2 3 4 5 5 7 6 6 7 11 7 13 9 8 8 17 8 19 9 10 13 23 9 10) ```

##### 067. Attractive Numbers
A number is an attractive number if the number of its prime factors is also a prime number.

The number 20 is an attractive number, whose prime factors are 2, 2 and 5. The number of prime factors is 3, which is also a prime number.

```(1..Inf).grep({ factors(\$_).grep( *.is-prime).elems.is-prime }); # 067 ``` ```> say (1..Inf).grep({ factors(\$_).grep( *.is-prime).elems.is-prime })[^20]; (4 6 8 9 10 12 14 15 18 20 21 22 25 26 27 28 30 32 33 34) ```

I have included the program «attractive-numbers» in the zip file.

## Factorial

This has nothing to do with Factors (Divisors), except the name similarity. But here they are, nevertheless.

The (postfix) Factorial Operator, which Raku is missing, is written as `4!` by mathematicians. This is the same as `4! = 4 * 3 * 2 * 1 = 24`

Raku makes it easy to add the missing operator:

File: factorial-operator ```unit sub MAIN (Int \$number = 20); sub postfix:(\$n) { return [*] 1 .. \$n; } ``` ```\$ ./factorial-operator 3 6 \$ ./factorial-operator 10 3628800 ```

##### 068. Factorial Sequence
We can get the factorial values like this:

```(my \$i=1, * * \$i++ ... Inf) # 068 ``` ```> say (my \$i=1, * * \$i++ ... Inf)[^10]; (1 1 2 6 24 120 720 5040 40320 362880) ```

That looks ok, as long as you accept that the first value (with index 0) is the value of `0!`.

##### 069. Factorial Number Length

The number of digits in the factorial values, instead of the numbers themselves:

```(my \$i=1, * * \$i++ ... Inf).map( *.chars ) # 069 ``` ```> say (my \$i=1, * * \$i++ ... Inf).map( *.chars )[^30] (1 1 1 1 2 3 3 4 5 6 7 8 9 10 11 13 14 15 16 18 19 20 22 23 24 26 27 29 30 31) ```
##### 070. Exponential Factorials

The Exponential Factorials start with the number 1 (at index 0). After that we take the index and raises it to the power of the previous number in the sequence:

```(my \$i=1, \$i++ ** * ... Inf) # 070 ``` ```> say (my \$i=1, \$i++ ** * ... Inf)[^5] (1 1 2 9 262144) ```

The next value is enormous:

```> say (my \$i=1, \$i++ ** * ... Inf)[5].chars; 183231 ```
##### 071. Alternating Factorials

The Alternating Factorials start with the number 1 (at index 1). After that we take the factorial of the index and subtract the previous number in the sequence:

```(my \$i = 1, { \$i++; ( [*] 1 .. \$i ) - \$^a } ... Inf) # 071a ``` ```> say (my \$i = 1, { \$i++; ( [*] 1 .. \$i ) - \$^a } ... Inf)[^10]; (1 1 5 19 101 619 4421 35899 326981 3301819 36614981 442386619) ```