Hàm Möbius


23

Hàm Möbius

Hàm Möbius là một hàm lý thuyết số quan trọng.

Việc gửi của bạn phải chấp nhận một số nguyên dương nvà trả về giá trị của hàm Möbius được ước tính tại n.

Định nghĩa

Hàm Möbius (n) được định nghĩa như sau:

       |  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được gọi là vuông góc nếu số mũ của thừa số nguyên tố của n hoàn toàn ít hơn hai. (Cách khác: Không có số nguyên tố nào cho lũy thừa của hai phép chia n).

Các trường hợp thử nghiệm

Tại đây bạn có thể thấy 50 giá trị đầu tiên của:

Hình ảnh miền công cộng từ Wikipedia

Hàm Möbius là số thứ tự A008683 trong OEIS.

Đây là 77 giá trị đầu tiên:

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

Các giá trị lớn hơn cũng có thể dễ dàng được kiểm tra trong Wolframalpha.com hoặc trong tệp b của OEIS , theo đề xuất của @ MartinBüttner.

Câu trả lời:


15

Python 2, 48 byte

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

Phiên bản 51 byte trước đó:

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

Möbius - đảo ngược trình tự 1,0,0,0,0....

Hàm Möbius có thuộc tính cho bất kỳ n>1, các hàm Möbius của ncác ước số của nó bằng 0. Vì vậy, đối với n>1, μ(n)được tính bằng cách phủ định tổng của μ(k)tất cả các ước số thích hợp kcủa n. Đối với n=1, đầu ra là 1.

Mã xử lý trường hợp cơ sở bằng cách thêm một phân chia sàn 1/n, cung cấp 1cho n==10nếu không.

Cảm ơn Dennis vì đã lưu 3 byte với khả năng xử lý đệ quy tốt hơn lấy cảm hứng từ một cấu trúc tương tự trong thử thách này .


13

Thạch , 7 byte

Mã số:

ÆF>1’PS

Giải trình:

Æ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

Ví dụ: số 10 :

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

Và kết quả trong 1 .

Hãy thử trực tuyến .


-1 byte: ÆFỊNPS(không chắc là đã được tích hợp sẵn hay chưa, nhưng bây giờ sẽ ổn).
Erik the Outgolfer

10

Toán học, 9 byte

MoebiusMu

Tất nhiên, Mathicala có tích hợp sẵn. (Và có lẽ sẽ bị Jelly đánh bại.)


7

CJam, 18 15 byte

WrimFz~\1&+f/:*

Việc CJam trả về 1 trong các nội dung tích hợp nhân tố n = 1khiến cho mọi thứ trở nên khó khăn một chút.

Dùng thử trực tuyến | Bộ kiểm tra

Cảm ơn @PeterTaylor về 1&+thủ thuật gọn gàng để xử lý 1 trường hợp.

Giải trình

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

Đối với n > 1, mảng sửa đổi chỉ là mảng số mũ. Nếu nlà hình vuông thì mảng là tất cả 1s, trở thành tất cả -1 sau khi chia. Mặt khác, nếu n có ước số nguyên tố vuông, thì sẽ có 0 ở đâu đó sau khi chia, cho sản phẩm là 0.

Đối với n = 1mảng được sửa đổi [1] + [1], sẽ trở thành [-1 -1]sau khi chia, cho sản phẩm là 1.


Phương án 16:

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

Điều này sử dụng #(tìm) trên mỗi [base exponent]mảng để tìm kiếm 1, sau đó ánh xạ -1 -> 0, 0 -> 1, 1 -> -1.


6

Ruby, 65 + 7 = 72 62 + 7 = 69 byte

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

+7 byte cho -rprimecờ.

Chúng tôi đang làm điều này theo cách rất ngây thơ:

->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
}

Phần "ma thuật" cho kết quả là 1 nếu số chẵn và -1 khác. Đây là cách thực hiện:

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

5

Bình thường, 9 byte

