Counting +1 primes

Define that the natural number p is a +1 prime of the natural number n if p is a prime number and the standard binary representation (i.e., without leading zeroes) of p can be obtained by adding (i.e., prepending, appending or inserting) a single 1 to the standard binary representation of n.

For example, the binary representation of 17 is 100012. The distinct natural numbers that can be formed by adding a 1 to 100012 are 1100012 or 49, 1010012 or 41, 1001012 or 37, and 1000112 or 35.

Among these, 41 and 37 are prime numbers, so 17 has two +1 primes.

Write a program or function that accepts a strictly positive integer n as input and prints or returns the number of distinct +1 primes of n.

Input and output must either be an integer, or its decimal or unary string representation.

Standard rules apply.

Test cases

Input:  4
Output: 0

Input:  1
Output: 1

Input:  17
Output: 2

Input:  33
Output: 3

Input:  553
Output: 4

Input:  3273
Output: 5

Input:  4145
Output: 6

Input:  4109
Output: 7

Input:  196869
Output: 8
• Cool! If I had time tonight I would answer right now Nov 7 '15 at 1:09

JavaScript ES6, 141 bytes 143147160

Saves 13 bytes, thanks to @Naouak

n=>[...t=n.toString(2)].map((l,i)=>t.slice(0,v=i+1)+1+t.slice(v)).filter((l,i,a)=>a.indexOf(l)==i&&(p=(n,c)=>n%c&&c>n-2||p(n,++c))('0b'+l,2))

Similar method to my TeaScript answer, uses RegExp (you heard me right) to check for primes.

Ungolfed

n=>
[...t = n.toString(2)]                  // To binary
.map((l,i)=>                            // Make cycles
t.slice(0, v = i+1)
+ 1
+ t.slice(v)
).filter((l,i,a)=>
a.indexOf(l) == i &&  // Remove Duplicates
(p=(n,c)=>            // Prime checking
n % c &&
c > n - 2 ||
p(n,++c)
)('0b'+l,2)
).length
• I think you can shorten a bit checking prime like this: (p=(n,c)=>n%c!=0?c>=n-1?1:p(n,++c):0)('0b'+l,2) instead of !Array(+('0b'+l)+1).join(1).match(/^1?$|^(11+?)\1+$/) Nov 7 '15 at 19:19
• @Naouak Awesome that saves 13 bytes! :) Nov 7 '15 at 19:22

Pyth, 20 bytes

s/LPd{mij\1c.BQ]d2hQ

Test Suite

s/LPd{mij\1c.BQ]d2hQ
Q = eval(input())
m           hQ    For insertion position in [0 ... Q]
.BQ         Convert Q to binary string
c   ]d       Chop at insertion position
j\1             Join on '1'
i         2      Convert to integer
{                  Deduplicate
/LPd                   Map each number to the number of times it occurs in its
prime factorization, e.g. whether or not it is prime.
s                       Sum and print.
• Huh, "deduplicate" is actually a word. Nov 8 '15 at 4:54

TeaScript, 22 bytes

TeaScript is starting to look like APL... The special characters are converted to longer, commonly repeated sequences

Online interpreter be sure to check "Inputs are numbers."

Explanation && Ungolfed

xT(2)sm(#P(xT(2)E(i+1,1),2))d()F($P)n xT(2) // Take input, convert to binary sm(# // Loop over input P( // Convert to decimal... xT(2) // Input to binary E(i+1,1) // Inset 1 into (above) at current index in loop ,2) )d() // Remove duplicates F($P)      // Filter items that aren't prime
n          // Grab length.
• It's 31 bytes, by the way, using gedit on Xubuntu Nov 7 '15 at 17:41
• It's 31 bytes with UTF-8 encoding, but 22 bytes with ISO-8859-1. Nov 7 '15 at 22:40

Julia, 55 52 bytes

n->sum(isprime,∪(2n+(k=2.^(0:endof(bin(n))))-n%k))

k=2.^(0:endof(bin(n))) generates an array containing the powers of 2 from 1 to the highest power less than n. 2n+k-n%k then uses array operations to determine all of the possible "+1 numbers". (equivalent to union, which does the same thing as unique in this situation) removes the repeat values. Then sum(isprime,) counts the number of primes on the list.

CJam, 26 bytes

Not a winner, but it beats the existing CJam answers quite solidly and it's the first time I got to use the 0.6.5 command e\.

1ri2b+_,{_)e\_}%_&{2bmp},,

Test it here.

Explanation

1       e# Push a 1 (this is the 1 we'll be inserting everywhere).
ri      e# Read input and convert to integer.
2b      e# Convert to base 2.
+       e# Prepend the 1.
_,      e# Duplicate and get the number of bits N.
{       e# Map this block over i from 0 to N-1...
_)    e#   Create a copy and increment to i+1.
e\    e#   Swap the bits at positions i and i+1, moving the 1 one step through the array.
_     e#   Duplicate so we keep this version on the stack.
}%
_&      e# Remove duplicates via set intersection with itself.
{       e# Filter the remaining digit lists based on this block...
2b    e#   Convert bits back to an integer.
mp    e#   Test for primality.
},
,       e# Get the length of the remaining list.

One thing worth noting is that we swap the bits at 0 and 1 before making the first copy, so we lose the original array with the 1 prepended to the front. However, the input is always positive, so the leading digit will always be one. That means after prepending another one, the digit list will always start with [1 1 ...] so the first swap will be a no-op in any case.

