That's a prime... almost

30

1

If you've ever learned about primes in math class, you've probably have had to, at one point, determine if a number is prime. You've probably messed up while you were still learning them, for example, mistaking 39 for a prime. Well, not to worry, as 39 is a semiprime, i.e., that it is the product of two primes.

Similarly, we can define a k-almost prime as being the product of k prime numbers. For example, 40 is the 4th 4-almost prime; 40 = 5*2*2*2, the product of 4 factors.

Your task is to write a program/function that accepts two integers n and k as input and output/return the nth k-almost prime number. This is a code-golf, so the shortest program in bytes wins.

Test cases

n, k => output
n, 1 => the nth prime number
1, 1 => 2
3, 1 => 5
1, 2 => 4
3, 2 => 9
5, 3 => 27

Miscellaneous

You have to generate the primes yourself by any means other than a simple closed form, if such a closed form exists.

Conor O'Brien

Posted 2016-02-22T17:36:42.077

Reputation: 36 228

Check your math in your first example: 40 is not equal to 52222. – GamrCorps – 2016-02-22T17:39:46.833

@GamrCorps Ah, yes, thank you. – Conor O'Brien – 2016-02-22T17:40:17.987

How do you define the nth k-almost prime? What determines what order the k-almost primes are in? – GamrCorps – 2016-02-22T17:51:58.727

@GamrCorps Similar to how you determine the nth prime: you can generate a list of the first n numbers with k prime factors, sorted from least to greatest, and take the last member in that list. – Conor O'Brien – 2016-02-22T17:55:54.287

3I don't think your expression for f in terms of f[n,1] is correct, since the lists of almost-primes contain odd numbers (e.g. the last two examples, which are not expressible as the product of a power of two and a prime). (And it also says that f[n,1] == 2*f[n,1].) – 2012rcampion – 2016-02-22T18:45:20.600

@2012rcampion Oh, my mistake. It was a simple observation that was not founded by proof. – Conor O'Brien – 2016-02-22T19:11:56.820

1Why is a simple closed form banned? – CalculatorFeline – 2016-02-23T05:14:31.420

Your last paragraph doesn't make sense. There's no known closed form for the problem you are asking, and in fact there are proofs that such a closed form does not exists (when taking operations from certain sets of operations [e.g. surely no polynomial exists that produces all primes ]). – Bakuriu – 2016-02-23T11:13:41.733

@Bakuriu I don't know much about the proofs. I was merely trying to ban trivial solutions. – Conor O'Brien – 2016-02-23T12:09:51.067

What I'm saying is that there aren't trivial solutions. Just say that it must work with 1 <= n <= 100 and 1 <= k <= 10, so that storing the solutions in a table is infeasible and you are done. – Bakuriu – 2016-02-23T12:49:57.650

Answers

8

Pyth, 9 bytes

e.fqlPZQE

Explanation

          - autoassign Q = eval(input())
     PZ   -      prime_factors(Z) 
    l     -     len(^)
   q   Q  -    ^ == Q
 .f     E -  first eval(input()) of (^ for Z in range(inf))
e         - ^[-1]

Try it here!

Or try a test suite!

Blue

Posted 2016-02-22T17:36:42.077

Reputation: 26 661

5

Brachylog, 9 bytes

Beating @sundar by using half as much bytes

{~l~ḋ}ᶠ⁽t

Explanation

                    --  Input like [n,k]
{    }ᶠ⁽            --      Find the first n values which
   ~ḋ               --          have a prime decomposition
 ~l                 --          of length k
        t           --      and take the last one

Try it online!

Kroppeb

Posted 2016-02-22T17:36:42.077

Reputation: 1 558

4

Jelly, 9 bytes

ÆfL=³
ç#Ṫ

Try it online!

How it works

Ç#Ṫ    Main link. Left input: k. Right input: n.

Ç      Apply the helper link to k, k + 1, k + 2, ... until...
 #       n matches are found.
  Ṫ    Retrieve the last match.


ÆfL=³  Helper link. Left argument: k (iterator)

Æf     Yield the prime factors of k.
  L    Compute the length of the list, i.e., the number of prime factors.
   =³  Compare the result with k (left input).

Dennis

Posted 2016-02-22T17:36:42.077

Reputation: 196 637

1I'm not aware of any encoding that can save these 9 characters as 9 bytes. – Oleh Prypin – 2016-02-23T13:49:32.133

1

Jelly uses a custom encoding that represents the 256 character it understands with single bytes.

– Dennis – 2016-02-23T14:12:13.323

4

Pyke (commit 29), 8 bytes (noncompetitive)

.fPlQq)e

Explanation:

         - autoassign Q = eval_or_not(input())
.f    )  - First eval_or_not(input) of (^ for i in range(inf))
  P      -    prime_factors(i)
   l     -   len(^)
     q   -  ^==V
    Q    -   Q
       e - ^[-1]

Blue

Posted 2016-02-22T17:36:42.077

Reputation: 26 661

4

Julia, 84 78 59 57 bytes

