莫比乌斯函数


23

莫比乌斯函数

莫比乌斯函数是重要的数论函数。

您的提交应接受一个正整数,n并返回在处评估的Möbius函数的值n

定义

莫比乌斯函数μ(n)定义如下:

       |  1 if n is squarefree and has an even number of distinct prime factors
μ(n) = | -1 if n is squarefree and has an odd number of distinct prime factors
       |  0 otherwise

n如果n的质数分解的指数严格都小于2,则称为方自由。(或者:两个分割的幂都不是素数n)。

测试用例

在这里,您可以看到μ的前50个值:

来自维基百科的公共领域图像

默比乌斯函数是OEIS中的序列号A008683

这些是前77个值:

1, -1, -1, 0, -1, 1, -1, 0, 0, 1, -1, 0, -1, 1, 1, 0, -1, 0, -1, 0, 1, 1, -1, 0, 0, 1, 0, 0, -1, -1, -1, 0, 1, 1, 1, 0, -1, 1, 1, 0, -1, -1, -1, 0, 0, 1, -1, 0, 0, 0, 1, 0, -1, 0, 1, 0, 1, 1, -1, 0, -1, 1, 0, 0, 1, -1, -1, 0, 1, -1, -1, 0, -1, 1, 0, 0, 1

如@MartinBüttner所建议的,也可以在Wolframalpha.comOEISb文件中轻松检查较大的值。

Answers:


15

Python 2,48个字节

m=lambda n,d=1:d%n and-m(d,n%d<1)+m(n,d+1)or 1/n

较早的51字节版本:

m=lambda n:1/n-sum(m(k)for k in range(1,n)if n%k<1)

莫比乌斯反转序列1,0,0,0,0...

莫比乌斯函数,对于任何财产n>1,的莫比乌斯功能n的除数总和为0。所以,对n>1μ(n)是通过否定的总和来计算μ(k)所有适当的除数kn。对于n=1,输出为1

该代码通过将地板分割处理基础案例1/n,这给1用于n==10其它。

感谢Dennis节省了3个字节,并在此挑战中得到了类似结构的启发,实现了更好的递归处理。


13

果冻,7个字节

码:

ÆF>1’PS

说明:

ÆF       # This computes the prime factorization as well as the exponent
  >1     # Compares each element if it's greater than 1, resulting in 1's and 0's
    ’    # Decrement on each element
     P   # Compute the product
      S  # Compute the sum of the list

例如,数字10

ÆF       # [[2, 1], [5, 1]]
  >1     # [[1, 0], [1, 0]]
    ’    # [[0, -1], [0, -1]]
     P   # [0, 1]
      S  # 1

结果为1

在线尝试


-1字节:(ÆFỊNPS不确定当时是否是内置的,但现在应该可以了)。
暴民埃里克(Erik the Outgolfer)'18年

10

Mathematica,9个字节

MoebiusMu

当然,Mathematica具有内置功能。(反正很可能会被果冻打败。)


7

CJam,18个 15字节

WrimFz~\1&+f/:*

CJam在因式分解内置函数中返回1的事实n = 1使事情变得有些棘手。

在线试用 | 测试套件

感谢@PeterTaylor提供了1&+处理1个案例的巧妙技巧。

说明

W                 Push -1
 ri               Push input as int
   mF             Factorise input into [base exponent] pairs
     z~           Zip and unwrap pairs, leaving stack like [-1 bases exponents]
       \1&        Setwise intersect bases with 1, giving [1] for 1 and [] otherwise
          +       Append to exponent array
           f/     Divide the previously pushed -1 by each element in the array 
                  This gives -1 for 1s and 0 otherwise, since / is int division
             :*   Take product

对于n > 1,修改后的数组只是指数数组。如果n为squarefree,则数组为全1,除后为全-1。否则,如果n具有一个素数平方除数,那么除法后某处将有一个0,得到的积为0。

对于n = 1修改后的数组是[1] + [1],它[-1 -1]在除法后变为1的乘积。


选项16:

