뫼비우스 기능


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

nn의 소인수 분해 지수가 모두 2보다 작 으면 squarefree 라고 합니다. (또는 두 분할의 거듭 제곱은 없습니다 n).

테스트 사례

여기서 μ의 처음 50 개 값을 볼 수 있습니다.

Wikipedia의 공개 도메인 이미지

Möbius 기능은 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.com 또는 OEISb 파일 에서 더 큰 값을 쉽게 확인할 수도 있습니다 .

답변:


15

파이썬 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)

Möbius 가 시퀀스를 반전 시킵니다 1,0,0,0,0....

뫼비우스 함수에 대한 모든 것을 갖는 속성 n>1의 뫼비우스 함수 n0 따라서 행의 약수의 합계에 대해 n>1, μ(n)합을 부정함으로써 계산되는 μ(k)모든 적절한 제수에 대한 k의이 n. 의 경우 n=1출력은 1입니다.

코드는 바닥 분할 첨가하여 기재를 처리하는 경우 1/n부여 1를 위해 n==1그리고 0그렇지.

이 과제 에서 유사한 구조에서 영감을 얻은 더 나은 재귀 처리로 3 바이트를 절약 해 준 Dennis에게 감사합니다 .


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( 내장 내장 인지 확실하지 않지만 지금은 괜찮습니다).
Outgolfer Erik

10

수학, 9 바이트

MoebiusMu

물론 Mathematica는 내장되어 있습니다. (그리고 어쩌면 젤리가 이길 것입니다.)


7

CJam, 18 15 바이트

WrimFz~\1&+f/:*

CJam이 인수 분해 내장에서 1을 반환한다는 사실 n = 1은 약간 까다로워집니다.

온라인으로 사용해보십시오 | 테스트 스위트

1&+1 건을 처리하기위한 깔끔한 트릭에 대한 @PeterTaylor에게 감사드립니다 .

설명

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제곱이없는 경우 배열은 모두 1이며 나누기 후 모두 -1이됩니다. 그렇지 않으면, n에 소수의 제곱이 있으면 나누기 후 어딘가에 0이 생기고 곱은 0이됩니다.

들면 n = 1변형 배열 [1] + [1]이되는, [-1 -1]하나의 제품을 제공 분할 후.


대안 16 :

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

이것은 #[base exponent]배열에서 (찾기)를 사용 하여 1을 찾은 다음 maps -1 -> 0, 0 -> 1, 1 -> -1합니다.


6

루비, 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
}

숫자가 짝수이면 "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
:
}
?   @ "}){/{=:
""({! "      ;
} )   :}}:={%"
* _}}){     ;
{      #}):{{
")`%#/{+

온라인으로 사용해보십시오!

간단한 설명

파이썬에서 사용되는 알고리즘의 포트는 다음과 같습니다.

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)

긴 설명

미로의 일반적인 입문서 :

  • 미로는 스택 기반이며 2 차원이며, 첫 번째 인식 된 문자부터 실행이 시작됩니다. 기본 스택과 보조 스택의 두 가지 스택이 있지만 대부분의 운영자는 기본 스택에서만 작업합니다.
  • 미로의 모든 지점에서 스택의 상단을 확인하여 다음에 갈 곳을 결정합니다. 음수는 좌회전, 0은 직진, 양수는 우회전입니다.

이 프로그램의 실행은 왼쪽 상단에서 시작됩니다 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 덕분입니다.


이렇게하면 각 정수에 대해 평가 된 Möbius 함수가 1에서 입력으로 반환되지만이 문제는 입력에서 Möbius 함수를 평가하는 것입니다.
Alex A.

Mathematica 답변의 행을 따라 numbers::moebius16 바이트를 간단하게 수행 할 수도 있습니다.
Alex A.

3

Pyth , 16 바이트

?nl{PQlPQZ^_1lPQ

온라인으로 사용해보십시오!

나의 첫번째 실제 Pyth 답변. 제안 감사합니다! :)

설명

내 솔루션은 소수에 두 번 이상 숫자가 포함되지 않으면 숫자에 제곱이 없다는 사실을 사용합니다. 입력 값에 제곱이없는 경우 Möbius-Function은 -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 인코딩을 사용합니다.


8888-1에

1
@ETHproductions 어? 그렇다면 어떤 종류의 인코딩입니까? 나는 이 사이트 에서 그것을 얻었다 .
Adnan

나는 그것이 확장 ASCII 라고 믿습니다 .
ETHproductions

@ETHproductions 감사합니다, 게시물을 편집했습니다 :)
Adnan

@ThomasKwa Ahh, 찾았습니다. 그것은 인 CP-1252 부호화.
Adnan

2

피스, 11

*{IPQ^_1lPQ

테스트 스위트

이는 소인수에 제곱이없는 경우의 부울 값에 해당 수의 소인수의 거듭 제곱을 곱합니다 -1.

I선행 연산자에 대한 불변성 검사입니다. 여기는 {고유 연산자입니다.



2

줄리아, 66 바이트

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

정수를 받아들이고 정수를 반환하는 람다 함수입니다. 호출하려면 변수에 지정하십시오.

언 골프 드 :

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 코어) , 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 바이트 : 간소화 된 루프, 반환 변수 추가 ( 케빈 크루 이슨 에게 감사함 )
-1 바이트 : b에서 0으로 설정을 b에서 0으로 삼진으로 변경 함 ( 케빈 크루이 센 에게 감사함 )
-7 바이트 : for 루프의 문을 3 항으로 변경 ( 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==0되었습니다 a%i<1. 로 변경 b*=-1;했습니다 b=-b;. 그리고 마침내를로 변경 return 0;했습니다 b=0;.
Kevin Cruijssen

네, 당신이 제안한 모든 것이 정확 해 보였습니다. 나는 당신이 그것이 옳지 않다고 말했을 때 약간 걱정했다. 왜냐하면 그것은 내 원래 코드가 잘못되었다는 것을 의미했기 때문이다! :)
Meerkat

1
그래, 미안해 :) 골프 1 바이트 이상은 BTW이다 if(a%i<1)b=0;b=a%i<1?0:b;.
Kevin Cruijssen

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 개 바이트를 저장합니다.
Kevin Cruijssen

1

GNU sed, 89 바이트

#!/bin/sed -rf
s/.*/factor &/e
s/.*://
/\b([0-9]+) \1\b/!{
s/[0-9]+//g
s/$/1/
s/  //g
y/ /-/
}
s/ .*/0/


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.

Nice solution =) (그러나이 언어는 질문보다 어리다고 생각합니다.)
flawr

@flawr 분명히 대답은 진지하게 잘 작동합니다. 실제로 온라인이 처음 온시기를 알 수 없으므로 안전을 위해 진지하게 변경했습니다.
Sherlock9

1

자바 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;}

@PeterTaylor 덕분에 -4 바이트 .

@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;.
Kevin Cruijssen

0

자바 스크립트 (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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.