^_{IPQlPQ

Giải trình:

^_{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.

Hãy thử nó ở đây .


5

Mê cung , 87 byte

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

Hãy thử trực tuyến!

Giải thích ngắn

Đây là một cổng của thuật toán được sử dụng, trong 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)

Giải thích dài

Các primer thông thường trên Labyrinth:

  • Labyrinth là dựa trên ngăn xếp và hai chiều, với việc thực hiện bắt đầu từ ký tự được nhận dạng đầu tiên. Có hai ngăn xếp, ngăn xếp chính và ngăn xếp phụ, nhưng hầu hết các toán tử chỉ hoạt động trên ngăn xếp chính.
  • Tại mỗi nhánh của mê cung, đỉnh của ngăn xếp được kiểm tra để xác định nơi tiếp theo. Tiêu cực là rẽ trái, không là thẳng về phía trước và tích cực là rẽ phải.

Thực thi cho chương trình này bắt đầu ở phía trên bên trái 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 byte

numbers::moebius

Yêu cầu bạn cài đặt gói số trên hệ thống của mình ...

Chỉnh sửa: Đơn giản hơn nhiều nếu tôi đọc thông số kỹ thuật một cách thích hợp [cảm ơn @AlexA.]


Điều này trả về hàm Möbius được ước tính cho mỗi số nguyên từ 1 đến đầu vào, nhưng nhiệm vụ cho thử thách này chỉ đơn giản là đánh giá hàm Möbius trên đầu vào.
Alex A.

Dọc theo dòng câu trả lời Mathicala, bạn thậm chí có thể làm đơn giản chỉ numbers::moebiusvới 16 byte.
Alex A.

3

Bình , 16 byte

?nl{PQlPQZ^_1lPQ

Hãy thử trực tuyến!

Câu trả lời thực tế đầu tiên của tôi. Gợi ý đánh giá cao! :)

Giải trình

Giải pháp của tôi sử dụng thực tế là một số là không vuông, nếu các thừa số nguyên tố của nó không chứa số nào nhiều hơn một lần. Nếu đầu vào là hình vuông, Hàm Möbius lấy giá trị -1 ^ (số lượng nguyên hàm).


?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 byte

tq?YftdAwn-1w^*

Điều này sử dụng bản phát hành hiện tại (10.1.0) của ngôn ngữ / trình biên dịch.

Hãy thử trực tuyến!

Giải trình

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 byte, không cạnh tranh

Khỉ thật, một lần nữa một lỗi khiến bài dự thi của tôi không cạnh tranh. Mã số:

.p0K1›<P

Giải trình:

.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

Sử dụng mã hóa CP-1252


không có trong ISO 8859-1 ...
Sản phẩm ETH

1
@ETHproductions Heh? Đó là loại mã hóa nào? Tôi đã nhận nó từ trang web này .
Ad Nam

Tôi tin rằng nó được gọi là ASCII mở rộng .
Sản phẩm ETH

@ETHproductions Cảm ơn, tôi đã chỉnh sửa bài đăng :)
Adnan

@ThomasKwa Ahh, tôi đã tìm thấy nó. Đó là mã hóa CP-1252 .
Ad Nam

2

Bình thường, 11