f(n,k,i=1)=n>0?f(n-(sum(values(factor(i)))==k),k,i+1):i-1

This is a recursive function that accepts two integers and returns an integer. The approach here is to check the sum of the exponents in the prime factorization against k.

Ungolfed:

function f(n, k, i=1)
    # We initialize a counter i as a function argument.

    # Recurse while we've encountered fewer than n k-almost primes
    if n > 0
        # If the sum of the exponents in the prime factorization of i is
        # equal to k, there are k prime factors of i. We subtract a boolean
        # from n, which is implicitly cast to an integer, which will
        # decrement n if i is k-almost prime and leave it as is otherwise.
        return f(n - (sum(values(factor(i))) == k), k, i + 1)
    else
        # Otherwise we return i-1 (i will have been incremented one too
        # many times, hence the -1)
        return i - 1
    end
end

Alex A.

Posted 2016-02-22T17:36:42.077

Reputation: 23 761

3

Brachylog, 18 bytes

,1{hH&t<NḋlH;N}ⁱ⁽t

Try it online!

                      Implicit input, say [5, 3]
,1                    Append 1 to the input list. [5, 3, 1]
  {           }ⁱ⁽     Repeat this predicate the number of times given by
                        the first element of the list (5),
                        on the rest of the list [3, 1]
   hH&                Let's call the first element H
      t<N             There is a number N greater than the second element
         ḋ            Whose prime factorization's
          l           length
           H          is equal to H
            ;N        Then, pair that N with H and let that be input for
                      the next iteration
                 t    At the end of iterations, take the last N
                      This is implicitly the output

sundar - Reinstate Monica

Posted 2016-02-22T17:36:42.077

Reputation: 5 296

1

MATL, 14 bytes

:YqiZ^!XpSu1G)

Try it on MATL Online

:               % Take first input n implicitly, make range 1 to n
 Yq             % Get corresponding prime numbers (1st prime to nth prime)
   i            % Take the second input k
    Z^          % Take the k-th cartesian power of the primes list 
                % (Getting all combinations of k primes)
      !Xp       % Multiply each combination (2*2*2, 2*2*3, 2*2*5, ...)
         Su     % Sort and unique
           1G)  % Take the n-th element of the result

sundar - Reinstate Monica

Posted 2016-02-22T17:36:42.077

Reputation: 5 296

1

Mathematica, 56 51 bytes

Last@Select[Range[2^##],PrimeOmega@#==n&/.n->#2,#]&

Warning: This is theoretical. Do not run for any values>4. Replace 2^## with a more efficient expression.

CalculatorFeline

Posted 2016-02-22T17:36:42.077

Reputation: 2 608

This doesn't work for n=1. – IPoiler – 2016-02-22T23:35:26.180

Also since PrimeOmega[1] evaluates to 0, &&#>1 is redundant. – IPoiler – 2016-02-22T23:41:13.727

1

Mathematica, 53 49 Bytes

Cases[Range[2^(#2+#)],x_/;PrimeOmega@x==#2][[#]]&

Generates a list of integers based on a loose upper bound. PrimeOmega counts the prime factors with multiplicities, the k-almost prime Cases are taken from the list, and the nth member of that subset is returned.

IPoiler

Posted 2016-02-22T17:36:42.077

Reputation: 151

2^(0+##), or just 2^## works. – CalculatorFeline – 2016-02-23T05:21:38.393

@CatsAreFluffy Try 2^Sequence[1,2] to see why the latter fails. – IPoiler – 2016-02-23T15:23:50.560

1

Haskell, 88 bytes

Can probably be golfed a lot more, as I'm still a newbie to Haskell. The function q returns the number of factors of its argument, and f uses that to get take the nth element of a list made from all numbers that have k factors.

q n|n<2=0|1>0=1+q(div n ([x|x<-[2..],mod n x<1]!!0))
f n k=filter(\m->q m==k)[1..]!!n-1

flawr

Posted 2016-02-22T17:36:42.077

Reputation: 40 560

0

Python 2, 76 bytes

f=lambda n,k,p=2,c=0:c==k if p>n else f(n,k,p+1,c)if n%p else f(n/p,k,p,c+1)

Try it online!

Chas Brown

Posted 2016-02-22T17:36:42.077

Reputation: 8 959

0

Python 3, 100 bytes

This is a very simple brute force function. It checks every number starting from 2 with sympy's factorint function until it has found n k-almost primes, at which point, the function returns the nth of these.

import sympy
def a(n,k):
 z=1;c=0
 while c<n:z+=1;c+=(sum(sympy.factorint(z).values())==k)
 return z

Ungolfed:

I use sum(factorint(a).values()) because factorint returns a dictionary of factor: exponent pairs. Grabbing the values of the dictionary (the exponents) and summing them tells me how many prime factors there are and thus what k this k-almost prime is.

from sympy import factorint
def almost(n, k):
    z = 1
    count = 0
    while count < n: 
        z += 1
        if sum(factorint(a).values()) == k:
            count += 1
    return z

Sherlock9

Posted 2016-02-22T17:36:42.077

Reputation: 11 664