# Attractive numbers

Attractive 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.

A number is an Attractive Number if the number of its prime factors (whether distinct or not) is also prime.

For example the number 20, whose prime decomposition is 2 * 2 * 5, is attractive because the number of its prime factors (3) is also prime.

Task

Show sequence items up to 120.

## C

Translation of: Go
`#include <stdio.h> #define TRUE 1#define FALSE 0#define MAX 120 typedef int bool; bool is_prime(int n) {    int d = 5;    if (n < 2) return FALSE;    if (!(n % 2)) return n == 2;    if (!(n % 3)) return n == 3;    while (d *d <= n) {        if (!(n % d)) return FALSE;        d += 2;        if (!(n % d)) return FALSE;        d += 4;    }    return TRUE;} int count_prime_factors(int n) {    int count = 0, f = 2;    if (n == 1) return 0;    if (is_prime(n)) return 1;    while (TRUE) {        if (!(n % f)) {            count++;            n /= f;            if (n == 1) return count;            if (is_prime(n)) f = n;        }         else if (f >= 3) f += 2;        else f = 3;    }} int main() {        int i, n, count = 0;    printf("The attractive numbers up to and including %d are:\n", MAX);    for (i = 1; i <= MAX; ++i) {        n = count_prime_factors(i);        if (is_prime(n)) {            printf("%4d", i);            if (!(++count % 20)) printf("\n");        }    }    printf("\n");    return 0;  }`
Output:
```The attractive numbers up to and including 120 are:
4   6   8   9  10  12  14  15  18  20  21  22  25  26  27  28  30  32  33  34
35  38  39  42  44  45  46  48  49  50  51  52  55  57  58  62  63  65  66  68
69  70  72  74  75  76  77  78  80  82  85  86  87  91  92  93  94  95  98  99
102 105 106 108 110 111 112 114 115 116 117 118 119 120
```

## C++

Translation of: C
`#include <iostream>#include <iomanip> #define MAX 120 using namespace std; bool is_prime(int n) {       if (n < 2) return false;    if (!(n % 2)) return n == 2;    if (!(n % 3)) return n == 3;    int d = 5;    while (d *d <= n) {        if (!(n % d)) return false;        d += 2;        if (!(n % d)) return false;        d += 4;    }    return true;} int count_prime_factors(int n) {        if (n == 1) return 0;    if (is_prime(n)) return 1;    int count = 0, f = 2;    while (true) {        if (!(n % f)) {            count++;            n /= f;            if (n == 1) return count;            if (is_prime(n)) f = n;        }         else if (f >= 3) f += 2;        else f = 3;    }} int main() {    cout << "The attractive numbers up to and including " << MAX << " are:" << endl;    for (int i = 1, count = 0; i <= MAX; ++i) {        int n = count_prime_factors(i);        if (is_prime(n)) {            cout << setw(4) << i;            if (!(++count % 20)) cout << endl;        }    }    cout << endl;    return 0;}`
Output:
```The attractive numbers up to and including 120 are:
4   6   8   9  10  12  14  15  18  20  21  22  25  26  27  28  30  32  33  34
35  38  39  42  44  45  46  48  49  50  51  52  55  57  58  62  63  65  66  68
69  70  72  74  75  76  77  78  80  82  85  86  87  91  92  93  94  95  98  99
102 105 106 108 110 111 112 114 115 116 117 118 119 120
```

## Factor

Works with: Factor version 0.99
`USING: formatting grouping io math.primes math.primes.factorsmath.ranges sequences ; "The attractive numbers up to and including 120 are:" print120 [1,b] [ factors length prime? ] filter 20 <groups>[ [ "%4d" printf ] each nl ] each`
Output:
```The attractive numbers up to and including 120 are:
4   6   8   9  10  12  14  15  18  20  21  22  25  26  27  28  30  32  33  34
35  38  39  42  44  45  46  48  49  50  51  52  55  57  58  62  63  65  66  68
69  70  72  74  75  76  77  78  80  82  85  86  87  91  92  93  94  95  98  99
102 105 106 108 110 111 112 114 115 116 117 118 119 120
```

## Go

Simple functions to test for primality and to count prime factors suffice here.

