Jump to content

Calmo numbers

From Rosetta Code
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

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

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 sum 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

ALGOL W

Translation of: ALGOL 68
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                                       %

    integer MAX_NUMBER, MAX_PRIME;
    MAX_NUMBER := 1000;                      % largest number we will consider %
    MAX_PRIME  := MAX_NUMBER * 3;          % largest prime we need to consider %
                         % as we are going to sum divisors in groups of three, %
                                       % it should be (more than) large enough %

    begin
        logical array prime ( 1 :: MAX_PRIME );
        integer array dsum, dcount ( 1 :: MAX_NUMBER );
        % sieve the primes to MAX_PRIME                                        %
        for i := 1 until MAX_PRIME do prime( i ) := true;
        prime( 1 ) := false;
        for i := 2 until truncate( sqrt( MAX_PRIME ) ) do begin
            if prime( i ) then begin
                for p := i * i step i until MAX_PRIME do prime( p ) := false
            end if_prime_i
        end for_i ;
        % 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                                          %
        for i := 1 until MAX_NUMBER do begin
            dsum( i ) := dcount( i ) := if prime( i ) then -1 else 0
        end for_i ;
        for i := 2 until MAX_NUMBER do begin
            for j := i + i step i until MAX_NUMBER do begin
                % have another proper divisor                                  %
                if dsum( j ) >= 0 then begin
                    % this number is still a candidate                         %
                    dsum(   j ) := dsum(   j ) + i;
                    dcount( j ) := dcount( j ) + 1;
                    if dcount( j ) = 3 then begin
                        % the divisor count is currently 3                     %
                        % if then divisor sum isn't prime, ignore it in future %
                        % if the divisor sum is prime, reset the sum and count %
                        dsum( j ) := dcount( j ) :=
                            if NOT prime( dsum( j ) ) then - 1 else 0
                    end if_dcount_j_eq_3
                end if_dsum_j_ge_0
            end for_j
        end for_i ;
        % show the numbers                                                    %
        for i := 2 until MAX_NUMBER do begin
            if dcount( i ) = 0 then writeon( i_w := 1, s_w := 0, " ", i )
        end for_i ;
    end
end.
Output:
 165 273 385 399 561 595 665 715 957

AppleScript

on properDivisors(n)
    set output to {}
    
    if (n > 1) then
        set sqrt to n ^ 0.5
        set limit to sqrt div 1
        if (limit = sqrt) then
            set end of output to limit
            set limit to limit - 1
        end if
        repeat with i from limit to 2 by -1
            if (n mod i is 0) then
                set beginning of output to i
                set end of output to n div i
            end if
        end repeat
        set beginning of output to 1
    end if
    
    return output
end properDivisors

