Find Primes in Pi

30

3

Primes are everywhere...

they hide inside Pi

3.1415926535897932384626433832795028841971693993751

Let's get those primes!

The Challenge

Given as input an integer n>0, find out how many primes are hidden inside the first n digits of Pi

Examples

For n=3 we should search for primes in [3,1,4]. There are 2 Primes (3,31), so your code should output 2
For n=10 , the first 10 digits are [3,1,4,1,5,9,2,6,5,3] and your code should output 12 because [2, 3, 5, 31, 41, 53, 59, 653, 4159, 14159, 314159, 1592653] were hidden (and found!)

Test Cases

input -> output

1->1  
3->2  
13->14  
22->28  
42->60  
50->93

150->197  
250->363  
500->895

Rules

Your code must be able to find all primes at least for n=50
Yes, you can hardcode the first 50 digits of Pi if you like
Entries hardcoding the answers are invalid

This is .Shortest answer in bytes wins!

user73398

Posted 2017-08-24T23:43:25.827

Reputation:

6"you can hardcode the first 50 digits of Pi if you like". First problem solved! Now for the golfed primality test on up to 50-digit integers... O_o (This is a nice challenge, but solid math built-ins or libraries are probably required.) – Arnauld – 2017-08-24T23:59:24.223

1First 50 values (thanks to Mathematica): [1, 2, 2, 3, 4, 8, 9, 9, 9, 12, 12, 12, 14, 21, 24, 25, 25, 28, 28, 28, 28, 28, 28, 28, 32, 33, 33, 39, 39, 42, 44, 44, 44, 44, 44, 44, 44, 48, 51, 54, 60, 60, 64, 72, 74, 79, 82, 88, 88, 93] – totallyhuman – 2017-08-25T01:01:44.280

For math-illiterate languages: would it be against the spirit of the challenge to encode the results instead? – Arnauld – 2017-08-25T01:07:01.203

1@Arnauld the spirit of challenge is... freedom! – None – 2017-08-25T01:09:38.403

3@totallyhuman That sequence not even in OEIS yet! Time for your claim to fame? – Sanchises – 2017-08-25T07:38:58.987

3IMO allowing hardcoding of the first 50 values is detrimental to this challenge. This challenge is basically two parts, 1) try to compress the first 50 values, or 2) actually do the challenge. – JAD – 2017-08-25T08:43:50.053

1@JarkoDubbeldam That is exactly the reason I picked 50. If someone can't "actually do the challenge" or the language he/she knows can't do it, then there is a second chance which costs +50 bytes. Are you actually going to do the challenge or you are here just to downvote? – None – 2017-08-25T12:05:37.270

This has nothing to do with languages not being able to do it, Python for example should be able to properly calculate it, but there is no reason to do so, because hardcoding is that much shorter. – JAD – 2017-08-25T12:08:02.360

2Usually in these kind of challenges, where calculation becomes harder/slower/memory intensive, it is enough for the program to work theoretically, instead of setting an arbitrary cutoff and allowing hardcoding. – JAD – 2017-08-25T12:10:17.597

1Is it me, or are the entries hardcoding the answers against the rules (they only allow "Yes, you can hardcode the first 50 digits of Pi if you like")? – TripeHound – 2017-08-25T15:25:45.887

@TripeHound You are absolutely right! Entries hardcoding the answers are invalid – None – 2017-08-25T15:43:25.397

3

@BillSteihn Updating rules after there are several answers is against the spirit of this website. Have you posted this question in the Sandbox? You would have had feedback really early that hardcoded answers would come in.

– Olivier Grégoire – 2017-08-25T15:58:44.577

@BillSteihn also, this should say: distinct primes. – Giuseppe – 2017-08-25T16:26:49.267

Answers

20

05AB1E,  10  8 bytes

-2 bytes thanks to Adnan (p vectorises)

<žsþŒÙpO

Try it online! (will work up to n=98413 but will be very slow even for n=50 due to the need to test such large numbers for primality - TIO times out at 60 seconds for n=50.)

How?

<žsþŒÙpO - implicitly push input, n
<        - decrement = n-1
 žs      - pi to that many decimal places (i.e. to n digits)
   þ     - only the digits (get rid of the decimal point)
    Π   - all sublists
     Ù   - unique values
      p  - is prime? (vectorises) 1 if so, 0 otherwise
       O - sum
         - implicitly print the top of the stack

Jonathan Allan

Posted 2017-08-24T23:43:25.827

Reputation: 67 804

<žsþŒÙpO should work for 8 bytes – Adnan – 2017-08-25T00:21:24.897

Ah yeah p vectorises thanks! – Jonathan Allan – 2017-08-25T00:22:52.887

