Reachable numbers

14

1

Definitions

  • Euler Phi Function (AKA totient function): a function which takes in a positive number and returns the number of positive numbers less than the given number which are co-prime with given number. It is denoted as φ(n).

  • Reachable number: if there exists a positive integer x such that φ(x) == n, then n is reachable.

Task

Write a function/program to determine if a given positive integer is reachable.

Input

A positive number, in any reasonable format. One can assume that the number is within the capability of the language. Unary input is accepted.

Output

Two consistent values, one for reachable numbers, and the other for unreachable numbers. The two values can be anything, as long as they are consistent.

Testcases

The reachable numbers bellow 100 are:

1, 2, 4, 6, 8, 10, 12, 16, 18, 20, 22, 24, 28, 30, 32, 36, 40, 42, 44, 46, 48, 52, 54, 56, 58, 60, 64, 66, 70, 72, 78, 80, 82, 84, 88, 92, 96

(A002202 on OEIS)

Rules

Standard loopholes apply.

Winning criterion

This is . Submission with lowest byte-count wins.

References

Leaky Nun

Posted 2017-04-29T04:40:46.640

Reputation: 45 011

also relevant: https://oeis.org/A264739

– Destructible Lemon – 2017-04-29T06:13:56.193

1I offer a bounty to a one-line Retina answer, where the one line is a plain regex (no backticks). – Leaky Nun – 2017-04-29T11:45:17.457

@LeakyNun I'm little confused, so far I understand that phi(n) = count { m : 1 <= m <= n AND (m,n) are coprime }.. is that true? – Khaled.K – 2017-05-22T11:59:57.787

@Khaled.K yes, that is true. – Leaky Nun – 2017-05-22T13:04:43.257

Answers

6

Jelly, 7 6 bytes

²RÆṪe@

Not exactly fast. Returns 1 or 0.

Try it online!

How it works

²RÆṪe@  Main link. Argument: n

²       Square; yield n².
 R      Range; yield [1, ..., n²].
  ÆṪ    Compute the totient of each integer in the range.
    e@  Exists swap; test if n occurs in the generated array.

Dennis

Posted 2017-04-29T04:40:46.640

Reputation: 196 637

How does it work? – Leaky Nun – 2017-04-29T04:59:48.120

1Brute force. There's a lower bound for the totient function, so it's enough to take a large enough range, map totient, and check for occurrences of the input. – Dennis – 2017-04-29T05:02:03.620

Can you prove that the square root is the minimum? – Leaky Nun – 2017-04-29T05:59:42.683

The square root is actually not a lower bound, but the square root divided by sqrt(2) is. I'm positive that doubling is not required, but a proof will have to wait until I've gotten some sleep. Too tired right now. – Dennis – 2017-04-29T06:05:11.857

This is a trivial modification, so I won't post it, but just out of interest, another possibility is to use i: for the last two bytes. – HyperNeutrino – 2017-04-29T06:09:06.890

4

@LeakyNun Actually, lemma 3 of this paper proves that the square root is a lower bound unless n = 2k with odd k. Since k and 2k have the same totient, doubling is not required.

– Dennis – 2017-04-29T06:09:52.077

@HyperNeutrino That might work (and if it does, I can double instead of squaring), but I'm not sure. – Dennis – 2017-04-29T06:14:13.300

haha it looks almost like it says rate – Destructible Lemon – 2017-04-29T06:14:58.303

I think your Range can start from n+1, since phi(x) <= x-1. – Khaled.K – 2017-05-22T16:06:51.780

@Khaled.K Well, yes, but that would cost two bytes. – Dennis – 2017-05-22T16:40:01.977

6

Mathematica, 28 bytes