*{IPQ^_1lPQ

Bộ kiểm tra

Điều này nhân giá trị boolean của nếu các thừa số nguyên tố không vuông góc -1với sức mạnh của số lượng các yếu tố nguyên tố mà số đó có.

Ilà một kiểm tra bất biến trên toán tử tiền xử lý, ở đây là {toán tử if-ify duy nhất.



2

Julia, 66 byte

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

Đây là hàm lambda chấp nhận một số nguyên và trả về một số nguyên. Để gọi nó, gán nó cho một biến.

Ung dung:

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 byte

moebius

Đáng buồn möbiuslà không có sẵn. :)


2

Nghiêm túc, 19 18 byte

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

Hãy thử trực tuyến!

Giải trình:

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

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

Hãy thử trực tuyến!

-13 byte: các vòng lặp được sắp xếp hợp lý, biến trả về được thêm vào (nhờ Kevin Cruijssen )
-1 byte: đã thay đổi cài đặt b thành 0 thành một ternary từ một if (nhờ Kevin Cruijssen )
-7 byte: thay đổi câu lệnh if trong vòng lặp thành một ternary (cảm ơn Peter TaylorKevin Cruijssen )

Ung dung:

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 byte tôi đã đổi int b=1;for(int i=1;thành int b=1,i=1;for(;. Loại bỏ các {}-brackets cho vòng lặp. Thay đổi cả a%i==0đến a%i<1. Thay đổi b*=-1;thành b=-b;. Và cuối cùng đã thay đổi return 0;thành b=0;.
Kevin Cruijssen

Vâng, tất cả mọi thứ bạn đề nghị nhìn chính xác. Tôi đã từng rất lo lắng khi bạn nói nó không đúng, vì điều đó có nghĩa là mã gốc của tôi cũng sai! :)
Meerkat

1
Vâng, xin lỗi về điều đó. :) hơn 1 byte để golf btw là if(a%i<1)b=0;để b=a%i<1?0:b;.
Kevin Cruijssen

2
Trên thực tế, điều đó bỏ qua một cải tiến dễ dàng: b=-b;b=a%i<1?0:b;chơi gônb=a%i<1?0:-b;
Peter Taylor

1
Tiếp tục trên @ golf PeterTaylor của trên, sau đó bạn có thể thay đổi if(a%i<1){a/=i;b=a%i<1?0:-b;}để b=a%i<1?(a/=i)%i<1?0:-b:b;tiết kiệm thêm 3 byte.
Kevin Cruijssen

1

GNU sed, 89 byte

#!/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, phiên bản tiếng Anh, 196 byte

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

Công thức ô Excel được nhập vào các ô từ A1 đến AX50.



1

Nghiêm túc, 11 byte

Gợi ý chơi golf chào mừng. Hãy thử trực tuyến!

;y;l0~ⁿ)π=*

Ungolfing

     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.

Giải pháp tốt đẹp =) (Tôi đoán tuy nhiên ngôn ngữ này trẻ hơn câu hỏi, phải không?)
flawr

@flawr Rõ ràng câu trả lời cũng hoạt động tốt trong Nghiêm túc và tôi không biết khi nào thực sự lần đầu tiên xuất hiện trên mạng, vì vậy tôi đã đổi thành Nghiêm túc để an toàn.
Sherlock9

1

Java 8, 72 68 65 byte

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

-4 byte nhờ @PeterTaylor .

Câu trả lời .NET C # của @ Meerkat , lần đầu tiên tôi chơi gôn xa hơn một chút, vì vậy hãy đảm bảo nâng cao anh ấy!

Hãy thử trực tuyến.

Giải trình:

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

Xem nhận xét của tôi về câu trả lời của Meerkat.
Peter Taylor

@PeterTaylor Thông minh, cảm ơn! Và sau đó có thể lưu thêm 3 byte bằng cách sử dụng r=n%i<1?(n/=i)%i<1?0:-r:r;.
Kevin Cruijssen

0

Javascript (ES6), 48 byte

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

Trước hết - đây là bài golf mã đầu tiên của tôi để tôi có thể hiểu sai các quy tắc ở một mức độ nào đó. Trong bài nộp này, ký tự cuối cùng ;có thể được bỏ qua và nó vẫn hoạt động nhưng tôi thậm chí không chắc mã có hợp lệ theo thông số kỹ thuật ES6 hay không. Dù sao, một lời giải thích ngắn.

Đầu tiên, tôi sẽ giải thích ý tưởng một chút; chúng tôi lấy nvà chúng tôi thử chia nó cho số nguyên i. Nếu nó chia hết, thì chúng tôi sẽ làm như vậy và chúng tôi kiểm tra xem nó có chia hết không i. Nếu đó là trường hợp, sau đó chúng ta cần phải trở lại 0. Nếu không, chúng ta có thể thử cái khác i. Điều thú vị là, chúng ta có thể bắt đầu i=2và chỉ cần tăng nó bằng cách1 mỗi lần, để chúng ta chia ra tất cả các yếu tố chính.

Vì vậy, mã hoạt động như thế này:

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

Vì vậy, đó là trình của tôi.


Chào mừng đến với trang web. Tôi không biết js, nhưng tôi có thể nói với bạn rằng ở đây chúng tôi không quan tâm đến thông số kỹ thuật, chỉ thực hiện. Vì vậy, nếu loại bỏ ;không phá vỡ nó, nó không quan trọng thông số kỹ thuật bạn có thể loại bỏ nó.
Thuật sĩ lúa mì

Tốt để biết! Tôi sẽ xóa nó sau đó;)
vrugtehagel
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.