Minkolang 0.11, 54 52 bytes

n1(2*d0c,)(0c1c$%$r2*1c*1c++1g2:d1G)rxSI1-[0g2M+]N.

Explanation

n             Get integer from input (let's call it n)
1(       )    Get the smallest power of 2 (say, k) greater than input (starting with 1)
2*d         Multiply by 2 and duplicate
0c,     Copy n and see if it's greater (while loop breaks on 0)

(0c1c$% Copy n, copy k, and divmod (pushes n//k, n%k)$r                     Swap top two elements
2*                   Multiply by 2
1c*                Copy k and multiply
1g2:        Get k and divide by 2
d1G)    Duplicate and put one copy back in its former place

rx            Reverse and dump (dumps n and top of stack is now 0)
S             Remove duplicates
I1-[     ]    Check each element for primality
0g        Get potential prime from bottom of stack
2M      1 if prime, 0 otherwise
+     Add (this is why I didn't dump the left-over 0 earlier)
N.            Output as integer and stop.
• I'm always excited to say another Minkolang version. Nov 7 '15 at 19:52

Mathematica, 87 bytes

Union[#~FromDigits~2&/@StringReplaceList[#~IntegerString~2,a_:>a<>"1"]]~Count~_?PrimeQ&

Julia, 110108104 87 bytes

n->sum(i->isprime(parse(Int,i,2)),(b=bin(n);∪([b[[1:i;1;i+1:end]]for i=1:endof(b)])))

This creates an unnamed function that accepts and integer and returns an integer. To call it, give it a name, e.g. f=n->....

Ungolfed:

function f(n::Integer)
# Get the binary representation of n as a string
b = bin(n)

# Construct an array consisting of binary strings with
# a one prepended, appended, and each insertion
x = [b[[1:i; 1; i+1:end]] for i = 1:endof(b)]

# Count the number of primes
c = sum(i -> isprime(parse(Int, i, 2)), unique(x))

return c
end

Saved 17 bytes thanks to Glen O!

• bin has to start with a 1, so you don't need to separately handle "1"b. And when i=length(b), you'll have b[i+1:end] equivalent to "", so no need for that entry (just need to handle b=bin(n) at some point). And sum will do the same thing as count for two fewer bytes. Nov 7 '15 at 14:54
• Also, since you're going to use a range over the length of b anyway, might as well get it with a bit of a trick - b=bin(n)[s=1:end] and then for i=s for the comprehension. Nov 7 '15 at 17:44
• You can also save another byte by using the fact that the first bit in bin should be 1, and you'll get this: n->sum(i->isprime(parse(Int,i,2)),(b=bin(n);unique([b[[1:i;1;i+1:end]]for i=1:endof(b)]))) - this brings the count down to 90 bytes. Nov 7 '15 at 17:52
• In fact, take off one more byte, by replacing unique with union - it will do the same thing, if given only one array as input. Or better yet, instead of union. Nov 7 '15 at 18:01
• @GlenO You're the master. Thank you, 先生! Nov 7 '15 at 19:45

CJam, 58 bytes

L{:TQ\=A+Q\+TWe\-2<s:~2b}q~2b0+:Q,(%{:BLe=!{B+:L}&}%~:mp:+

This took me a day, and this was my 4th iteration.

Japt-x, 14 11 bytes

Æ¤iX1Ãâ ®Íj
Æ¤iX1Ãâ ®Íj     :Implicit input of integer U
Æ               :Map each X in the range [0,U)
¤              :  Convert U to binary string
iX1           :  Insert "1" at 0-based index X
Ã          :End map
â         :Deduplicate
®       :Map
Í      :  Convert to decimal
j     :  Is prime?
:Implicit output of array sum

PHP, 145 bytes

function($n){for($b=base_convert;++$i<=strlen($s=$b($n,10,2));$r+=!$s[$i]&$k<=$j) for($j=1;($k=$b(substr_replace($s,1,$i,0),2,10))%++$j;);echo$r;}

Try it online!

Husk, 20 bytes

←#ṗumȯḋJ1`Cḋ¹oSze↔ŀḋ

Try it online!

Barely got away with a single byte.

Husk, 21 bytes

#oṗḋumJ1§z§e↑↓oΘŀo¢;ḋ

Try it online!

There's probably a much shorter way to do this.

• Down to 18 bytes now... Nov 7 '20 at 20:13

Husk, 18 17 bytes

#oṗḋużoJ1eḣḋ¹mtṫḋ

Try it online!

Different approach to Razetime's Husk answer, saving 2 3 bytes.

How?

#oṗḋużoJ1eḣḋ¹mtṫḋ
#o                      # how many
ṗ                     # prime numbers
ḋ                    # among numbers formed by binary digits of
u                   # unique elements of
żo                 # zip together 2 lists of lists,
J1e              # joining each pair with the digit '1'
ḣḋ¹           # list 1:
ḣ             # all prefixes of
ḋ¹           # binary digits of input
mtṫḋ       # list 2:
mt         # remove first element from
ṫ        # all suffixes of
ḋ       # binary digits of input
• Very nicely done. Nov 8 '20 at 3:48

Python 2, 103 bytes

lambda n:sum(all(i%j for j in range(2,i))for i in{n%2**i+((n>>i)*2+1<<i)for i in range(len(bin(n))-2)})

Try it online!