`package main import "fmt" func isPrime(n int) bool {    switch {    case n < 2:        return false    case n%2 == 0:        return n == 2    case n%3 == 0:        return n == 3    default:        d := 5        for d*d <= n {            if n%d == 0 {                return false            }            d += 2            if n%d == 0 {                return false            }            d += 4        }        return true    }} func countPrimeFactors(n int) int {    switch {    case n == 1:        return 0    case isPrime(n):        return 1    default:        count, f := 0, 2        for {            if n%f == 0 {                count++                n /= f                if n == 1 {                    return count                }                if isPrime(n) {                    f = n                }            } else if f >= 3 {                f += 2            } else {                f = 3            }        }        return count    }} func main() {    const max = 120    fmt.Println("The attractive numbers up to and including", max, "are:")    count := 0    for i := 1; i <= max; i++ {        n := countPrimeFactors(i)        if isPrime(n) {            fmt.Printf("%4d", i)            count++            if count % 20 == 0 {                fmt.Println()            }        }           }    fmt.Println()}`
Output:
```The attractive numbers up to and including 120 are:
4   6   8   9  10  12  14  15  18  20  21  22  25  26  27  28  30  32  33  34
35  38  39  42  44  45  46  48  49  50  51  52  55  57  58  62  63  65  66  68
69  70  72  74  75  76  77  78  80  82  85  86  87  91  92  93  94  95  98  99
102 105 106 108 110 111 112 114 115 116 117 118 119 120
```

## Haskell

`import Data.Numbers.Primesimport Data.Bool (bool) attractiveNumbers :: [Integer]attractiveNumbers =  [1 ..] >>= (bool [] . return) <*> (isPrime . length . primeFactors) main :: IO ()main = print \$ takeWhile (<= 120) attractiveNumbers`

Or equivalently, as a list comprehension:

`import Data.Numbers.Primes attractiveNumbers :: [Integer]attractiveNumbers =  [ x  | x <- [1 ..]   , isPrime (length (primeFactors x)) ] main :: IO ()main = print \$ takeWhile (<= 120) attractiveNumbers`

Or simply:

`import Data.Numbers.Primes attractiveNumbers :: [Integer]attractiveNumbers =  filter    (isPrime . length . primeFactors)    [1 ..] main :: IO ()main = print \$ takeWhile (<= 120) attractiveNumbers`
Output:
`[4,6,8,9,10,12,14,15,18,20,21,22,25,26,27,28,30,32,33,34,35,38,39,42,44,45,46,48,49,50,51,52,55,57,58,62,63,65,66,68,69,70,72,74,75,76,77,78,80,82,85,86,87,91,92,93,94,95,98,99,102,105,106,108,110,111,112,114,115,116,117,118,119,120]`

## Java

Translation of: C
`public class Attractive {     static boolean is_prime(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;    }     static int count_prime_factors(int n) {        if (n == 1) return 0;        if (is_prime(n)) return 1;        int count = 0, f = 2;        while (true) {            if (n % f == 0) {                count++;                n /= f;                if (n == 1) return count;                if (is_prime(n)) f = n;            }            else if (f >= 3) f += 2;            else f = 3;        }    }     public static void main(String[] args) {        final int max = 120;        System.out.printf("The attractive numbers up to and including %d are:\n", max);        for (int i = 1, count = 0; i <= max; ++i) {            int n = count_prime_factors(i);            if (is_prime(n)) {                System.out.printf("%4d", i);                if (++count % 20 == 0) System.out.println();            }        }        System.out.println();    }}`
Output:
```The attractive numbers up to and including 120 are:
4   6   8   9  10  12  14  15  18  20  21  22  25  26  27  28  30  32  33  34
35  38  39  42  44  45  46  48  49  50  51  52  55  57  58  62  63  65  66  68
69  70  72  74  75  76  77  78  80  82  85  86  87  91  92  93  94  95  98  99
102 105 106 108 110 111 112 114 115 116 117 118 119 120
```

## Julia

`using Primes # oneliner is println("The attractive numbers from 1 to 120 are:\n", filter(x -> isprime(sum(values(factor(x)))), 1:120)) isattractive(n) = isprime(sum(values(factor(n)))) printattractive(m, n) = println("The attractive numbers from \$m to \$n are:\n", filter(isattractive, m:n)) printattractive(1, 120) `
Output:
```The attractive numbers from 1 to 120 are:
[4, 6, 8, 9, 10, 12, 14, 15, 18, 20, 21, 22, 25, 26, 27, 28, 30, 32, 33, 34, 35, 38, 39, 42, 44, 45, 46, 48, 49, 50, 51, 52, 55, 57, 58, 62, 63, 65, 66, 68, 69, 70, 72, 74, 75, 76, 77, 78, 80, 82, 85, 86, 87, 91, 92, 93, 94, 95, 98, 99, 102, 105, 106, 108, 110, 111, 112, 114, 115, 116, 117, 118, 119, 120]
```

