Il derivato aritmetico


34

La derivata di una funzione è una pietra angolare della matematica, dell'ingegneria, della fisica, della biologia, della chimica e anche di un gran numero di altre scienze. Oggi calcoleremo qualcosa solo tangenzialmente correlato: la derivata aritmetica.

Definizione

La derivata aritmetica a(n)o n'è definita qui ( A003415 ) da un numero di proprietà che sono simili alla derivata di una funzione.

  • a(0) = a(1) = 0,
  • a(p) = 1, dov'è pun numero primo e
  • a(mn) = m*a(n) + n*a(m).

La terza regola è basata sulla regola del prodotto per la differenziazione di funzioni: per le funzioni f(x)e g(x), (fg)' = f'g + fg'. Quindi, con i numeri, (ab)' = a'b + ab'.

Inoltre, poiché la derivata aritmetica può essere estesa ai numeri negativi tramite questa semplice relazione a(-n) = -a(n), l'input può essere negativo.

Regole

  • Scrivi un programma o una funzione che, dato un numero intero n, restituisca la derivata aritmetica di n.
  • Gli input saranno , per evitare problemi con dimensioni di numeri interi e numeri troppo grandi per tener conto di un ragionevole lasso di tempo. Il tuo algoritmo dovrebbe essere comunque in grado di calcolare teoricamente la derivata aritmetica dei numeri al di fuori di questo intervallo.-230 < n < 230
  • Sono ammessi elementi incorporati per la matematica simbolica, la scomposizione in fattori primi e la differenziazione.

Esempi

> a(1)
0
> a(7)
1
> a(14)   # a(7)*2 + a(2)*7 = 1*2 + 1*7 = 9
9
> a(-5)   # a(-5) = -a(5) = -1
-1
> a(8)    # a(8) = a(2**3) = 3*2**2 = 12
12
> a(225)  # a(225) = a(9)*25 + a(25)*9 = 6*25 + 10*9 = 150 + 90 = 240
240
> a(299792458)  # a(299792458) = a(2)*149896229 + a(7)*42827494 + a(73)*4106746 + a(293339)*1022 = 1*149896229 + 1*42827494 + 1*4106746 + 1*1022 = 149896229 + 42827494 + 4106746 + 1022 = 196831491
196831491

Come sempre, se il problema non è chiaro, per favore fatemi sapere. Buona fortuna e buon golf!


Che cosa, esattamente, è primein a(prime)? È solo un numero primo?
Stackstuck,

Inoltre, non capisco come hai decomposto l'ultimo esempio.
Stackstuck

@Stackstuck Sì, è un numero primo. Ho modificato per chiarezza. Inoltre, ho aggiunto all'ultimo esempio per renderlo più chiaro.
Sherlock9,

Risposte:


10

MATL , 12 byte

|1>?GtYf/s}0

Provalo online!

Spiegazione

Considera un numero intero a con | a |> 1 e lasciare che i fattori primi (possibilmente ripetuti) di | a | essere f 1 , ..., f n . Quindi il risultato desiderato è un · (1 / f 1 + ... + 1 / f n ).

|1>     % take input's absolute value. Is it greater than 1?
?       % if so:
  Gt    %   push input twice
  Yf    %   prime factors. For negative input uses its absolute value
  /     %   divide element-wise
  s     %   sum of the array
}       % else:
  0     %   push 0

La somma dei fattori primi di 1 non è uguale a 0? O non funziona in MATL?
wythagoras,

@wythagoras In realtà 1indica 1la sua scomposizione numerica "principale". È un risultato strano (un array vuoto sarebbe più significativo). Ma è così che funziona Matlab. E anche CJam. Quindi suppongo che ci debba essere una buona ragione per produrre 1in quel caso? Cosa pensi? Sono stato tentato di ridefinire la Yffunzione di output di un array vuoto 1, ma non ero sicuro
Luis Mendo,

1
Pyth fornisce un array vuoto, prima di tutto.
isaacg,

@isaacg Grazie! Forse lo cambierò
Luis Mendo il

Lo stesso in Mathematica (era quasi un problema una volta)
CalculatorFeline

7

Python, 59 byte

