计算Phi(非Pi)


73

不,我不是说ϕ = 1.618...π = 3.14159...。我的意思是功能

  • φ(x)的是一个整数小于或等于的数量x互质到x
  • π(x)是小于或等于的素数x
  • 假设“非pi”为π̅(x),并将其定义为小于或等于的复合x

任务

给定一个严格的正整数x计算φ(π̅(x))。得分以字节为单位。

例子

每行包括输入(从1到100,包括1和100),以及由空格分隔的相应输出。

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

使用此链接可以计算任何输入的预期输出。另外,pastebin上x <= 1000提供了输入和输出的列表。(使用此Minkolang程序生成。)


排行榜

这是一个堆栈片段,用于按语言生成常规排行榜和获胜者概述。

为确保您的答案显示出来,请使用以下Markdown模板以标题开头。

## Language Name, N bytes

N您提交的文件大小在哪里。如果您提高了分数,则可以通过打败旧分数保持标题。例如:

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

如果要在标头中包含多个数字(例如,因为您的分数是两个文件的总和,或者您想单独列出解释器标志罚分),请确保实际分数是标头中的最后一个数字:

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

您还可以将语言名称设置为链接,然后该链接将显示在页首横幅代码段中:

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


输入的大小是否有限制?
lirtosiast 2015年

4
这个问题是对用户PhiNotPi的致敬吗?
primo

24
@primo为什么会这样呢?
Mego

2
@primo:它的灵感来自于他的名字,绝对是一个双关语,但不完全是对他的致敬。
El'endia Starman

1
@ edc65:是的,显然是这样,正如我昨天发现的那样。
El'endia Starman

Answers:


27

GS212 10个字节

V@'◄l.1&‼l

源代码使用CP437编码。在线尝试!

测试运行

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

这个怎么运作

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
文件名比程序长。
弗洛里斯2015年

43

正则表达式(.NET),122个 113字节

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

假设输入和输出为一元,则输出取自正则表达式的主匹配项。

正则表达式的细分:

  • ^(?=((?=.*$(?<=^(\3+(.+.))(.*?(?>(.\4)?)))).)+(.*)) 计算π̅(x)并在捕获组6中捕获其余字符串,以在第二部分中进行断言。

    • .*$将指针设置为字符串的末尾,以便我们x在一个方向上具有整数。
    • (?<=^(\3+(.+.))(.*?(?>(.\4)?))) 从右到左匹配,并从x到0循环检查复合数字。
      • (.*?(?>(.\4)?))是一个“变量”,它在第一个迭代中从0开始,从上一个迭代中的数字开始,一直循环到x。由于最小的组合数是4,因此(.\4)?如果捕获组4可用,匹配将永不失败。
      • ^(\3+(.+.))检查上面的“变量”(即x - "variable")剩下的内容是否是一个复合数字。
  • ((?=.*(?=\6$)(?<=(?!(.+.)\8*(?=\6$)(?<=^\8+))(.+?(?>\9?)))).)+通过使用限制从左到右的运算来计算φ(π̅(x))(?=\6$)

    • .*(?=\6$)将指针设置为位置π̅(x)。让我们表示y =π̅(x)。
    • (?<=(?!(.+.)\8*(?=\6$)(?<=^\8+))(.+?(?>\9?))) 从右到左匹配,并通过从(y-1)到0循环来检查相对素数
      • (.+?(?>\9?)) 是一个“变量”,它在第一个迭代中从1开始,从上一个迭代中的数字开始,一直循环到y
      • (?!(.+.)\8*(?=\6$)(?<=^\8+))从左到右 1匹配,并检查“变量”和y是否是相对质数。
        • (.+.)\8*(?=\6$) 选择大于1的“变量”的除数,副作用是我们的整数y在左侧。
        • (?<=^\8+) 检查“变量”的除数是否也是y的除数。

