Quantas maneiras de escrever N como um produto de M inteiros?

12

Dado um número inteiro N , conte quantas maneiras ele pode ser expresso como um produto de M números inteiros> 1.

A entrada é simplesmente N e M e a saída é a contagem total de grupos inteiros distintos . Ou seja, você pode usar um número inteiro mais de uma vez, mas cada grupo deve ser distinto ( 3 x 2 x 2não contaria se 2 x 2 x 3estiver presente).

Restrições

1 < N <2 31
1 < M <30

Exemplos

A entrada 30 2fornece saída 3, pois pode ser expressa de três maneiras:

2 x 15
3 x 10
5 x 6

A entrada 16 3fornece saída 1, pois há apenas um grupo distinto:

2 x 2 x 4

Entrada 2310 4fornece saída 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

A entrada 15 4fornece saída 0, pois não pode ser feita.

Regras

Aplicam-se brechas de golfe de código padrão, juntamente com definições padrão de entrada / saída. As respostas podem ser uma função ou um programa completo. Funções internas para fatoração e / ou particionamento não são permitidas, mas outras são boas. O código é contado em bytes.

Geobits
fonte
O que você quer dizer com particionamento?
Optimizer
@Optimizer Agrupando uma lista em sublistas não sobrepostas. Alguns idiomas têm isso incorporado, como o Mathematica .
Geobits
Existe limite de tempo? Um algoritmo particularmente ingênuo pode levar séculos para obter um grande valor de M. Coisas simples como notar que só pode haver um fator maior que o sqrt (N) obviamente ajuda muito.
Level River St
1
@steveverrill Dado o limite superior de N , deve haver apenas 30 fatores no máximo, o que acelera bastante as coisas. No entanto, sinta-se livre para ser ingênuo. Se o seu algoritmo não fornecer uma resposta dentro de algumas horas, uma prova de conceito bem explicada pode ajudar os eleitores a decidir.
Geobits
um construído em que permite que você faça produto cartesiano de duas listas é permitido?
Optimizer

Respostas:

5

Pyth - 24 23 22 21 bytes

Não é uma solução complicada. Vai jogar mais. Apenas leva produto cartesiano de listas e filtros. A mesma estratégia do @optimizer (acho que por causa de seu comentário, na verdade não decifrou esse CJam) Graças a @FryAmTheEggman por 2 bytes e engane com M.

Ml{m`Sdfqu*GHT1G^r2GH

Define uma função gcom args GeH

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

O trabalho em todos os argumentos de teste, exceto o último, foi lento demais, mas não há limite de tempo.

Maltysen
fonte
A entrada é boa nesse formato.
Geobits
1
Dica de golfe em Pyth: se você obtiver 2 argumentos, geralmente é mais curto o uso Mque define a função gde 2 argumentos Ge H. Isto é o que eu recebo para isso: Ml{msdfqu*GHT1G^r2GH. Sempre bom ver outro usuário Pyth :)
FryAmTheEggman
@FryAmTheEggman atualizou obrigado pela dica.
Maltysen
1
Isso parece dar uma resposta incorreta para a entrada 72 3, que retorna 5, mas há, de facto 6 respostas,(2, 2, 18), (2, 3, 12), (2, 4, 9), (2, 6, 6), (3, 3, 8)
isaacg
1
@isaacg oh ok, vou reverter para a minha versão de 21 caracteres. Não achei que resumir funcionaria, mas parecia, então voltarei ao repr. Obrigado pela captura.
Maltysen 27/01
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

Contamos potenciais divisores i. Com o argumento adicional icomo o divisor mais baixo permitido, a relação recursiva principal é

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

Para cada um i, escolhemos incluí-lo (possível como repetição); nesse caso, dividimos o produto necessário Npor ie diminuímos M. Se não o fizermos, aumentamos iem 1, mas apenas se i<N, já que não adianta verificar divisores maiores que N.

Quando o divisor mínimo iexcede N, não há mais divisores em potencial. Portanto, verificamos se conseguimos ver se M==0 and N==1, ou, equivalentemente M+1==N==1ou M+1==N<2, desde quando M+1==N, o valor mútuo é garantido como um número inteiro positivo (obrigado a FryAmTheEggman por essa otimização).

Esse código causará um estouro de pilha para Ncerca de 1000 na maioria dos sistemas, mas você pode executá-lo no Stackless Python para evitar isso. Além disso, é extremamente lento por causa de sua ramificação recursiva exponencial.

xnor
fonte
Eu acho que você pode usar-~M==N<2
FryAmTheEggman
@FryAmTheEggman Eu pensei que daria falsos positivos, mas realmente funciona, graças às restrições conjuntas sobre Me N. Obrigado!
Xnor
4

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

Realmente razoavelmente eficiente para uma definição recursiva. Para cada par divisor [d,q]de n, dsendo o menor, somamos o resultado de f[q,m-1]. A parte complicada é que, nas chamadas internas, limitamos os fatores a valores maiores ou iguais a d, para não acabarmos contando duas vezes.

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 
histocrata
fonte
2

CJam, 48 bytes

Isso pode ser muito mais curto, mas eu adicionei algumas verificações para fazê-lo funcionar com um número decente Mno compilador online.

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

Experimente online aqui

Optimizer
fonte
Isso é buggy. Tente entrada 2 1. Saída esperada: 1. Saída real: 0.
Peter Taylor
@PeterTaylor Sigh. Fixo.
Optimizer
2

T-SQL 456 373

Tenho certeza de que isso quebrará quando as entradas estiverem perto de serem grandes.

Agradecemos ao @MickyT por ajudar a salvar muitos caracteres com CONCAT e SELECTing em vez de vários SETs.

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)
marcações
fonte
Gostaria de aprovar isso, mas não consigo encontrar uma maneira simples de testá-lo. Alguma ideia? A confirmação de terceiros de que funciona também é boa.
Geobits
Eu recebo alguns erros de conversão que eu executei (2012). Eles parecem pertencer a estas afirmações SET @C+=',# A'+@e:SET @D+='*A'+@+'.A'SET @E+=' AND A'+(@-1)+'.A<=A'+@+'.A'
MickyT
Você também precisará corrigir SET @C+=@D+'=@N'+@E+' SELECT @'. O @Nestá dentro das aspas, tornando-o fora do escopo quando você executa @C. Também acho que você vai acabar contando duplicatas
MickyT
Agora eu testei em 2012. Deve funcionar.
marca
2
Funciona bem agora :) Alguns lugares onde você pode fazer a barba de alguns personagens. Tente usar CONCATpara criar suas strings. Então você pode soltar os CONVERT. Tente SELECT @+=1,@C+=CONCAT(...),@D+=CONCAT(...),@E+=CONCAT(...)no seu WHILEloop. Deve poupar um número razoável
MickyT