## Kotlin

Translation of: Go
`// Version 1.3.21 const val MAX = 120 fun isPrime(n: Int) : Boolean {    if (n < 2) return false    if (n % 2 == 0) return n == 2    if (n % 3 == 0) return n == 3    var d : Int = 5    while (d * d <= n) {        if (n % d == 0) return false        d += 2        if (n % d == 0) return false        d += 4    }    return true} fun countPrimeFactors(n: Int) =    when {        n == 1  -> 0        isPrime(n) -> 1        else -> {            var nn = n            var count = 0            var f = 2            while (true) {                if (nn % f == 0) {                    count++                    nn /= f                    if (nn == 1) break                    if (isPrime(nn)) f = nn                } else if (f >= 3) {                    f += 2                } else {                    f = 3                }            }            count        }    } fun main() {    println("The attractive numbers up to and including \$MAX are:")    var count = 0    for (i in 1..MAX) {        val n = countPrimeFactors(i)        if (isPrime(n)) {            System.out.printf("%4d", i)            if (++count % 20 == 0) println()        }    }    println()}`
Output:
```The attractive numbers up to and including 120 are:
4   6   8   9  10  12  14  15  18  20  21  22  25  26  27  28  30  32  33  34
35  38  39  42  44  45  46  48  49  50  51  52  55  57  58  62  63  65  66  68
69  70  72  74  75  76  77  78  80  82  85  86  87  91  92  93  94  95  98  99
102 105 106 108 110 111 112 114 115 116 117 118 119 120
```

## Perl

Library: ntheory
`use ntheory <is_prime factor>; is_prime +factor \$_ and print "\$_ " for 1..120;`
Output:
`4 6 8 9 10 12 14 15 18 20 21 22 25 26 27 28 30 32 33 34 35 38 39 42 44 45 46 48 49 50 51 52 55 57 58 62 63 65 66 68 69 70 72 74 75 76 77 78 80 82 85 86 87 91 92 93 94 95 98 99 102 105 106 108 110 111 112 114 115 116 117 118 119 120`

## Perl 6

Works with: Rakudo version 2019.03

This algorithm is concise but not really well suited to finding large quantities of consecutive attractive numbers. It works, but isn't especially speedy. More than a hundred thousand or so gets tedious. There are other, much faster (though more verbose) algorithms that could be used. This algorithm is well suited to finding arbitrary attractive numbers though.

`use Prime::Factor; sub display (\$n,\$m) { (\$n..\$m).hyper.grep: *.&prime-factors.elems.is-prime } sub count (\$n,\$m) { +(\$n..\$m).race(:16batch).grep: *.&prime-factors.elems.is-prime } sub comma { \$^i.flip.comb(3).join(',').flip } # The Taskput "Attractive numbers from 1 to 120:\n" ~display(1, 120)».fmt("%3d").rotor(20, :partial).join: "\n"; # Robusto!for 1, 1000,  1, 10000,  2**73 + 1, 2**73 + 100 -> \$a, \$b {    put "\nCount of attractive numbers from {comma \$a} to {comma \$b}:\n" ~    count \$a, \$b}`
Output:
```Attractive numbers from 1 to 120:
4   6   8   9  10  12  14  15  18  20  21  22  25  26  27  28  30  32  33  34
35  38  39  42  44  45  46  48  49  50  51  52  55  57  58  62  63  65  66  68
69  70  72  74  75  76  77  78  80  82  85  86  87  91  92  93  94  95  98  99
102 105 106 108 110 111 112 114 115 116 117 118 119 120

Count of attractive numbers from 1 to 1,000:
636

Count of attractive numbers from 1 to 10,000:
6396

Count of attractive numbers from 9,444,732,965,739,290,427,393 to 9,444,732,965,739,290,427,492:
58```

## REXX

Programming notes: The use of a table that contains some low primes is one fast method to test for primality of the
various prime factors.   This fast method can be used for numbers up to approximately   1029.

The   cFact   (count factors)   function   is optimized way beyond what this task requires,   and it can be optimized
further by expanding the     do whiles     clauses   (lines   3──►6   in the   cFact   function).

