Calculate the prime factors

27

4

We had a prime factorization challenge a while ago, but that challenge is nearly six years old and barely meets our current requirements, so I believe it's time for a new one.

Challenge

Write a program or function that takes as input an integer greater than 1 and outputs or returns a list of its prime factors.

Rules

  • Input and output may be given by any standard method and in any standard format.
  • Duplicate factors must be included in the output.
  • The output may be in any order.
  • The input will not be less than 2 or more than 231 - 1.
  • Built-ins are allowed, but including a non-builtin solution is encouraged.

Test cases

2 -> 2
3 -> 3
4 -> 2, 2
6 -> 2, 3
8 -> 2, 2, 2
12 -> 2, 2, 3
255 -> 3, 5, 17
256 -> 2, 2, 2, 2, 2, 2, 2, 2
1001 -> 7, 11, 13
223092870 -> 2, 3, 5, 7, 11, 13, 17, 19, 23
2147483646 -> 2, 3, 3, 7, 11, 31, 151, 331
2147483647 -> 2147483647

Scoring

This is , so the shortest code in bytes wins.

ETHproductions

Posted 2016-12-26T04:00:21.613

Reputation: 47 880

2Would've been much better if you disallowed built-ins. – Buffer Over Read – 2016-12-27T00:25:50.803

2

@TheBitByte Challenges that disallow built-ins are generally looked down upon as Do X without Y challenges, especially since it's sometimes hard to tell whether a solution is technically a built-in.

– ETHproductions – 2016-12-27T00:29:49.910

1Well then, enjoy the influx of <5 byte solutions! As I write this, Pyth already does it in 1 byte. – Buffer Over Read – 2016-12-27T00:30:59.137

2@TheBitByte Think of it as a language-by-language challenge, primarily. Try to beat Python's solution, or some other language without a builtin. – isaacg – 2016-12-27T02:30:10.343

1@isaacg Well, language-by-language is a better way of looking at it, I agree. – Buffer Over Read – 2016-12-27T02:47:46.570

I can't seem to find the "standard format" meta post. Are trailing separators allowed? i.e. Input 4, Output 2,2,? – Brian J – 2016-12-27T14:31:49.297

@BrianJ I don't know that we have one. I'll allow that for this challenge. – ETHproductions – 2016-12-27T20:31:27.720

1Why do you mark my question as a duplicate of yours when your question is clearly the duplicate as it has been posted later? Please rectify this decision. – FUZxxl – 2016-12-28T18:24:48.700

1

@FUZxxl It's the community consensus that old questions should be closed as duplicates of newer ones if the newer one has a very clear spec. The main reasons for this are that old challenges tend not to be up-to-date with today's challenge specs, and newer languages can participate in newer challenges. However, as the output format is quite different for your challenge, I've reopened it.

– ETHproductions – 2016-12-28T19:15:05.397

1@ETHproductions So is my spec not very clear? Can you explain where it is unclear? You should avoid conflicts-of-interest like these where you use your permissions to close another users question over yours. – FUZxxl – 2016-12-28T20:51:02.230

@FUZxxl After talking with other users, I've decided that closing your question was not the action I should have taken. It would have been better to let the community decide whether your spec is clear enough, and thus whether or not to close it. I apologize for the ruckus I've caused. – ETHproductions – 2016-12-29T00:51:51.867

Answers

15

Pyth, 1 byte

P

I like Pyth's chances in this challenge.

isaacg

Posted 2016-12-26T04:00:21.613

Reputation: 39 268

16Until the "P" language comes along and does it in 0 bytes – downrep_nation – 2016-12-26T13:03:04.220

13

Python 2, 55 bytes

f=lambda n,k=2:n/k*[0]and(f(n,k+1),[k]+f(n/k,k))[n%k<1]

Try it online!

Dennis

Posted 2016-12-26T04:00:21.613

Reputation: 196 637

1I'd bet you've had this waiting for most of an hour... – ETHproductions – 2016-12-26T04:02:42.380

10

Python 2, 53 bytes

f=lambda n,i=2:n/i*[f]and[f(n,i+1),[i]+f(n/i)][n%i<1]

