La función de Möbius


23

La función de Möbius

La función de Möbius es una función teórica de números importantes.

Su envío debe aceptar un número entero positivo ny devolver el valor de la función de Möbius evaluada en n.

Definición

La función de Möbius μ (n) se define de la siguiente manera:

       |  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

nse llama cuadrado libre si los exponentes de la factorización prima de n son estrictamente menores que dos. (Alternativamente: no primar el poder de dos divisiones n).

Casos de prueba

Aquí puede ver los primeros 50 valores de μ:

Imagen de dominio público de Wikipedia

La función de Möbius es el número de secuencia A008683 en el OEIS.

Estos son los primeros 77 valores:

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

Los valores más grandes también se pueden verificar fácilmente en Wolframalpha.com o en el archivo b de OEIS , como lo sugiere @ MartinBüttner.

Respuestas:


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

Versión anterior de 51 bytes:

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

Möbius invierte la secuencia 1,0,0,0,0....

La función de Möbius tiene la propiedad de que, para cualquiera n>1, las funciones de Möbius de nlos divisores suman 0. Por lo tanto, para n>1, μ(n)se calcula negando la suma de μ(k)para todos los divisores propios kde n. Para n=1, la salida es 1.

El código maneja el caso base agregando una división de piso 1/n, que da 1para n==1y de lo 0contrario.

Gracias a Dennis por guardar 3 bytes con un mejor manejo recursivo inspirado en una estructura similar en este desafío .


13

Jalea , 7 bytes

Código:

ÆF>1’PS

Explicación:

Æ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

Por ejemplo, el número 10 :

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

Y resultados en 1 .

Pruébalo en línea .


-1 byte: ÆFỊNPS(no estoy seguro si era una función integrada en ese momento, pero ahora debería estar bien)
Erik the Outgolfer

10

Mathematica, 9 bytes

MoebiusMu

Por supuesto, Mathematica tiene una función incorporada. (Y probablemente será golpeado por Jelly de todos modos).


7

CJam, 18 15 bytes

WrimFz~\1&+f/:*

El hecho de que CJam devuelve 1 en factorización incorporada para n = 1 hace que las cosas sean un poco complicadas.

Pruébalo en línea | Banco de pruebas

Gracias a @PeterTaylor por el buen 1&+truco para manejar el caso 1.

Explicación

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

Para n > 1, la matriz modificada es solo la matriz de exponentes. Sin tiene cuadrados, la matriz es todos 1, que se convierten en todos -1 después de la división. De lo contrario, si n tiene un divisor cuadrado primo, entonces habrá un 0 en algún lugar después de la división, dando un producto de 0.

Para n = 1la matriz modificada es [1] + [1], que se convierte [-1 -1]después de la división, dando un producto de 1.


Alternativa 16:

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

Esto utiliza #(buscar) en cada [base exponent]matriz para buscar un 1, luego los mapas -1 -> 0, 0 -> 1, 1 -> -1.


6

Rubí, 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 para la -rprimebandera.

Lo estamos haciendo de la manera más ingenua:

->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 parte "mágica" da como resultado 1 si el número es par y -1 en caso contrario. Así es cómo:

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

Explicación:

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

Probarlo aquí .


5

Laberinto , 87 bytes

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

Pruébalo en línea!

Explicación breve

Aquí hay un puerto del algoritmo utilizado, 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)

Larga explicación

La cartilla habitual en Labyrinth:

  • Labyrinth está basado en pila y es bidimensional, y la ejecución comienza en el primer carácter reconocido. Hay dos pilas, una pila principal y una pila auxiliar, pero la mayoría de los operadores solo trabajan en la pila principal.
  • En cada rama del laberinto, se comprueba la parte superior de la pila para determinar a dónde ir después. Negativo es girar a la izquierda, cero es recto y positivo es girar a la derecha.

La ejecución de este programa comienza en la esquina superior izquierda 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

Requiere que tenga el paquete de números instalado en su sistema ...

Editar: Mucho más simple si leo las especificaciones apropiadamente [gracias @AlexA.]


Esto devuelve la función de Möbius evaluada para cada número entero de 1 a la entrada, pero la tarea para este desafío es simplemente evaluar la función de Möbius en la entrada.
Alex A.

En la línea de la respuesta de Mathematica, incluso podría hacerlo simplemente numbers::moebiuspor 16 bytes.
Alex A.

3

Pyth , 16 bytes

?nl{PQlPQZ^_1lPQ

Pruébalo en línea!

Mi primera respuesta real de Pyth. Sugerencias apreciadas! :)

Explicación

Mi solución utiliza el hecho de que un número es cuadrado, si sus factores primos no contienen ningún número más de una vez. Si la entrada es cuadrada, la función Möbius toma el valor -1 ^ (número de factores primos).


?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^*

Esto usa la versión actual (10.1.0) del lenguaje / compilador.

Pruébalo en línea!

