g | x | w | all
Bytes Lang Time Link
005Vyxal 3240919T183853ZGinger
033Ruby rprime240908T161847ZJordan
003Husk240908T064229Zint 21h
002Thunno 2 L230709T090034ZThe Thon
055Python 2220717T224718ZDeadcode
006Japt230315T150831ZShaggy
004Stax230315T145731Zemirps
nan230315T115314ZThe Thon
022Retina 0.8.2160923T204646Zmbomb007
002Vyxal l220717T194947ZDeadcode
049C clang220719T172512Zc--
032Regex Perl / Java / PCRE210327T210623ZDeadcode
165Python 3210407T201214ZSymmetr1
042Haskell210406T225019ZDonat
012APL Dyalog Unicode210331T164809ZAndrew O
085Kotlin180331T201631ZJohnWell
017Add++180331T161718Zcaird co
150APL NARS180118T185113Zuser5898
006Pyth180119T023511Zericesch
003Pyt180116T223607Zmudkip20
009MATL160923T220303ZLuis Men
138pure BASH180117T135039Zuser1921
040Python 3180118T005546ZSandeep
077C# 5.0180116T212044ZAriel Be
013APL Dyalog Unicode180117T105124ZAdá
084Java 8170512T142017ZKevin Cr
031Perl 6180117T004359ZSean
060Racket160925T034915Zrnso
043JavaScript ES6160923T220753ZETHprodu
092PHP160923T225158ZMario
003Actually160925T063151ZSherlock
015PARI/GP160925T050016Zalephalp
033Perl160923T212435ZTon Hosp
010Actually160925T032306ZSherlock
006Jelly160923T215612ZJonathan
035q160924T201211Zreuben t
102Java 7160924T190634ZNumberkn
006Jelly160924T190518ZDennis
043JavaScript ES6160923T212256ZHedi
003Jelly160923T213541ZJonathan
nanMediaWiki templates with ParserFunctions160924T173432ZDuhHello
010Actually160924T120841ZSherlock
003Jelly160924T015034ZDennis
045Python 2160923T232521Zxnor
005Jelly160923T202432ZLuis Men
060Matlab160923T215032Zptev
005MATL160923T200342ZDJMcMayh
157C#160923T210111ZYodle
00305AB1E160923T204702ZDennis
00505AB1E160923T203745ZAdnan
098PowerShell v2+160923T203216ZAdmBorkB
006Pyke160923T195254ZBlue
030Bash + coreutils160923T201952ZDigital
006Pyth160923T201456ZMaltysen

Vyxal 3, 5 bytes

ÞPᶤ⁰>

Vyxal It Online!

  ᶤ     Index of the first item
ÞP      in the set of all primes
   ⁰>   which is greater than the input

Ruby -rprime, 33 bytes

->n{Prime.take_while{_1<=n}.size}

Attempt This Online!

Husk, 3 bytes

#ṗḣ

Try it online!

A very simple solution. Commented:

#    // count
 ṗ   // all primes
  ḣ  // in the range [1...input number]

Thunno 2 L, 2 bytes

Try it online!

Port of Dennis's 05AB1E answer.

Explanation

wƑ  # Implicit input
w   # Factorial of input
 Ƒ  # Unique prime factors
    # Implicit output of length

Python 2, 55 bytes

n=input()
s=p=i=1
while i<n:p*=i*i;i+=1;s+=p%i
print~-s

Try it online!

A programification of the below. The Python 3 equivalent is 62 bytes.

Note that although xnor's recursive answer outgolfs this at 45 bytes, it cannot handle an input of 999 or greater, due to Python's recursion limit: Try it online! - this limit can be increased, though: Try it online!

This 55 byte solution can go well beyond that. For example, all inputs up to 3000: Try it online!

Python 3.8+, 57 54 bytes

lambda n,p=1:sum([(p:=p*i*i)%-~i for i in range(1,n)])

Try it online! / Attempt This Online!

A lambdafication of the below, taking advantage of the := operator.