Tries each potential divisor i in turn. If i is a divisor, prepends it and restarts with n/i. Else, tries the next-highest divisor. Because divisors are checked in increasing order, only the prime ones are found.

As a program, for 55 bytes:

n=input();i=2
while~-n:
 if n%i:i+=1
 else:n/=i;print i

xnor

Posted 2016-12-26T04:00:21.613

Reputation: 115 687

8

Mathematica, 38 30 bytes

Thanks @MartinEnder for 8 bytes!

Join@@Table@@@FactorInteger@#&

JungHwan Min

Posted 2016-12-26T04:00:21.613

Reputation: 13 290

How about FactorInteger[#][[All, 1]]&? 26 bytes – David G. Stork – 2019-03-19T04:40:26.977

@DavidG.Stork that wouldn't work because it would not repeat the prime factors if the power is greater than 1. – JungHwan Min – 2019-03-19T07:16:41.473

5

Jelly, 2 bytes

Æf

Try it online!

Dennis

Posted 2016-12-26T04:00:21.613

Reputation: 196 637

5

Haskell, 48 bytes

(2%)
n%1=[]
n%m|mod m n<1=n:n%div m n|k<-n+1=k%m

Try it online! Example usage: (2%) 1001 yields [7,11,13].

Laikoni

Posted 2016-12-26T04:00:21.613

Reputation: 23 676

4

JavaScript (ES6), 44 bytes

f=(n,x=2)=>n-1?n%x?f(n,x+1):[x,...f(n/x)]:[]

Horribly inefficient due to the fact that it iterates from 2 up to every prime factor, including the last. You can cut the time complexity dramatically at the cost of 5 bytes:

f=(n,x=2)=>x*x>n?[n]:n%x?f(n,x+1):[x,...f(n/x,x)]

ETHproductions

Posted 2016-12-26T04:00:21.613

Reputation: 47 880

4

Cubix, 37 32 bytes

vs(...<..1I>(!@)s)%?w;O,s(No;^;<

Try it online! or Watch it in action.

ETHproductions

Posted 2016-12-26T04:00:21.613

Reputation: 47 880

3

Actually, 6 bytes

w`in`M

Try it online!

Explanation:

w`in`M
w       factor into primes and exponents
 `in`M  repeat each prime # of times equal to exponent

Mego

Posted 2016-12-26T04:00:21.613

Reputation: 32 998

You can probably just use o now, right? – Oliver – 2018-06-21T01:42:49.837

@Oliver Yes, but I don't usually update old answers with builtins. – Mego – 2018-06-21T02:00:29.983

3

J, 2 bytes

q:

Body must be at least 30 characters.

alephalpha

Posted 2016-12-26T04:00:21.613

Reputation: 23 988

3

MATL, 2 bytes

Yf

Try it online!

Obligatory "boring built-in answer".

James

Posted 2016-12-26T04:00:21.613

Reputation: 54 537

3

Japt, 2 bytes

Uk

A built-in k used on the input U. Also refers to a country.

Test it online!

ETHproductions

Posted 2016-12-26T04:00:21.613

Reputation: 47 880

2

tone-deaf, 3 bytes

This language is quite young and not really ready for anything major yet, but it can do prime factorization:

A/D

This will wait for user input, and then output the list of prime factors.

Kade

Posted 2016-12-26T04:00:21.613

Reputation: 7 463

2

MATLAB, 6 bytes

I think this does not require any explanation.

factor

flawr

Posted 2016-12-26T04:00:21.613

Reputation: 40 560

1

Bash + coreutils, 19 bytes

factor|sed s/.*:.//

Try it online!

Dennis

Posted 2016-12-26T04:00:21.613

Reputation: 196 637

You can shave off a byte if whitespace doesn't matter in the output using factor|sed s/.*://. Also factor|cut -d: -f2 (or factor|cut -d\ -f2 to match your current output) is the same byte length but is going to run faster and use less memory overhead. – Caleb – 2016-12-26T10:17:56.757

I'll ask the OP about whitespace. Sadly, I'd need factor|cut -d\ -f2- to eliminate the leading space, which is one byte longer. – Dennis – 2016-12-26T16:01:30.817

1

Batch, 96 bytes

@set/an=%1,f=2,r=0
:l
@set/af+=!!r,r=n%%f
@if %r%==0 echo %f%&set/an/=f
@if %n% gtr 1 goto l

Neil

Posted 2016-12-26T04:00:21.613

Reputation: 95 035

1

Pyke, 1 byte

P

Try it here!

Prime factors builtin.

Blue

Posted 2016-12-26T04:00:21.613

Reputation: 26 661

1

Hexagony, 58 bytes

Not done golfing yet, but @MartinEnder should be able to destroy this anyway

Prints out factors space-separated, with a trailing space

Golfed:

2}\..}$?i6;>(<...=.\'/})."@...>%<..'':\}$"!>~\{=\)=\}&<.\\

Laid-out:

     2 } \ . .
    } $ ? i 6 ;
   > ( < . . . =
  . \ ' / } ) . "
 @ . . . > % < . .
  ' ' : \ } $ " !
   > ~ \ { = \ )
    = \ } & < .
     \ \ . . .

