A Função Möbius


23

A Função Möbius

A função Möbius é uma importante função teórica dos números.

Seu envio deve aceitar um número inteiro positivo ne retornar o valor da função Möbius avaliada em n.

Definição

A função Möbius μ (n) é definida da seguinte forma:

       |  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é chamado de livre de quadrados se os expoentes da fatoração primária de n forem estritamente menores que dois. (Como alternativa: não há primo no poder de duas divisões n).

Casos de teste

Aqui você pode ver os primeiros 50 valores de μ:

Imagem de domínio público da Wikipedia

A função Möbius é o número de sequência A008683 no OEIS.

Estes são os primeiros 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

Valores maiores também podem ser facilmente verificados no Wolframalpha.com ou no arquivo b do OEIS , conforme sugerido por @ MartinBüttner.

Respostas:


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

Versão anterior de 51 bytes:

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

Möbius inverte a sequência 1,0,0,0,0....

A função Möbius possui a propriedade de que, para qualquer n>1, as funções Möbius dos ndivisores de somam 0. Portanto, pois n>1, μ(n)é calculado negando a soma de μ(k)todos os divisores apropriados kde n. Pois n=1, a saída é 1.

O código lida com o caso base adicionando uma divisão de piso 1/n, que fornece 1para n==1e de 0outra forma.

Agradecemos a Dennis por salvar 3 bytes com melhor tratamento recursivo inspirado por uma estrutura semelhante neste desafio .


13

Geléia , 7 bytes

Código:

ÆF>1’PS

Explicação:

Æ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 exemplo, o número 10 :

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

E resulta em 1 .

Experimente online .


-1 byte: ÆFỊNPS(não tenho certeza se era um built-in naquela época, mas deve estar bom agora).
Erik the Outgolfer

10

Mathematica, 9 bytes

MoebiusMu

Obviamente, o Mathematica possui um built-in. (E provavelmente será derrotado por Jelly de qualquer maneira.)


7

CJam, 18 15 bytes

WrimFz~\1&+f/:*

O fato de o CJam retornar 1 em fatores de fatoração n = 1torna as coisas um pouco complicadas.

Experimente online | Suíte de teste

Agradecemos a @PeterTaylor pelo 1&+truque para lidar com o caso 1.

Explicação

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

Pois n > 1, a matriz modificada é apenas a matriz dos expoentes. Se nestiver livre de quadrados, a matriz será toda 1s, que se tornará todos os -1s após a divisão. Caso contrário, se n tiver um divisor quadrado primo, haverá um 0 em algum lugar após a divisão, fornecendo um produto de 0.

Para n = 1a matriz modificada é [1] + [1], que se torna [-1 -1]após a divisão, resultando em um produto 1.


Alternativa 16:

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

Isso usa #(localizar) em cada [base exponent]matriz para procurar um 1 e depois mapear -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 para o -rprimesinalizador.

Estamos fazendo isso da maneira mais ingênua:

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

A parte "mágica" resulta em 1 se o número for par e -1 em caso contrário. Aqui está como:

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

5

Pitão, 9 bytes

^_{IPQlPQ

Explicação:

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

Experimente aqui .


5

Labirinto , 87 bytes

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

Experimente online!

Breve explicação

Aqui está uma porta do algoritmo usado, em 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)

Explicação longa

A cartilha usual em Labyrinth:

  • O labirinto é baseado em pilha e bidimensional, com a execução iniciando no primeiro caractere reconhecido. Existem duas pilhas, uma pilha principal e uma pilha auxiliar, mas a maioria dos operadores trabalha apenas na pilha principal.
  • Em todas as ramificações do labirinto, a parte superior da pilha é verificada para determinar para onde ir a seguir. Negativo é virar à esquerda, zero é reto e positivo é virar à direita.

A execução deste programa começa no canto superior esquerdo 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

Requer que você tenha o pacote de números instalado no seu sistema ...

Editar: muito mais simples se eu ler as especificações adequadamente [obrigado @AlexA.]


Isso retorna a função Möbius avaliada para cada número inteiro de 1 à entrada, mas a tarefa desse desafio é simplesmente avaliar a função Möbius na entrada.
Alex A.

Na linha da resposta do Mathematica, você pode fazer até numbers::moebius16 bytes.
Alex A.

3

Pyth , 16 bytes

?nl{PQlPQZ^_1lPQ

Experimente online!

Minha primeira resposta Pyth real. Sugestões apreciadas! :)

Explicação

Minha solução usa o fato de que um número é livre de quadratura, se seus fatores primos não contiverem número mais de uma vez. Se a entrada não for quadrada, a Função Möbius assume o valor -1 ^ (número de primefatores).


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

Isso usa a versão atual (10.1.0) do idioma / compilador.

Experimente online!

