La funzione Möbius


23

La funzione Möbius

La funzione Möbius è un'importante funzione teorica numerica.

L'invio deve accettare un numero intero positivo ne restituire il valore della funzione Möbius valutato in n.

Definizione

La funzione Möbius μ (n) è definita come segue:

       |  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

nviene chiamato squarefree se gli esponenti della scomposizione in fattori primi di n sono tutti strettamente inferiori a due. (In alternativa: nessun numero primo per la potenza di due divisioni n).

Casi test

Qui puoi vedere i primi 50 valori di μ:

Immagine di dominio pubblico da Wikipedia

La funzione Möbius è il numero progressivo A008683 nell'OEIS.

Questi sono i primi 77 valori:

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

Valori più grandi possono anche essere facilmente verificati in Wolframalpha.com o nel file b di OEIS , come suggerito da @ MartinBüttner.

Risposte:


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

Versione a 51 byte precedente:

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

Möbius inverte la sequenza 1,0,0,0,0....

La funzione di Möbius ha la proprietà che per qualsiasi n>1, le funzioni di Möbius dei ndivisori di 'sommano a 0. Quindi, per n>1, μ(n)viene calcolata negando la somma di μ(k)per tutti i divisori propri kdi n. Per n=1, l'output è 1.

Il codice gestisce il caso base aggiungendo una divisione di piano 1/n, che dà 1per n==1e 0altrimenti.

Grazie a Dennis per aver salvato 3 byte con una migliore gestione ricorsiva ispirata a una struttura simile in questa sfida .


13

Gelatina , 7 byte

Codice:

ÆF>1’PS

Spiegazione:

Æ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

Ad esempio, il numero 10 :

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

E risulta in 1 .

Provalo online .


-1 byte: ÆFỊNPS(non sono sicuro se all'epoca fosse un built-in, ma ora dovrebbe andare bene).
Erik the Outgolfer,

10

Mathematica, 9 byte

MoebiusMu

Naturalmente, Mathematica ha un built-in. (E probabilmente sarà battuto da Jelly comunque.)


7

CJam, 18 15 byte

WrimFz~\1&+f/:*

Il fatto che CJam restituisca 1 nei builtin di fattorizzazione n = 1rende le cose un po 'complicate.

Provalo online | Suite di test

Grazie a @PeterTaylor per il 1&+trucco accurato per la gestione del 1 caso.

Spiegazione

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

Per n > 1, l'array modificato è solo l'array di esponenti. Se nè quadrato, l'array è tutto 1s, che diventa tutto -1s dopo la divisione. Altrimenti, se n ha un divisore quadrato primo, allora ci sarà uno 0 da qualche parte dopo la divisione, dando un prodotto di 0.

Per n = 1l'array modificato è [1] + [1], che diventa [-1 -1]dopo la divisione, dando un prodotto di 1.


Alternativa 16:

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

Questo utilizza #(trova) su ciascun [base exponent]array per cercare un 1, quindi le mappe -1 -> 0, 0 -> 1, 1 -> -1.


6

Rubino, 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 per la -rprimebandiera.

Lo stiamo facendo nel modo più ingenuo:

->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 "magica" risulta in 1 se il numero è pari e -1 altrimenti. Ecco come:

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

5

Pyth, 9 byte

^_{IPQlPQ

Spiegazione:

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

Provalo qui .


5

Labirinto , 87 byte

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

Provalo online!

Breve spiegazione

Ecco una porta dell'algoritmo usato, in 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)

Lunga spiegazione

Il solito primer su Labyrinth:

  • Labyrinth è basato su stack e bidimensionale, con l'esecuzione che inizia dal primo carattere riconosciuto. Esistono due pile, una pila principale e una pila ausiliaria, ma la maggior parte degli operatori lavora solo sulla pila principale.
  • Ad ogni ramo del labirinto, la parte superiore della pila viene controllata per determinare dove andare dopo. Il negativo è girare a sinistra, zero è dritto e il positivo è girare a destra.

L'esecuzione per questo programma inizia in alto a sinistra 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

Richiede l' installazione del pacchetto numeri sul sistema ...

Modifica: molto più semplice se leggo le specifiche in modo appropriato [grazie @AlexA.]


Ciò restituisce la funzione Möbius valutata per ogni numero intero da 1 all'input, ma il compito di questa sfida è semplicemente valutare la funzione Möbius sull'input.
Alex A.

Sulla falsariga della risposta di Mathematica, potresti persino fare semplicemente numbers::moebius16 byte.
Alex A.

3

Pyth , 16 byte

?nl{PQlPQZ^_1lPQ

Provalo online!

La mia prima vera risposta Pyth. Suggerimenti apprezzati! :)

Spiegazione

La mia soluzione utilizza il fatto che un numero è quadrato, se i suoi fattori primi non contengono un numero più di una volta. Se l'ingresso è quadrato, la funzione Möbius assume il valore -1 ^ (numero di fattori primi).


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

Questo utilizza l' attuale versione (10.1.0) del linguaggio / compilatore.

Provalo online!

Spiegazione

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, non concorrenti

Accidenti, ancora una volta un bug che rende la mia presentazione non competitiva. Codice:

.p0K1›<P

Spiegazione:

.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

Utilizza la codifica CP-1252


non è in ISO 8859-1 ...
ETHproductions

1
@ETHproductions Heh? Che tipo di codifica è allora? L'ho preso da questo sito .
Adnan,

Credo che si chiama Extended ASCII .
ETHproductions

@ETHproductions Grazie, ho modificato il post :)
Adnan,

@ThomasKwa Ahh, l'ho trovato. È la codifica CP-1252 .
Adnan,

2

Pyth, 11

*{IPQ^_1lPQ

Suite di test

Questo moltiplica il valore booleano di se i fattori primi sono quadrati -1per la potenza del numero di fattori primi che il numero ha.

Iè un controllo di invarianza sull'operatore precedente, che qui è {, che è l'operatore univoco.



2

Julia, 66 byte

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

Questa è una funzione lambda che accetta un numero intero e restituisce un numero intero. Per chiamarlo, assegnarlo a una variabile.

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 byte

moebius

Purtroppo möbiusnon è disponibile. :)


2

Scherzi a parte, 19 18 byte

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

Provalo online!

Spiegazione:

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

Provalo online!

-13 byte: loop semplificati, aggiunta della variabile return (grazie a Kevin Cruijssen )
-1 byte: cambiata l'impostazione da b a zero in un ternario da un if (grazie a Kevin Cruijssen )
-7 byte: cambiato se istruzione in per il ciclo in un ternario (grazie 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 byte ho cambiato int b=1;for(int i=1;a int b=1,i=1;for(;. Rimosse le {}staffe per il loop. Cambiato sia a%i==0a a%i<1. Modificato il b*=-1;to b=-b;. E finalmente cambiato la return 0;a b=0;.
Kevin Cruijssen,

Sì, tutto ciò che hai suggerito sembrava corretto. Ero così leggermente preoccupato quando hai detto che non era giusto, perché ciò avrebbe significato che anche il mio codice originale era sbagliato! :)
Meerkat,

1
Sì, scusa per quello. :) 1 più byte a golf è btw if(a%i<1)b=0;a b=a%i<1?0:b;.
Kevin Cruijssen,

2
In realtà, ciò trascura un facile miglioramento: il b=-b;b=a%i<1?0:b;golf ab=a%i<1?0:-b;
Peter Taylor,

1
Continuando sul golf di @ PeterTaylor qui sopra, è possibile passare if(a%i<1){a/=i;b=a%i<1?0:-b;}a b=a%i<1?(a/=i)%i<1?0:-b:b;per salvare altri 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, versione britannica, 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)),""))),"")

