Le dérivé arithmétique


34

La dérivée d'une fonction est une pierre angulaire des mathématiques, de l'ingénierie, de la physique, de la biologie, de la chimie et d'un grand nombre d'autres sciences. Aujourd'hui, nous allons calculer quelque chose qui ne concerne que de manière tangentielle: la dérivée arithmétique.

Définition

Le dérivé arithmétique a(n)ou n'est défini ici ( A003415 ) par un certain nombre de propriétés similaires au dérivé d’une fonction.

  • a(0) = a(1) = 0,
  • a(p) = 1, où pest tout premier, et
  • a(mn) = m*a(n) + n*a(m).

La troisième règle est basée sur la règle du produit de différenciation des fonctions: des fonctions f(x)et g(x), (fg)' = f'g + fg'. Donc , avec des chiffres, (ab)' = a'b + ab'.

À noter également, puisque la dérivée arithmétique peut être étendue aux nombres négatifs via cette relation simple a(-n) = -a(n), l’entrée peut être négative.

Règles

  • Ecrivez un programme ou une fonction qui, avec n'importe quel entier n, retourne la dérivée arithmétique de n.
  • Les entrées seront , pour éviter les problèmes avec les tailles entières et les nombres trop grands pour prendre en compte une quantité de temps raisonnable. Votre algorithme devrait toujours pouvoir théoriquement calculer la dérivée arithmétique des nombres en dehors de cette plage.-230 < n < 230
  • Les fonctions intégrées pour les mathématiques symboliques, la décomposition en facteurs premiers et la différenciation sont autorisées.

Exemples

> 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

Comme toujours, si le problème n'est pas clair, merci de me le faire savoir. Bonne chance et bon golf!


Qu'est - ce, exactement, est primeen a(prime)? Est-ce juste un nombre premier?
Stackstuck

De plus, je ne comprends pas comment vous avez décomposé le dernier exemple.
Stackstuck

@ Stackstuck Oui, c'est n'importe quel prime. J'ai édité pour plus de clarté. De plus, j’ai ajouté au dernier exemple pour le rendre plus clair, espérons-le.
Sherlock9

Réponses:


10

MATL , 12 octets

|1>?GtYf/s}0

Essayez-le en ligne!

Explication

Considérons un entier a avec | a |> 1, et laissez les facteurs premiers (éventuellement répétés) de | a | être f 1 , ..., f n . Alors le résultat souhaité est 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 somme des facteurs premiers de 1 n'est-elle pas égale à 0? Ou est-ce que ça ne marche pas dans MATL?
Wythagoras

@wythagoras 1donne en fait 1comme "premier" décomposition en nombre. C'est un résultat étrange (un tableau vide serait plus significatif). Mais c'est comme ça que Matlab fonctionne. Et aussi CJam. Donc je suppose qu'il doit y avoir une bonne raison de sortir 1dans ce cas? Qu'est-ce que tu penses? J'ai été tenté de redéfinir la Yffonction pour générer un tableau vide 1, mais je n'étais pas sûr
Luis Mendo

1
Pyth donne un tableau vide, fwiw.
isaacg

@isaacg Merci! Peut-être que je changerai ça
Luis Mendo

Même chose dans Mathematica (était presque un problème une fois)
CalculatorFeline

7

Python, 59 octets

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

Une fonction récursive. Sur les grandes entrées, la profondeur de pile sur les systèmes classiques est insuffisante, à moins que vous ne l' utilisiez avec quelque chose comme Pile sans pile .

La définition récursive est implémentée directement, en comptant jusqu'à la recherche de facteurs premiers candidats. Depuis f(prime)=1, sin a pun facteur premier, nous avons f(n) == p*f(n/p)+n/p.


Vous n'avez pas besoin d'entrer et d'imprimer? Au moins quand je lance ceci (Python 2), je n’obtiens aucun résultat.
wythagoras

@wythagoras Par défaut, les fonctions sont autorisées comme alternative aux programmes. En outre, ce défi dit "programme ou fonction".
xnor

7

Gelée, 8 7 octets

-1 octet par @Dennis

ÆfḟṠ³:S

Utilise la même formule que tout le monde. Cependant, il y a un petit truc à gérer 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.

Essayez ici .


Pouvez-vous s'il vous plaît ajouter une explication? J'aime les réponses pour avoir des explications avant de les invoquer.
Sherlock9

@ Sherlock9 Fait.
lirtosiast

Je vois que votre réponse a été mise en échec et que l'explication est maintenant obsolète. Pourriez-vous résoudre ce problème? Merci: D
Sherlock9

5

Python 2, 87 78 76 74 octets

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

Améliorations grâce à @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

Amélioration ultérieure de deux octets:

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

Amélioration supplémentaire grâce à @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

Explication

La dérivée arithmétique de aest égale à afois la somme des inverses des facteurs premiers de a. Aucune exception pour 1 n'est nécessaire puisque la somme des inverses des facteurs premiers de 1 est égale à zéro.


abs(a)>1peut être a*a>1.
xnor

@xnor Oui, merci.
Wythagoras

Remplacer la ligne 2 pard,s = 2,0
Agnishom Chattopadhyay

@AgnishomChattopadhyay Les deux sont de 8 octets au total.
Wythagoras

4

Haskell, 203 90 octets

Merci @nimi!

