Calmo numbers

Revision as of 13:23, 19 March 2023 by Thundergnat (talk | contribs) (→‎{{header|Raku}}: Add a Raku example)

Let n be a natural number having k divisors (other than 1 and n itself) where k is exactly divisible by 3.

Calmo numbers is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.
Definition

Add the first three eligible divisors, then the next three, and so on until the eligible divisors are exhausted. If the resulting partial sums are prime numbers, then n is called a Calmo number.

Example

Consider n = 165.

It has 6 eligible divisors, namely [3 5 11 15 33 55].

The sum of the first three is: 3 + 5 + 11 = 19 which is a prime number.

The sum of the next three is: 15 + 33 + 55 = 103 which is also a prime number.

Hence n is a Calmo number.

Task

Find and show here all Calmo numbers under 1000.

ALGOL 68

Works with: ALGOL 68G version Any - tested with release 2.8.3.win32

Note, the source of primes.incl.a68 is on Rosetta Code (see above link).

BEGIN # find some "Calmo" numbers: numbers n such that they have 3k divisors  #
      # (other than 1 and n) for some k > 0 and the sum of their divisors     #
      # taken three at a time is a prime                                      #
    PR read "primes.incl.a68" PR      # include prime utilities               #
    INT max number = 1 000;           # largest number we will consider       #
    # construct a sieve of (hopefully) enough primes - as we are going to sum #
    # the divisors in groups of three, it should be (more than) large enough  #
    []BOOL prime = PRIMESIEVE ( max number * 3 );
    # construct tables of the divisor counts and divisor sums and check for   #
    # the numbers as we do it                                                 #
    # as we are ignoring 1 and n, the initial counts and sums will be 0       #
    # but we should ignore primes                                             #
    [ 1 : max number ]INT dsum;
    [ 1 : max number ]INT dcount;
    FOR i TO UPB dcount DO
        dsum[ i ] := dcount[ i ] := IF prime[ i ] THEN -1 ELSE 0 FI
    OD;
    FOR i FROM 2 TO UPB dsum
        DO FOR j FROM i + i BY i TO UPB dsum DO
            # have another proper divisor                                     #
            IF dsum[ j ] >= 0 THEN
                # this number is still a candidate                            #
                dsum[   j ] +:= i;
                dcount[ j ] +:= 1;
                IF dcount[ j ] = 3 THEN
                    # the divisor count is currently 3                        #
                    dsum[ j ] := dcount[ j ] := 
                        IF NOT prime[ dsum[ j ] ] THEN
                            # divisor sum isn't prime, ignore it in future    #
                            -1
                        ELSE
                            # divisor count is prime, reset the sum and count #
                            0
                        FI
                FI
            FI
        OD
    OD;
    # show the numbers                                                        #
    FOR i FROM 2 TO UPB dcount DO
        IF dcount[ i ] = 0 THEN
            # have a number                                                   #
            print( ( " ", whole( i, 0 ) ) )
        FI
    OD;
    print( ( newline ) )
END
Output:
 165 273 385 399 561 595 665 715 957

Raku

use Prime::Factor;
use List::Divvy;

my $upto = 1e3;

my @found = (2..Inf).hyper.grep({
    (so my @d = .&proper-divisors(:s)) &&
    (@d.elems %% 3) &&
    (all @d.batch(3)».sum».is-prime)
}).&upto($upto);

put "{+@found} found before $upto using sums of proper-divisors:\n" ~
@found.batch(10)».fmt("%4d").join: "\n";

@found = (2..Inf).hyper.grep({
    (so my @d = .&proper-divisors(:s).&after: 1) &&
    (@d.elems %% 3) &&
    (all @d.batch(3)».sum».is-prime)
}).&upto($upto);

put "\n{+@found} found before $upto using sums of some bizarre\nbespoke definition for divisors:\n" ~
@found.batch(10)».fmt("%4d").join: "\n";
Output:
85 found before 1000 using sums of proper-divisors:
   8   21   27   35   39   55   57   65   77   85
 111  115  125  129  155  161  185  187  201  203
 205  209  221  235  237  265  291  299  305  309
 319  323  327  335  341  365  371  377  381  391
 413  415  437  451  485  489  493  497  505  515
 517  535  579  611  623  649  655  667  669  671
 687  689  697  707  731  737  755  767  779  781
 785  831  835  851  865  893  899  901  917  921
 939  955  965  979  989

9 found before 1000 using sums of some bizarre
bespoke definition for divisors:
 165  273  385  399  561  595  665  715  957

Ring