`/*REXX program finds and lists (or counts) the  attractive  numbers up to a specified N.*/p= 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109,  113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233,  239 241 251 257 263 269 271 277 281 283 293 307 311 313 317 331 337 347 349 353 359 367@.=0     do i=1  for words(p);  _=word(p,i);  @._=1  /*define low prime table, it's good for*/     end   /*i*/                                 /*   numbers to around 10^29 (or 2^79).*/#= 0                                             /*the number of primes found (so far). */parse arg N .                                    /*get optional argument from the C.L.  */if N=='' | N==","  then N= 120                   /*Not specified?  Then use the default.*/cnt= N<0                                         /*semaphore used to control the output.*/N= abs(N)                                        /*ensure that  N  is a positive number.*/sw= linesize() - 1                               /*SW:    is the usable screen width.   */if \cnt  then say 'attractive numbers up to and including '     N     " are:"\$=                                               /*a list of attractive numbers (so far)*/    do j=1  for N;              a= cFact(j)      /*call cFact to count the factors in J.*/    if \@.a  then iterate                        /*if # of factors not prime, then skip.*/    #= # + 1                                     /*add  the index and number of factors.*/    if cnt   then iterate                        /*if not displaying numbers, skip list.*/    _= \$  j                                                 /*append a number to \$ list.*/    if length(_)>sw  then do;  say strip(\$);  \$= j;  end    /*display a line of numbers.*/                     else                     \$= _          /*append the latest number. */    end   /*j*/ if \$\==''  &  \cnt   then say strip(\$)           /*display any residual numbers in list.*/say;  say #  ' attractive numbers found up to and including '      Nexit                                             /*stick a fork in it,  we're all done. *//*──────────────────────────────────────────────────────────────────────────────────────*/cFact: procedure;  parse arg z 1 oz;  if z<2  then return z  /*if Z too small, return Z.*/       #=0                                       /*#:  is the number of factors (so far)*/             do  while z//2==0;  #= #+1;  z= z%2;  end  /*maybe add the factor of two.  */             do  while z//3==0;  #= #+1;  z= z%3;  end  /*  "    "   "     "    " three.*/             do  while z//5==0;  #= #+1;  z= z%5;  end  /*  "    "   "     "    " five. */             do  while z//7==0;  #= #+1;  z= z%7;  end  /*  "    "   "     "    " seven.*/                                                 /* [↑]  reduce  Z  by some low primes. */          do k=11  by 6  while k<=z              /*insure that  K  isn't divisible by 3.*/          parse var k  ''  -1  _                 /*get the last decimal digit of  K.    */          if _\==5  then do  while z//k==0;  #= #+1;   z= z%k;   end   /*maybe reduce Z.*/          if _ ==3  then iterate                 /*Next number ÷ by 5?  Skip.   ____    */          if k*k>oz then leave                   /*are we  greater  than the   √ OZ  ?  */          y= k + 2                               /*get next divisor,  hopefully a prime.*/                         do while  z//y==0;  #= #+1;   z= z%y;   end   /*maybe reduce Z.*/          end   /*k*/        if z\==1  then return # + 1               /*if residual isn't unity, then add it.*/                      return #                   /*return the number of factors in  OZ. */`

This REXX program makes use of   LINESIZE   REXX program (or BIF) which is used to determine the screen width (or linesize) of the terminal (console).
Some REXXes don't have this BIF.   It is used here to automatically/idiomatically limit the width of the output list.

The   LINESIZE.REX   REXX program is included here   ───►   LINESIZE.REX.

output   when using the default input:
```attractive numbers up to and including  120  are:
4 6 8 9 10 12 14 15 18 20 21 22 25 26 27 28 30 32 33 34 35 38 39 42 44 45 46 48 49 50 51 52 55 57 58 62 63 65 66 68 69 70 72 74
75 76 77 78 80 82 85 86 87 91 92 93 94 95 98 99 102 105 106 108 110 111 112 114 115 116 117 118 119 120

74  attractive numbers found up to and including  120
```
output   when using the input of:     -10000
```6396  attractive numbers found up to and including  10000
```

## Ring