Explanation coming later.

Blue

Posted 2016-12-26T04:00:21.613

Reputation: 1 986

1

Erik the Outgolfer

Posted 2016-12-26T04:00:21.613

Reputation: 38 134

1I wonder how many people will outgolf Dennis... – Erik the Outgolfer – 2016-12-26T23:28:21.970

1

CJam, 2 bytes

mf

cjam.aditsu.net/...

This is a function. Martin, it seems I was sleepy.

Erik the Outgolfer

Posted 2016-12-26T04:00:21.613

Reputation: 38 134

1

C, 92 bytes

int p(int n){for(int i=2;i<n;i++)if(n%i==0)return printf("%d, ",i)+p(n/i);printf("%d\n",n);}

Ungolfed version:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int prime(int number) {
    for (int i = 2; i < number; i++) {
        if (number % i == 0) {
            printf("%d, ", i);
            return prime(number / i); //you can golf away a few bytes by returning the sum of your recursive function and the return of printf, which is an int
        }                             //this allow you to golf a few more bytes thanks to inline calls
    }
    printf("%d\n", number);
}

int main(int argc, char **argv) {
    prime(atoi(argv[1]));
}

Valentin Mariette

Posted 2016-12-26T04:00:21.613

Reputation: 51

1

Japt, 1 byte (non-competing)

k

Try it online!

Oliver

Posted 2016-12-26T04:00:21.613

Reputation: 7 160

1

PHP, 51 bytes

for($i=2;1<$a=&$argn;)$a%$i?$i++:$a/=$i*print"$i ";

Try it online!

Jörg Hülsermann

Posted 2016-12-26T04:00:21.613

Reputation: 13 026

1

C (gcc), 51 bytes

i;f(n){for(i=2;i<=n;)n%i?i++:printf("%d ",i,n/=i);}

Try it online!

gastropner

Posted 2016-12-26T04:00:21.613

Reputation: 3 264

0

Perl 6,  77  64 bytes

{my$a=$_;.is-prime??$_!!map ->\f{|({$a%f||($a/=f)&&f}...^*!= f)},(2... *>$a)}

Try it

{my$a=$_;map ->\f{|({$a%f||($a div=f)&&f}...^ f>*)},(2... *>$a)}

