Calcular Phi (não Pi)


73

Não, eu não quero dizer ϕ = 1.618...e π = 3.14159.... Quero dizer as funções .

  • φ (x) é o número de números inteiros menores ou iguais aos xque são relativamente primos para x.
  • π (x) é o número de primos menor ou igual a x.
  • Digamos que "not pi" seja então π̅ (x) e defina-o como o número de compósitos menor ou igual a x.

Tarefa

Dado um número inteiro estritamente positivo x, calcule φ (π̅ (x)) . A pontuação está em bytes.

Exemplos

Cada linha consiste na entrada (de 1 a 100, inclusive) e na saída correspondente separada por um espaço.

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 link para calcular a saída esperada para qualquer entrada. Além disso, uma lista de entradas e saídas x <= 1000é fornecida aqui em pastebin . (Gerado com este programa Minkolang .)


Classificação

Aqui está um snippet de pilha para gerar uma classificação regular e uma visão geral dos vencedores por idioma.

Para garantir que sua resposta seja exibida, inicie-a com um título, usando o seguinte modelo de remarcação:

## Language Name, N bytes

onde Nestá o tamanho do seu envio. Se você melhorar sua pontuação, poderá manter as pontuações antigas no título, identificando-as. Por exemplo:

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

Se você quiser incluir vários números no cabeçalho (por exemplo, porque sua pontuação é a soma de dois arquivos ou você deseja listar as penalidades do sinalizador de intérpretes separadamente), verifique se a pontuação real é o último número no cabeçalho:

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

Você também pode transformar o nome do idioma em um link que será exibido no snippet do placar de líderes:

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


Existem limites para o tamanho da entrada?
lirtosiast

4
Esta pergunta é uma homenagem ao usuário PhiNotPi ?
primo

24
@primo Por que você acha isso?
Mego

2
@primo: Foi inspirado pelo nome dele, e definitivamente um trocadilho, mas não exatamente um tributo a ele.
El'endia Starman 13/11/2015

11
@ edc65: Sim, aparentemente , como descobri ontem.
El'endia Starman 13/11/2015

Respostas:


27

GS2 , 12 10 bytes

V@'◄l.1&‼l

O código-fonte usa a codificação CP437 . Experimente online!

Execução de teste

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

Como 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
O nome do arquivo é maior que o programa.
Floris

43

Regex (.NET), 122 113 bytes

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

Supondo que a entrada e a saída estejam unárias, e a saída é obtida da correspondência principal da regex.

Repartição do regex:

  • ^(?=((?=.*$(?<=^(\3+(.+.))(.*?(?>(.\4)?)))).)+(.*)) calcula π̅ (x) e captura o restante da sequência no grupo de captura 6 para afirmação na segunda parte.

    • .*$define o ponteiro para o final da string para que tenhamos o número inteiro xem uma direção.
    • (?<=^(\3+(.+.))(.*?(?>(.\4)?))) corresponde da direita para a esquerda e verifica o número composto fazendo um loop de x a 0.
      • (.*?(?>(.\4)?))é uma "variável" que começa em 0 na primeira iteração e continua no número da iteração anterior e faz um loop até x. Como o menor número composto é 4, (.\4)?nunca falha na correspondência se o grupo de captura 4 estiver disponível.
      • ^(\3+(.+.))verifica o que é deixado pela "variável" acima (ie x - "variable") se é um número composto.
  • ((?=.*(?=\6$)(?<=(?!(.+.)\8*(?=\6$)(?<=^\8+))(.+?(?>\9?)))).)+calcula φ (π̅ (x)), limitando as operações da esquerda para a direita com (?=\6$).

    • .*(?=\6$)define o ponteiro para a posição π̅ (x). Vamos denotar y = π̅ (x).
    • (?<=(?!(.+.)\8*(?=\6$)(?<=^\8+))(.+?(?>\9?))) corresponde da direita para a esquerda e verifica o prime relativo, fazendo um loop de (y - 1) a 0
      • (.+?(?>\9?)) é uma "variável" que começa em 1 na primeira iteração e continua no número da iteração anterior e faz um loop até y
      • (?!(.+.)\8*(?=\6$)(?<=^\8+))corresponde da esquerda para a direita 1 e verifica se a "variável" ey são primos relativos.
        • (.+.)\8*(?=\6$) escolhe um divisor de "variável" maior que 1 e um efeito colateral é que temos o número inteiro y à esquerda.
        • (?<=^\8+) verifica se o divisor de "variável" também é o divisor de y.

