Die Möbius-Funktion


23

Die Möbius-Funktion

Die Möbius-Funktion ist eine wichtige zahlentheoretische Funktion.

Ihre Übermittlung sollte eine positive ganze Zahl akzeptieren nund den Wert der Möbius-Funktion zurückgeben, die bei ausgewertet wird n.

Definition

Die Möbius-Funktion μ (n) ist wie folgt definiert:

       |  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

nwird als quadratfrei bezeichnet, wenn die Exponenten der Primfaktorisierung von n alle genau kleiner als zwei sind. (Alternativ: Keine Primzahl hoch zwei Teilungen n).

Testfälle

Hier sehen Sie die ersten 50 Werte von μ:

Public Domain Bild von Wikipedia

Die Möbius-Funktion hat im OEIS die laufende Nummer A008683 .

Dies sind die ersten 77 Werte:

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

Größere Werte können auch problemlos in Wolframalpha.com oder in der B-Datei von OEIS überprüft werden , wie von @ MartinBüttner vorgeschlagen.

Antworten:


15

Python 2, 48 Bytes

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

Frühere 51-Byte-Version:

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

Möbius-invertiert die Sequenz 1,0,0,0,0....

Die Möbius - Funktion hat die Eigenschaft , dass für jede n>1, die Möbius - Funktionen von n‚s Teilern Summe auf 0 Also, für n>1, μ(n)durch Negieren der Summe berechnet wird , μ(k)für alle echten Teiler kvon n. Für n=1ist die Ausgabe 1.

Der Code behandelt den Basisfall durch Hinzufügen einer Bodeneinteilung 1/n, die 1für n==1und 0andernfalls gibt.

Vielen Dank an Dennis für das Speichern von 3 Bytes bei besserer rekursiver Behandlung, inspiriert von einer ähnlichen Struktur in dieser Herausforderung .


13

Gelee , 7 Bytes

Code:

ÆF>1’PS

Erläuterung:

Æ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

Zum Beispiel die Nummer 10 :

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

Und ergibt 1 .

Probieren Sie es online aus .


-1 Byte: ÆFỊNPS( Ich bin mir nicht sicher, ob es sich damals um ein eingebautes Byte handelte , sollte aber jetzt in Ordnung sein).
Erik der Outgolfer

10

Mathematica, 9 Bytes

MoebiusMu

Natürlich hat Mathematica eine eingebaute. (Und wird wahrscheinlich sowieso von Jelly geschlagen.)


7

CJam, 18 15 Bytes

WrimFz~\1&+f/:*

Die Tatsache, dass CJam in Faktorisierungs-Builtins für 1 zurückgibt, n = 1macht die Sache etwas schwierig.

Versuchen Sie es online | Testsuite

Vielen Dank an @PeterTaylor für den tollen 1&+Trick zur Bearbeitung des 1-Falls.

Erläuterung

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

Denn n > 1das modifizierte Array ist nur das Exponenten-Array. Wenn nes quadratfrei ist, ist das Array alle 1s, die nach der Division alle -1s werden. Wenn andernfalls n einen quadratischen Primteiler hat, gibt es irgendwo nach der Division eine 0, was ein Produkt von 0 ergibt.

Für n = 1das modifizierte Array ergibt sich [1] + [1], was [-1 -1]nach Division wird, ein Produkt von 1.


Alternative 16:

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

Dies verwendet #(find) für jedes [base exponent]Array, um nach einer 1 zu suchen, und ordnet dann zu -1 -> 0, 0 -> 1, 1 -> -1.


6

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

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

+7 Bytes für das -rprimeFlag.

Wir machen das ganz naiv:

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

Der "magische" Teil ergibt 1, wenn die Zahl gerade ist, und -1, wenn nicht. Hier ist wie:

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

5

Pyth, 9 Bytes

^_{IPQlPQ

Erläuterung:

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

Probieren Sie es hier aus .


5

Labyrinth , 87 Bytes

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

Probieren Sie es online!

Kurze Erklärung

Hier ist ein Port des in Python verwendeten Algorithmus:

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)

