Calcular Phi (no Pi)


73

No, no quiero decir ϕ = 1.618...y π = 3.14159.... Me refiero a las funciones .

  • φ (x) es el número de enteros menores o iguales a los xque son relativamente primos x.
  • π (x) es el número de primos menores o iguales que x.
  • Digamos que "no pi" es entonces π̅ (x) y defínalo como el número de compuestos menores o iguales a x.

Tarea

Dado un entero estrictamente positivo x, calcule φ (π̅ (x)) . La puntuación está en bytes.

Ejemplos

Cada línea consta de la entrada (de 1 a 100, inclusive) y la salida correspondiente separada por un espacio.

1 0 
2 0 
3 0 
4 1 
5 1 
6 1 
7 1 
8 2 
9 2 
10 4 
11 4 
12 2 
13 2 
14 6 
15 4 
16 6 
17 6 
18 4 
19 4 
20 10 
21 4 
22 12 
23 12 
24 6 
25 8 
26 8 
27 16 
28 6 
29 6 
30 18 
31 18 
32 8 
33 12 
34 10 
35 22 
36 8 
37 8 
38 20 
39 12 
40 18 
41 18 
42 12 
43 12 
44 28 
45 8 
46 30 
47 30 
48 16 
49 20 
50 16 
51 24 
52 12 
53 12 
54 36 
55 18 
56 24 
57 16 
58 40 
59 40 
60 12 
61 12 
62 42 
63 20 
64 24 
65 22 
66 46 
67 46 
68 16 
69 42 
70 20 
71 20 
72 32 
73 32 
74 24 
75 52 
76 18 
77 40 
78 24 
79 24 
80 36 
81 28 
82 58 
83 58 
84 16 
85 60 
86 30 
87 36 
88 32 
89 32 
90 48 
91 20 
92 66 
93 32 
94 44 
95 24 
96 70 
97 70 
98 24 
99 72 
100 36

Use este enlace para calcular la salida esperada para cualquier entrada. Además, aquíx <= 1000 se proporciona una lista de entradas y salidas para pastebin . (Generado con este programa Minkolang ).


Tablas de clasificación

Aquí hay un fragmento de pila para generar una tabla de clasificación regular y una descripción general de los ganadores por idioma.

Para asegurarse de que su respuesta se muestre, comience con un título, utilizando la siguiente plantilla de Markdown:

## Language Name, N bytes

¿Dónde Nestá el tamaño de su envío? Si mejora su puntaje, puede mantener los puntajes antiguos en el título, tachándolos. Por ejemplo:

## Ruby, <s>104</s> <s>101</s> 96 bytes

Si desea incluir varios números en su encabezado (por ejemplo, porque su puntaje es la suma de dos archivos o desea enumerar las penalizaciones de la bandera del intérprete por separado), asegúrese de que el puntaje real sea el último número en el encabezado:

## Perl, 43 + 2 (-p flag) = 45 bytes

También puede hacer que el nombre del idioma sea un enlace que luego aparecerá en el fragmento de la tabla de clasificación:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes


¿Hay límites en el tamaño de la entrada?
lirtosiast el

44
¿Es esta pregunta un homenaje al usuario PhiNotPi ?
primo

24
@primo ¿Por qué piensas eso?
Mego

2
@primo: Fue inspirado por su nombre, y definitivamente fue un juego de palabras, pero no exactamente un homenaje a él.
El'endia Starman

1
@ edc65: Sí, aparentemente así , como descubrí ayer.
El'endia Starman

Respuestas:


27

GS2 , 12 10 bytes

V@'◄l.1&‼l

El código fuente usa la codificación CP437 . Pruébalo en línea!

Prueba de funcionamiento

$ xxd -r -ps <<< 564027116c2e3126136c > phinotpi.gs2
$ wc -c phinotpi.gs2 
10 phinotpi.gs2
$ gs2 phinotpi.gs2 <<< 1000
552

Cómo funciona

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.

25
El nombre del archivo es más largo que el programa.
Floris

43

Regex (NET), 122 113 bytes

