Java - 278 Characters
A golfed version of the Java answer already demonstrated here without changing the spirit of the answer, because the original poster's idea golfed could have saved 50%, which is huge compared to most other languages!
class T {public static void main(String[] a) {int n,i,j;double k;n=Integer.parseInt(a[0]);int l[]=new int[n];for(i=0;i<n;)l[i]=1+i++;for (i=1;i<n;i++) {k=Math.sqrt(l[i]);if(k==Math.floor(k))for (j=i;j<n;j+=i+1)l[j]=-1;}j=0;for(i=0;i<n;)if(l[i++]!=-1)j++;System.out.println(j);}}
Specifically, a few Java golfing tricks were used to optimize this:
- Removed long variable names
- Removed the use of a Reader in favor of using an argument (saves a huge amount of characters, including import, Exception handling, and casting the reader in general)
- Removed extra brackets and parentheses using single-line actions for ifs and fors where applicable
- Declare ints beforehand together to reduce calls to int
- Declare a double and optimize square calculation
- Extracted ++ where possible
This shows that the original ungolfed solution of 565 characters can be brought down to a very respectable <300 character answer even with a more structured language like Java.
Ungolfed
class T {
public static void main(String[] a) {
int n, i, j;
double k;
n = Integer.parseInt(a[0]);
int l[] = new int[n];
for (i = 0; i < n;)
l[i] = 1 + i++;
for (i = 1; i < n; i++) {
k = Math.sqrt(l[i]);
if (k == Math.floor(k))
for (j = i; j < n; j += i + 1)
l[j] = -1;
}
j = 0;
for (i = 0; i < n;)
if (l[i++] != -1)
j++;
System.out.println(j);
}
}
+
or*
- they all are functions. \$\endgroup\$