Calculate Phi (not Pi)
Regex (.NET), 122 113 bytes
^(?=((?=.*$(?<=^(\3+(.+.))(.*?(?>(.\4)?)))).)+(.*))((?=.*(?=\6$)(?<=(?!(.+.)\8*(?=\6$)(?<=^\8+))(.+?(?>\9?)))).)+
Assuming input and output are in unary, and the output is taken from the main match of the regex.
Breakdown of the regex:
^(?=((?=.*$(?<=^(\3+(.+.))(.*?(?>(.\4)?)))).)+(.*))
calculates π̅(x) and captures the rest of the string in capturing group 6 for assertion in the second part..*$
sets the pointer to the end of the string so that we have the whole numberx
in one direction.(?<=^(\3+(.+.))(.*?(?>(.\4)?)))
matches from right to left and checks for composite number by looping from x to 0.(.*?(?>(.\4)?))
is a "variable" which starts from 0 in the first iteration and continues from the number in previous iteration and loops up to x. Since the smallest composite number is 4,(.\4)?
never fails to match if capturing group 4 is available.^(\3+(.+.))
checks what is left by the "variable" above (i.e.x - "variable"
) whether it is a composite number.
((?=.*(?=\6$)(?<=(?!(.+.)\8*(?=\6$)(?<=^\8+))(.+?(?>\9?)))).)+
calculates φ(π̅(x)), by limiting the left-to-right operations with(?=\6$)
..*(?=\6$)
sets the pointer to position π̅(x). Let's denote y = π̅(x).(?<=(?!(.+.)\8*(?=\6$)(?<=^\8+))(.+?(?>\9?)))
matches from right to left and checks for relative prime by looping from (y - 1) to 0(.+?(?>\9?))
is a "variable" which starts from 1 in the first iteration and continues from the number in previous iteration and loops up to y(?!(.+.)\8*(?=\6$)(?<=^\8+))
matches from left to right 1 and checks whether the "variable" and y are relative prime.(.+.)\8*(?=\6$)
picks a divisor of "variable" which is larger than 1, and a side effect is that we have whole number y on the left.(?<=^\8+)
checks whether the divisor of "variable" is also the divisor of y.
1 In .NET, look-ahead sets the direction to LTR instead of following the current direction; look-behind sets the direction to RTL instead of reversing the direction.
Test the regex at RegexStorm.
Revision 2 drops non-capturing groups and uses atomic groups instead of conditional syntax.
GS2, 12 10 bytes
V@'◄l.1&‼l
The source code uses the CP437 encoding. Try it online!
Test run
$ xxd -r -ps <<< 564027116c2e3126136c > phinotpi.gs2
$ wc -c phinotpi.gs2
10 phinotpi.gs2
$ gs2 phinotpi.gs2 <<< 1000
552
How it works
V Read an integer n from STDIN.
@ Push a copy of n.
' Increment the copy of n.
◄l Push 1 and call primes; push the list of all primes below n+1.
. Count the primes.
1 Subtract the count from n.
& Decrement to account for 1 (neither prime nor composite).
‼l Push 3 and call primes; apply Euler's totient function.
J, 15 14 bytes
5 p:<:-_1 p:>:
This is a tacit, monadic verb. Try it online with J.js.
How it works
Right argument: y
>: Increment y.
_1 p: Calculate the number of primes less than y+1.
<: Decrement y.
- Calculate the difference of the results to the left and right.
5 p: Apply Euler's totient function to the difference.