1在.NET中,前瞻方向设置为LTR,而不是遵循当前方向。向后查找将方向设置为RTL,而不是反转方向。

RegexStorm中测试正则表达式。

修订版2删除不捕获的组,并使用原子组而不是条件语法。


24
先生,你生气了。
RK。

9
我觉得他对Zalgo有所了解。
curiousdannii 2015年

11
现在您有两个问题。(严重地不知道您可以使用Regex来做这种事情...)
Darrel Hoffman 2015年

21

J,15 14字节

5 p:<:-_1 p:>:

这是一个默认的单调动词。使用J.js在线尝试。

这个怎么运作

                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
我可以解释吗?:P
anOKsquirrel 2015年

23
我添加了解释
丹尼斯

5
我正要说,我upvoted这一点,因为它有很多的表情图标,但文字告诉我,以避免那些:(
Doddy

@Dennis:您的第一个答复使我笑得很辛苦,谢谢!
Mehrdad

19

严重的是,27个字节

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

是的,我击败了CJam!在线尝试

说明(a指的是堆栈的顶部,b指的是从上至下的第二个):

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

注意:自发布此答案以来,我已将pi和phi函数添加到“认真”中。这是这些功能的非竞争性答案:

,;▓1-@-▒

说明(某些命令转移为不与其他命令重叠):

,    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
您已严重超出@Dennis!
TanMath

请不要告诉我,你知道这在你的头顶..
DividedByZero

1
GJ击败CJam =)
瑕疵的

14

朱莉娅,52 50字节

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

这将创建一个未命名的函数,该函数接受和整数并返回一个整数。要给它起个名字,例如f=x->...

取消高尔夫:

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

使用sum而不是count保存几个字符。但是,这有点令人沮丧-计算质数的另一种方法sum(isprime,1:x)与的长度完全相同endof(primes(x))
Glen O

1
@GlenO感谢您的建议,但sumcount返回0时无法进行空集合。因此sum不会产生所需的结果x<4
Alex A.

8

Mathematica,24个字节

EulerPhi[#-PrimePi@#-1]&

2
当然数学有这一切建立在...
拍拍

@ConfusedMr_C显然:)但是,它并没有被取消参赛资格,原因很明显:数学软件无法在简单的组合任务中击败高尔夫语言:)

@ConfusedMr_C PhiNotPi@#&:11个字节:P
LegionMammal978

8

Pyth,14个字节

JlftPTSQ/iLJJ1

演示验证

我们使用一个简单的过滤器来计算合成,取其长度并将其保存到J。然后,我们将J每个数字的gcd取到J,并计算有多少结果等于1。


7

Minkolang 0.11,12个字节(不具有竞争力)

这个答案没有竞争力。在发布问题之前,我将pi和phi内置为实现,这给了我不公平的优势。我仅针对那些对语言感兴趣的人发布此信息。

nd9M-1-9$MN.

在这里尝试。

说明

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
我认为发布无效答案不是一个好主意...
Yeti 2015年

20
只要他们有免责声明,我认为它没有任何问题。对于较旧的挑战,这实际上很常见。
丹尼斯

4
@yeti:从技术上讲,它不是无效的。在发布挑战之前,此处使用的所有功能均已实现。我只是取消了参赛资格,因为我推迟发布挑战,直到实现了两个特定功能(我曾经用来生成示例列表)。
El'endia Starman 2015年

1
相同。𝔼𝕊𝕄𝕚𝕟不断更新时,我经常这样做。
Mama Fun Roll

6

CJam,28个字节

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

在CJam解释器中尝试这种小提琴,或者立即验证所有测试用例

这个怎么运作

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.

我尝试了“验证所有情况”链接,并获得了:1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111。那正确吗?
El'endia Starman

是的,它检查将代码应用于左列(输入)是否等于右列(输出)。
丹尼斯

5
我可以对dis1进行解释吗?
anOKsquirrel