EulerPhi@Range[#^2]~FreeQ~#&

Like Dennis's Jelly answer, we compute the φ-values of all the numbers up to the square of the input and see if the input appears therein. Returns False if the input is reachable and True if it's not. Yep, that's confusing. But FreeQ is a byte shorter than MatchQ, and hey, the spec said any two consistent values >:)

Greg Martin

Posted 2017-04-29T04:40:46.640

Reputation: 13 940

2

JavaScript (ES6), 90 82 bytes

Returns 0 or true.

f=(n,x=n*2)=>x?(p=i=>(c=(a,b)=>a?c(b%a,a):b<2)(i,x)+(i&&p(--i)))(x)==n||f(n,x-1):0

This is based on the assumption that if x exists then x ≤ 2n. If proven false, this should be updated to use x=n*n instead of x=n*2 (same size, much slower).

An edge case is n = 128 which requires to compute ϕ(255).

Demo

f=(n,x=n*2)=>x?(p=i=>(c=(a,b)=>a?c(b%a,a):b<2)(i,x)+(i&&p(--i)))(x)==n||f(n,x-1):0

for(n = 1; n <= 50; n++) {
  console.log(n, f(n));
}

Arnauld

Posted 2017-04-29T04:40:46.640

Reputation: 111 334

Conveniently the Fermat primes are all consecutive giving rise to consecutive edge cases n=2, n=8, n=128, n=32768 and n=2147483648. – Neil – 2017-04-29T19:31:24.727

1

Axiom, 56 bytes

f(x:PI):Boolean==member?(x,[eulerPhi(i)for i in 1..2*x])

i don't know if it is right...test code and results

(35) -> [i  for i in 1..100|f(i)]
   (35)
   [1, 2, 4, 6, 8, 10, 12, 16, 18, 20, 22, 24, 28, 30, 32, 36, 40, 42, 44, 46,
    48, 52, 54, 56, 58, 60, 64, 66, 70, 72, 78, 80, 82, 84, 88, 92, 96, 100]

The range 1..(2*x) would be ok until input x=500...

RosLuP

Posted 2017-04-29T04:40:46.640

Reputation: 3 036

1

05AB1E, 5 bytes

nLÕså

Explanation:

n       Square [implicit] input
 L      Range [1 .. a]
  Õ     Euler totient
   s    Put first input at the top of the stack
    å   Is it in the list?

Try it online!

Okx

Posted 2017-04-29T04:40:46.640

Reputation: 15 025

1

Pari/GP, 34 bytes

x->![n|n<-[1..x^2],eulerphi(n)==x]

Returns 0 if reachable, 1 if not.

Try it online!

alephalpha

Posted 2017-04-29T04:40:46.640

Reputation: 23 988

0

05AB1E, 13 12 bytes

EDIT: Saved a byte because input is reused if the stack doesn't have enough elements.

Outputs 1 if reachable, 0 if not.

Relies on assumption that x ≤ 2n if it exists.

xGNÕQi1,q}}0

Try it online!

How it works

              # implicit input    
x            # push input, 2 * input
 G           # for N in 1..2*input
             # implicit push input
  N          # push N
   Õ         # push totient of N
    Q        # check if both are equal
     i.      # if equal
      1,     # print 1
        q    # quit program
         }   # end if
          }  # end for
           0 # push 0 if condition never reached
             # implicit print

Neil A.

Posted 2017-04-29T04:40:46.640

Reputation: 2 038

0

C, 123 bytes

g(a,b){return!a?b:g(b%a,a);}
i;r;f(n){for(i=2,r=1;i<n;i++)r+=(g(i,n)==1);}
t;k;s(m){for(k=m,t=0;!t&(k<m*m);)f(++k),t=(r==m);}

Try Online

#include <stdio.h>

// gcd function
g(a,b){return!a?b:g(b%a,a);}

// Euler phi(x) function
i;r;f(n){for(i=2,r=1;i<n;i++)r+=(g(i,n)==1);}

// check if m is reachable, phi(x) for x in (m , m^2]
t;k;s(m){for(k=m,t=0;!t&(k<m*m);)f(++k),t=(r==m);}

main()
{
    // print all reachable number below 50
    for(int x=1; x<50; x++)
    {
        s(x);

        if(t)
        {
            printf(" %d ~ phi(%d) \n", x, k);
        }
    }
}

Khaled.K

Posted 2017-04-29T04:40:46.640

Reputation: 1 435

102 bytes – ceilingcat – 2019-04-29T22:18:37.173