1 No .NET, o olhar à frente define a direção como LTR em vez de seguir a direção atual; look-behind define a direção para RTL em vez de inverter a direção.

Teste a regex em RegexStorm .

A revisão 2 descarta grupos não capturadores e usa grupos atômicos em vez de sintaxe condicional.


24
Senhor, você está bravo.
RK.

9
Ele tem um toque do Zalgo, eu acho.
curiousdannii

11
E agora você tem dois problemas. (Sério não tinha idéia de que você poderia fazer esse tipo de coisa com Regex ...)
Darrel Hoffman

21

J, 15 14 bytes

5 p:<:-_1 p:>:

Este é um verbo tácito e monádico. Experimente online com J.js .

Como 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
eu posso explicação haz? : P
anOKsquirrel 13/11/2015

23
i haz adicionou explicação
Dennis

5
Eu estava prestes a dizer que eu upvoted isso porque tem muita smileys, mas o texto me disse para evitar esses :(
Doddy

@Dennis: Sua primeira resposta me fez rir bastante, obrigado por isso!
Mehrdad

19

Sério , 27 bytes

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

Sim, eu venci o CJam! Experimente online

Explicação ( arefere-se ao topo da pilha, brefere-se ao segundo da parte superior):

,;       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 a publicação desta resposta, adicionei as funções pi e phi ao Seriously. Aqui está uma resposta não competitiva com essas funções:

,;▓1-@-▒

Explicação (alguns comandos são alterados para não se sobreporem a outros):

,    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))

11
Você sériamente superou @Dennis!
TanMath

Por favor, não me diga que você sabia isso no topo de sua cabeça ..
DividedByZero

11
GJ batendo CJam =)
flawr

14

Julia, 52 50 bytes

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

Isso cria uma função sem nome que aceita e número inteiro e retorna um número inteiro. Para chamá-lo, dê um nome, por exemplo f=x->....

Ungolfed:

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 em sumvez de countpara salvar alguns caracteres. É um pouco frustrante, no entanto - a outra maneira de contar os números primos sum(isprime,1:x)é exatamente do mesmo tamanho que endof(primes(x)).
Glen O

11
@GlenO Obrigado pela sugestão, mas sumfalha em coleções vazias enquanto countretorna 0. Portanto sum, não produzirá o resultado desejado para x<4.
Alex A.

8

Mathematica, 24 bytes

EulerPhi[#-PrimePi@#-1]&

2
É claro que o Mathematica tem tudo isso construído em ...
clap

@ConfusedMr_C Obviamente :) No entanto, não foi desclassificado, por uma razão óbvia: o software matemático não pode superar os lances do golfe em tarefas combinatórias simples :)
yo '

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

8

Pitão, 14 bytes

JlftPTSQ/iLJJ1

Demonstração , Verificador

Nós calculamos compostos usando um filtro simples, pegamos seu tamanho e salvamos em J. Em seguida, pegamos o MDC de Jcada número até Je contamos quantos resultados são iguais a 1.


7

Minkolang 0.11 , 12 bytes (NÃO competitivo)

Esta resposta NÃO é competitiva. Eu implementei pi e phi como integrados antes de postar a pergunta, o que me dá uma vantagem injusta. Eu publico isso apenas para aqueles que estão interessados ​​no idioma.

nd9M-1-9$MN.

Experimente aqui.

Explicação

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
Eu não acho que a publicação de respostas inválidas é uma boa idéia ...
yeti

20
Contanto que tenham um aviso, não acho que haja algo errado com isso. Na verdade, é bastante comum para desafios mais antigos.
Dennis

4
@ yeti: Tecnicamente, não é inválido. Os recursos usados ​​aqui foram implementados antes do lançamento do desafio. Eu simplesmente o desqualifico porque adiei a postagem do desafio até que dois recursos específicos foram implementados (que eu costumava gerar as listas de exemplos, aliás).
El'endia Starman 13/11/2015

11
Mesmo. Faço isso muito quando estou atualizando.
Mama Fun Roll

6

CJam, 28 bytes

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

Experimente este violino no intérprete CJam ou verifique todos os casos de teste de uma só vez .

Como 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.

Eu tentei o link "verificar todos os casos" e tenho esse: 1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111. Isso está certo?
El'endia Starman 13/11/2015

Sim, verifica se a aplicação do código na coluna esquerda (entrada) é igual à coluna direita (saída).
Dennis

5
posso haz explicação sobre dis1?
Anoksquirrel 13/11/2015

9
@anOKsquirrel i haz explicou dis1 2
Dennis

5
@ Dennis kthxbai
anOKsquirrel