f=lambda n,p=2:+(n*n>1)and(n%p and f(n,p+1)or p*f(n/p)+n/p)

Una funzione ricorsiva. Su input di grandi dimensioni, si esaurisce la profondità dello stack nei sistemi tipici a meno che non venga eseguito con qualcosa come Stackless Python .

La definizione ricorsiva viene implementata direttamente, contando fino alla ricerca dei fattori primi candidati. Dal momento che f(prime)=1, se nha un numero primo pcome fattore, abbiamo f(n) == p*f(n/p)+n/p.


Non hai bisogno di input e stampa? Almeno quando eseguo questo (Python 2), non ottengo alcun risultato.
wythagoras,

@wythagoras Per impostazione predefinita, le funzioni sono consentite in alternativa ai programmi. Inoltre, questa sfida dice "programma o funzione".
xnor

7

Gelatina, 8 7 byte

-1 byte di @Dennis

ÆfḟṠ³:S

Utilizza la stessa formula che fanno tutti gli altri. Tuttavia, c'è un piccolo trucco da affrontare 0.

o¬AÆfİS×     Main link. Inputs: n
o¬             Logical OR of n with its logical NOT
               That is, 0 goes to 1 and everything else goes to itself.
  A            Then take the absolute value
   Æf          get its list of prime factors
     İ         divide 1 by those
      S        sum
       ×       and multiply by the input.

Provalo qui .


Potete per favore aggiungere una spiegazione? Mi piacciono le risposte per avere spiegazioni prima di votarle.
Sherlock9,

@ Sherlock9 Fatto.
lirtosiast,

Vedo che la tua risposta è stata risolta e la spiegazione non è più aggiornata. Per favore, lo aggiusteresti? Grazie: D
Sherlock9,

5

Python 2, 87 78 76 74 byte

a=b=input()
d=2
s=0
while d<=abs(b):
    if a%d==0:
        a=a/d
        s+=b/d
    else:
        d+=1
print s

Miglioramenti grazie a @Maltysen:

a=b=input()
d=2
s=0
while d<=abs(b):
    if a%d==0:a/=d;s+=b/d
    else:d+=1
print s

Ulteriore miglioramento di due byte:

a=b=input()
d=2
s=0
while abs(a)>1:
    if a%d<1:a/=d;s+=b/d
    else:d+=1
print s

Ulteriore miglioramento grazie a @xnor:

a=b=input()
d=2
s=0
while a*a>1:
    if a%d<1:a/=d;s+=b/d
    else:d+=1
print s

Spiegazione

La derivata aritmetica di aè uguale a avolte la somma dei reciproci dei fattori primi di a. Non è necessaria alcuna eccezione per 1 poiché la somma dei reciproci dei fattori primi di 1 è zero.


abs(a)>1può essere a*a>1.
xnor

@xnor Sì, grazie.
wythagoras,

Sostituisci la riga 2 cond,s = 2,0
Agnishom Chattopadhyay il

@AgnishomChattopadhyay Entrambi sono 8 byte in totale.
wythagoras,

4

Haskell, 203 90 byte

Grazie @nimi!

Non ho ancora idea di quando quali rientranze causino quale interpretazione, questa è la più breve che ho gestito finora e, come sempre, sono sicuro che può essere giocato molto di più. Ci riproverò di sera.

n#(x:_)|y<-div n x=x*a y+y*a x;_#_=1
a n|n<0= -a(-n)|n<2=0|1<2=n#[i|i<-[2..n-1],mod n i<1]

1
Grazie mille, insegnante =) Posso sempre imparare così tanto ogni volta che mi aiuti qui! Sentiti libero di aggiungere la tua versione come risposta personale!
Flawr,

4

J, 30 27 19 caratteri

Grazie a @Dennis per aver tagliato 3 personaggi.

Grazie a @Zgarb per aver tagliato 8 caratteri.