Although xnor's recursive answer outgolfs this at 46 bytes when ported to Python 3, it still can't handle an input of 999 or greater: Try it online! - this limit can be increased: Attempt This Online!

Python, 59 bytes

def P(n):
 s=p=i=1
 while i<n:p*=i*i;i+=1;s+=p%i
 return~-s

Try it online! - Python 2
Try it online! - Python 3

Based on miles's answer to "Is it a super-prime?".

This exploits Wilson's theorem and Python's arbitrary precision integers to count primes. At each iteration of the loop, with \$i\in[2,n]\$, it calculates \${(i-1)^2}!\pmod i\$. This \$\equiv 1\$ when \$i\$ is prime and \$\equiv 0\$ otherwise. The squaring is done to compensate for the fact that \$4\$ is the only exception, with \$(4-1)!\equiv 2\pmod 4\$, but \$(4-1)^2!\equiv 0\pmod 4\$. Note that squaring also changes the modulus from \$-1\$ to \$1\$ for prime \$i\$.

If not for the exception at i=4, we could have done

while i<n:p*=i;i+=1;s+=-p%i

For 1 byte less, because Python returns a positive result when taking a negative number modulo a positive number.

Japt, 6 bytes

Êk â Ê

Try it

Êk â Ê     :Implicit input of integer
Ê          :Factorial
 k         :Prime factors
   â       :Deduplicate
     Ê     :Length

Stax, 4 bytes

Ü:÷/

Run and debug it

Same approach as many other answers. This is a packed stax program which unpacks to the following 5 bytes:

|F:F%

Run and debug it

Explanation

|F    # factorial of input
  :F  # distinct prime factors
    % # length

Thunno, \$ 4 \log_{256}(96) \approx \$ 3.29 bytes

FAFL

Attempt This Online!

Port of Dennis's 05AB1E answer.

Explanation

F       # Push the factorial of the input
 AF     # Get the unique prime factors
   L    # Push the length of the list

Retina 0.8.2, 31 22 bytes

Byte count assumes ISO 8859-1 encoding.

.+
$*
(?!(..+)\1+$).\B

Try it online - Input much larger than 2800 either times out or runs out of memory.

References:

Martin's range generator

Martin's prime checker

Vyxal l, 2 bytes

¡Ǐ

Try it Online! - test cases only

This is the same as the 3 byte answer below except the length is taken by the l flag rather than an L element.

Vyxal, 3 bytes

¡ǏL

Try it Online!

¡  # Factorial
Ǐ  # Prime factorization - list of distinct prime factors
L  # Length of that list

Direct port of Dennis's 05AB1E solution, which is the accepted answer, so one would infer that it meets the challenge's specifications.

The element could be considered a "prime-counting function", even though it counts the distinct prime factors of the input, not the primes less than or equal to the input. The solution using that built-in is 2 bytes:

¡†

Try it Online!

¡  # Factorial
†  # Number of distinct prime factors

Vyxal, 9 bytes

ɾ⟑‹¡²$%;∑

Try it Online!

With no factorization built-ins, instead using Wilson's theorem:

ɾ  # Inclusive One Range (from 1 to input)
⟑  # Apply lambda to each individual list item:
‹  # Subtract 1
¡  # Factorial
²  # Square
$  # Swap 
%  # Modulo - this will be (n-1)!² % n
;  # Close lambda
∑  # Sum

With the r flag this is 8 bytes: Try it Online!
With the rs flags this is 6 bytes: Try it Online!

C (clang), 49 bytes

p(n,i){for(i=n;--i&&n%i;);return--n?p(n)+!--i:0;}

Assumes n is positive.

Try it online!

Regex (Perl / Java / PCRE), 32 bytes

((?=(\2?+x*?(?!(xx+)\3+$))xx)x)*

Try it online! - Perl
Try it online! - Java
Try it online! - PCRE

Takes its input in unary, as a string of x characters whose length represents the number. Returns its output as the length of the match.

        # tail = N = input value; no anchor needed, as every value returns a match