9
@anOKsquirrel我已经解释了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
我想你可以通过删除之间的空间节省2个字节range(n) if])) if
DankMemes

3
鉴于Python的高尔夫能力相对较低(由于空白要求等),这非常令人印象深刻!
felixphew

@DankMemes,谢谢你的提示!
wnnmaw 2015年

5

视网膜,48字节

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

在线尝试!

说明

.+
$*

将输入转换为一元。

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

通过计算匹配包含至少两次重复系数至少为2的字符串的频率来计算不大于输入的复合数字。

.+
$*

再次转换为一元。

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

通过从多少个位置进行计数来计算φ,从那个位置不可能找到后缀的一个因子(至少2个),这也是前缀的一个因子(如果我们找到这样的因子,则该i <= n因子与n因此不是互斥的)。将.在年底确保我们不指望零(对此我们无法找到至少2倍)。


5

正则表达式(.NET),88 86字节

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

在线尝试!(作为Retina程序。)

使用与n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀h̷̰̀的答案相同的I / O ,即一元输入,它匹配结果长度的子字符串。

通过用正向引用替换两个或两个平衡组,可以进一步缩短此时间。

在相同字节数下的替代方法:

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

前半部分也有其他选择,例如对组合数字使用负前瞻而不是正数,或者在其中也使用条件。

说明

我假设您对平衡组有基本的了解,但是简而言之,.NET中的捕获组是堆栈(因此,每次重用捕获组时,新捕获都将推入顶部)并(?<-x>...)从堆栈中弹出捕获x。这对计算事物非常有帮助。

^                   # 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

果冻,不竞争

7 个字节 该答案是非竞争性的,因为它使用的是后一种挑战的语言。

ÆC_@’ÆṪ

这个怎么运作

Æ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

八度,52 51

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

编辑:感谢Thomas Kwa保存了1个字节

说明:

@(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字节

euler_phi(n-1-prime_pi(n))

得益于Sage的实施,即使在n=0和时也能很好地工作n=1





2

MATL,9字节(非竞争)

这个答案没有竞争力,因为该语言将挑战推迟了。

:Zp~sq_Zp

使用语言/编译器的版本(10.1.0)

在线尝试!

说明

:       % 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字节

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

Number(l,p)计算l满足多少个元素p。为了补偿1既不是素数也不是复合数的事实,我必须从n中减去大于n的素数个数。我不-1以两个字节为单位,而是以-2而不是1或2开头列表,因此添加了一个多的数字,IsPrime仅对一个额外的字节加上了一个素数。


2

Python 3.5-130字节

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

如果不能以p(n,0,0)的形式传递函数,则+3个字节。

这利用了以下事实:我使用威尔逊定理来检查数字是否为合成数,并且必须调用阶乘函数的数学模块。Python 3.5在math模块中添加了gcd函数。

如果数字是复合数字,则代码的第一个循环将k加1,否则将0加。(尽管威尔逊定理仅适用于大于1的整数,但将1视为质数,因此允许我们利用此定理)。

然后,第二个循环将在复合数范围内循环,并且仅当非pi和l的值互质时才增加g。

g是小于或等于n的复合数的数量。



1

05AB1E11 8字节

LDpÈÏg<Õ

在线尝试!

这可能是非竞争性的-我找不到05AB1E的制造时间。

这个怎么运作

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 个字节

řṗ¬Ʃ⁻Ț

说明:

                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


在线尝试!


1

APL NARS,38个字节,19个字符

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

13π是上位函数,2π是计数素数函数<=其自变量。测试

  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

加+,21字节

L,RþPbL1_dRdVÞ%bLG!!+

在线尝试!

这个怎么运作

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

π¯(n)

RþPbL1_

RþPþPbL1_x=π¯(n)

φ(n)

dRdVÞ%bLG!!+

xdRÞ%xxbL

n1nG!!

是的,我确实很想尝试新的LaTex

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.