0:`(*[:+/%@q:@|)@.*

Provalo online!

Input di esempio:

0:`(*[:+/%@q:@|)@.* _8
_12

0:`(*[:+/%@q:@|)@.* 0
0

0:`(*[:+/%@q:@|)@.* 8
12

Come funziona:

0:`(*[:+/%@q:@|)@.* N
XX`YYYYYYYYYYYYY@.Z   if Z then Y else X end
0:                        X:  return 0
                  Z       Z:  signum(N)
   (*[:+/%@q:@|)          Y:  N*add_all(reciprocal_all(all_prime_factors(abs(N))))
                              N
    *                          *
      [:+/                      add_all(                                         )
          %@                            reciprocal_all(                         )
            q:@                                       all_prime_factors(      )
               |                                                        abs( )
                                                                            N

3

Pyth - 10 8 byte

Adoro l'input implicito! Dovrebbe portarlo alla pari con Jelly per la maggior parte delle cose (tranne le abilità di golf di Dennis).

*scL1P.a

Test Suite .

*             Times the input, implicitly (This also adds the sign back in)
 s            Sum
  cL1         Reciprocal mapped over lit
   P          Prime factorization
    .a        Absolute value of input, implicitly

3

Haskell, 59 byte

n%p|n*n<2=0|mod n p>0=n%(p+1)|r<-div n p=r+p*r%2
(%2)

Implementa direttamente la definizione ricorsiva, con una variabile ausiliaria pche conta fino alla ricerca di potenziali fattori primi, a partire da 2. L'ultima riga è la funzione principale, che si collegap=2 alla funzione binaria definita nella prima riga.

La funzione controlla a turno ogni caso:

  • Se n*n<2, allora nè uno dei -1,0,1, e il risultato è0 .
  • Se nnon è un multiplo di p, quindi incrementare pe continuare.
  • Altrimenti, espresso n=p*re con la proprietà "derivata", il risultato è r*a(p)+p*a(r), che si semplifica r+p*a(r)perché pè primo.

L'ultimo caso salva i byte legandosi rin una protezione , che evita anche il 1>0per il boilerplate otherwise. Se rpotesse essere associato in precedenza, la seconda condizione mod n p>0potrebbe essere verificata come r*p==n, che è di 3 byte in meno, ma non vedo come farlo.


3

Scherzi a parte , 17 14 11 12 byte

La mia prima risposta seria in assoluto. Questa risposta si basa sulla risposta MATL di Luis Mendo e sull'idea che la derivata aritmetica di un numero mè uguale a dove si trova ogni fattore primo della molteplicità. La mia aggiunta è di notare che, se , allora . Grazie a Mego per il golf e l'aiuto nella risoluzione dei bug. Provalo online!m·(1/p1 + 1/p2 + ... + 1/pn)p1...pnnm = p1e1·p2e2·...·pnena(m) = m·(e1/p1 + e2/p2 + ... + en/pn)

,;w`i@/`MΣ*l

Ungolfing:

,             get a single input
 ;w           duplicate input and get prime factorization, p_f
               for input [-1..1], this returns [] and is dealt with at the end
   `   `M     map the function inside `` to p_f
    i         pop all elements of p_f[i], the prime and the exponent, to the stack
     @        rotate so that the exponent is at the top of the stack
      /       divide the exponent by the prime
         Σ    sum it all together
          *   multiply this sum with the input
           l  map and multiply do not affect an empty list, so we just take the length, 0
               l is a no-op for a number, so the result is unchanged for all other inputs


3

APL (Dyalog Extended) , 13 9 byte

Una soluzione semplice La versione Unicode di Dyalog era semplicemente una versione più lunga di questo, quindi è stata omessa.

Modifica: salvato 4 byte adottando il metodo nella soluzione Jelly di lirtosiast .

{+/⍵÷⍭|⍵}

Provalo online!

Ungolfing

{+/⍵÷⍭|⍵}

{        }  A dfn, a function in {} brackets.
     ⍭|⍵   The prime factors of the absolute value of our input.
   ⍵÷      Then divide our input by the above array,
            giving us a list of products for the product rule.
 +/         We sum the above numbers, giving us our arithmetic derivative.

2

Rubino, 87 66 80 75 70 68 byte

Questa risposta si basa sulla risposta di Luis Mendo MATL , risposta Python wythagoras , e l'idea che il derivato aritmetica di un numero mè pari a dove è ogni fattore primo di alla molteplicità.m·(1/p1 + 1/p2 + ... + 1/pn)p1...pnn

->n{s=0;(2...m=n.abs).map{|d|(m/=d;s+=n/d)while m%d<1};m<2?0:s+0**s}

Questa funzione viene chiamata nel modo seguente:

> a=->n{s=0;(2...m=n.abs).map{|d|(m/=d;s+=n/d)while m%d<1};m<2?0:s+0**s}
> a[299792458]
196831491

Ungolfing:

def a(n)
  s = 0
  m = n.abs
  (2...m).each do |z|
    while m%d == 0
      m /= d
      s += n / d
    end
  end
  if s == 0
    if n > 1
      s += 1 # if s is 0, either n is prime and the while loop added nothing, so add 1
             # or n.abs < 2, so return 0 anyway
             # 0**s is used in the code because it returns 1 if s == 0 and 0 for all other s
    end
  end
  return s
end

2

Julia, 72 43 byte

n->n^2>1?sum(p->n÷/(p...),factor(n^2))/2:0

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

Per un intero di input n , se n 2 ≤ 1 restituisce 0. In caso contrario, ottenere la fattorizzazione in primo piano di n 2 come a Dict, quindi per ciascuna coppia primo / esponente, dividere il primo per il suo esponente, quindi dividere n per il risultato. Questo sta semplicemente calcolando n x / p , dove p è il fattore primo e x è il suo esponente, che è lo stesso della somma n / p , x volte. Sommiamo l'array risultante e lo dividiamo per 2, poiché abbiamo sommato il doppio di cui abbiamo bisogno. Ciò è dovuto al fatto che stiamo considerando n. 2piuttosto che n . (Questo è un byte più breve del factoring | n |.)

Risparmiato 29 byte grazie a Dennis!



1

Mathematica 10.0, 39 byte

Tr[If[#>1,#2/#,0]&@@@FactorInteger@#]#&

1
Potete per favore aggiungere una spiegazione? Mi piacciono le risposte per avere spiegazioni prima di votarle.
Sherlock9

1
@ Sherlock9 Questa è una risposta poco interessante quindi non ho intenzione di aggiungerne una. Va bene se nessuno lo vota.
feersum

Bene allora. Buona giornata :)
Sherlock9

Nell'attuale versione di Mathematica, FactorInteger@1cede {1,1}, quindi la Iffunzione non è più necessaria, risparmiando 10 byte.
Greg Martin,

@GregMartin Seriamente? Questo è ancora più incoerente rispetto al valore, {{1,1}}restituito dalla mia versione ( {}è il risultato atteso per me).
feersum,

1

APL (NARS), 35 caratteri, 70 byte

{1≥a←∣⍵:0⋄1=≢k←πa:×⍵⋄c+m×∇c←⍵÷m←↑k}

test e come usare:

  f←{1≥a←∣⍵:0⋄1=≢k←πa:×⍵⋄c+m×∇c←⍵÷m←↑k}
  f 14
9
  f 8
12
  f 225
240
  f ¯5
¯1
  f 299792458
196831491

Ho pensato che non sarebbe stato ok perché non so se la variabile c sia composta (e non un numero primo) ... Ma sembra ok per il test ...



0

Perl 5, 62 byte

perl -MMath::Prime::Util=:all -E"map$i+=1/$_,factor abs($j=<>);say$i*$j"

Utilizza la formula (da OEIS): If n = Product p_i^e_i, a(n) = n * Sum (e_i/p_i).


0

Perl 6, 90

sub A(\n) {0>n??-A(-n)!!(n>1)*{$_??n/$_*A($_)+$_*A n/$_!!1}(first n%%*,2..^n)};say A slurp

Questo potrebbe essere un po 'lento per grandi numeri. Sostituisci 2..^ncon 2..n.sqrtper codice più lungo ma calcolo più veloce.


0

Inchiostro , 183 byte

==function a(n)
{n<0:
~return-a(-n)
}
{n<2:
~return 0
}
~temp f=t(n,2)
{f:
~return a(n/f)*f+n/f
}
~return 1
==function t(n,i)
{n>1&&n-i:
{n%i:
~return t(n,i+1)
}
~return i
}
~return 0

Provalo online!

Mi rifiuto di credere che questa sia una buona soluzione, ma non vedo neanche un modo per migliorarla.


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.