# Count the number of primes <= N, from the largest to the smallest prime.
(       # J = 0
    (?=
        # \2 starts at zero, and on each subsequent iteration, contains the difference
        # N-P-(J-1) where P is the previously found prime, and J is the running total of
        # our prime count.
        (
            \2?+           # Start from the previous value of \2, atomically so that it
                           # can't be backtracked and started again from zero if the
                           # following fails to match. This will make tail = P-1, where
                           # P is the previously found prime.
            x*?            # Advance as little as necessary to make the following match,
                           # and add this to \2, while subtracting it from tail.
            (?!(xx+)\3+$)  # Assert tail is not composite; note that this needs to be
                           # inside group \2 for it to work in PCRE1 and older versions of
                           # PCRE2, which atomicize groups that have nested backreferences
        )
        xx                 # Assert tail is prime by eliminating the false positives 0, 1
    )
    x   # J += 1; tail -= 1
)*      # Iterate zero or more times, until there are no more smaller primes
# Return J as our match

Regex (Pythonregex / Ruby), 41 39 bytes

((?=(?=(\3?))(\2x*?(?!(xx+)\4+$))xx)x)*

Try it online! - Python import regex
Try it online! - Ruby

This is a port of the Perl/Java/PCRE regex to flavors that have no support for nested backreferences. Python's built-in re module does not even support forward backreferences, so for Python this requires regex.

        # tail = N = input value; no anchor needed, as every value returns a match
# Count the number of primes <= N, from the largest to the smallest prime.
(       # J = 0
    (?=
        # \2 starts at zero, and on each subsequent iteration, contains the difference
        # N-P-(J-1) where P is the previously found prime, and J is the running total of
        # our prime count.
        (?=(\3?))          # \2 = \3 (or 0 if \3 is unset), to make up for the lack of
                           #      nested backreferences
        (
            \2             # Start from the previous value of \3 (as copied into \2).
                           # This will make tail = P-1, where P is the previously found
                           # prime.
            x*?            # Advance as little as necessary to make the following match,
                           # and add this to \3, while subtracting it from tail.
            (?!(xx+)\4+$)  # Assert tail is not composite; note that this needs to be
                           # inside group \3 for it to work in PCRE1 and older versions of
                           # PCRE2, which atomicize groups that have nested backreferences
        )
        xx                 # Assert tail is prime by eliminating the false positives 0, 1
    )
    x   # J += 1; tail -= 1
)*      # Iterate zero or more times, until there are no more smaller primes
# Return J as our match

Regex (.NET), 35 bytes

((?=((?>\2?)x*?(?!(xx+)\3+$))xx)x)*

Try it online!

This is a direct port of the Perl/Java/PCRE regex.

Regex (.NET), 35 bytes

^(?=(x*?(?!(xx+)\2+$)x)*x)(?<-1>x)*

Try it online!

This uses the .NET feature of balanced groups to do the counting. It does not return a value for zero, but doing so only requires +1 byte (36 bytes):

^(?=(x*?(?!(xx+)\2+$)x)*x|)(?<-1>x)*

Try it online!

^                      # tail = N = input number
(?=
    (
        x*?            # Advance as little as necessary to make the following match
        (?!(xx+)\3+$)  # Assert tail is not composite
        x              # Eliminate the false primality positive of 0, and advance forward
                       # so that the next prime can be found (if we didn't do this, the
                       # regex engine would exit the loop due to a zero-width match)
    )*                 # Every time this loop matches an iteration, the capture group 1
                       # match is pushed onto the stack. This (balanced groups) is how we
                       # count the number of primes.
    x                  # Eliminate the false primality positive of 1
|                      # Allow us to return a value of 0 for N=0
)
(?<-1>x)*              # Pop all of the group 2 captures off the stack, doing head += 1
                       # for each one. This gives us our return value match.

I strongly suspect this function is impossible to implement in ECMAScript regex, even with the addition of (?*) or (?<=) / (?<!). There doesn't seem to be room to multiplex the count and the current prime into a single tail variable, but I don't know if this can be proved.

Only one variable can be modified within a loop, such that must decrease by at least 1 on every step – and only \$O(n)\$ space is available; no variable may contain a value larger than \$n\$, and the language has no concept of arrays (although it is possible to take them as immutable input), only scalar variables (i.e. capture groups and the cursor position).

