La fonction Möbius


23

La fonction Möbius

La fonction de Möbius est une fonction théorique des nombres importante.

Votre soumission doit accepter un entier positif net renvoyer la valeur de la fonction Möbius évaluée à n.

Définition

La fonction Möbius μ (n) est définie comme suit:

       |  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

nest appelé sans carré si les exposants de la factorisation première de n sont tous strictement inférieurs à deux. (Alternativement: pas d'amorce à la puissance de deux divisions n).

Cas de test

Ici, vous pouvez voir les 50 premières valeurs de μ:

Image du domaine public de Wikipedia

La fonction Möbius est le numéro de séquence A008683 dans l'OEIS.

Ce sont les 77 premières valeurs:

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

De plus grandes valeurs peuvent également être vérifiées facilement sur Wolframalpha.com ou dans le fichier b d'OEIS , comme suggéré par @ MartinBüttner.

Réponses:


15

Python 2, 48 octets

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

Version antérieure de 51 octets:

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

Möbius inverse la séquence 1,0,0,0,0....

La fonction de Möbius a la propriété que, pour tout n>1, les fonctions de Möbius des ndiviseurs de s totalisent 0. Donc, pour n>1, μ(n)est calculé en annulant la somme de μ(k)pour tous les diviseurs propres kde n. Pour n=1, la sortie est 1.

Le code gère le cas de base en ajoutant une division au sol 1/n, qui donne 1pour n==1et 0autrement.

Merci à Dennis d'avoir économisé 3 octets avec une meilleure gestion récursive inspirée d'une structure similaire dans ce défi .


13

Gelée , 7 octets

Code:

ÆF>1’PS

Explication:

Æ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

Par exemple, le nombre 10 :

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

Et résulte en 1 .

Essayez-le en ligne .


-1 octet: ÆFỊNPS(je ne sais pas si c'était intégré à l'époque, mais ça devrait aller maintenant).
Erik the Outgolfer

10

Mathematica, 9 octets

MoebiusMu

Bien sûr, Mathematica a une fonction intégrée. (Et sera probablement battu par Jelly de toute façon.)


7

CJam, 18 15 octets

WrimFz~\1&+f/:*

Le fait que CJam renvoie 1 dans les intégrations de factorisation pour n = 1rend les choses un peu délicates.

Essayez-le en ligne | Suite de tests

Merci à @PeterTaylor pour la bonne 1&+astuce pour gérer le 1 cas.

Explication

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

Pour n > 1, le tableau modifié n'est que le tableau des exposants. Si nest sans carré, le tableau contient tous les 1, qui deviennent tous les -1 après la division. Sinon, si n a un diviseur carré premier, alors il y aura un 0 quelque part après la division, donnant un produit de 0.

Pour n = 1le tableau modifié est [1] + [1], qui devient [-1 -1]après division, donnant un produit de 1.


Variante 16:

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

Cela utilise #(find) sur chaque [base exponent]tableau pour rechercher un 1, puis mappe -1 -> 0, 0 -> 1, 1 -> -1.


6

Rubis, 65 + 7 = 72 62 + 7 = 69 octets

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

+7 octets pour le -rprimedrapeau.

Nous faisons cela de manière très naïve:

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

La partie "magique" donne 1 si le nombre est pair et -1 sinon. Voici comment:

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

5

Pyth, 9 octets

^_{IPQlPQ

Explication:

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

Essayez-le ici .


5

Labyrinthe , 87 octets

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

Essayez-le en ligne!

Brève explication

Voici un port de l'algorithme utilisé, en 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)

Longue explication

L'amorce habituelle sur Labyrinth:

  • Le labyrinthe est basé sur une pile et en deux dimensions, avec une exécution commençant au premier caractère reconnu. Il y a deux piles, une pile principale et une pile auxiliaire, mais la plupart des opérateurs ne travaillent que sur la pile principale.
  • À chaque branche du labyrinthe, le haut de la pile est vérifié pour déterminer où aller ensuite. Négatif est tourner à gauche, zéro est tout droit et positif est tourner à droite.

L'exécution de ce programme commence en haut à gauche 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 octets

numbers::moebius

Vous oblige à avoir le package de numéros installé sur votre système ...

Edit: beaucoup plus simple si je lis les spécifications correctement [merci @AlexA.]


Cela renvoie la fonction Möbius évaluée pour chaque entier de 1 à l'entrée, mais la tâche de ce défi consiste simplement à évaluer la fonction Möbius sur l'entrée.
Alex A.

Dans le sens de la réponse Mathematica, vous pouvez même faire simplement numbers::moebiuspour 16 octets.
Alex A.

3

Pyth , 16 octets

?nl{PQlPQZ^_1lPQ

Essayez-le en ligne!

Ma première vraie réponse Pyth. Suggestions appréciées! :)

Explication

Ma solution utilise le fait qu'un nombre est sans carré, si ses facteurs premiers ne contiennent aucun nombre plus d'une fois. Si l'entrée est sans carré, la fonction Möbius prend la valeur -1 ^ (nombre de facteurs premiers).


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

tq?YftdAwn-1w^*

Cela utilise la version actuelle (10.1.0) du langage / compilateur.

Essayez-le en ligne!

Explication

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 octets, non concurrent

Bon sang, encore une fois un bug qui rend ma soumission non compétitive. Code:

.p0K1›<P

Explication:

.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

Utilise l'encodage CP-1252


n'est pas dans ISO 8859-1 ...
ETHproductions

1
@ETHproductions Heh? De quel type d'encodage s'agit-il alors? Je l'ai obtenu sur ce site .
Adnan

Je crois que cela s'appelle ASCII étendu .
ETHproductions

@ETHproductions Merci, j'ai édité le post :)
Adnan

@ThomasKwa Ahh, je l'ai trouvé. Il s'agit du codage CP-1252 .
Adnan

2

Pyth, 11

*{IPQ^_1lPQ

Suite de tests

Cela multiplie la valeur booléenne de si les facteurs premiers sont sans carré par -1la puissance du nombre de facteurs premiers que le nombre a.

Iest une vérification d'invariance sur l'opérateur précédent, qui est ici {, qui est l'opérateur unique-ify.



2

Julia, 66 octets

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

Il s'agit d'une fonction lambda qui accepte un entier et renvoie un entier. Pour l'appeler, affectez-le à une variable.

Non golfé:

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 octets

moebius

Malheureusement, möbiusn'est pas disponible. :)


2

Sérieusement, 19 18 octets

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

Essayez-le en ligne!

Explication:

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

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

Essayez-le en ligne!

-13 octets: boucles rationalisées, variable de retour ajoutée (merci à Kevin Cruijssen )
-1 octet: changé le réglage b à zéro en un ternaire d'un if (merci à Kevin Cruijssen )
-7 octets: changé l'instruction if dans une boucle pour un ternaire (merci à Peter Taylor et Kevin Cruijssen )

Non golfé:

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 octets, j'ai changé int b=1;for(int i=1;pour int b=1,i=1;for(;. Suppression des {}-brackets pour la boucle. Changé a%i==0pour les deux a%i<1. Changé b*=-1;en b=-b;. Et finalement changé le return 0;en b=0;.
Kevin Cruijssen

Oui, tout ce que vous avez suggéré semblait correct. J'étais un peu inquiet lorsque vous avez dit que ce n'était pas correct, car cela aurait signifié que mon code d'origine était également incorrect! :)
Meerkat

1
Ouais, désolé pour ça. :) 1 octet de plus pour golf btw est if(a%i<1)b=0;à b=a%i<1?0:b;.
Kevin Cruijssen du

2
En fait, cela néglige une amélioration facile: les b=-b;b=a%i<1?0:b;golfs àb=a%i<1?0:-b;
Peter Taylor

1
En continuant sur @ le golf PeterTaylor ci - dessus, vous pouvez changer if(a%i<1){a/=i;b=a%i<1?0:-b;}pour b=a%i<1?(a/=i)%i<1?0:-b:b;sauver plus de 3 octets.
Kevin Cruijssen du

1

GNU sed, 89 octets

#!/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, version britannique, 196 octets

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

Formule de cellule Excel à saisir dans les cellules A1 à AX50.



1

Sérieusement, 11 octets

Suggestions de golf bienvenues. Essayez-le en ligne!

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

Belle solution =) (je suppose cependant que cette langue est plus jeune que la question, n'est-ce pas?)
flawr

@flawr Apparemment, la réponse fonctionne aussi bien dans Sérieusement, et je ne sais pas quand Actually est apparu pour la première fois, j'ai donc changé pour Sérieusement juste pour être en sécurité.
Sherlock9

1

Java 8, 72 68 65 octets

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

-4 octets grâce à @PeterTaylor .

Port de la réponse .NET C # de @ Meerkat , que j'ai d'abord joué un peu plus loin, alors assurez-vous de lui donner un vote positif!

Essayez-le en ligne.

Explication:

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

Voir mon commentaire sur la réponse de Meerkat.
Peter Taylor

@PeterTaylor Smart, merci! Et puis 3 octets supplémentaires peuvent être enregistrés en utilisant r=n%i<1?(n/=i)%i<1?0:-r:r;.
Kevin Cruijssen du

0

Javascript (ES6), 48 octets

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

Tout d'abord - c'est mon premier article de golf de code, donc je peux mal comprendre les règles dans une certaine mesure. Dans cette soumission, le dernier caractère; pourrait être omis et cela fonctionnera toujours, mais je ne suis même pas sûr que le code soit valide selon les spécifications ES6. Quoi qu'il en soit, une courte explication.

Je vais d'abord expliquer un peu l'idée; nous prenons n, et nous essayons de le diviser par l'entieri . S'il est divisible, nous le faisons et nous vérifions s'il est divisible par à inouveau. Si tel est le cas, nous devons revenir 0. Sinon, nous pouvons en essayer un autre i. Ce qui est cool, c'est que nous pouvons simplement commencer i=2et ajouter1 chaque fois, afin de diviser tous les facteurs premiers.

Donc, le code fonctionne comme ceci:

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

Voilà donc ma soumission.


Bienvenue sur le site. Je ne connais pas js, mais je peux vous dire qu'ici nous ne nous soucions pas des spécifications, seulement des implémentations. Donc, si la suppression ;ne la casse pas, peu importe les spécifications, vous pouvez la supprimer.
Wheat Wizard

Bon à savoir! Je l'enlèverai alors;)
vrugtehagel
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.