5

Python, 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
Eu acho que você pode salvar 2 bytes, removendo os espaços entre range(n) ife])) if
DankMemes

3
Dada a capacidade de golfe relativamente baixa do Python (devido aos requisitos de espaço em branco, etc.), isso é bastante impressionante!
Felixphew #

@DankMemes, obrigado pela dica!
wnnmaw

5

Retina , 48 bytes

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

Experimente online!

Explicação

.+
$*

Converter entrada para unário.

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

Conte números compostos não maiores que a entrada, contando com que frequência podemos corresponder a uma sequência que consiste em pelo menos duas repetições de um fator de pelo menos 2.

.+
$*

Converta para unário novamente.

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

Calcular φ contando de quantas posições não é possível encontrar um fator (de pelo menos 2) do sufixo dessa posição, que também é um fator do prefixo (se encontrarmos esse fator, isso i <= ncompartilha um fator com nportanto, não é coprime). O .final garante que não contemos zero (para o qual não conseguimos encontrar um fator de pelo menos 2).


5

Regex (.NET), 88 86 bytes

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

Experimente online! (Como um programa Retina.)

Usa a mesma E / S da resposta de n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̷̨̰́̀ĥ̷̳ , ou seja, entrada unária e corresponde a uma substring do comprimento do resultado.

Pode ser possível reduzir ainda mais isso, substituindo um ou ambos os grupos de balanceamento por referências futuras.

Alternativa na mesma contagem de bytes:

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

Existem também algumas alternativas para a primeira metade, por exemplo, usar um lookahead negativo em vez de positivo para os números de composição, ou usar um condicional também.

Explicação

Suponho que você tenha um entendimento básico dos grupos de balanceamento , mas, em resumo, os grupos de captura no .NET são pilhas (portanto, toda vez que você reutiliza o grupo de captura, a nova captura é colocada na parte superior) e (?<-x>...)exibe uma captura da pilha x. Isso é muito útil para contar as coisas.

^                   # 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 , não concorrente

7 bytes Esta resposta não é concorrente, pois usa um idioma que pós-data do desafio.

ÆC_@’ÆṪ

Como 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

Oitava, 52 51

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

Edit: economizou 1 byte graças a Thomas Kwa

Explicação:

@(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 bem mesmo para n=0e n=1, graças à implementação do Sage.





2

MATL , 9 bytes (não concorrente)

Essa resposta não é competitiva, pois o idioma pós-desafio.

:Zp~sq_Zp

Usa a versão (10.1.0) do idioma / compilador.

Experimente online!

Explicação

:       % 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)conta quantos elementos de lsatisfazem p. Para compensar o fato de que 1 não é nem primo nem composto, preciso subtrair de n um a mais que o número de primos até n. Em vez de fazer -1por dois bytes, inicio a lista com -2 em vez de 1 ou 2, adicionando mais um número que é considerado primo por IsPrimeapenas um byte extra.


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

Se não for aceitável passar a função como p (n, 0,0), então +3 bytes.

Isso tira proveito do fato de eu usar o teorema de Wilson para verificar se um número é composto e precisar chamar o módulo de matemática para a função fatorial. O Python 3.5 adicionou uma função gcd ao módulo de matemática.

O primeiro loop do código aumentará k em um se o número for composto e aumentará em 0 de outra maneira. (Embora o teorema de Wilson seja válido apenas para números inteiros maiores que 1, ele trata 1 como primo, portanto, podemos explorar isso).

O segundo loop passará pelo intervalo de número de compostos e incrementará g somente quando o valor de não pi e l forem co-primos.

g é então o número de valores menor ou igual ao número de números compostos menores ou iguais a n.



1

05AB1E , 11 8 bytes

LDpÈÏg<Õ

Experimente online!

Isso pode não ser competitivo - não consigo descobrir quando 05AB1E foi criado.

Como 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

řṗ¬Ʃ⁻Ț

Explicação:

                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


Experimente online!


1

NARS APL, 38 bytes, 19 caracteres

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

13π é a função totiente e 2π é a função prime de contagem <= seu argumento. Teste

  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

Adicionar ++ , 21 bytes

L,RþPbL1_dRdVÞ%bLG!!+

Experimente online!

Como funciona

π¯(n)φ(n)π¯(n)φ(n)

π¯(n)

RþPbL1_

RþPþPbL1_x=π¯(n)

φ(n)

dRdVÞ%bLG!!+

xdRÞ%xxbL

n1nG!!

Sim, eu realmente queria experimentar o novo LaTex

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.