conditional_euler_totient_function.sf 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940
  1. #!/usr/bin/ruby
  2. # Daniel "Trizen" Șuteu
  3. # Date: 04 July 2018
  4. # https://github.com/trizen
  5. # Find the number of k = 1..n for which GCD(n,k) satisfies a certain condition (e.g.:
  6. # GCD(n,k) is a prime number), using the divisors of `n` and the Euler totient function.
  7. # See also:
  8. # https://oeis.org/A117494 -- Number of k = 1..n for which GCD(n, k) is a prime
  9. # https://oeis.org/A116512 -- Number of k = 1..n for which GCD(n, k) is a power of a prime
  10. # https://oeis.org/A206369 -- Number of k = 1..n for which GCD(n, k) is a square
  11. # https://oeis.org/A078429 -- Number of k = 1..n for which GCD(n, k) is a cube
  12. # https://oeis.org/A063658 -- Number of k = 1..n for which GCD(n, k) is divisible by a square greater than 1
  13. func foo(n, condition) { # slow
  14. 1..n -> count {|k|
  15. condition(gcd(n,k))
  16. }
  17. }
  18. func bar(n, condition) { # fast
  19. n.divisors.sum {|d|
  20. condition(d) ? euler_phi(n/d) : 0
  21. }
  22. }
  23. func condition(d) {
  24. d.is_prime
  25. }
  26. say 25.of {|n| foo(n, condition) }
  27. say 25.of {|n| bar(n, condition) }
  28. assert_eq(
  29. 100.of {|n| foo(n, condition) },
  30. 100.of {|n| bar(n, condition) }
  31. )