So it would seem that calculating this function would require \$O({n^2\over log(n)})\$ scratch space, to multiplex the iteration count and current prime into a single number. While multiple loops in a row would be able to get closer to \$\pi(n)\$ than a single loop, the number of such loops could only be a constant; it seems that it would need to be able to grow with \$n\$ to be able to actually asymptotically calculate \$\pi(n)\$. And a nested loop would still have to distill all the information gained by its innermost loop into a single number \$\le n\$.

But these things are just indications and vague evidence, not a proof. I have set a bounty regarding this open question.

Python 3, 197 165 bytes

Removed the need for the import math by checking every divisor of i besides i itself, though mathematically only checking up to the square root is required.

def c(x):
    p=0
    for i in range(2,x+1):
        P=1
        for d in range(1,i):
            if i%d==0 and d!=1:
                P=0
        p+=1*P
    return p

Original:

import math
def c(x):
    p=0
    for i in range(2,x+1):
        P=1
        for d in range(1,round(math.sqrt(i))+1):
            if i%d==0 and d!=1:
                P=0
        p+=1*P
    return p

Haskell, 46 42 bytes

p n=sum[mod(product[1..i-1]^2)i|i<-[1..n]]

Try it online!

APL (Dyalog Unicode), 12 bytes

(≢⊢~∘.×⍨)1↓⍳
 ≢ ⍝ tally
  ⊢~ ⍝ index values not in matrix of composite numbers
    ∘.×⍨ ⍝ outer product of positive integers with themselves
        1↓⍳ ⍝ range from 1–n less the first element

h/t @adám

Try it online!

Kotlin, 85 bytes

{n:Int->var r=0
for(i in 2..n){var t=1
for(p in 2..i/2)if(i%p==0){t--
break}
r+=t}
r}

Try it online!

Try lambda for first time as saved 16 bytes.

Kotlin, 101 bytes

fun c(n:Int):Int{var r=0
for(i in 2..n){var t=1
for(p in 2..i/2)if(i%p==0){t--
break}
r+=t}
return r}

Try it online!

Add++, 17 bytes

L,RB*f0b]@bLA1=!*

Try it online!

APL NARS, 150 bytes

∇r←g n;h;i;k
i←0⋄h←1+⍳n-1⋄→B
A:k←i⊃h⋄h←k∪(0≠k∣h)/h
B:→A×⍳(⍴h)≥i+←1
r←⍴h
∇

this would be the "Crivello di Eratostene" or something as that.

If h=2..n

In the first iteration of the loop eliminate each multiple of 2 in h except 2

in the second iteration of the loop eliminate each multiple of 3 in h except 3

...

return the number of final element of h.(in h primes return ⍴h)

  g¨1 2 5
0  1  3 
  g 20000
2262

As note negative for the question: There would be a range limit for the arg of the function; something as 1..20000 and each answer would indicate the range the argument has to be for to be safe to pass to the function (without one seg fault in the code, without one memory insufficient for the program, without one incorrect value return as result )

Pyth, 6 bytes