Formula di cella Excel da inserire nelle celle da A1 a AX50.



1

Scherzi a parte, 11 byte

Suggerimenti di golf benvenuti. Provalo 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.

Bella soluzione =) (Immagino comunque che questa lingua sia più giovane della domanda, vero?)
flawr

@flawr Apparentemente la risposta funziona altrettanto bene in Seriamente, e non so quando Veramente è online per la prima volta, quindi sono passato a Seriamente solo per sicurezza.
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 grazie a @PeterTaylor .

Porta della risposta .NET C # di @ Meerkat , che ho giocato a golf un po 'più avanti, quindi assicurati di votarlo!

Provalo online.

Spiegazione:

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

Vedi il mio commento sulla risposta di Meerkat.
Peter Taylor,

@PeterTaylor Smart, grazie! Quindi è possibile salvare altri 3 byte utilizzando 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

Prima di tutto, questo è il mio primo post di golf in codice, quindi potrei fraintendere le regole in una certa misura. In questa presentazione l'ultimo personaggio; potrebbe essere omesso e continuerà a funzionare ma non sono nemmeno sicuro che il codice sia valido in base alle specifiche ES6. Comunque, una breve spiegazione.

Prima spiegherò un po 'l'idea; prendiamo ne proviamo a dividerlo per l'intero i. Se è divisibile, lo facciamo e controlliamo se è divisibile di inuovo. In tal caso, dobbiamo tornare 0. Altrimenti, possiamo provarne un altro i. Il bello è che possiamo solo iniziare i=2e aggiungere aumentarlo 1ogni volta, in modo da dividere tutti i fattori primi.

Quindi, il codice funziona in questo modo:

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

Quindi, questa è la mia presentazione.


Benvenuti nel sito. Non conosco js, ​​ma posso dirti che qui non ci importa delle specifiche, solo delle implementazioni. Quindi, se la rimozione ;non lo rompe, non importa le specifiche che è possibile rimuoverlo.
Mago del grano,

Buono a sapersi! Lo rimuoverò quindi;)
vrugtehagel,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.