rimF{1#2+3%(}%:*

#在每个[base exponent]数组上使用(查找)查找1,然后映射-1 -> 0, 0 -> 1, 1 -> -1


6

Ruby,65 + 7 = 72 62 + 7 = 69字节

->x{((d=x.prime_division).all?{|_,n|n<2}?1:0)*(d.size%2*-2+1)}

-rprime标志的+7个字节。

我们这样做是非常幼稚的:

->x{
 (
  (d=x.prime_division)  # ex. input 20 results in [[2,2],[5,1]] here
  .all?{|_,n|n<2}?      # are all factors' exponents under 2?
  1:0                   # if so, result in a 1; otherwise, a 0
 )
 *                      # multiply that 1 or 0 by...
  (d.size%2*-2+1)       # magic
}

如果数字为偶数,则“魔术”部分的结果为1,否则为-1。这是如何做:

Expression       Even  Odd
--------------------------
d.size%2         0     1
d.size%2*-2      0     -2
d.size%2*-2+1    1     -1

5

Pyth,9个字节

^_{IPQlPQ

说明:

^_{IPQlPQ    Implicit: Q=input
    PQ       Prime factorization of Q
  {I         Is invariant under uniquify.
  {IPQ       1 if Q is squarefree; 0 otherwise.
 _{IPQ       -1 if Q is squarefree; 0 otherwise.
^     lPQ    Exponentiation to length of PQ.

在这里尝试。


5

迷宫,87字节

1
:
}
?   @ "}){/{=:
""({! "      ;
} )   :}}:={%"
* _}}){     ;
{      #}):{{
")`%#/{+

在线尝试!

简短说明

这是Python中使用的算法的端口:

divisor = 1
mobius = 1
n = int(input())

while n != 1:
  divisor += 1
  count = 0

  while n % divisor == 0:
    n //= divisor
    count += 1

  mobius *= (count + 3)//(count + 1)%3*-1 + 1

print(mobius)

详细说明

迷宫的常用入门书:

  • 迷宫是基于堆栈的和二维的,执行从第一个可识别的字符开始。有两个堆栈,一个主堆栈和一个辅助堆栈,但是大多数操作员仅在主堆栈上工作。
  • 在迷宫的每个分支上,都要检查堆栈的顶部以确定下一步要去的地方。负数是左转,零是正数,正数是右转。

该程序的执行从左上角开始1

Outer preparation
=================

1        Pop 0 (stack is bottomless and filled with 0s) and push 0*10+1 = 1
:}       Duplicate and shift to auxiliary stack
?        Read int from input
         Stack is now [div=1 n | mob=1]

Top of stack positive but can't turn right. Turn left into outer loop.

Begin outer loop
================
Inner preparation
-----------------

(        Decrement top of stack

If top was 1 (and is now zero), move forward and do...
------------------------------------------------------

{!       Print mob
@        Terminate

If top of stack was greater than 1, turn right and do...
--------------------------------------------------------

)        Increment n back to its previous value
_}       Push 0 and shift to aux
         This will count the number of times n can be divided by div
}){      Increment div
         Stack is now [div n | count mob]

Inner loop
----------

:}}      Dup n, shift both n's to aux
:=       Dup div and swap top of main with top of aux
{%       Shift div down and take mod
         Stack is now [div n%div | n count mob]

If n%div == 0, move forward and do...
-----------------------------------

;        Pop n%div
:={/     Turn n into n/div
{)}      Increment count
         (continue inner loop)

If n%div != 0, turn right (breaking out of inner loop) and do...
================================================================

;        Pop n%div
{{       Pull n and count from aux
:)}      Dup and increment count, giving (count+1), and shift to aux
#+       Add length of stack to count, giving (count+3)
{/       Calculate (count+3)/(count+1)
#%       Mod by length of stack, giving (count+3)/(count+1)%3
`        Multiply by -1
)        Increment, giving (count+3)/(count+1)%3*-1 + 1
         This is 1 if count was 0, -1 if count was 1 and 0 if count > 1
{*}      Multiply mob by this number
         (continue outer loop)


4

R 39 16字节

numbers::moebius

要求您在系统上安装号码软件包...

编辑:如果我正确地阅读了规格,则要简单得多[感谢@AlexA。]


这会将针对每个整数(从1开始)评估的Möbius函数返回到输入,但是此挑战的任务只是评估输入上的Möbius函数。
Alex A.

按照Mathematica的答案,您甚至可以仅用numbers::moebius16个字节来完成。
Alex A.

3

Pyth,16个字节

?nl{PQlPQZ^_1lPQ

在线尝试!

我的第一个Pyth实际答案。建议表示赞赏!:)

说明

我的解决方案使用以下事实:如果数字的素因数最多包含一次,则该数字是无平方的。如果输入是无平方的,则Möbius函数的值将为-1 ^(素因数)。


?n        if not equal
  l{PQ      length of the list of the distinct input-Primefactors
  lPQ       length of the list of primefactors including duplicates    
    Z         Input is not squarefree, so output Zero
  ^_1lPQ  if input is squarefree, output -1^(number of prime-factors)

3

MATL,15 17字节

tq?YftdAwn-1w^*

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

在线尝试!

说明

t         % implicit input. Duplicate that
q         % decrement by 1. Gives truthy (nonzero) if input exceeds 1
?         % if input exceeds 1, compute function. Otherwise leave 1 on the stack
  Yf      % vector of prime factors. Results are sorted and possibly repeated
  td      % duplicate and compute differences
  A       % true if all differences are nonzero
  w       % swap
  n       % number of elements in vector of prime factors, "x"
  -1w^    % -1^x: gives -1 if x odd, 1 if x even 
  *       % multiply by previously obtained true/false value, so non-square-free gives 0
          % implicitly end "if"
          % implicitly display stack contents

3

05AB1E,8字节,非竞争

该死,再次是一个使我的提交失去竞争的错误。码:

.p0K1›<P

说明:

.p        # Get the prime factorization exponents
  0K      # Remove all zeroes from the list
    1›    # Compare each element if greater than 1
      <   # Decrement on each element
       P  # Take the product

使用CP-1252编码


不在ISO 8859-1中...
ETHproductions'Jan

1
@ETHproductions嘿?那是什么样的编码?我从这个网站上得到的。
阿德南

我相信它叫做扩展ASCII
ETHproductions 2016年

@ETHproductions谢谢,我已经编辑了帖子:)
Adnan

@ThomasKwa Ahh,我找到了。它是CP-1252编码。
阿德南

2

珀斯,11岁

*{IPQ^_1lPQ

测试套件

如果素数是平方无方的-1,这会将布尔值乘以该数具有的素数的幂。

I是对先前运算符的不变性检查,这里是{,这是唯一化运算符。



2

朱莉娅66字节

n->(f=factor(n);any([values(f)...].>1)?0:length(keys(f))%2>0?-1:1)

这是一个lambda函数,它接受一个整数并返回一个整数。要调用它,请将其分配给变量。

取消高尔夫:

function µ(n::Int)
    # Get the prime factorization of n as a Dict with keys as primes
    # and values as exponents
    f = factor(n)

    # Return 0 for non-squarefree, otherwise check the length of the list
    # of primes
    any([values(f)...] .> 1) ? 0 : length(keys(f)) % 2 > 0 ? -1 : 1
end

2

PARI / GP,7个字节

moebius

可悲的möbius是不可用。:)


2

严重的是19 18字节

,w;`iX1=`Mπ)l1&τD*

在线尝试!

说明:

,w;`iXDY`Mπ)l1&τD*
,w;                push two copies of the full prime factorization of the input
                      (a list of [base, exponent] pairs)
   `    `M         map the following function:
    iX1=             flatten list, discard, equal to 1
                        (push 1 if exponent == 1 else 0)
          π)       product of list, push to bottom of stack
            1&     push 1 if the # of prime factors is even else 0
              τD   double and decrement (transform [0,1] to [-1,1])
                *  multiply

2

C#(.NET Core)86 73 72 65字节

a=>{int b=1,i=1;for(;++i<=a;)b=a%i<1?(a/=i)%i<1?0:-b:b;return b;}

在线尝试!

-13字节:简化的循环,添加了返回变量(感谢Kevin Cruijssen
-1字节:将设置b从if更改为三进制(感谢Kevin Cruijssen
-7字节:将if语句在for循环中更改为三进制(感谢Peter TaylorKevin Cruijssen

取消高尔夫:

a => {
    int b = 1, i = 1;           // initialize b and i to 1

    for(; ++i <= a;)            // loop from 2 (first prime) to a
        b = a % i < 1 ?                     // ternary: if a is divisible by i
            ((a /= i) % i < 1 ? 0 : -b) :   // if true: set b to 0 if a is divisible by i squared, otherwise flip sign of b
            b;                              // if false: don't change b

    return b;                   // return b (positive for even numbers of primes, negative for odd, zero for squares)
}

1
73个字节,我已更改int b=1;for(int i=1;int b=1,i=1;for(;。删除{}了循环的- 括号。都更改a%i==0a%i<1。更改b*=-1;b=-b;。最后更改return 0;b=0;
凯文·克鲁伊森

是的,您建议的所有内容看起来都是正确的。当您说这是不对的时候,我曾经有点担心,因为那也意味着我的原始代码也是错误的!:)
猫鼬(Meerkat)'18年

1
是的,对此感到抱歉。:)高尔夫1个字节BTW是if(a%i<1)b=0;b=a%i<1?0:b;
凯文·克鲁伊森

2
实际上,这忽略了一个简单的改进:b=-b;b=a%i<1?0:b;前往b=a%i<1?0:-b;
泰勒·泰勒

1
继续对@ PeterTaylor高尔夫上面,你就可以改变if(a%i<1){a/=i;b=a%i<1?0:-b;},以b=a%i<1?(a/=i)%i<1?0:-b:b;挽救3个字节。
凯文·克鲁伊森



1

Microsoft Office Excel,英语版,196字节

=IF(ROW()>=COLUMN(),IF(AND(ROW()=1,COLUMN()=1),1,IF(COLUMN()=1,
-SUM(INDIRECT(ADDRESS(ROW(),2)&":"&ADDRESS(ROW(),ROW()))),
IF(MOD(ROW(),COLUMN())=0,INDIRECT(ADDRESS(FLOOR(ROW()/COLUMN(),1),
1)),""))),"")

在单元格A1至AX50中输入Excel单元格公式。



1

严重的是11个字节

欢迎打高尔夫球。在线尝试!

;y;l0~ⁿ)π=*

开球

     Implicit input n.
;    Duplicate n.
y    Push a list of the distinct prime factors of n. Call it dpf.
;    Duplicate dpf.
l    Push len(dpf).
0~   Push -1.
ⁿ    Push (-1)**len(dpf).
)    Rotate (-1)**len(dpf) to BOS. Stack: dpf, n, (-1)**len(dpf)
π    Push product(dpf).
=    Check if product(dpf) == n.
      This is only true if n is squarefree.
*    Multiply (n is squarefree) by (-1)**len(dpf).
     Implicit return.

不错的解决方案=)(但是我想这个语言比问题还年轻吗?)
更加模糊的

@flawr显然,在“认真”中答案也同样有效,并且我不知道“实际上”何时首次上线,因此为了安全起见,我改为“认真”。
Sherlock16年

1

Java 8,72 68 65字节

n->{int r=1,i=1;for(;++i<=n;)r=n%i<1?(n/=i)%i<1?0:-r:r;return r;}

-4个字节,感谢@PeterTaylor

@Meerkat 的.NET C#答案的端口,我首先对其打了一点点,所以请确保对他投票!

在线尝试。

说明:

n->{                 // Method with integer as both parameter and return-type
  int r=1,           //  Result-integer, starting at 1
  i=1;for(;++i<=n;)  //  Loop `i` in the range [1, n]:
    r=n%i<1?         //   If `n` is divisible by `i`:
       (n/=i)        //    Divide `n` by `i` first
        %i<1?        //    And if `n` is still divisible by `i`:
         0           //     Change `r` to 0
        :            //    Else:
         -r          //     Swap the sign of `r` (positive to negative or vice-versa)
      :              //    Else:
       r;            //     Leave `r` unchanged
  return r;}         //  Return `r` as result

请参阅我对Meerkat答案的评论。
彼得·泰勒

@PeterTaylor Smart,谢谢!然后使用可以再保存3个字节r=n%i<1?(n/=i)%i<1?0:-r:r;
凯文·克鲁伊森

0

Javascript(ES6),48个字节

f=(n,i=1)=>n-1?n%++i?f(n,i):(n/=i)%i?-f(n,i):0:1

首先-这是我的第一个代码高尔夫球场,所以在某种程度上我可能会误解规则。在此提交中,最后一个字符;可以省略,并且仍然可以使用,但是我什至不确定代码是否根据ES6规范有效。无论如何,简短的解释。

首先,我将稍微解释一下这个想法;我们取n,然后尝试将其除以整数i。如果可以将其整除,那么我们会这样做,然后i再次检查是否可以将其整除。如果是这种情况,那么我们需要返回0。否则,我们可以尝试另一个i。很酷的事情是,我们可以每次都从i=2添加开始就增加它1,这样我们就可以划分出所有主要因素。

因此,代码如下所示:

f=(n,i=1)=>                                           We will increase i by one at the start of
                                                         the function body, so default is 1
           n-1?                                       Check if n==1.
               n%++i?                                 If i isn't, increase i by 1, check if n
                                                         is divisible by i
                     f(n,i):                          if it isn't, we check the next i
                            (n/=i)%i?                 if it is, divide n by i, and check for
                                                         divisibility by i again
                                     -f(n,i):         if it not, then we flip the value to
                                                         account for the 1 and -1 depending on the
                                                         amount of factors
                                             0:       if it's divisible by i twice, done.
                                               1      if we're at 1, divided out all factors,
                                                         then we return 1. The line with
                                                         -f(n,i) will then take care of the sign

所以,那是我的意见书。


欢迎来到该网站。我不了解js,但我可以告诉您,这里我们不关心规格,仅关心实现。因此,如果删除;不会破坏它,则可以删除它的规格都没有关系。
小麦巫师

很高兴知道!然后我将其删除;)
vrugtehagel
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.