^(?=((?=.*$(?<=^(\3+(.+.))(.*?(?>(.\4)?)))).)+(.*))((?=.*(?=\6$)(?<=(?!(.+.)\8*(?=\6$)(?<=^\8+))(.+?(?>\9?)))).)+

Suponiendo que la entrada y la salida están en unario, y la salida se toma de la coincidencia principal de la expresión regular.

Desglose de la expresión regular:

  • ^(?=((?=.*$(?<=^(\3+(.+.))(.*?(?>(.\4)?)))).)+(.*)) calcula π̅ (x) y captura el resto de la cadena en el grupo de captura 6 para su afirmación en la segunda parte.

    • .*$establece el puntero al final de la cadena para que tengamos el número entero xen una dirección.
    • (?<=^(\3+(.+.))(.*?(?>(.\4)?))) coincide de derecha a izquierda y comprueba el número compuesto haciendo un bucle de x a 0.
      • (.*?(?>(.\4)?))es una "variable" que comienza desde 0 en la primera iteración y continúa desde el número en la iteración anterior y recorre hasta x. Como el número compuesto más pequeño es 4, (.\4)?nunca falla si el grupo de captura 4 está disponible.
      • ^(\3+(.+.))comprueba lo que queda por la "variable" de arriba (es decir, x - "variable"si es un número compuesto).
  • ((?=.*(?=\6$)(?<=(?!(.+.)\8*(?=\6$)(?<=^\8+))(.+?(?>\9?)))).)+calcula φ (π̅ (x)), limitando las operaciones de izquierda a derecha con (?=\6$).

    • .*(?=\6$)establece el puntero en la posición π̅ (x). Denotemos y = π̅ (x).
    • (?<=(?!(.+.)\8*(?=\6$)(?<=^\8+))(.+?(?>\9?))) coincide de derecha a izquierda y comprueba el primo relativo haciendo un bucle de (y - 1) a 0
      • (.+?(?>\9?)) es una "variable" que comienza desde 1 en la primera iteración y continúa desde el número en la iteración anterior y recorre hasta y
      • (?!(.+.)\8*(?=\6$)(?<=^\8+))coincide de izquierda a derecha 1 y comprueba si la "variable" e y son primos relativos.
        • (.+.)\8*(?=\6$) elige un divisor de "variable" que es mayor que 1, y un efecto secundario es que tenemos el número entero y a la izquierda.
        • (?<=^\8+) comprueba si el divisor de "variable" es también el divisor de y.

1 En .NET, la vista anticipada establece la dirección en LTR en lugar de seguir la dirección actual; mirar hacia atrás establece la dirección en RTL en lugar de invertir la dirección.

Prueba la expresión regular en RegexStorm .

La revisión 2 elimina los grupos que no capturan y usa grupos atómicos en lugar de sintaxis condicional.


24
Señor, usted está enojado
RK.

9
Tiene un toque de Zalgo, creo.
curiousdannii

11
Y ahora tienes dos problemas. (En serio, no tenía idea de que podría hacer este tipo de cosas con Regex ...)
Darrel Hoffman

21

J, 15 14 bytes

5 p:<:-_1 p:>:

Este es un verbo tácito y monádico. Pruébalo en línea con J.js .

Cómo funciona

                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.

14
¿Puedo hacer una explicación? : P
anOKsquirrel

23
Explicación agregada de Haz
Dennis