(* on isCalmo(n)
    set pds to properDivisors(n)
    set pdCount to (count pds)
    if ((pdCount - 3) mod 3 ≠ 1) then return false
    repeat with i from 2 to (pdCount - 1) by 3
        if (properDivisors((pds's item i) + (pds's item (i + 1)) + (pds's item (i + 2))) ≠ {1}) then ¬
            return false
    end repeat
    
    return true
end isCalmo *)

-- It turns out that every Calmo number < 5,000,000 is odd
-- and has exactly 6 "eligible" (ie. 7 proper) divisors, so:
on isCalmo(n)
    if (n mod 2 = 0) then return false
    set pds to properDivisors(n)
    return (((count pds) = 7) and ¬
        (properDivisors((pds's item 2) + (pds's item 3) + (pds's item 4)) = {1}) and ¬
        (properDivisors((pds's item 5) + (pds's item 6) + (pds's end)) = {1}))
end isCalmo

on calmoNumbers(limit)
    set output to {}
    repeat with n from 20 to limit
        if (isCalmo(n)) then set end of output to n
    end repeat
    return output
end calmoNumbers

return calmoNumbers(999)
Output:
{165, 273, 385, 399, 561, 595, 665, 715, 957}

Arturo

calmo?: function [n][
    f: (factors n) -- @[1 n]
    unless zero? (size f) % 3 -> return false
    every? f [x y z] -> prime? x+y+z
]

1..1000 | select => calmo?
        | print
Output:
165 273 385 399 561 595 665 715 957

BASIC

BASIC256

include "isprime.kbs"

for n = 1 to 1000-1
	if isCalmo(n) then print n; " ";
next n
end

function isCalmo(n)
	limite = sqr(n)
	cont = 0: SumD = 0: SumQ = 0: k = 0: q = 0
	d = 2
	do
		q = n/d
		if n mod d = 0 then
			cont += 1
			SumD += d
			SumQ += q
			if cont = 3 then
				k += 3
				if not IsPrime(SumD) then return False
				if not IsPrime(SumQ) then return False
				cont = 0: SumD = 0: SumQ = 0
			end if
		end if
		d += 1
	until d >= limite
	if cont <> 0 or k = 0 then return False
	return True
end function
Output:
Same as FreeBASIC entry.

FreeBASIC

#include "isprime.bas"

Function isCalmo(n As Integer) As Boolean
    Dim As Integer limite = Sqr(n)
    Dim As Integer cont = 0, SumD = 0, SumQ = 0, k = 0, q = 0, d = 2
    
    Do 
        q = n/d
        If (n Mod d) = 0 Then
            cont += 1
            SumD += d
            SumQ += q
            If cont = 3 Then
                k += 3
                If Not IsPrime(SumD) Orelse Not IsPrime(SumQ) Then Return False
                cont = 0: SumD = 0: SumQ = 0
            End If   
        End If
        d += 1
    Loop Until d >= limite
    If cont <> 0 Or k = 0 Then Return False
    Return True
End Function

For n As Integer = 1 To 1000-1
    If isCalmo(n) Then Print n;
Next n

Sleep
Output:
165 273 385 399 561 595 665 715 957

Run BASIC

Works with: Just BASIC
for n = 1 to 1000-1
    if isCalmo(n) then print n; " ";
next n
end

function isPrime(n)
if n < 2       then isPrime = 0 : goto [exit]
if n = 2       then isPrime = 1 : goto [exit]
if n mod 2 = 0 then isPrime = 0 : goto [exit]
isPrime = 1
for i = 3 to int(n^.5) step 2
  if n mod i = 0 then isPrime = 0 : goto [exit]
next i
[exit]
end function

function isCalmo(n)
limite = sqr(n)
cont = 0: SumD = 0: SumQ = 0: k = 0: q = 0
d = 2
[start]
    q = n/d
    if n mod d = 0 then
        cont = cont +1
        SumD = SumD +d
        SumQ = SumQ +q
        if cont = 3 then
            k = k + 3
            if not(isPrime(SumD)) then isCalmo = 0 : goto [exit]
            if not(isPrime(SumQ)) then isCalmo = 0 : goto [exit]
            cont = 0: SumD = 0: SumQ = 0
        end if
    end if
    d = d +1
if d < limite then [start]
if cont <> 0 or k = 0 then isCalmo = 0 : goto [exit]
isCalmo = 1
[exit]
end function
Output:
Same as FreeBASIC entry.

Yabasic

import isprime

for n = 1 to 1000-1
    if isCalmo(n)  print n, " ";
next n
print
end

sub isCalmo(n)
    local limite, cont, SumD, SumQ, k, d, q
    
    limite = sqrt(n)
    cont = 0: SumD = 0: SumQ = 0: k = 0: q = 0: d = 2
    repeat 
        q = n/d
        if mod(n, d) = 0 then
            cont = cont+1
            SumD = SumD+d
            SumQ = SumQ+q
            if cont = 3 then
                k = k+3
                if not isPrime(SumD)  return False
                if not isPrime(SumQ)  return False
                cont = 0: SumD = 0: SumQ = 0
            fi
        fi
        d = d+1
    until d >= limite
    if cont <> 0 or k = 0  return False
    return True
end sub
Output:
Same as FreeBASIC entry.

C

Translation of: Go
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define LIMIT 1000

bool isPrime(int n) {
    if (n < 2) return false;
    if (n%2 == 0) return n == 2;
    if (n%3 == 0) return n == 3;
    int d = 5;
    while (d*d <= n) {
        if (n%d == 0) return false;
        d += 2;
        if (n%d == 0) return false;
        d += 4;
    }
    return true;
}

int compare(const void* a, const void* b) {
    int arg1 = *(const int*)a;
    int arg2 = *(const int*)b;
    if (arg1 < arg2) return -1;
    if (arg1 > arg2) return 1;
    return 0;
}

void eligibleDivisors(int n, int *divs, int *length) {
    if (n < 1) {
        *length = 0;
        return;
    }
    int i, j, k = 1, c = 0;
    if (n%2) k = 2;
    for (i = k + 1; i*i <= n; i += k) {
        if (!(n%i)) {
           divs[c++] = i;
           j = n / i;
           if (j != i) divs[c++] = j;
        }
    }
    if (c > 1) qsort(divs, c, sizeof(int), compare);
    *length = c;
}

int main() {
    int i, j, sum, edc, psc, cnc = 0;
    int ed[30], ps[5];
    bool isCalmo;
    printf("Calmo numbers under 1,000:\n");
    printf("Number  Eligible divisors           Partial sums\n");
    printf("------------------------------------------------\n");
    for (i = 2; i < LIMIT; ++i) {
        eligibleDivisors(i, ed, &edc);
        if (edc == 0 || edc % 3 != 0 ) continue;
        isCalmo = true;
        psc = 0;        
        for (j = 0; j < edc; j += 3) {
            sum = ed[j] + ed[j+1] + ed[j+2];
            if (!isPrime(sum)) {
                isCalmo = false;
                break;
            }
            ps[psc++] = sum;
        }
        if (isCalmo) {
            printf("%3d     [", i);            
            for (j = 0; j < edc; ++j) printf("%d, ", ed[j]);
            printf("\b\b]  \t\b\b\b\b[");
            for (j = 0; j < psc; ++j) printf("%d, ", ps[j]);
            printf("\b\b]\n");
        }
    }     
    return 0;
}
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] 

Delphi

Works with: Delphi version 6.0


function GetAllProperDivisors(N: Integer;var IA: TIntegerDynArray): integer;
{Make a list of all the "proper dividers" for N}
{Proper dividers are the of numbers the divide evenly into N}
var I: integer;
begin
SetLength(IA,0);
for I:=1 to N-1 do
 if (N mod I)=0 then
	begin
	SetLength(IA,Length(IA)+1);
	IA[High(IA)]:=I;
	end;
Result:=Length(IA);
end;


var Facts: TIntegerDynArray;

function IsCalmoNumber(N: integer): boolean;
{Test number to see if it a Calmo number}
var Inx,Sum: integer;
begin
Result:=False;
{Get all divisors}
GetAllProperDivisors(N,Facts);
{strip off 1 }
Facts:=Copy(Facts,1,High(Facts));
if Length(Facts)<3 then exit;
{Must be at least three}
if (Length(Facts) mod 3)<>0 then exit;
Inx:=0;
repeat
	begin
	{Sum three factors}
	Sum:=Facts[Inx]+Facts[Inx+1]+Facts[Inx+2];
	{Exit if not primve}
	if not IsPrime(Sum) then exit;
	{Index to next three}
	Inc(Inx,3);
	end
until Inx>High(Facts)-1;
Result:=True;
end;


procedure ShowCalmoNumbers(Memo: TMemo);
{Show all Calmo numbers less than 1,000}
var I,J: integer;
var S: string;
begin
for I:=1 to 1000 do
 if IsCalmoNumber(I) then
	begin
	S:='';
	for J:=0 to High(Facts) do
	  S:=S+Format('%4d',[Facts[J]]);
	S:=Trim(S);
	Memo.Lines.Add(IntToStr(I)+'   ['+S+']');
	end;
end;
Output:
165   [3   5  11  15  33  55]
273   [3   7  13  21  39  91]
385   [5   7  11  35  55  77]
399   [3   7  19  21  57 133]
561   [3  11  17  33  51 187]
595   [5   7  17  35  85 119]
665   [5   7  19  35  95 133]
715   [5  11  13  55  65 143]
957   [3  11  29  33  87 319]

Elapsed Time: 11.747 ms.

Factor

USING: combinators.short-circuit grouping.extras kernel math
math.functions math.primes math.primes.factors math.vectors
prettyprint ranges sequences sequences.extras ;
IN: calmo

: calmo? ( n -- ? )
    divisors 1 -1 rot subseq* {
        [ empty? not ]
        [ length 3 divisor? ]
        [ [ + + prime? ] 3 group-map vall? ]
    } 1&& ;

MAIN: [ 2 1000 [a..b) [ calmo? ] filter . ]
Output:
V{ 165 273 385 399 561 595 665 715 957 }

FutureBasic

local fn IsPrime( n as NSUInteger ) as BOOL
  BOOL       isPrime = YES
  NSUInteger i
  
  if n < 2        then exit fn = NO
  if n = 2        then exit fn = YES
  if n mod 2 == 0 then exit fn = NO
  for i = 3 to int(n^.5) step 2
    if n mod i == 0 then exit fn = NO
  next
end fn = isPrime

local fn IsCalmo( n as NSUInteger ) as BOOL
  BOOL       isCalmo = YES
  double     limit = sqr(n)
  NSUInteger count = 0, sumd = 0, sumq = 0, k = 0, q = 0, d = 2
  
  while ( d < limit )
    q = n/d
    if ( n mod d == 0 )
      count++ : sumd += d : sumq += q
      if ( count == 3 )
        k += 3
        if fn IsPrime( sumd ) == NO then exit fn = NO
        if fn IsPrime( sumq ) == NO then exit fn = NO
        count = 0 : sumd = 0 : sumq = 0
      end if
    end if
    d++
  wend
  if count != 0 or k == 0 then exit fn = NO
end fn = isCalmo

NSUInteger n

for n = 1 to 1000 -1
  if fn IsCalmo( n ) then print n; " ";
next

HandleEvents
Output:
165 273 385 399 561 595 665 715 957

Go

Library: Go-rcu
package main

import (
    "fmt"
    "rcu"
    "strconv"
    "strings"
)

func main() {
    const limit = 1000
    fmt.Println("Calmo numbers under 1,000:\n")
    fmt.Println("Number  Eligible divisors      Partial sums")
    fmt.Println("-------------------------------------------")
    for i := 2; i < limit; i++ {
        ed := rcu.ProperDivisors(i)[1:]
        l := len(ed)
        if l == 0 || l%3 != 0 {
            continue
        }
        isCalmo := true
        var ps []int
        for j := 0; j < l; j += 3 {
            sum := ed[j] + ed[j+1] + ed[j+2]
            if !rcu.IsPrime(sum) {
                isCalmo = false
                break
            }
            ps = append(ps, sum)
        }
        if isCalmo {
            eds := make([]string, len(ed))
            for k, e := range ed {
                eds[k] = strconv.Itoa(e)
            }
            seds := "[" + strings.Join(eds, " ") + "]"
            fmt.Printf("%3d     %-21s  %v\n", i, seds, ps)
        }
    }
}
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]

Haskell

import Data.List (group, sort)
import Data.List.Split (chunksOf)
import Data.Numbers.Primes (isPrime, primeFactors)

---------------------- CALMO NUMBERS ---------------------

isCalmo :: Int -> Bool
isCalmo n =
  let xs = properDivisors n
      m = length xs
   in m > 3 
        && 0 == mod (pred m) 3
        && all (isPrime . sum) (chunksOf 3 $ tail xs)


--------------------------- TEST -------------------------
main :: IO ()
main = print $ takeWhile (< 1000) $ filter isCalmo [1 ..]


------------------------- GENERIC ------------------------

properDivisors :: Int -> [Int]
properDivisors =
  init
    . sort
    . foldr --
      (flip ((<*>) . fmap (*)) . scanl (*) 1)
      [1]
    . group
    . primeFactors
Output:
[165,273,385,399,561,595,665,715,957]


J

If we ignore 1 and primes (see talk page):

   isCalmo=: {{*/((,*)+/)1 p:}:_3+/\/:~_ _ _,~.}.}:*/@>,{1 ,&.>q:y}} ::0:"0
   I.isCalmo i.1000
165 273 385 399 561 595 665 715 957

(This implementation relies on infinity not being specifically prime nor non-prime, and on treating the error case as "not a Calmo number").

JavaScript

Translation of: ALGOL 68

Procedural, uses console.log to show the numbers.

{  // 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

   'use strict'

   const maxNumber = 1000                  // 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
   let  isPrime = []
   const maxPrime = maxNumber * 3
   for( let sPos = 1; sPos <= maxPrime; sPos ++ ){ isPrime[ sPos ] = sPos % 2 == 1 }
   isPrime[ 1 ] = false
   isPrime[ 2 ] = true
   const rootMaxPrime = Math.floor( Math.sqrt( maxPrime ) )
   for( let sPos = 3; sPos <= rootMaxPrime; sPos += 2 ) {
      if( isPrime[ sPos ] ){
          for( let p = sPos * sPos; p <= maxPrime; p += sPos ){ isPrime[ p ] = false }
      }
   }

   // 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
   let dsum = [], dcount = []
   for( let i = 1; i <= maxNumber; i ++ ){
       dsum[ i ] = dcount[ i ] = ( isPrime[ i ] ? -1 : 0 )
   }
   for( let i = 2; i <= maxNumber; i ++ ){
       for( let j = i + i; j <= maxNumber; j += i ){
           // have another proper divisor
           if( dsum[ j ] >= 0 ){
               // this number is still a candidate
               dsum[   j ] = dsum[   j ] + i
               dcount[ j ] = dcount[ j ] + 1
               if( dcount[ j ] == 3 ){
                   // the divisor count is currently 3
                   // if the divisor sum isn't prime, ignore it in future
                   // if the divisor sum is prime, reset the sum and count
                   dsum[ j ] = dcount[ j ] = ( ! isPrime[ dsum[ j ] ] ? -1 : 0 )
               }
           }
       }
   }
   // show the numbers, they will have 0 in the divisor count
   let calmoNumbers = []
   for( let i = 2; i <= maxNumber; i ++ ){
       if( dcount[ i ] == 0 ){
           calmoNumbers.push( i )
       }
   }
   console.log( calmoNumbers )
}
Output:
[ 165, 273, 385, 399, 561, 595, 665, 715, 957 ]

Or, by functional composition, and preferring to return a value directly (avoiding `console.log`, which is not defined in ECMAScript, and is not available to all JS interpreters):

(() => {
    "use strict";

    // ------------------ CALMO NUMBERS ------------------

    // isCalmo :: Int -> Bool
    const isCalmo = n => {
        const
            ds = properDivisors(n),
            nd = ds.length;

        return 3 < nd && (
            0 === (nd - 1) % 3
        ) && chunksOf(3)(ds.slice(1)).every(
            triple => isPrime(sum(triple))
        );
    };

    // ---------------------- TEST -----------------------
    const main = () =>
        enumFromTo(1)(1000).filter(
            isCalmo
        );


    // --------------------- GENERIC ---------------------

    // chunksOf :: Int -> [a] -> [[a]]
    const chunksOf = n => {
        // xs split into sublists of length n.
        // The last sublist will be short if n
        // does not evenly divide the length of xs .
        const go = xs => {
            const chunk = xs.slice(0, n);

            return 0 < chunk.length
                ? [chunk, ...go(xs.slice(n))]
                : [];
        };

        return go;
    };


    // enumFromTo :: Int -> Int -> [Int]
    const enumFromTo = m =>
        n => Array.from({
            length: 1 + n - m
        }, (_, i) => m + i);


    // enumFromThenTo :: Int -> Int -> Int -> [Int]
    const enumFromThenTo = m =>
        // Integer values enumerated from m to n
        // with a step defined by (nxt - m).
        nxt => n => {
            const d = nxt - m;

            return Array.from({
                length: (Math.floor(n - nxt) / d) + 2
            }, (_, i) => m + (d * i));
        };


    // isPrime :: Int -> Bool
    const isPrime = n => {
        // True if n is prime.
        if (n === 2 || n === 3) {
            return true;
        }
        if (2 > n || 0 === (n % 2)) {
            return false;
        }
        if (9 > n) {
            return true;
        }
        if (0 === (n % 3)) {
            return false;
        }

        const p = x =>
            0 === n % x || 0 === (n % (2 + x));

        return !enumFromThenTo(5)(11)(1 + Math.sqrt(n))
        .some(p);
    };


    // properDivisors :: Int -> [Int]
    const properDivisors = n => {
        const
            rRoot = Math.sqrt(n),
            intRoot = Math.floor(rRoot),
            lows = enumFromTo(1)(intRoot)
            .filter(x => 0 === (n % x));

        return lows.concat(
            lows.map(x => n / x)
            .reverse()
            .slice(
                rRoot === intRoot
                    ? 1
                    : 0,
                -1
            )
        );
    };


    // sum :: [Num] -> Num
    const sum = xs =>
        // The numeric sum of all values in xs.
        xs.reduce((a, x) => a + x, 0);


    // MAIN ---
    return JSON.stringify(main());
})();
Output:
[165,273,385,399,561,595,665,715,957]

Julia

using Primes

function divisors(n::Integer)::Vector{Int}
    sort(vec(map(prod,Iterators.product((p.^(0:m) for (p,m) in eachfactor(n))...))))
end

function isCalmo(n)
    divi = divisors(n)[begin+1:end-1]
    ndiv = length(divi)
    return ndiv > 0 && ndiv % 3 == 0 && all(isprime, sum(reshape(divi, (3, :)), dims = 1))
end

println(filter(isCalmo, 1:1000))

Lua

Translation of: ALGOL 68
do --[[ 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
   --]]

    local maxNumber = 1000                  -- 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
    local isPrime, maxPrime = {}, maxNumber * 2
    for sPos = 1, maxPrime do isPrime[ sPos ] = sPos % 2 == 1 end
    isPrime[ 1 ] = false
    isPrime[ 2 ] = true
    for sPos = 3, math.sqrt( maxPrime ), 2 do
        if isPrime[ sPos ] then
            for p = sPos * sPos, maxPrime, sPos do isPrime[ p ] = false end
        end
    end

    -- 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
    local dsum, dcount = {}, {}
    for i = 1, maxNumber do
        dcount[ i ] = ( isPrime[ i ] and -1 or 0 )
        dsum[   i ] = dcount[ i ]
    end
    for i = 2, maxNumber do
        for j = i + i, maxNumber, i do
            -- have another proper divisor
            if dsum[ j ] >= 0 then
                -- this number is still a candidate
                dsum[   j ] = dsum[   j ] + i
                dcount[ j ] = dcount[ j ] + 1
                if dcount[ j ] == 3 then
                    -- the divisor count is currently 3
                    -- if the divisor sum isn't prime, ignore it in future
                    -- if the divisor sum is prime, reset the sum and count
                    dcount[ j ] = ( not isPrime[ dsum[ j ] ] and -1 or 0 )
                    dsum[   j ] = dcount[ j ]
                end
            end
        end
    end
    -- show the numbers, they will have 0 in the divisor count
    for i = 2, maxNumber do
        if dcount[ i ] == 0 then
            io.write( " ", i )
        end
    end
    io.write( "\n" )
end
Output:
 165 273 385 399 561 595 665 715 957

Mathematica /Wolfram Language

(*Function to get the divisors of a number excluding 1 and the number itself*)
EligibleDivisors[n_Integer] := 
 Select[Divisors[n], # != 1 && # != n &]

(*Function to check if the sum of every three consecutive eligible divisors is prime*)
IsCalmoNumber[n_Integer] := 
 Module[{divisors, sums, divisorsLength}, 
  divisors = EligibleDivisors[n];
  divisorsLength = Length[divisors];
  If[Mod[divisorsLength, 3] != 0 || divisorsLength <= 0, 
   Return[False]];
  sums = Total /@ Partition[divisors, 3];
  AllTrue[sums, PrimeQ]
]

(*Find all Calmo numbers under 1000*)
calmoNumbers =  Select[Range[2, 999], IsCalmoNumber]

(*Output the Calmo numbers*)
calmoNumbers // Print
Output:
{165, 273, 385, 399, 561, 595, 665, 715, 957}

MiniScript

isPrime = function(n)
	if n < 2 then return false
	if n < 4 then return true
	for i in range(2,floor(n ^ 0.5))
		if n % i == 0 then return false
	end for
	return true
end function

getFactors = function(n)
	factors = {}
	for i in range(1, floor(n ^ 0.5))
		if n % i == 0 then
			factors[i] = 1
			factors[n /i ] = 1
		end if
	end for
	return factors.indexes.sort
end function

isCalmo = function(n)
	factors = getFactors(n)
	if not(factors.len >= 5 and (factors.len - 2) % 3 == 0) then return false
	for i in range(1, factors.len - 4, 3)
		if not isPrime(factors[i] + factors[i+1] + factors[i+2]) then return false
	end for
	return true
end function

for i in range(1, 1000)
	if isCalmo(i) then print i
end for
Output:
165
273
385
399
561
595
665
715
957

Nim

func isPrime(n: Natural): bool =
  if n < 2: return false
  if (n and 1) == 0: return n == 2
  if n mod 3 == 0: return n == 3
  var d = 5
  var step = 2
  while d * d <= n:
    if n mod d == 0:
      return false
    inc d, step
    step = 6 - step
  return true

func divisors(n: Positive): seq[int] =
  for d in 2..<n:
    if n mod d == 0:
      result.add d

func isCalmoNumber(n: Positive): bool =
  let d = n.divisors
  if d.len == 0 or d.len mod 3 != 0:
    return false
  for i in countup(0, d.high, 3):
    if not isPrime(d[i] + d[i + 1] + d[i + 2]):
      return false
  return true

for n in 1..1000:
  if n.isCalmoNumber:
    stdout.write ' ', n
echo()
Output:
 165 273 385 399 561 595 665 715 957

PARI/GP

\\ Function to get the divisors of a number excluding 1 and the number itself
eligibleDivisors(n) = {
  my(divs = divisors(n)); \\ Compute all divisors of n
  if (#divs <= 2, return([])); \\ If there are no divisors other than 1 and n, return an empty list
  vecextract(divs, "2..-2"); \\ Extract divisors without the first and last elements (1 and n)
};

\\ Function to check if the sum of every three consecutive eligible divisors is prime
isCalmoNumber(n) = {
  my(divisors, sums, i, k);
  divisors = eligibleDivisors(n); \\ Get eligible divisors
  
  if ((#divisors % 3 != 0) || (#divisors == 0), return(0)); \\ If not divisible by 3 or no divisors, return false
  
  sums = vector(#divisors \ 3, i, sum(k = 1, 3, divisors[3*i + k - 3])); \\ Compute sums of every three divisors
  
  for (i = 1, #sums,
    if (!isprime(sums[i]), return(0)); \\ If any sum is not prime, return false
  );
  
  return(1); \\ If all sums are prime, return true
};

{
  \\ Find all Calmo numbers under 1000
  calmoNumbers = [];
  for (n = 1, 1000,
    if (isCalmoNumber(n), calmoNumbers = concat(calmoNumbers, n)); \\ Check if n is a Calmo number and add to the list
  );
  print(calmoNumbers); \\ Print all Calmo numbers found under 1000
}
Output:
[165, 273, 385, 399, 561, 595, 665, 715, 957]


Perl

Library: ntheory
use v5.36;
use ntheory<is_prime divisors>;
use List::Util 'all';
use experimental 'for_list';

sub c_divisors ($n) { my @d = divisors $n; pop @d; shift @d; @d }

for (2..1000) {
    my @d = c_divisors $_;
    next unless @d and 0 == @d%3;
    my @sums;
    for my($a,$b,$c) (@d) { push @sums, $a+$b+$c }
    print "$_ " if all { is_prime $_ } @sums;
}
say '';
Output:
165 273 385 399 561 595 665 715 957

Phix

with javascript_semantics
function calmo(integer n)
    sequence f = factors(n)
    integer l = length(f)
    if l=0 or remainder(l,3)!=0 then return false end if
    for i=1 to l by 3 do
        if not is_prime(sum(f[i..i+2])) then return false end if
    end for
    return true
end function
?filter(tagset(1000),calmo)
Output:
{165,273,385,399,561,595,665,715,957}

Python

#!/usr/bin/python

def isPrime(n):
    for i in range(2, int(n**0.5) + 1):
        if n % i == 0:
            return False        
    return True

def isCalmo(n):
    limite = pow(n, 0.5)
    cont = 0
    SumD = 0
    SumQ = 0
    k = 0
    q = 0
    d = 2
    while d < limite:
        q = n/d
        if n % d == 0:
            cont += 1
            SumD += d
            SumQ += q
            if cont == 3:
                k += 3
                if not isPrime(SumD):
                    return False
                if not isPrime(SumQ):
                    return False
                cont = 0
                SumD = 0
                SumQ = 0
        d += 1
    if cont != 0 or k == 0:
        return False
    return True


if __name__ == "__main__":
    for n in range(1, 1000-1):
        if isCalmo(n):
            print(n, end=" ");
Output:
Same as FreeBASIC entry.

Quackery

factors is defined at Factors of an integer#Quackery.

  [ true swap
    factors dup size 3 < iff
      [ drop not ] done
    1 split nip
    -1 split drop
    dup size 3 mod 0 != iff
      [ drop not ] done
    [ 3 split
      0 rot witheach +
      factors size 2 != iff
        [ dip not ] done
      dup [] = until ]
    drop ]                   is calmo ( n --> b )

  [] 1000 times [ i^ calmo if [ i^ join ] ]
  echo
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...

RPL

≪ DUP FACTORS 
  IF DUP SIZE 3 MOD THEN DROP2 0 ELSE
    {} 1 3 PICK SIZE FOR j
       OVER j GET + 
    2 STEP 
    NIP SWAP OVER / + SORT 
    1 CF
    1 OVER SIZE FOR j
       DUP j DUP 2 + SUB ∑LIST
       IF ISPRIME? NOT THEN 1 SF DUP SIZE 'j' STO END
    3 STEP DROP
    1 FC?
  END
≫ 'CALMO?' STO

≪ { } 2 1000 FOR j IF j CALMO? THEN j + END NEXT ≫ 'TASK' STO
Output:
1: { 165 273 385 399 561 595 665 715 957 }

Runs in 2 minutes 54 seconds on a HP-50g.


Scala

Translation of: Python
object Main extends App {
  
  def isPrime(n: Int): Boolean = {
    for (i <- 2 to math.sqrt(n).toInt) {
      if (n % i == 0) {
        return false
      }
    }
    true
  }

  def isCalmo(n: Int): Boolean = {
    val limite = math.sqrt(n)
    var cont = 0
    var sumD = 0
    var sumQ = 0
    var k = 0
    var q = 0
    var d = 2
    while (d < limite) {
      q = n / d
      if (n % d == 0) {
        cont += 1
        sumD += d
        sumQ += q
        if (cont == 3) {
          k += 3
          if (!isPrime(sumD)) {
            return false
          }
          if (!isPrime(sumQ)) {
            return false
          }
          cont = 0
          sumD = 0
          sumQ = 0
        }
      }
      d += 1
    }
    if (cont != 0 || k == 0) {
      return false
    }
    true
  }

  for (n <- 1 until 1000) {
    if (isCalmo(n)) {
      print(n + " ")
    }
  }
}
Output:
165 273 385 399 561 595 665 715 957 


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]

XPL0

func IsPrime(N);        \Return 'true' if N is prime
int  N, I;
[if N <= 2 then return N = 2;
if (N&1) = 0 then \even >2\ return false;
for I:= 3 to sqrt(N) do
    [if rem(N/I) = 0 then return false;
    I:= I+1;
    ];
return true;
];

func IsCalmo(N);        \Return 'true' if N is a Calmo number
int  N, Limit, Count, SumD, SumQ, K, D, Q;
[Limit:= sqrt(N);
Count:= 0;  SumD:= 0;  SumQ:= 0;  K:= 0;
D:= 2;
repeat  Q:= N/D;
        if rem(0) = 0 then
            [Count:= Count+1;
            SumD:= SumD+D;
            SumQ:= SumQ+Q;
            if Count = 3 then
                [K:= K+3;
                if not IsPrime(SumD) then return false;
                if not IsPrime(SumQ) then return false;
                Count:= 0;  SumD:= 0;  SumQ:= 0;
                ];
            ];
        D:= D+1;
until   D >= Limit;
if Count # 0 or K = 0 then return false;
return true;
];

int  N;
[for N:= 1 to 1000-1 do
    if IsCalmo(N) then
        [IntOut(0, N);  ChOut(0, ^ )];
]
Output:
165 273 385 399 561 595 665 715 957 
Cookies help us deliver our services. By using our services, you agree to our use of cookies.