` # Project: Attractive Numbers decomp = []nump = 0see "Attractive Numbers up to 120:" + nlwhile nump < 120decomp = []nump = nump + 1for i = 1 to nump    if isPrime(i) and nump%i = 0       add(decomp,i)       dec = nump/i       while dec%i = 0             add(decomp,i)             dec = dec/i       end    oknextif isPrime(len(decomp))    see string(nump) + " = ["for n = 1 to len(decomp)    if n < len(decomp)       see string(decomp[n]) + "*"    else       see string(decomp[n]) + "] - " + len(decomp) + " is prime" + nl    oknextokend  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:
```Attractive Numbers up to 120:
4 = [2*2] - 2 is prime
6 = [2*3] - 2 is prime
8 = [2*2*2] - 3 is prime
9 = [3*3] - 2 is prime
10 = [2*5] - 2 is prime
12 = [2*2*3] - 3 is prime
14 = [2*7] - 2 is prime
15 = [3*5] - 2 is prime
18 = [2*3*3] - 3 is prime
20 = [2*2*5] - 3 is prime
...
...
...
102 = [2*3*17] - 3 is prime
105 = [3*5*7] - 3 is prime
106 = [2*53] - 2 is prime
108 = [2*2*3*3*3] - 5 is prime
110 = [2*5*11] - 3 is prime
111 = [3*37] - 2 is prime
112 = [2*2*2*2*7] - 5 is prime
114 = [2*3*19] - 3 is prime
115 = [5*23] - 2 is prime
116 = [2*2*29] - 3 is prime
117 = [3*3*13] - 3 is prime
118 = [2*59] - 2 is prime
119 = [7*17] - 2 is prime
120 = [2*2*2*3*5] - 5 is prime
```

## Ruby

`require "prime" p (1..120).select{|n| n.prime_division.sum(&:last).prime? } `
Output:
```[4, 6, 8, 9, 10, 12, 14, 15, 18, 20, 21, 22, 25, 26, 27, 28, 30, 32, 33, 34, 35, 38, 39, 42, 44, 45, 46, 48, 49, 50, 51, 52, 55, 57, 58, 62, 63, 65, 66, 68, 69, 70, 72, 74, 75, 76, 77, 78, 80, 82, 85, 86, 87, 91, 92, 93, 94, 95, 98, 99, 102, 105, 106, 108, 110, 111, 112, 114, 115, 116, 117, 118, 119, 120]
```

## Sidef

`func is_attractive(n) {    n.bigomega.is_prime} 1..120 -> grep(is_attractive).say`
Output:
```[4, 6, 8, 9, 10, 12, 14, 15, 18, 20, 21, 22, 25, 26, 27, 28, 30, 32, 33, 34, 35, 38, 39, 42, 44, 45, 46, 48, 49, 50, 51, 52, 55, 57, 58, 62, 63, 65, 66, 68, 69, 70, 72, 74, 75, 76, 77, 78, 80, 82, 85, 86, 87, 91, 92, 93, 94, 95, 98, 99, 102, 105, 106, 108, 110, 111, 112, 114, 115, 116, 117, 118, 119, 120]
```

## zkl

Using GMP (GNU Multiple Precision Arithmetic Library, probabilistic primes) because it is easy and fast to test for primeness.

`var [const] BI=Import("zklBigNum");  // libGMPfcn attractiveNumber(n){ BI(primeFactors(n).len()).probablyPrime() } println("The attractive numbers up to and including 120 are:");[1..120].filter(attractiveNumber)   .apply("%4d".fmt).pump(Void,T(Void.Read,19,False),"println");`
`fcn primeFactors(n){  // Return a list of factors of n   acc:=fcn(n,k,acc,maxD){  // k is 2,3,5,7,9,... not optimum      if(n==1 or k>maxD) acc.close();      else{	 q,r:=n.divr(k);   // divr-->(quotient,remainder)	 if(r==0) return(self.fcn(q,k,acc.write(k),q.toFloat().sqrt()));	 return(self.fcn(n,k+1+k.isOdd,acc,maxD))      }   }(n,2,Sink(List),n.toFloat().sqrt());   m:=acc.reduce('*,1);      // mulitply factors   if(n!=m) acc.append(n/m); // opps, missed last factor   else acc;}`
Output:
```The attractive numbers up to and including 120 are:
4   6   8   9  10  12  14  15  18  20  21  22  25  26  27  28  30  32  33  34
35  38  39  42  44  45  46  48  49  50  51  52  55  57  58  62  63  65  66  68
69  70  72  74  75  76  77  78  80  82  85  86  87  91  92  93  94  95  98  99
102 105 106 108 110 111 112 114 115 116 117 118 119 120
```