55
Estaba a punto de decir que he votado por esto porque tiene muchos emoticonos, pero el texto me dijo que evitara esos :(
Doddy

@ Dennis: Tu primera respuesta me hizo reír mucho, ¡gracias por eso!
Mehrdad

19

En serio , 27 bytes

,;R`p`MΣ(-D;n;;╟@RZ`ig1=`MΣ

¡Sí, le gané a CJam! Pruébalo en línea

Explicación (se arefiere a la parte superior de la pila, se brefiere al segundo desde arriba):

,;       take input and duplicate it
R`p`MΣ   push sum([is_prime(i) for i in [1,...,a]]) (otherwise known as the pi function)
(-D      rotate stack right by 1, subtract top two elements, subtract 1, push
            (@ could be used instead of (, but I was hoping the unmatched paren would bother someone)
;n;;     dupe top, push a b times, dupe top twice (effectively getting a a+1 times)
╟        pop n, pop n elements and append to list, push
@        swap top two elements
RZ       push [1,...,a], zip a and b
`ig1=`   define a function:
  i        flatten list
  g1=      compute gcd(a,b), compare to 1 (totient function)
MΣ       perform the function a on each element of b, sum and push

Nota: desde la publicación de esta respuesta, he agregado las funciones pi y phi a Seriously. Aquí hay una respuesta no competitiva con esas funciones:

,;▓1-@-▒

Explicación (algunos comandos se desplazan para no superponerse a otros):

,    get input (hereafter referred to as x)
;    duplicate x
 ▓   calculate pi(x) (we'll call this p)
1-   calculate 1-p
@-   bring x back on top, calculate x-1-p (not pi(x))
  ▒  calculate phi(not pi(x))

1
¡Has superado gravemente a @Dennis!
TanMath

Por favor, no me digas que sabías esto en la parte superior de tu cabeza ..
DividedByZero

1
GJ venciendo a CJam =)
falla

14

Julia, 52 50 bytes

x->count(i->gcd(i,p)<2,1:(p=x-endof(primes(x))-1))

Esto crea una función sin nombre que acepta un número entero y devuelve un número entero. Para llamarlo, asígnele un nombre, p. Ej.f=x->... .

Sin golf:

function phinotpi(x::Integer)
    # The number of composites less than or equal to x is
    # x - the number of primes less than or equal to x -
    # 1, since 1 is not composite
    p = x - length(primes(x)) - 1

    # Return the number of integers i between 1 and p such
    # that gcd(i, p) = 1. This occurs when i is relatively
    # prime to p.
    count(i -> gcd(i, p) == 1, 1:p)
end

Use en sumlugar de countguardar un par de caracteres. Sin embargo, es un poco frustrante: la otra forma de contar los números primos sum(isprime,1:x)es exactamente la misma longitud que endof(primes(x)).
Glen O

1
@GlenO Gracias por la sugerencia, pero sumfalla por colecciones vacías mientras countdevuelve 0. Por sumlo tanto , no producirá el resultado deseado para x<4.
Alex A.

8

Mathematica, 24 bytes

EulerPhi[#-PrimePi@#-1]&

2
Por supuesto, Mathematica tiene todo esto incorporado ...
aplaude el

@ConfusedMr_C Obviamente :) Sin embargo, no fue descalificado, por una razón obvia: el software matemático no puede superar los problemas del golf en simples tareas combinatorias :)
yo '

@ConfusedMr_C PhiNotPi@#&: 11 bytes: P
LegionMammal978

8

Pyth, 14 bytes

JlftPTSQ/iLJJ1

Demostración , verificador

Calculamos los compuestos usando un filtro simple, tomamos su longitud y lo guardamos en J. Luego, tomamos el mcd de Jcon cada número hasta Jy contamos cuántos resultados equivalen a 1.


7

Minkolang 0.11 , 12 bytes (NO competitivo)

Esta respuesta NO es competitiva. Implementé pi y phi como elementos integrados antes de publicar la pregunta, lo que me da una ventaja injusta. Publico esto solo para aquellos que estén interesados ​​en el idioma.

nd9M-1-9$MN.

Pruébalo aquí.

Explicación

n      Read in integer from input
d      Duplicate
9M     Pops off the top of stack as x and pushes pi(x)
-      Subtracts the top two elements on the stack (x - pi(x))
1-     Subtracts 1 (x-1 - pi(x))
9$M    Pops off the top of stack as x and pushes phi(x) (phi(x-1 - pi(x)))
N.     Outputs as integer and stops.

2
No creo que publicar respuestas no válidas sea una buena idea ...
yeti

20
Mientras tengan un descargo de responsabilidad, no creo que haya nada malo en ello. En realidad, es bastante común para los desafíos más antiguos.
Dennis

44
@yeti: Técnicamente, no es inválido. Las características utilizadas aquí se implementaron antes de que se publicara el desafío. Simplemente lo descalifico porque retrasé la publicación del desafío hasta que se implementaron dos características particulares (que utilicé para generar las listas de ejemplos, por cierto).
El'endia Starman

1
Mismo. Hago esto mucho cuando 𝔼𝕊𝕄𝕚𝕟 sigue actualizándose.
Mama Fun Roll

6

CJam, 28 bytes

ri){mf1>},,_,f{){_@\%}h)=}1b

