Calmo numbers: Difference between revisions

From Rosetta Code
Content added Content deleted
(Added Algol 68)
Line 8: Line 8:
<big>Task</big>
<big>Task</big>
let's find Calmo numbers under 1000.
let's find Calmo numbers under 1000.


=={{header|ALGOL 68}}==
{{works with|ALGOL 68G|Any - tested with release 2.8.3.win32}}
{{libheader|ALGOL 68-primes}}
Note, the source of primes.incl.a68 is on Rosetta Code (see above link).
<br>
Assuming the task author intended that 1 and n should be excluded when considering the divisors of n,
the output confirms the task author's original sample which they deleted for some reason.
<syntaxhighlight lang="algol68">
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
</syntaxhighlight>
{{out}}
<pre>
165 273 385 399 561 595 665 715 957
</pre>

Revision as of 12:21, 19 March 2023

Definition Let n be a natural number. Let the real divisors of n be: d(1),d(2),d(3),...,d(k), where k is divisible by 3. Add the first three divisors, then the next three, and so on. If the partial sums are prime numbers, then n is called a Calmo number. Example n = 165 divisors = [3 5 11 15 33 55] 3 + 5 + 11 = 19 is prime number 15 + 33 + 55 = 103 is prime number Task let's find 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).
Assuming the task author intended that 1 and n should be excluded when considering the divisors of n, the output confirms the task author's original sample which they deleted for some reason.

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