Lange Erklärung

Die übliche Grundierung auf Labyrinth:

  • Labyrinth ist stapelbasiert und zweidimensional, wobei die Ausführung beim ersten erkannten Zeichen beginnt. Es gibt zwei Stapel, einen Hauptstapel und einen Hilfsstapel, aber die meisten Bediener arbeiten nur mit dem Hauptstapel.
  • In jedem Zweig des Labyrinths wird die Oberseite des Stapels überprüft, um festzustellen, wohin als Nächstes zu gehen ist. Negativ ist links abbiegen, Null ist geradeaus und positiv ist rechts abbiegen.

Die Ausführung für dieses Programm beginnt oben links 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 Bytes

numbers::moebius

Erfordert, dass Sie das Nummernpaket auf Ihrem System installiert haben ...

Edit: Viel einfacher, wenn ich die Spezifikationen entsprechend lese [danke @AlexA.]


Dadurch wird die Möbius-Funktion, die für jede Ganzzahl von 1 ausgewertet wird, an die Eingabe zurückgegeben. Die Aufgabe für diese Abfrage besteht jedoch lediglich darin, die Möbius-Funktion für die Eingabe auszuwerten.
Alex A.

In Anlehnung an die Mathematica-Antwort könnten Sie dies sogar einfach numbers::moebiusfür 16 Bytes tun .
Alex A.

3

Pyth , 16 Bytes

?nl{PQlPQZ^_1lPQ

Probieren Sie es online!

Meine erste tatsächliche Pyth-Antwort. Vorschläge geschätzt! :)

Erläuterung

Meine Lösung nutzt die Tatsache, dass eine Zahl quadratfrei ist, wenn ihre Primfaktoren nicht mehr als eine Zahl enthalten. Ist die Eingabe quadratisch, nimmt die Möbius-Funktion den Wert -1 ^ (Anzahl der Primfaktoren) an.


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

tq?YftdAwn-1w^*

Dies nutzt aktuelle Version (10.1.0) der Sprache / des Compilers.

Probieren Sie es online!

Erläuterung

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 Bytes, nicht konkurrierend

Verdammt noch mal, ein Fehler, der meine Einsendung nicht konkurrieren lässt. Code:

.p0K1›<P

Erläuterung:

.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

Verwendet die CP-1252-Codierung


ist nicht in ISO 8859-1 ...
ETHproductions

1
@ETHproductions Heh? Um welche Art von Codierung handelt es sich dann? Ich habe es von dieser Seite bekommen .
Adnan

Ich glaube, es heißt Extended ASCII .
ETHproductions

@ETHproductions Danke, ich habe den Beitrag bearbeitet :)
Adnan

@ ThomasKwa Ahh, ich habe es gefunden. Es ist die CP-1252- Codierung.
Adnan

2

Pyth, 11