Pruébelo este violín en el intérprete CJam o verifique todos los casos de prueba a la vez .

Cómo funciona

ri                            Read an integer N from STDIN.
  )                           Increment it. 
   {    },                    Filter; for each I in [0 ... N]:
    mf                          Push I's prime factorization.
      1>                        Discard the first prime.
                              If there are primes left, keep I.
          ,                   Count the kept integers. Result: C
           _,                 Push [0 ... C-1].
             f{          }    For each J in [0 ... C-1], push C and J; then:
               )                Increment J.
                {    }h         Do:
                 _                Push a copy of the topmost integer..
                  @               Rotate the integer below on top of it.
                   \%             Take that integer modulo the other integer.
                                If the residue is non-zero, repeat the loop.
                                This computes the GCD of C and J+1 using the
                                Euclidean algorithm.
                       )        Increment the 0 on the stack. This pushes 1.

                        =     Push 1 if the GCD is 1, 0 if not.
                          1b  Add all Booleans.

Probé el enlace "verificar todos los casos" y tengo la siguiente: 1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111. ¿Está bien?
El'endia Starman

Sí, comprueba que aplicar el código a la columna izquierda (entrada) es igual a la columna derecha (salida).
Dennis

55
¿Puedo hacer una explicación en dis1?
anOKsquirrel

9
@anOKsquirrel i haz explicó dis1 2
Dennis

55
@Dennis kthxbai
anOKsquirrel

5

Pitón, 137 139

n=input()
print n,len([b for b in range(len([a for a in range(n)if not all(a%i for i in xrange(2,a))]))if all(b%i for i in xrange(2,b))])

2
Creo que puede ahorrar 2 bytes eliminando los espacios entre range(n) ify])) if
DankMemes

3
Dada la relativamente baja capacidad de Golf de Python (debido a los requisitos de espacio en blanco, etc.) ¡esto es bastante impresionante!
Felixphew

@DankMemes, gracias por el consejo!
wnnmaw

5

Retina , 48 bytes

.+
$*
M&`(..+)\1+$
.+
$*
(?!(..+)\1*$(?<=^\1+)).

Pruébalo en línea!

Explicación

.+
$*

Convierta la entrada a unario.

M&`(..+)\1+$

Cuente números compuestos que no sean mayores que la entrada contando con qué frecuencia podemos hacer coincidir una cadena que consta de al menos dos repeticiones de un factor de al menos 2.

.+
$*

Convierte a unario nuevamente.

(?!(..+)\1*$(?<=^\1+)).

Calcule φ contando a partir de cuántas posiciones no es posible encontrar un factor (de al menos 2) del sufijo de esa posición, que también es un factor del prefijo (si encontramos ese factor, entonces i <= ncomparte un factor con nPor lo tanto, no es coprime). Al .final se asegura que no contamos cero (para lo cual no podemos encontrar un factor de al menos 2).


5

Regex (.NET), 88 86 bytes

^(?=((?=(..+)\2+$)?.)+)(?=(?<-2>.)*(.+))(?=(((?!(..+)\6*(?<=^\6+)\3$))?.)*\3)(?<-5>.)*

Pruébalo en línea! (Como un programa de retina).

Utiliza la misma E / S que la respuesta de n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ , es decir, una entrada unaria y coincide con una subcadena de la longitud del resultado.

Es posible acortar esto aún más reemplazando uno o ambos grupos de equilibrio con referencias hacia adelante.

Alternativa al mismo número de bytes:

^(?=((?=(..+)\2+$)?.)+)(?=(?<-2>.)*(.+))(?=(?((..+)\4*(?<=^\4+)\3$).|(.))*\3)(?<-5>.)*

