Combien de façons d'écrire N comme produit de M entiers?


12

Étant donné un entier N , comptez combien de façons il peut être exprimé comme un produit de M entiers> 1.

L'entrée est simplement N et M , et la sortie est le nombre total de groupes entiers distincts . Cela signifie que vous pouvez utiliser un entier plus d'une fois, mais chaque groupe doit être distinct ( 3 x 2 x 2ne compterait pas s'il 2 x 2 x 3est présent).

Contraintes

1 < N <2 31
1 < M <30

Exemples

L'entrée 30 2donne la sortie 3, car elle peut être exprimée de 3 façons:

2 x 15
3 x 10
5 x 6

L'entrée 16 3donne la sortie 1, car il n'y a qu'un seul groupe distinct:

2 x 2 x 4

L'entrée 2310 4donne la sortie 10:

5 x 6 x 7 x 11
3 x 7 x 10 x 11
3 x 5 x 11 x 14
3 x 5 x 7 x 22
2 x 7 x 11 x 15
2 x 5 x 11 x 21
2 x 5 x 7 x 33
2 x 3 x 11 x 35
2 x 3 x 7 x 55
2 x 3 x 5 x 77

L'entrée 15 4donne la sortie 0, car cela ne peut pas être fait.

Règles

Les failles de golf de code standard s'appliquent, ainsi que les définitions standard d'entrée / sortie. Les réponses peuvent être une fonction ou un programme complet. Les fonctions intégrées de factorisation et / ou de partitionnement ne sont pas autorisées, mais d'autres conviennent. Le code est compté en octets.


Qu'entendez-vous par partitionnement?
Optimizer

@Optimizer Regroupement d'une liste en sous-listes sans chevauchement. Certaines langues ont cela intégré, comme Mathematica .
Geobits

Y a-t-il un délai? Un algorithme particulièrement naïf pourrait prendre des siècles pour une grande valeur de M. Des choses simples comme noter qu'il ne peut y avoir qu'un seul facteur plus grand que sqrt (N) aident évidemment beaucoup.
Level River St

1
@steveverrill Étant donné la limite supérieure de N , il ne devrait y avoir que 30 facteurs (premiers) max, ce qui accélère un peu les choses. Cependant, n'hésitez pas à être naïf. Si votre algorithme n'est pas susceptible de fournir une réponse dans quelques heures, une preuve de concept bien expliquée pourrait aider les électeurs à décider.
Geobits

un construit en qui vous permet de faire un produit cartésien de deux liste est-il autorisé?
Optimizer

Réponses:


5

Pyth - 24 23 22 21 octets

Pas une solution compliquée. Jouera plus au golf. Prend juste un produit cartésien de listes et de filtres. Même stratégie que @optimizer (je suppose qu'en raison de son commentaire, n'a pas réellement déchiffré ce CJam) Merci à @FryAmTheEggman pour 2 octets et astuce avec M.

Ml{m`Sdfqu*GHT1G^r2GH

Définit une fonction gavec args GetH

M                    function definition of g with args G and H
 l                   length of
  {                  set (eliminates duplicates)
   m                 map
    `Sd              repr of sorted factors so can run set (on bash escape ` as \`)
    f                filter
     q      G        equals first arg
      u*GHT1         reduce by multiplication
     ^     H         cartesian product by repeat second arg
       r2G           range 2 to first arg

A travaillé sur tous les arguments de test sauf le dernier, était trop lent sur celui-ci, mais aucune limite de temps n'est donnée.


L'entrée est correcte dans ce format.
Geobits

1
Astuce golf Pyth: si vous obtenez 2 arguments, il est généralement plus court à utiliser Mqui définit la fonction gde 2 arguments, Get H. Voilà ce que je reçois pour cela: Ml{msdfqu*GHT1G^r2GH. Toujours agréable de voir un autre utilisateur Pyth :)
FryAmTheEggman

@FryAmTheEggman mis à jour merci pour le conseil.
Maltysen

1
Cela semble donner une réponse incorrecte pour l'entrée 72 3, qui renvoie 5, mais il y a en fait 6 réponses,(2, 2, 18), (2, 3, 12), (2, 4, 9), (2, 6, 6), (3, 3, 8)
isaacg

1
@isaacg oh ok, je vais revenir à ma version 21 caractères. Je ne pensais pas que résumer cela fonctionnerait, mais il me semblait, alors je reviendrai sur repr. Merci pour la capture.
Maltysen

9

Python 3, 59

f=lambda N,M,i=2:i<=N and f(N/i,M-1,i)+f(N,M,i+1)or-~M==N<2

Nous comptons les diviseurs potentiels i. Avec l'argument supplémentaire icomme le plus petit diviseur autorisé, la relation récursive de base est

f(N,M,i)=f(N/i,M-1,i)+f(N,M,i+1)

Pour chacun i, nous choisissons de l'inclure (possible en tant que répétition), auquel cas nous divisons le produit requis Npar iet décrémentons M. Si nous ne le faisons pas, nous augmentons ide 1, mais seulement si i<N, puisqu'il ne sert à rien de vérifier les diviseurs supérieurs à N.

Lorsque le diviseur minimum idépasse N, il n'y a plus de diviseurs potentiels. Nous vérifions donc si nous avons réussi en voyant si M==0 and N==1, ou, de manière équivalente, M+1==N==1ou M+1==N<2, depuis quand M+1==N, la valeur mutuelle est garantie d'être un entier positif (merci à FryAmTheEggman pour cette optimisation).

Ce code provoquera un débordement de pile d' Nenviron 1000 sur la plupart des systèmes, mais vous pouvez l'exécuter en Stackless Python pour éviter cela. De plus, il est extrêmement lent en raison de sa ramification exponentielle récursive.


Je pense que vous pouvez utiliser-~M==N<2
FryAmTheEggman

@FryAmTheEggman Je pensais que cela donnerait des faux positifs, mais en effet cela fonctionne, grâce aux contraintes conjointes sur Met N. Merci!
xnor

4

Rubis, 67

f=->n,m,s=2,r=0{m<2?1:s.upto(n**0.5){|d|n%d<1&&r+=f[n/d,m-1,d]}&&r}

Effectivement raisonnablement efficace pour une définition récursive. Pour chaque paire [d,q]de diviseurs de n, détant la plus petite, nous additionnons le résultat de f[q,m-1]. La partie délicate est que dans les appels internes, nous limitons les facteurs à ceux supérieurs ou égaux à d afin de ne pas finir par un double comptage.

1.9.3-p327 :002 > f[30,2]
 => 3 
1.9.3-p327 :003 > f[2310,4]
 => 10 
1.9.3-p327 :004 > f[15,4]
 => 0 
1.9.3-p327 :005 > f[9,2]
 => 1 

2

CJam, 48 octets

Cela peut être beaucoup plus court mais j'ai ajouté certaines vérifications pour le faire fonctionner pour un nombre décent de Msur le compilateur en ligne.

q~\:N),2>{N\%!},a*{_,2/)<m*{(+$}%}*{1a+:*N=},_&,

Essayez-le en ligne ici


C'est buggy. Essayez la saisie 2 1. Sortie attendue: 1. Sortie réelle: 0.
Peter Taylor

@PeterTaylor Sigh. Fixé.
Optimizer

2

T-SQL 456 373

Je suis sûr que cela se cassera lorsque les entrées seront même proches d'être grandes.

Merci à @MickyT d'avoir aidé à sauver beaucoup de caractères avec CONCAT et SELECT au lieu de plusieurs SET.

CREATE PROC Q(@N INT,@M INT)AS
DECLARE @ INT=2,@C VARCHAR(MAX)='SELECT COUNT(*)FROM # A1',@D VARCHAR(MAX)=' WHERE A1.A',@E VARCHAR(MAX)=''CREATE TABLE #(A INT)WHILE @<@N
BEGIN
INSERT INTO # VALUES(@)SET @+=1
END
SET @=1
WHILE @<@M
BEGIN
SELECT @+=1,@C+=CONCAT(',# A',@),@D+=CONCAT('*A',@,'.A'),@E+=CONCAT(' AND A',@-1,'.A<=A',@,'.A')END
SET @C+=CONCAT(@D,'=',@N,@E)EXEC(@C)

Je voudrais voter positivement, mais je ne trouve pas de moyen simple de le tester. Des idées? La confirmation par un tiers que cela fonctionne est également bonne.
Geobits du

Je reçois quelques erreurs de conversion lorsque je l'exécute (2012). Ils semblent provenir de ces déclarations SET @C+=',# A'+@etSET @D+='*A'+@+'.A'SET @E+=' AND A'+(@-1)+'.A<=A'+@+'.A'
MickyT

Vous devrez également corriger SET @C+=@D+'=@N'+@E+' SELECT @'. Le @Nest à l'intérieur des guillemets, ce qui le rend hors de la portée lors de l'exécution @C. Je pense aussi que vous
finirez

Maintenant, je l'ai testé en 2012. Cela devrait fonctionner.
bmarks

2
Fonctionne bien maintenant :) Un endroit où vous pouvez raser certains personnages. Essayez d'utiliser CONCATpour créer vos chaînes. Ensuite, vous pouvez supprimer le CONVERTs. Essayez SELECT @+=1,@C+=CONCAT(...),@D+=CONCAT(...),@E+=CONCAT(...)dans votre WHILEboucle. Devrait vous faire économiser un nombre raisonnable
MickyT
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.