Try it ( Note: it doesn't have enough time allotted to finish )


A much more performant version is slightly longer at 100 bytes.

{my$a=$_;map ->\f{|({$a.is-prime??($/=$a)&&($a=0)||$/!!($a%f||($a div=f)&&f)}...^ f>*)},(2... *>$a)}

Try it


Expanded: (64 byte version)

{
  my $a = $_;  # the input 「$_」 is read-only by default
  map
    -> \f {
      |(              # slip ( flattens into outer list )

        # generate sequence of 0 or more 「f」s
        {
          $a % f      # is it not evenly divisible

          ||          # if it is evenly divisible
          ($a div=f)  # divide it
          &&          # and
          f           # return 「f」
        }
        ...^   # keep doing that until
        f > *  # 「f」 is bigger
      )

    },

    # do that over the following list

    (2 ... * > $a) # generate a sequence from 2
                   # up to whatever the value of $a
                   # is at the time of the check
}

Brad Gilbert b2gills

Posted 2016-12-26T04:00:21.613

Reputation: 12 713

0

VB.NET, 86 bytes

Had this sitting around from some Project Euler programs. Removed the optimizations in the interest of shortness, and this is the result. Naturally, VB is very verbose, so it's fairly long. I'm not counting the leading whitespace. It can be omitted, but is easier to read with it.

This takes an integer as a parameter, and prints the prime factors with a comma after. There is a trailing comma at the end.

Sub A(a)
    For i=2To a ' VB re-evaluates a each time, so the /= at the end of the loop shortens this
        While a Mod i=0 ' this is a factor. We've grabbed primes before this, so this must be a prime factor
            Console.Write(i &",") ' output
            a/=i ' "mark" the prime as "used"
        End While
    Next
End Sub

Brian J

Posted 2016-12-26T04:00:21.613

Reputation: 653

0

Perl 6, 51 bytes

A recursive solution:

sub f(\n,\d=2){n-1??n%d??f n,d+1!!(d,|f n/d,d)!!()}

Sean

Posted 2016-12-26T04:00:21.613

Reputation: 4 136

0

Java (OpenJDK), 259 bytes

import java.util.*;interface g{static void main(String[]z){int a=new Scanner(System.in).nextInt();int b=0;int[]l={};for(int i=2;i<=a;i++){for(;a%i<1;l[b-1]=i){l=Arrays.copyOf(l,b=l.length+1);a/=i;}}for(int i=0;i<b;i++)System.out.print(l[i]+(i<b-1?", ":""));}}

Try it online!

Pavel

Posted 2016-12-26T04:00:21.613

Reputation: 8 585

Refer to this gist to see how this submission can be golfed further: https://gist.github.com/kritixilithos/fde37dc5a8ae54852aa134a6e70ea495. If you need to clarify something, feel free to ping me at the 19th byte :)

– user41805 – 2017-01-07T10:34:40.073

0

Ruby, 61 bytes

require'prime';->x{x.prime_division.flat_map{|x|[x[0]]*x[1]}}

Shortest builtin-version I could think of.

Seims

Posted 2016-12-26T04:00:21.613

Reputation: 631

0

Ruby, 48 bytes

->x{r,*c=2;0while(x%r<1?(x/=r)&&c<<r:x>=r+=1);c}

Try it online!

A little late to the party, but... why not?

G B

Posted 2016-12-26T04:00:21.613

Reputation: 11 099

0

Pyt, 1 byte

Boring built-in answer

Try it online!

mudkip201

Posted 2016-12-26T04:00:21.613

Reputation: 833

Unfortunately, the non-built-in solution doesn't work on any number containing a duplicate factor (e.g. 8) – ETHproductions – 2018-02-23T05:13:13.647

Yep, you're right. Lemme delete it. – mudkip201 – 2018-02-23T13:32:45.657

0

Gol><>, 19 bytes

IT1WP2K%ZB|:N,:M?t;

Try it online!

Explanation

IT                  < [n]     read input to n then mark cell (T)
  1WP     |         < [n m=2] from 2 onwards (m=1;while m:m++;)
     2K%ZB          < [n m+1] copy two elements, mod, break if n%m==0
           :N       < [n m] (< where n%m==0) print m with newline
             ,:M?t; < [n/m] (< new n)        divide, if not 1 redo from T else exit

Unihedron

Posted 2016-12-26T04:00:21.613

Reputation: 1 115

0

APL(NARS), 1 char, 2 bytes

π

That is...

RosLuP

Posted 2016-12-26T04:00:21.613

Reputation: 3 036

... rather short? – Jonathan Frech – 2019-03-18T09:47:49.210

@JonathanFrech yes it is short... Less than a character should be impossible... – RosLuP – 2019-03-18T10:02:22.267