También hay algunas alternativas para la primera mitad, por ejemplo, usar una anticipación negativa en lugar de una positiva para los números compositivos, o también usar un condicional allí.

Explicación

Asumiré que tiene una comprensión básica de los grupos de equilibrio , pero en resumen, los grupos de captura en .NET son pilas (por lo que cada vez que reutiliza el grupo de captura, la nueva captura se coloca en la parte superior) y (?<-x>...)saca una captura de la pila x. Eso es muy útil para contar cosas.

^                   # Only look at matches from the beginning of the input.
(?=                 # First, we'll compute the number of composites less than
                    # or equal to the input in group 2. This is done in a
                    # lookahead so that we don't actually advance the regex
                    # engine's position in the string.
  (                 #   Iterate through the input, one character at a time.
    (?=(..+)\2+$)?  #     Try to match the remainder of the input as a
                    #     composite number. If so the (..+) will add one
                    #     one capture onto stack 2. Otherwise, this lookahead
                    #     is simply skipped.
    .
  )+
)
(?=                 # It turns out to be more convienient to work with n minus
                    # the number of composites less than or equal to n, and to
                    # have that a single backreference instead of the depth of
                    # a stack.
  (?<-2>.)*         #   Match one character for each composite we found.
  (.+)              #   Capture the remainder of the input in group 3.
)
(?=                 # Now we compute the totient function. The basic idea is
                    # similar to how we computed the number of composites,
                    # but there are a few differences.
                    # a) Of course the regex is different. However, this one
                    #    is more easily expressed as a negative lookahead (i.e.
                    #    check that the values don't share a factor), so this
                    #    won't leave a capture on the corresponding stack. We
                    #    fix this by wrapping the lookahead itself in a group
                    #    and making the entire group optional.
                    # b) We only want to search up the number of composites,
                    #    not up to the input. We do this by asserting that we
                    #    can still match our backreference \3 from earlier.

  (                 #   Iterate through the input, one character at a time.
    ((?!            #     Try not to match a number that shares a factor with
                    #     the number of composites, and if so push a capture
                    #     onto stack 5.
      (..+)\6*      #     Look for a factor that's at least 2...
      (?<=^\6+)     #     Make sure we can reach back to the input with that
                    #     factor...
      \3$           #     ...and that we're exactly at the end of the number
                    #     of composites.
    ))?
    .
  )*
  \3                #   Match group 3 again to make sure that we didn't look
                    #   further than the number of composites.
)
(?<-5>.)*           # Finally, match one character for each coprime number we
                    # found in the last lookahead.


4

Gelatina , no competidora

7 bytes Esta respuesta no es competitiva, ya que utiliza un lenguaje posterior al desafío.

ÆC_@’ÆṪ

Cómo funciona

ÆC_@’ÆṪ  Input: n

ÆC       Count the primes less than or equal to n.
    ’    Yield n - 1.
  _@     Subtract the count from n - 1.
     ÆṪ  Apply Euler's totient function.

3

Octava, 52 51

@(b)nnz((d=[1:(c=b-1-nnz(primes(b)))])(gcd(d,c)<2))

Editar: guardado 1 byte gracias a Thomas Kwa

Explicación:

@(b)                                            # Define anonymous func with parameter b
  nnz(                                          # Count elements in φ(c)
    (                                           #
      d = [1:                                   # Create d= array of 1 to π̅(b)
            ( c = b - 1 - nnz(primes(b)) )      # Calculate c=π̅(b) by subtracting the
                                                #  number of elements in the array of prime
          ]                                     #  numbers from the number of ints in 2:b
    )(gcd(d, c) < 2)                            # Calculate φ(c) by using gcd to filter
  )                                             # relative primes from d


3

SageMath 26 bytes

euler_phi(n-1-prime_pi(n))

Funciona bien incluso para n=0y n=1, gracias a la implementación de Sage.





2

MATL , 9 bytes (no competitivos)

Esta respuesta no es competitiva, ya que el lenguaje es posterior al desafío.

:Zp~sq_Zp