Explicación

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, no competitivos

Maldición, una vez más un error que hace que mi presentación no sea competitiva. Código:

.p0K1›<P

Explicación:

.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

Utiliza la codificación CP-1252


no está en ISO 8859-1 ...
ETHproductions

1
@ETHproductions ¿Eh? ¿Qué tipo de codificación es entonces? Lo obtuve de este sitio .
Adnan

Creo que se llama ASCII extendido .
ETHproductions

@ETHproductions Gracias, he editado la publicación :)
Adnan

@ThomasKwa Ahh, lo he encontrado. Es la codificación CP-1252 .
Adnan

2

Pyth, 11

*{IPQ^_1lPQ

Banco de pruebas

Esto multiplica el valor booleano de si los factores primos no cuadran por -1la potencia del número de factores primos que tiene el número.

Ies una verificación de invariancia en el operador anterior, que aquí es {, que es el operador único.



2

Julia, 66 bytes

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

Esta es una función lambda que acepta un entero y devuelve un entero. Para llamarlo, asígnelo a una variable.

Sin 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 bytes

moebius

Lamentablemente möbiusno está disponible. :)


2

En serio, 19 18 bytes

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

Pruébalo en línea!

Explicación:

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

Pruébalo en línea!

-13 bytes: bucles simplificados, variable de retorno agregada (gracias a Kevin Cruijssen )
-1 byte: cambió la configuración b a cero a un ternario de un if (gracias a Kevin Cruijssen )
-7 bytes: cambió la instrucción if en bucle for a un ternary (gracias a Peter Taylor y Kevin Cruijssen )

Sin 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 bytes he cambiado int b=1;for(int i=1;a int b=1,i=1;for(;. Se eliminaron los {}soportes para el bucle. Cambiado tanto a%i==0a a%i<1. Cambió el b*=-1;a b=-b;. Y finalmente cambió el return 0;a b=0;.
Kevin Cruijssen

Sí, todo lo que sugeriste parecía correcto. Estaba un poco preocupado cuando dijiste que no estaba bien, ¡porque eso habría significado que mi código original también estaba equivocado! :)
Suricata

1
Sí, perdón por eso. :) 1 byte más que el golf es cierto if(a%i<1)b=0;a b=a%i<1?0:b;.
Kevin Cruijssen

2
En realidad, eso pasa por alto una mejora fácil: b=-b;b=a%i<1?0:b;golf ab=a%i<1?0:-b;
Peter Taylor

1
Continuando en el campo de golf de @ PeterTaylor arriba, puede cambiar if(a%i<1){a/=i;b=a%i<1?0:-b;}a b=a%i<1?(a/=i)%i<1?0:-b:b;para guardar 3 bytes más.
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, versión británica, 196 bytes

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

Fórmula de celda de Excel para ingresar en las celdas A1 a AX50.



1

En serio, 11 bytes

Sugerencias de golf bienvenidas. Pruébalo en línea!

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

Buena solución =) (Supongo, sin embargo, que este idioma es más joven que la pregunta, ¿verdad?)
error

@flawr Aparentemente, la respuesta funciona igual de bien en serio, y no sé cuándo entró en línea por primera vez, así que cambié a serio para estar seguro.
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 gracias a @PeterTaylor .

Puerto de la respuesta .NET C # de @ Meerkat , que primero jugué un poco más, ¡así que asegúrese de votarlo!

Pruébalo en línea.

Explicación:

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

Vea mi comentario sobre la respuesta de Meerkat.
Peter Taylor

@PeterTaylor Smart, gracias! Y luego se pueden guardar 3 bytes más usando r=n%i<1?(n/=i)%i<1?0:-r:r;.
Kevin Cruijssen

0

Javascript (ES6), 48 bytes

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

En primer lugar, esta es mi primera publicación de código de golf, por lo que puedo entender mal las reglas hasta cierto punto. En este envío, ;se puede omitir el último carácter y seguirá funcionando, pero ni siquiera estoy seguro de si el código sería válido de acuerdo con las especificaciones de ES6. De todos modos, una breve explicación.

Primero, explicaré un poco la idea; tomamos ne intentamos dividirlo por el entero i. Si es divisible, entonces lo hacemos y verificamos si es divisible inuevamente. Si ese es el caso, entonces tenemos que regresar 0. De lo contrario, podemos probar con otro i. Lo bueno es que simplemente podemos comenzar i=2y agregar aumentarlo 1cada vez, para que podamos dividir todos los factores primos.

Entonces, el código funciona así:

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

Entonces, esa es mi sumisión.


Bienvenido al sitio. No sé js, pero puedo decirte que aquí no nos importan las especificaciones, solo las implementaciones. Entonces, si eliminarlo ;no lo rompe, no importa las especificaciones, puede eliminarlo.
Wheat Wizard

¡Bueno saber! Lo eliminaré entonces;)
vrugtehagel
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.