Je ne sais toujours pas quand les indentations causent quelle interprétation, c’est le plus court j’ai réussi jusqu’à présent, et comme toujours, je suis sûr que cela peut être joué beaucoup plus. Je vais essayer à nouveau dans la soirée.

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
Merci beaucoup, professeur =) Je peux toujours apprendre autant de choses lorsque vous m'aidez ici! N'hésitez pas à ajouter votre version comme votre propre réponse!
mardi

4

J, 30 27 19 caractères

Merci à @Dennis d' avoir coupé 3 personnages.

Merci à @Zgarb d' avoir coupé 8 caractères.

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

Essayez-le en ligne!

Exemple de saisie:

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

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

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

Comment ça marche:

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 octets

Lovin 'l'entrée implicite! Devrait le mettre sur un pied d'égalité avec Jelly pour la plupart des choses (sauf les compétences de golf de Dennis).

*scL1P.a

Suite de test .

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

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

Implémente directement la définition récursive, avec une variable auxiliaire pqui compte jusqu'à la recherche de facteurs premiers potentiels, à partir de 2. La dernière ligne est la fonction principale, qui se connecte p=2à la fonction binaire définie dans la première ligne.

La fonction vérifie chaque cas successivement:

  • Si n*n<2, alors nest l'un des -1,0,1, et le résultat est 0.
  • Si nn'est pas un multiple de p, puis incrémentez pet continuez.
  • Autrement, express n=p*r, et par la propriété "dérivé", le résultat est r*a(p)+p*a(r), ce qui simplifie r+p*a(r)parce que pest premier.

Le dernier cas économise des octets en se liant rà un garde , ce qui évite également le 1>0pour le passe-partout otherwise. Si rpouvait être lié plus tôt, la deuxième condition mod n p>0pourrait être vérifiée r*p==n, c'est-à-dire 3 octets de moins, mais je ne vois pas comment faire.


3

Sérieusement , 17 14 11 12 octets

Ma première réponse sérieusement. Cette réponse est basée sur la réponse MATL de Luis Mendo et sur l'idée que la dérivée arithmétique d'un nombre mest égale à où est chaque facteur premier de multiplicité. Mon ajout est à noter que, si , alors . Merci à Mego pour son aide au golf et à la correction des bugs. Essayez-le en ligne!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 octets

Une solution simple La version Dyalog Unicode était simplement une version plus longue de celle-ci, elle a donc été omise.

Edit: Sauvegardé 4 octets en adoptant la méthode dans la solution Jelly de lirtosiast .

{+/⍵÷⍭|⍵}

Essayez-le en ligne!

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

Ruby, 87 66 80 75 70 68 octets

Cette réponse est basée sur la réponse de MATL de Luis Mendo , la réponse Python wythagoras , et l'idée que la dérivée arithmétique d'un nombre mest égal à où est chaque facteur premier de la multiplicité.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}

Cette fonction est appelée de la manière suivante:

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

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

C'est une fonction anonyme qui accepte un entier et renvoie un float. Pour l'appeler, assignez-le à une variable.

Pour un entier en entrée n , si n 2 ≤ 1, renvoyer 0. Sinon, obtenir la factorisation première de n 2 sous la forme a Dict, puis pour chaque paire nombre premier / exposant, divisez le nombre premier par son exposant, puis divisez n par le résultat. Il ne s’agit que de calculer n x / p , où p est le facteur premier et x son exposant, ce qui revient à sommer n / p , x fois. Nous additionnons le tableau résultant et le divisons par 2, car nous avons additionné deux fois plus que nécessaire. C'est dû au fait que nous factorisons n 2plutôt que |.)n n. (Faire cela est un octet plus court que l'affacturage |

Sauvegardé 29 octets grâce à Dennis!


1

Jolf, 13 octets

*jmauΜm)jd/1H

Félicitations à la réponse MATL pour l'algorithme! Essayez ici , ou de les tester à la fois . (Les sorties [key, out] dans un tableau.)

Explication

*jmauΜm)jd/1H
*j             input times
      m)j         p.f. of input
     Μ   d/1H      mapped to inverse
    u            sum of
  ma            abs of

1

Mathematica 10.0, 39 octets

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

1
Pouvez-vous s'il vous plaît ajouter une explication? J'aime les réponses pour avoir des explications avant de les invoquer.
Sherlock9

1
@ Sherlock9 C'est une réponse assez inintéressante, donc je n'ai pas l'intention d'en ajouter une. Ce n'est pas grave si personne ne lève le ton.
Feersum

Très bien alors. Passez une bonne journée :)
Sherlock9

Dans la version actuelle de Mathematica, le résultat est FactorInteger@1obtenu {1,1}, de sorte que la Iffonction n'est plus nécessaire, en économisant 10 octets.
Greg Martin

@ GregMartin Sérieusement? C'est encore plus incohérent que la valeur, {{1,1}}renvoyée par ma version ( {}c'est le résultat attendu pour moi).
Feersum

1

APL (NARS), 35 caractères, 70 octets

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

test et comment utiliser:

  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

Je pensais que ça ne serait pas correct parce que je ne sais pas si c variable est composée (et non un nombre premier) ... Mais semble bien pour le test ...



0

Perl 5, 62 octets

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

Utilise la formule (d'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

Cela pourrait être un peu lent pour les grands nombres. Remplacez 2..^npar 2..n.sqrtpour un code plus long mais un calcul plus rapide.


0

Encre , 183 octets

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

Essayez-le en ligne!

Je refuse de croire que c'est une bonne solution, mais je ne vois pas non plus de moyen de l'améliorer.


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.