## Semi prime numbers

16

2

The high school textbook I am using has the example of semi-prime numbers. They wanted students to find (by "perspiration") all the semi-prime numbers less than $50$ (for a question on set theory).

A semi-prime number is the product of exactly two prime numbers (not necessarily distinct).

How would I generate the first $n$ semi-prime numbers using Mathematica?

Closely related: Generating a list of cubefree numbers

– Artes – 2014-01-28T13:11:10.823

As always, the help of this community is very much appreciated! Thank you to everyone who responded. – Tom De Vries – 2014-01-29T13:18:34.427

16

You could use FactorInteger to find out whether or not there are exactly two primes building up a number:

SemiPrimeQ[n_Integer] := With[{factors = FactorInteger[n]},
Total[factors[[All, 2]]] == 2
]


The rest is easy:

Select[Range[50], SemiPrimeQ]
(* {4, 6, 9, 10, 14, 15, 21, 22, 25, 26, 33, 34, 35, 38, 39, 46, 49} *)


And for those who like inline anonymous functions

Select[Range[50], Total[Last /@ FactorInteger[#]] == 2 &]
(* {4, 6, 9, 10, 14, 15, 21, 22, 25, 26, 33, 34, 35, 38, 39, 46, 49} *)


## Update

If you want to create all semi primes which consist of primes smaller than the n-th prime, then this is a one-liner too. Here are all semi primes for the first 10 prime numbers:

Union[Times @@@ Tuples[Array[Prime, 10], 2]]
(* {4, 6, 9, 10, 14, 15, 21, 22, 25, 26, 33, 34, 35, 38, 39, \
46, 49, 51, 55, 57, 58, 65, 69, 77, 85, 87, 91, 95, 115, 119, 121, \
133, 143, 145, 161, 169, 187, 203, 209, 221, 247, 253, 289, 299, 319, \
323, 361, 377, 391, 437, 493, 529, 551, 667, 841} *)


Wow, that was fast, and I appreciate that answer. Makes sense to me! I was messing around with lists of Primes and Tuples. This does just what I wanted, THANK YOU, I'll just wait a bit and see if there are other answers. – Tom De Vries – 2014-01-27T16:26:33.480

@TomDeVries, yes, waiting is always good, because people tend to look on unaccepted question to gain reputation. Many surprising answer can come up this way and you will see many different approaches. – halirutan – 2014-01-27T16:31:28.723

@RunnyKine In fact... let me check. – halirutan – 2014-01-27T16:45:08.253

@RunnyKine You have to check further ;-) The problem is that the last list is (due to Tuples) not sorted. – halirutan – 2014-01-27T16:48:32.517

Ah, you're right. My mistake. – RunnyKine – 2014-01-27T16:50:13.180

@RunnyKine But the list contained duplicates as well, so I wrapped a Union around it. Thanks for paying attention! – halirutan – 2014-01-27T16:52:16.747

No worries :). +1 – RunnyKine – 2014-01-27T16:53:14.693

20

The built-in functionPrimeOmega gives you the number of prime factors and counts multiplicities. Therefore, this can easily be used to give you semi-primes as you have defined them:

With[{r = Range[50]}, Pick[r, PrimeOmega[r], 2]]


1Thanks for that, no idea about that function – Tom De Vries – 2014-01-27T16:50:12.870

2

Never mistake PrimeOmega with OmegaPrime! +1

– halirutan – 2014-01-29T17:10:47.247

1@halirutan "Semi-Primes Assemble!" – KennyColnago – 2014-01-31T17:14:50.000

8

By using a pregenerated list of prime numbers:

lst = Prime[Range@PrimePi[25]];
Select[Union@Flatten[lst*# & /@ lst], # < 50 &]
(* {4, 6, 9, 10, 14, 15, 21, 22, 25, 26, 33, 34, 35, 38, 39, 46, 49} *)


1

For fun, here's an approach that uses ReplaceList:

With[{n = 50},
Union @@ ReplaceList[
Array[Prime, n], {pre___, y_, rest___} :> y {pre, y}]]

(* {4, 6, 9, 10, 14, 15, 21, 22, 25, 26, 33, 34, 35, 38, 39, 46, 49, 51, \
55, 57, 58, 65, 69, 77, 85, 87, 91, 95, 115, 119, 121, 133, 143, 145, \
161, 169, 187, 203, 209, 221, 247, 253, 289, 299, 319, 323, 361, 377, \
391, 437, 493, 529, 551, 667, 841} *)