see "works..." + nl
numCalmo = 0
limit = 1000
for n = 1 to limit
    Calmo = []
    for m = 2 to n/2
        if n % m = 0
           add(Calmo,m)
        ok
    next
    flag = 1
    lenCalmo = len(Calmo)
    if (lenCalmo > 5) and (lenCalmo % 3 = 0)
        for p = 1 to lenCalmo - 2 step 3
            sum = Calmo[p] + Calmo[p+1] + Calmo[p+2]
            if not isPrime(sum)
               flag = 0
               exit
            ok
        next
        if flag = 1
           numCalmo++
           see "n(" + numCalmo + ") = " + n + nl
           see "divisors = ["
           for p = 1 to lenCalmo - 2 step 3
               sumCalmo = Calmo[p] + Calmo[p+1] + Calmo[p+2]
               if not isPrime(sumCalmo)
                  exit
               else
                  if p = 1
                     see "" + Calmo[p] + " " + Calmo[p+1] + " " + Calmo[p+2]
                  else
                     see " " + Calmo[p] + " " + Calmo[p+1] + " " + Calmo[p+2]
                  ok
               ok 
            next
            see "]" + nl
            for p = 1 to lenCalmo - 2 step 3
                sumCalmo = Calmo[p] + Calmo[p+1] + Calmo[p+2]
                if isPrime(sumCalmo)
                   see "" + Calmo[p] + " + " + Calmo[p+1] + " + " + Calmo[p+2] + " = " + sumCalmo + " is prime" + nl
                ok
            next
            see nl
        ok
     ok
next
see "Found " + numCalmo + " Calmo numbers" + nl
see "done..." + nl

func isPrime num
     if (num <= 1) return 0 ok
     if (num % 2 = 0 and num != 2) return 0 ok
     for i = 3 to floor(num / 2) -1 step 2
         if (num % i = 0) return 0 ok
     next
     return 1
Output:
works...
n(1) = 165
divisors = [3 5 11 15 33 55]
3 + 5 + 11 = 19 is prime
15 + 33 + 55 = 103 is prime

n(2) = 273
divisors = [3 7 13 21 39 91]
3 + 7 + 13 = 23 is prime
21 + 39 + 91 = 151 is prime

n(3) = 385
divisors = [5 7 11 35 55 77]
5 + 7 + 11 = 23 is prime
35 + 55 + 77 = 167 is prime

n(4) = 399
divisors = [3 7 19 21 57 133]
3 + 7 + 19 = 29 is prime
21 + 57 + 133 = 211 is prime

n(5) = 561
divisors = [3 11 17 33 51 187]
3 + 11 + 17 = 31 is prime
33 + 51 + 187 = 271 is prime

n(6) = 595
divisors = [5 7 17 35 85 119]
5 + 7 + 17 = 29 is prime
35 + 85 + 119 = 239 is prime

n(7) = 665
divisors = [5 7 19 35 95 133]
5 + 7 + 19 = 31 is prime
35 + 95 + 133 = 263 is prime

n(8) = 715
divisors = [5 11 13 55 65 143]
5 + 11 + 13 = 29 is prime
55 + 65 + 143 = 263 is prime

n(9) = 957
divisors = [3 11 29 33 87 319]
3 + 11 + 29 = 43 is prime
33 + 87 + 319 = 439 is prime

Found 9 Calmo numbers
done...

Wren

Library: Wren-math
Library: Wren-seq
Library: Wren-fmt
import "./math" for Int, Nums
import "./seq" for Lst
import "./fmt" for Fmt

var limit = 1000
var calmo = []
for (i in 2...limit) {
    var ed = Int.properDivisors(i)
    ed.removeAt(0)
    if (ed.count == 0 || ed.count % 3 != 0) continue
    var isCalmo = true
    var ps = []
    for (chunk in Lst.chunks(ed, 3)) {
        var sum = Nums.sum(chunk)
        if (!Int.isPrime(sum)) {
            isCalmo = false
            break
        }
        ps.add(sum)
    }
    if (isCalmo) calmo.add([i, ed, ps])
}
System.print("Calmo numbers under 1,000:\n")
System.print("Number  Eligible divisors         Partial sums")
System.print("----------------------------------------------")
for (e in calmo) {
    Fmt.print("$3d     $-24n  $n", e[0], e[1], e[2])
}
Output:
Calmo numbers under 1,000:

Number  Eligible divisors         Partial sums
----------------------------------------------
165     [3, 5, 11, 15, 33, 55]    [19, 103]
273     [3, 7, 13, 21, 39, 91]    [23, 151]
385     [5, 7, 11, 35, 55, 77]    [23, 167]
399     [3, 7, 19, 21, 57, 133]   [29, 211]
561     [3, 11, 17, 33, 51, 187]  [31, 271]
595     [5, 7, 17, 35, 85, 119]   [29, 239]
665     [5, 7, 19, 35, 95, 133]   [31, 263]
715     [5, 11, 13, 55, 65, 143]  [29, 263]
957     [3, 11, 29, 33, 87, 319]  [43, 439]