Explicação

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, não concorrente

Droga, mais uma vez um bug que torna minha submissão não competitiva. Código:

.p0K1›<P

Explicação:

.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

Usa a codificação CP-1252


não está na ISO 8859-1 ...
ETHproductions

1
@ETHproductions Heh? Que tipo de codificação é então? Comprei neste site .
Adnan

Eu acredito que é chamado ASCII estendido .
ETHproductions

@ETHproductions Obrigado, eu editei o post :)
Adnan

@ThomasKwa Ahh, eu encontrei. É a codificação CP-1252 .
Adnan

2

Pyth, 11

*{IPQ^_1lPQ

Suíte de teste

Isso multiplica o valor booleano de se os fatores primos são livres de quadrados pela -1potência do número de fatores primos que o número possui.

Ié uma verificação de invariância no operador anterior, que aqui é {, que é o operador ify exclusivo.



2

Julia, 66 bytes

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

Esta é uma função lambda que aceita um número inteiro e retorna um número inteiro. Para chamá-lo, atribua-o a uma variável.

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

Infelizmente möbiusnão está disponível. :)


2

Sério, 19 18 bytes

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

Experimente online!

Explicação:

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

Experimente online!

-13 bytes: loops simplificados, adição de variável de retorno (graças a Kevin Cruijssen )
-1 byte: alteração da configuração b para zero para um ternário de um if (graças a Kevin Cruijssen )
-7 bytes: alterado se a instrução for for loop para um ternário (obrigado a Peter Taylor e 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 eu mudei int b=1;for(int i=1;para int b=1,i=1;for(;. Removidos os {}colchetes para o loop. Alterou ambos a%i==0para a%i<1. Mudou o b*=-1;para b=-b;. E, finalmente, mudou o return 0;para b=0;.
Kevin Cruijssen 30/10

Sim, tudo o que você sugeriu parecia correto. Fiquei um pouco preocupado quando você disse que não estava certo, porque isso significaria que meu código original também estava errado! :)
Meerkat

1
Sim, desculpe por isso. :) Mais 1 byte para o golfe é if(a%i<1)b=0;para b=a%i<1?0:b;.
Kevin Cruijssen 30/10

2
Na verdade, com vista para uma melhoria fácil: b=-b;b=a%i<1?0:b;golfs parab=a%i<1?0:-b;
Peter Taylor

1
Continuando @ golfe do PeterTaylor acima, você pode então mudar if(a%i<1){a/=i;b=a%i<1?0:-b;}para b=a%i<1?(a/=i)%i<1?0:-b:b;salvar mais 3 bytes.
Kevin Cruijssen 30/10

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, versão 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 célula do Excel a ser inserida nas células A1 a AX50.



1

Sério, 11 bytes

Sugestões de golfe são bem-vindas. Experimente 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.

Agradável solução =) (eu acho, porém, que esta linguagem é mais jovem que a questão, não é)?
flawr

@flawr Aparentemente, a resposta funciona tão bem quanto o Seriously, e eu não sei quando o Actually ficou online pela primeira vez, então mudei para o Seriously apenas por segurança.
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 graças a @PeterTaylor .

Porta da resposta .NET C # do @ Meerkat , que eu joguei um pouco mais longe, então, vote-o novamente!

Experimente online.

Explicação:

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

Veja meu comentário sobre a resposta de Meerkat.
Peter Taylor

@PeterTaylor Smart, obrigado! E então mais 3 bytes podem ser salvos usando r=n%i<1?(n/=i)%i<1?0:-r:r;.
Kevin Cruijssen 30/10

0

Javascript (ES6), 48 bytes

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

Primeiro de tudo - este é o meu primeiro post de código de golfe, para que eu possa entender mal as regras até certo ponto. Nesta submissão, o último caractere ;pode ser omitido e ainda funcionará, mas nem tenho certeza se o código seria válido de acordo com as especificações do ES6. De qualquer forma, uma breve explicação.

Primeiro, vou explicar um pouco a ideia; nós npegamos e tentamos dividi-lo pelo número inteiro i. Se é divisível, fazemos isso e verificamos se é divisível inovamente. Se for esse o caso, precisamos retornar 0. Caso contrário, podemos tentar outro i. O legal é que podemos simplesmente começar i=2e adicionar aumentá-lo a 1cada vez, para dividirmos todos os fatores principais.

Portanto, o código funciona assim:

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

Então, essa é a minha submissão.


Bem vindo ao site. Não conheço js, ​​mas posso lhe dizer que aqui não nos importamos com especificações, apenas implementações. Portanto, se a remoção ;não a quebra, não importa as especificações que você pode removê-la.
Assistente de trigo 28/10

Bom saber! Eu vou removê-lo então;)
vrugtehagel
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.