2Yes! Finally a very short code golf answer that I actually understand! :D – Fabian Röling – 2017-08-26T09:22:28.430

11

Mathematica, 76 bytes

Tr[1^Union@Select[FromDigits/@Subsequences@#&@@RealDigits[Pi,10,#],PrimeQ]]&

J42161217

Posted 2017-08-24T23:43:25.827

Reputation: 15 931

Oh, no fair, I'm not familiar with Mathematica golf. :P (+1) – totallyhuman – 2017-08-25T00:50:45.763

@totallyhuman We posted this at the same time. this is so weird! – J42161217 – 2017-08-25T00:52:10.107

I golfed my answer using some of the syntactical tricks but I kept the functions I used before. I hope you don't mind. – totallyhuman – 2017-08-25T01:09:19.703

Tr[1^...] That is a clever way of finding the length of the list, nice! – numbermaniac – 2017-08-28T08:22:10.220

6

Mathematica, 104 97 90 bytes

Length@DeleteDuplicates@Select[FromDigits/@Subsequences@First@RealDigits[Pi,10,#],PrimeQ]&

Hahahaha, I managed to make this work. I have no idea how to use Mathematica. XD

Input:

[50]

totallyhuman

Posted 2017-08-24T23:43:25.827

Reputation: 15 378

1you posted some seconds ahead of me. and our answers are very much alike! +1 – J42161217 – 2017-08-25T00:57:28.233

Are you sure about the numbers you just posted (double check the rounding of the digits) I see slightly different results using Python and sympy

– Jonathan Allan – 2017-08-25T01:05:13.043

@JonathanAllan 50 96 The OP says 50 digits contain 93 primes, so Sympy's accuracy might be off..? – totallyhuman – 2017-08-25T01:06:38.527

@JonathanAllan Is Sympy using a probabilistic or a deterministic primality test? (Same question for Mathematica's PrimeQ.) – Arnauld – 2017-08-25T01:11:25.957

@Arnauld good point, not sure. – Jonathan Allan – 2017-08-25T01:13:29.693

First deviation is at n=12: sympy's pi yields 3.14159265359 and finds 15 primes (rather than the 12 reported by Mathematica): [2, 3, 5, 31, 41, 53, 59, 359, 653, 4159, 14159, 314159, 1592653, 4159265359, 314159265359] – Jonathan Allan – 2017-08-25T01:15:50.240

^... I see that the evalf of sympy means rounding occurs :/ – Jonathan Allan – 2017-08-25T01:18:37.417

@JonathanAllan which are the 15 sympy's primes? – None – 2017-08-25T01:18:54.517

@BillSteihn I listed them above - but I see that pi should be 3.14159265358 not 3.14159265359 (last digit). I thought adding 1 to the digit length and truncating would have avoided that, but I was wrong. – Jonathan Allan – 2017-08-25T01:20:21.903

@Downvoter I'm afraid I must sincerely ask you. Why? ;-; – totallyhuman – 2017-08-26T16:41:56.793

3

Python 3, 274 237 207 194 189 bytes

-37 bytes thanks to Wheat Wizard! -14 bytes thanks to Mr.Xcoder.

Hardcodes the first 50 digits of pi but manually computes everything else.

x=int(input());l="31415926535897932384626433832795028841971693993751"[:x]
print(sum(all(i%m for m in range(2,i))for i in{int(i)for w in range(x)for i in[l[j:j-~w]for j in range(x-w)]}-{1}))

Try it online!

totallyhuman

Posted 2017-08-24T23:43:25.827

Reputation: 15 378

2You could save a bunch of bytes – Post Rock Garf Hunter – 2017-08-25T17:40:53.737

l=list("31415...) should save ~40 chars. And that change lets you replace map(str,i) with just i. – AShelly – 2017-08-25T17:54:12.007

You could save another bunch of bytes (200)! – Mr. Xcoder – 2017-08-25T18:01:31.427

195 bytes by removing some strange code. – Mr. Xcoder – 2017-08-25T18:03:43.250

194 bytes by declaring len(l) – Mr. Xcoder – 2017-08-25T18:05:22.807

1

R, 156 123 bytes

cat(cumsum(c(1,1,0,1,1,4,1,0,0,3,0,0,2,7,3,1,0,3,0,0,0,0,0,0,4,1,0,6,0,3,2,0,0,0,0,0,0,4,3,3,6,0,4,8,2,5,3,6,0,5))[scan()])

Super interesting solution. Working on a proper one.

Saved 33 bytes thanks to @Giuseppe.

R (+ numbers and gmp), 198 bytes

function(n,x=unique(gmp::as.bigz(unlist(sapply(1:n,function(x)substring(gsub("[.]","",numbers::dropletPi(50)),x,x:n))))))min(length(x),sum(sapply(sapply(x[x>0&!is.na(x)],gmp::factorize),length)==1))

Proper solution. Takes n as input.

Uses numbers::dropletPi(50) to generate the first 50 decimal places of pi. gsub removes the decimal point. substring takes every possible substring (surprise surprise) of pi up to n.

The returned list is flattened and converted to gmp's bigz format. This format is required to store integers of length 50. unique takes the unique values of that vector. This result gets stored in x.

Then we check for primality. This is tricky, because there are a bunch of edge-cases and annoyances:

  • For high n, there is a 0 in pi. This leads to substrings with a leading zero. as.bigz produces NAs with that, which have to be removed.

  • On a similar note, the substring "0" will crash gmp::factorize, so has to be removed as well.

  • For n=1, x = 3. Which in itself is ok, but the bigz representation of 3 is iterable, so sapply will get confused and report 16 primes. To this end we take the minimum of the length of the vector x, and the amount of primes in it.

  • gmp::isprime can't seem to reliably handle the large numbers reliably. So instead we use gmp::factorize and check of the length of the output is 1.

So in all, we remove 0 and NA from x. We factorize all of x and check for the length. We count the number of occurrences of 1 and return the min(occurences, length(x)).

JAD

Posted 2017-08-24T23:43:25.827

Reputation: 2 898

there you are! Now let's see if someone out there can outgolf this with a more interesting solution. could be you! – None – 2017-08-25T12:25:41.617

use cumsum(c(1,1,0,1,1,4,1,0,0,3,0,0,2,7,3,1,0,3,0,0,0,0,0,0,4,1,0,6,0,3,2,0,0,0,0,0,0,4,3,3,6,0,4,8,2,5,3,6,0,5)) instead of your vector for 123 bytes :) – Giuseppe – 2017-08-25T13:05:36.067

@Giuseppe Nice one. That 'compression' will definitely beat any legit solution. – JAD – 2017-08-25T13:08:56.583

I think it's impossible in R without hardcoding or introducing another package since R has only 32-bit ints, which will certainly not represent a 50-digit integer. – Giuseppe – 2017-08-25T13:14:12.290

The solution I am currently working on uses both numbers and gmp. The problem is getting a 50 digit representation of pi, along with primality tests for such values. numbers::dropletPi handles the first, but its isPrime is unsatisfactory. Same for gmp::isprime. So I am currently using gmp::factorize and checking for length()==1. However, for n=1 we would get a bigz representation of 3, which is iterable in itself (because of how bigz works) so it throws off sapply. – JAD – 2017-08-25T13:17:37.073

Maybe this can be turned into a recursive solution, removing one of the sapply calls in the definition of x. I seem to be thinking a lot in terms of recursion lately.... – JAD – 2017-08-25T13:34:46.743

1

Yeah, I may think about this some more as well. 82 hardcoded bytes

– Giuseppe – 2017-08-25T14:06:24.500

Entries hardcoding the answers are invalid. You may only hardcode the first 50 digits of Pi. I think you should remove the first answer – None – 2017-08-25T15:47:11.990

161 bytes – Giuseppe – 2017-08-25T16:32:52.940

@Giuseppe I can't run this yet, but by the looks of it, would "028" and "28" be counted as duplicates? I don't see anything that accounts for this – JAD – 2017-08-25T17:11:19.593

@JarkoDubbeldam you're right, it'll crash on that, and for 0 as well... – Giuseppe – 2017-08-25T17:32:50.897

161 bytes, again (I actually tested this time :P) – Giuseppe – 2017-08-25T18:04:05.820

0

Jelly, 59 32 bytes

-27 bytes thanks to Erik the Outgolfer.

“!⁶⁷¬,6½ạEC.wʠ€Ẉ!+Ẉfṭ¡’Ṿḣ³ẆVQÆPS

Try it online!

Explanation

“...’Ṿḣ³ẆVQÆPS

“...’           compressed string that evaluates to first 50 digits of pi (314159...)
     Ṿ          uneval; stringify
      ḣ³        first n characters of the string where n is the first command-line argument
        Ẇ       all sublists
         V      convert all elements to integers
          Q     deduplicate
           ÆP   convert all prime elements to 1 and others to 0
             S  sum

totallyhuman

Posted 2017-08-24T23:43:25.827

Reputation: 15 378

Why did you spam this with answers? – Zacharý – 2017-08-25T22:54:07.187

Because nobody else was answering, and I hit rep cap anyways. :P – totallyhuman – 2017-08-25T23:19:44.403