l{P.!Q

Explanation follows:

   .!Q Factorial of input
  P    List primes of factorial with multiplicity
 {     Remove duplicates formed by said multiplicity
l      Length of deduplicated list

Pyt, 3 bytes

řṗƩ

Explanation:

ř         Push [1,2,...,input]
 ṗ        Elementwise isPrime(k)
  Ʃ       Sum of array (autoconverts booleans to 0/1)

Try it online!

MATL, 9 bytes

This avoids prime-factor decomposition. Its complexity is O(n²).

:t!\~s2=s

Try it online!

:     % Range [1 2 ... n] (row vector)
t!    % Duplicate and transpose into a column vector
\     % Modulo with broadcast. Gives matrix in which entry (i,j) is i modulo j, with
      % i, j in [1 2 ... n]. A value 0 in entry (i,j) means i is divisible by j
~     % Negate. Now 1 means i is divisible by j
s     % Sum of each column. Gives row vector with the number of divisors of each j
2=    % Compare each entry with 2. A true result corresponds to a prime
s     % Sum

(pure) BASH, 138 bytes

Look, Mom!
No preloaded prime tables, no prime related builtins, not even a division or plultimication!

a=2
l=0
while((a<=$1));do if((b[a]))
then((c=b[a]));else((c=a,l++));fi;((d=a+c))
while((b[d]));do((d+=c));done
((b[d]=c,a++));done;echo $l

Eating the pudding:

$ for i in 1 2 3 11033 ; do bash fsoe-primecounter-in-bash $i ; done
0
1
2
1337

Ok, probably looping while looking at candidates modulo all possible divisors would have been shorter in "pure BASH" too but we've seen those loops at least 1001 times now.

This solution builds its own prime table on the fly and so is bearably fast even in "pure BASH".

Python 3, 40 bytes

f=lambda n:1if n<1else(2**n%n==2)+f(n-1)

An odd integer k is prime if an only if 2**(k-1) is congruent to 1 mod k. Thus, we just check for this condition and add 1 for the case of k=2.

C# 5.0 78 77

int F(int n){int z=n;if(n<2)return 0;for(;n%--z!=0;);return(2>z?1:0)+F(n-1);}

Ungolfed

int F(int n)
{
    var z = n;
    if (n < 2) return 0;
    for (; n % --z != 0;) ;
    return F(n - 1) + (2 > z ? 1 : 0);
}

APL (Dyalog Unicode), 13 bytesSBCS

2+.=0+.=⍳∘.|⍳

Try it online!

ɩndices 1…N
 ⧽ ∘.| remainder-table (using those two as axes)
ɩndices 1…N

0+.= the sum of the elements equal to zero (i.e. how many dividers does each have)

2+.= the sum of the elements equal to two (i.e. how many primes are there)

Java 8, 95 84 bytes

z->{int c=0,n=2,i,x;for(;n<=z;c+=x>1?1:0)for(x=n++,i=2;i<x;x=x%i++<1?0:x);return c;}

Explanation:

Try it online.

z->{                // Method with integer parameter and integer return-type
  int c=0,          //  Start the counter at 0
      n=2,          //  Starting prime is 2
      i,x;          //  Two other temp integers
  for(;n<=z;        //  Loop (1) as long as `n` is smaller than or equal to the input `z`
       c+=x>1?1:0)  //    and increase the counter if we've came across a prime
                    //    (if `x` is larger than 0, it means the current `n` is a prime)
     for(x=n++,i=2;i<x;x=x%i++<1?0:x);
                    //   Determine if the next integer in line is a prime by setting `x`
                    //   (and increase `n` by 1 afterwards)
                    //  End of loop (1) (implicit / single-line body)
  return c;         //  Return the resulting counter
}                   // End of method

Perl 6, 31 bytes

{+grep {$_%%none 2..^$_},2..$_}

Try it online!

Racket 60 bytes

(require math)(λ(n)(length(filter prime?(range 1(+ 1 n)))))

Testing:

(require math)
(define f
    (λ(n) (length (filter prime? (range 1 (+ 1 n)))))
)

(f 1)
(f 2)
(f 3)
(f 5)

Output:

0
1
2
3

JavaScript (ES6), 45 43 bytes

f=(n,x=n)=>n>1&&(--x<2)+(n%x?f(n,x):f(n-1))

A modification of my 36 35 33-byte primality function (1 byte saved by @Neil, 2 by @Arnauld):

f=(n,x=n)=>n>1&--x<2||n%x&&f(n,x)

(I can't post this anywhere because Is this number a prime? only accepts full programs...)

Test snippet

f=(n,x=n)=>n>1&&(--x<2)+(n%x?f(n,x):f(n-1))
<input type="number" oninput="console.log('f('+this.value+') is '+f(this.value))" value=2>

PHP, 96 92 bytes

for($j=$argv[1]-1;$j>0;$j--){$p=1;for($i=2;$i<$j;$i++)if(is_int($j/$i))$p=0;$t+=$p;}echo $t;

Saved 4 bytes thanks to Roman Gräf

Test online

Ungolfed testing code:

$argv[1] = 5;

for($j=$argv[1]-1;$j>0;$j--) {
    $p=1;
    for($i=2;$i<$j;$i++) {
        if(is_int($j/$i)) {
            $p=0;
        }
    }
    $t+=$p;
}
echo $t;

Test online

Actually, 3 bytes

This uses a prime factorization function, which may or may not be allowed after the OP clarifies. Golfing suggestions welcome. Try it online!

!yl

Ungolfing

     Implicit input n.
!    Push n factorial.
 y   Push a list of all of the positive prime factors of n! (every prime < n)
  l  Take the length of that list of primes.
     Implicit return.

PARI/GP, 15 bytes

n->#factor(n!)~

Take the factorial and count its unique prime factors.

Perl, 33 bytes

Includes +1 for -p

Give the input number on STDIN

primecount.pl

#!/usr/bin/perl -p
$_=1x$_;$_=s%(?!(11+)\1+$)%%eg-2

Gives the wrong result for 0 but that's OK, the op asked for support for positive integers only.

Actually, 10 bytes

If my first Actually answer is disallowed for using a prime-generating function, here is a backup answer using Wilson's theorem. Golfing suggestions welcome. Try it online!

R`;D!²%`MΣ

Try it online

         Implicit input n.
R        Push range [1..n]
`...`M   Map the following function over the range. Variable k.
  ;        Duplicate k.
  D        Decrement one of the copies of k.
  !²       Push ((k-1)!)².
  %        Push ((k-1)!)² % k. This returns 1 if k is prime, else 0.
Σ        Sums the result of the map, adding all the 1s that represent primes, 
          giving the total number of primes less than n.
         Implicit return.

Jelly, 13 11 10 9 8 7 6 bytes

Using no built-in prime functions whatsoever
-1 byte thanks to @miles (use a table)
-1 byte thanks to @Dennis (convert from unary to count up the divisors)

ḍþḅ1ċ2

TryItOnline
Or see the first 100 terms of the series n=[1,100], also at TryItOnline

How?

ḍþḅ1ċ2 - Main link: n
 þ     - table or outer product, n implicitly becomes [1,2,3,...n]
ḍ      - divides
  ḅ1   - Convert from unary: number of numbers in [1,2,3,...,n] that divide x
                             (numbers greater than x do not divide x)
    ċ2 - count 2s: count the numbers in [1,2,3,...,n] with exactly 2 divisors
                   (only primes have 2 divisors: 1 and themselves)

q 35 bytes

{sum 1=sum'[0=2_' a mod\: a:til x]}

Java 7,102 bytes

Brute force

int f(int n){int i=2,j=2,c=1,t=0;for(;i<=n;j=2,c+=t==1?1:0,i++)for(;j<i;t=i%j++==0?j=i+1:1);return c;}

Ungolfed

int f(int n){
int i=2,j=2,c=1,t=0;
for(;i<=n;j=2,c+=t==1?1:0,i++)
    for(;j<i;)
        t=i%j++==0?j=i+1:1;
    return c;
 }

Jelly, 6 bytes

Ḷ!²%RS

This uses only basic arithmetic and Wilson's theorem. Try it online! or verify all test cases.

How it works

Ḷ!²%RS  Main link. Argument: n

Ḷ       Unlength; yield [0, ..., n - 1].
 !      Factorial; yield [0!, ..., (n - 1)!].
  ²     Square; yield [0!², ..., (n - 1)!²].
    R   Range; yield [1, ..., n].
   %    Modulus; yield [0!² % 1, ..., (n - 1)!² % n].
        By a corollary to Wilson's theorem, (k - 1)!² % k yields 1 if k is prime
        and 0 if k is 1 or composite.
     S  Sum; add the resulting Booleans.

JavaScript (ES6), 50+2 46+2 43 bytes

Saved 3 5 bytes thanks to Neil:

f=n=>n&&eval(`for(z=n;n%--z;);1==z`)+f(n-1)

eval can access the n parameter.
The eval(...) checks if n is prime.


Previous solutions:
Byte count should be +2 because I forgot to name the function f= (needed for recursion)

46+2 bytes (Saved 3 bytes thanks to ETHproductions):

n=>n&&eval(`for(z=n=${n};n%--z;);1==z`)+f(n-1)

50+2 bytes:

n=>n&&eval(`for(z=${n};${n}%--z&&z;);1==z`)+f(n-1)

Jelly, 3 bytes

ÆRL

Jelly has a built-in prime counting function, ÆC and a prime checking function, ÆP, this instead uses a built-in prime generating function, ÆR and takes the length L.

I guess this is about as borderline as using prime factorisation built-ins, which would also take 3 bytes with !Æv (! factorial, Æv count prime factors)

MediaWiki templates with ParserFunctions, 220 + 19 = 239 bytes

{{#ifexpr:{{{2}}}+1={{{1}}}|0|{{#ifexpr:{{{3}}}={{{2}}}|{{P|{{{1}}}|{{#expr:{{{2}}}+1}}|2}}|{{#ifexpr:{{{2}}} mod {{{3}}}=0|{{#expr:1+{{P|{{{1}}}|{{#expr:{{{2}}}+1}}|2}}|{{P|{{{1}}}|{{{2}}}|{{#expr:{{{2}}}+1}}}}}}}}}}}}

To call the template:

{{{P|{{{n}}}|2|2}}}

Arranged in Lisp style:

{{#ifexpr:{{{2}}} + 1 = {{{1}}}|0|
    {{#ifexpr:{{{3}}} = {{{2}}} |
        {{P|{{{1}}}|{{#expr:{{{2}}} + 1}}|2}} |
            {{#ifexpr:{{{2}}} mod {{{3}}} = 0 |
                {{#expr:1 + {{P|{{{1}}}|{{#expr:{{{2}}} + 1}}|2}} |
                {{P|{{{1}}}|{{{2}}}|{{#expr:{{{2}}} + 1}}}}}}}}}}}}

Just a basic primality test from 2 to n. The numbers with three braces around them are the variables, where {{{1}}} is n, {{{2}}} is the number being tested, {{{3}}} is the factor to check.

Actually, 10 bytes

This was the shortest solution I found that didn't run into interpreter bugs on TIO. Golfing suggestions welcome. Try it online!

;╗r`P╜>`░l

Ungolfing

         Implicit input n.
;╗       Duplicate n and save a copy of n to register 0.
r        Push range [0..(n-1)].
`...`░   Push values of the range where the following function returns a truthy value.
  P        Push the a-th prime
  ╜        Push n from register 0.
  >        Check if n > the a-th prime.
l        Push len(the_resulting_list).
         Implicit return.

Jelly, 3 bytes

!Æv

Try it online!

How it works

!Æv  Main link. Argument: n

!    Compute the factorial of n.
 Æv  Count the number of distinct prime factors.

Python 2, 45 bytes

f=lambda n,k=1,p=1:n/k and p%k+f(n,k+1,p*k*k)

Uses the Wilson's Theorem prime generator. The product p tracks (k-1)!^2, and p%k is 1 for primes and 0 for nonprimes.

Jelly, 8 5 bytes

3 bytes saved thanks to @Dennis!

RÆESL

Try it online!

Port of DJMcMayhem's MATL answer (former version) refined by Dennis.

R          Range of input argument
 ÆE        List of lists of exponents of prime-factor decomposition
   S       Vectorized sum. This right-pads inner lists with zeros
    L      Length of result

Matlab, 60 bytes

Continuing my attachment to one-line Matlab functions. Without using a factorisation built-in:

f=@(x) nnz(arrayfun(@(x) x-2==nnz(mod(x,[1:1:x])),[1:1:x]));

Given that a prime y has only two factors in [1,y]: we count the numbers in the range [1,x] which have only two factors.

Using factorisation allows for significant shortening (down to 46 bytes).

g=@(x) size(unique(factor(factorial(x))),2);

Conclusion: Need to look into them golfing languages :D

MATL, 11, 10, 8, 5 bytes

:pYFn

Try it online!

I wrote a version that had a really cool explanation of how MATL's matrices work:

:YF!s1=1

But it's no longer relevant. Check out the revision history if you want to see it.

New explanation:

:p      % Compute factorial(input)
  YF    % Get the exponenents of prime factorization
    n   % Get the length of the array

Three bytes saved thanks to Dennis's genius solution

C#, 157 bytes

n=>{int c=0,i=1,j;bool f;for(;i<=n;i++){if(i==1);else if(i<=3)c++;else if(i%2==0|i%3==0);else{j=5;f=1>0;while(j*j<=i)if(i%j++==0)f=1<0;c+=f?1:0;}}return c;};

Full program with test cases:

using System;

class a
{
    static void Main()
    {
        Func<int, int> s = n =>
            {
                int c = 0, i = 1, j;
                bool f;
                for (; i <= n; i++)
                {
                    if (i == 1) ;
                    else if (i <= 3) c++;
                    else if (i % 2 == 0 | i % 3 == 0) ;
                    else
                    {
                        j = 5;
                        f = 1 > 0;
                        while (j * j <= i)
                            if (i % j++ == 0)
                                f = 1 < 0;
                        c += f ? 1 : 0;
                    }
                }
                return c;
            };

        Console.WriteLine("1 -> 0 : " + (s(1) == 0 ? "OK" : "FAIL"));
        Console.WriteLine("2 -> 1 : " + (s(2) == 1 ? "OK" : "FAIL"));
        Console.WriteLine("5 -> 3 : " + (s(5) == 3 ? "OK" : "FAIL"));
        Console.WriteLine("10 -> 4 : " + (s(10) == 4 ? "OK" : "FAIL"));
        Console.WriteLine("100 -> 25 : " + (s(100) == 25 ? "OK" : "FAIL"));
        Console.WriteLine("1,000 -> 168 : " + (s(1000) == 168 ? "OK" : "FAIL"));
        Console.WriteLine("10,000 -> 1,229 : " + (s(10000) == 1229 ? "OK" : "FAIL"));
        Console.WriteLine("100,000 -> 9,592 : " + (s(100000) == 9592 ? "OK" : "FAIL"));
        Console.WriteLine("1,000,000 -> 78,498 : " + (s(1000000) == 78498 ? "OK" : "FAIL"));
    }
}

Starts to take awhile once you go above 1 million.

05AB1E, 3 bytes

!fg

This assumes that factorization built-ins are allowed. Try it online!

How it works

!    Compute the factorial of the input.
 f   Determine its unique prime factors.
  g  Get the length of the resulting list.

05AB1E, 5 bytes

Assumes that prime factorization builtins are allowed.

Code:

LÒ1ùg

Explanation:

L      # Get the range [1, ..., input]
 Ò     # Prime factorize each with duplicates
  1ù   # Keep the elements with length 1
    g  # Get the length of the resulting array

Uses the CP-1252 encoding. Try it online!

PowerShell v2+, 98 bytes

param($n)if($j='001'[$n]){}else{for($i=1;$i-lt$n){for(;'1'*++$i-match'^(?!(..+)\1+$)..'){$j++}}}$j

Caution: This is slow for large input.

Basically the unary-based lookup from Is this number a prime?, coupled with a for loop and a $j++ counter. A little additional logic on the front to account for edge cases input 1 and 2, due to how the fenceposting works in the for loops.

Pyke, 8 6 bytes

SmPs}l

Try it here!

Thanks to Maltysen for new algorithm

SmP    -    map(factorise, input)
   s   -   sum(^)
    }  -  uniquify(^)
     l - len(^)

Bash + coreutils, 30

seq $1|factor|egrep -c :.\\S+$

Ideone.


Bash + coreutils + BSD-games package, 22

primes 1 $[$1+1]|wc -l

This shorter answer requires that you have the bsdgames package installed: sudo apt install bsdgames.

Pyth - 7 6 bytes

Since others are using prime factorization functions...

l{sPMS

Test Suite.