*{IPQ^_1lPQ

Testsuite

Dies multipliziert den Booleschen Wert von, wenn die Primfaktoren quadratisch sind, mit -1 der Potenz der Anzahl der Primfaktoren, die die Zahl hat.

Iist eine Invarianzprüfung für den vorhergehenden Operator, der hier {der Unique-Ify-Operator ist.



2

Julia, 66 Bytes

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

Dies ist eine Lambda-Funktion, die eine Ganzzahl akzeptiert und eine Ganzzahl zurückgibt. Um es aufzurufen, weisen Sie es einer Variablen zu.

Ungolfed:

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 Bytes

moebius

Leider möbiusist nicht verfügbar. :)


2

Im Ernst, 19 18 Bytes

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

Probieren Sie es online!

Erläuterung:

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

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

Probieren Sie es online!

-13 Bytes: optimierte Schleifen, zusätzliche Rückgabevariable (danke an Kevin Cruijssen )
-1 Bytes: Änderung der Einstellung b auf null von einem If (dank Kevin Cruijssen )
-7 Bytes: Änderung der if-Anweisung in for-Schleife zu einem Ternary (Danke an Peter Taylor und Kevin Cruijssen )

Ungolfed:

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 Bytes Ich habe geändert int b=1;for(int i=1;zu int b=1,i=1;for(;. Die {}Klammern für die Schleife wurden entfernt. Geändert a%i==0zu a%i<1. Geändert b*=-1;zu b=-b;. Und schließlich änderte sich die return 0;zu b=0;.
Kevin Cruijssen

Ja, alles, was Sie vorgeschlagen haben, sah korrekt aus. Ich war immer ein bisschen besorgt, als Sie sagten, dass es nicht richtig war, denn das hätte bedeutet, dass mein ursprünglicher Code auch falsch war! :)
Erdmännchen

1
Ja, tut mir leid. :) 1 weiteres Byte zum Golfen ist übrigens if(a%i<1)b=0;zu b=a%i<1?0:b;.
Kevin Cruijssen

2
Eigentlich übersieht das eine leichte Verbesserung: b=-b;b=a%i<1?0:b;Golfen bisb=a%i<1?0:-b;
Peter Taylor

1
Weiter auf @ PeterTaylor Golf oben können Sie dann ändern , if(a%i<1){a/=i;b=a%i<1?0:-b;}um b=a%i<1?(a/=i)%i<1?0:-b:b;3 weitere Bytes zu speichern.
Kevin Cruijssen

1

GNU sed, 89 Bytes

#!/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, britische Version, 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)),""))),"")

Excel-Zellenformel zur Eingabe in die Zellen A1 bis AX50.



1

Im Ernst, 11 Bytes

Golfvorschläge sind willkommen. Probieren Sie es online!

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

Schöne Lösung =) (Ich denke jedoch, dass diese Sprache jünger ist als die Frage, oder?)
Fehler

@flawr Anscheinend funktioniert die Antwort in Seriously genauso gut, und ich weiß nicht, wann Actually zum ersten Mal online ging, also habe ich aus Sicherheitsgründen zu Seriously gewechselt.
Sherlock9

1

Java 8, 72 68 65 Bytes

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

-4 Bytes dank @PeterTaylor .

Port von @ Meerkats .NET C # -Antwort, die ich zuerst ein bisschen weiter ausprobiert habe.

Probieren Sie es online aus.

Erläuterung:

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

Siehe meinen Kommentar zu Meerkats Antwort.
Peter Taylor

@ PeterTaylor Smart, danke! Und dann können 3 weitere Bytes mit gespeichert werden 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

Zuallererst - dies ist mein erster Code-Golfpost, damit ich die Regeln bis zu einem gewissen Grad missverstehe. In dieser Vorlage das letzte Zeichen; weggelassen werden und es wird immer noch funktionieren, aber ich bin nicht einmal sicher, ob der Code gemäß den ES6-Spezifikationen gültig wäre. Trotzdem eine kurze Erklärung.

Zuerst erkläre ich die Idee ein bisschen; wir nehmen nund wir versuchen, es durch die ganze Zahl zu teilen i. Wenn es teilbar ist, dann tun wir das und prüfen, ob es wieder teilbar ist i. Wenn das der Fall ist, müssen wir zurückkehren 0. Ansonsten können wir es mit einem anderen versuchen i. Das Coole ist, wir können einfach anfangen i=2und es durch Hinzufügen erhöhen1 jedem Mal , so dass wir alle Primfaktoren aufteilen.

Der Code funktioniert also so:

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

Das ist also meine Vorlage.


Willkommen auf der Seite. Ich kenne js nicht, aber ich kann Ihnen sagen, dass wir uns hier nicht um Spezifikationen, sondern nur um Implementierungen kümmern. Wenn das Entfernen es ;also nicht zerstört, spielt es keine Rolle, welche Spezifikationen Sie entfernen können.
Weizen-Assistent

Gut zu wissen! Ich werde es dann entfernen;)
vrugtehagel
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.