Utiliza la versión (10.1.0) del lenguaje / compilador.

Pruébalo en línea!

Explicación

:       % implicitly input a number "N" and produce array [1,2,...,N]
Zp      % true for entries that are prime
~       % negate. So it gives true for entries of [1,2,...,N] that are non-prime
s       % sum elements of array. So it gives number of non-primes
q       % subtract 1. Needed because number 1 is not prime, but not composite either
_       % unary minus
Zp      % with negative input, computes totient function of absolute value of input
        % implicit display

2

GAP, 33 bytes

n->Phi(n-Number([-2..n],IsPrime))

Number(l,p)cuenta cuántos elementos de lsatisfacer p. Para compensar el hecho de que 1 no es primo ni compuesto, tengo que restar de n uno más que el número de primos hasta n. En lugar de hacerlo -1por dos bytes, comienzo la lista por -2 en lugar de 1 o 2, agregando así un número más que se considera primo por IsPrimesolo un byte adicional.


2

Python 3.5 - 130 bytes

from math import*
def p(n,k,g):
 for i in range(1,n+1):k+=factorial(i-1)%i!=i-1
 for l in range(1,k):g+=gcd(k,l)<2      
 return g

Si no es aceptable pasar la función como p (n, 0,0), entonces +3 bytes.

Esto aprovecha el hecho de que uso el teorema de Wilson para verificar si un número es compuesto y tengo que llamar al módulo matemático para la función factorial. Python 3.5 agregó una función gcd en el módulo matemático.

El primer bucle del código incrementará k en uno si el número es compuesto y aumentará en 0 de lo contrario. (Aunque el teorema de Wilson solo es válido para enteros mayores que 1, trata 1 como primo, por lo que nos permite explotar esto).

El segundo bucle se repetirá en el rango de número de compuestos e incrementará g solo cuando el valor de no pi y l sean primos conjuntos.

g es entonces el número de valores menor o igual que el número de números compuestos menor o igual que n.



1

05AB1E , 11 8 bytes

LDpÈÏg<Õ

Pruébalo en línea!

Esto podría no ser competitivo: no puedo saber cuándo se creó 05AB1E.

Cómo funciona

L             # this gets us the list of numbers [1 .. a]
 D            # duplicates this list
  p           # applies isPrime to each element of the list, vectorised.
   È          # is the element even? (does 05AB1E not have a logical not?)
    Ï         # push elements of the first list where the same index in the 
              # second list is 1
     g<       # finds the length and subtracts 1 (as the list contains 1)
              # this is the not pi function
       Õ      # euler totient function

1

Pyt , 6 bytes

řṗ¬Ʃ⁻Ț

Explicación:

                Implicit input
ř               Push [1,2,...,input]
 ṗ              [is 1 prime?, is 2 prime?, ..., is input prime?]
  ¬             [is 1 not prime?, is 2 not prime?, ... is input not prime?]
   Ʃ            Number of non-primes (sums the array - booleans implicitly converted to ints)
    ⁻           Subtract one to remove the counting of '1'
     Ț          Euler's totient function


Pruébalo en línea!


1

NARS APL, 38 bytes, 19 caracteres

{⍵≤3:0⋄13π¯1+⍵-2π⍵}

13π es la función totient y 2π es la función prime count <= su argumento. Prueba

  b←{⍵≤3:0⋄13π¯1+⍵-2π⍵}     
  (⍳12),¨b¨⍳12
1 0  2 0  3 0  4 1  5 1  6 1  7 1  8 2  9 2  10 4  11 4  12 2 
  (95..100),¨b¨(95..100)
95 24  96 70  97 70  98 24  99 72  100 36

1

Agregar ++ , 21 bytes

L,RþPbL1_dRdVÞ%bLG!!+

Pruébalo en línea!

Cómo funciona

Esto simplemente implementa π¯(n)φ(n)π¯(n)φ(n)

π¯(n)

RþPbL1_

RþPþPbL1_x=π¯(n)

φ(n)

dRdVÞ%bLG!!+

xdRÞ%xxbL

n1nG!!

Sí, realmente quería probar el nuevo LaTex

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.