Produto de dígitos

10

Para um determinado número inteiro positivo N, escreva um programa completo para encontrar o M natural mínimo, de modo que o produto dos dígitos de M seja igual a N. N seja menor que 1.000.000.000. Se não existir M, imprima -1. Seu código não deve demorar mais de 10 segundos para qualquer caso.

Sample Inputs
1
3
15
10 
123456789
32
432
1296

Sample Outputs
1
3
35
25
-1
48
689
2899
fR0DDY
fonte
4
1dar 1é um caso de teste importante.
Peter Taylor
11
Você deve adicionar casos mais complexos, como os três que usei abaixo: 32, 432, 1296. A menos que você deixe isso como um exercício para o codificador.
Mellamokb
@ marca 26, eh. Número menor.
FR0DDY 29/04
Acredito que também devemos testar o óbvio 387420489 (9 ^ 9) e 1000000000 por diversão.
Asoundmove
2
Porque esta é uma questão antiga e o OP está inativo, isto é apenas uma nota para posts futuros: "10 segundos" está claro de acordo com o padrão atual (em que máquina?)
user202729

Respostas:

4

Golfscript, 45 43 40 caracteres

~9{{1$1$%!{\1$/1$}*}12*(}8*>{];-1}*]$1or

Substitui a versão que não agrupa primos pequenos em poderes e salva 8 caracteres ao fazê-lo. Nota: 12 = piso (9 log 10 / log 5).

Agradecimentos: dois caracteres salvos com um truque de @mellamokb; 3 salvos com uma dica do @Nabb.

Peter Taylor
fonte
11
O que! Você pode escrever Golfscript sem testá-lo? +1, parece bom, exceto 123456789, leva mais de um minuto na minha máquina e eu acabei com o processo. 12345me dê -1, então talvez funcione 123456789também se eu puder esperar o suficiente.
VOCÊ
@ S.Mark, obrigado. Parece que não consigo me safar do algoritmo de fatoração ingênuo.
Peter Taylor
@ Peter: Dá respostas erradas para casos mais complexos. 32 -> 22222, deve ser 48. 432 -> 2222333, deve ser 689. 1296 -> 22223333, deve ser 2899. etc.
mellamokb
@mellamokb, bom ponto. Acho que vou ter que reescrever e testar.
31511 Peter
Uau, 17 caracteres a menos. Eu preciso de um algoritmo melhor, lol!
precisa saber é o seguinte
6

Javascript ( 84 78 76 74 72 70 68)

n=prompt(m="");for(i=9;i-1;)n%i?i--:(m=i+m,n/=i);alert(n-1?-1:m?m:1)

http://jsfiddle.net/D3WgU/7/

Editar: idéia de entrada / saída emprestada de outra solução e lógica de saída mais curta.

Editar 2: salvou 2 caracteres removendo chaves desnecessárias em forloop.

Editar 3: salvou 2 caracteres reescrevendo o whileloop como ifinstrução com i++.

Editar 4: salvou 2 caracteres movendo-se e reduzindo as operações i.

Editar 5: Converter a declaração if em formato ternário, economizando mais 2 caracteres.

Editar 6: Salve 2 caracteres movendo i--- se para a parte verdadeira do ternário, remova ++i.

mellamokb
fonte
Você contou caracteres apenas para a função. Este é um programa completo? Você pode executá-lo aqui ideone.com
fR0DDY 29/04
11
parece que existe uma entrada semelhante para javascript com spidermonkey na ideone ele vinculou - ideone.com/samples#sample_lang_112
VOCÊ
@ fR0DDY: OK, agora é um programa completo :)
mellamokb
Finalmente reduzi o meu para 69 caracteres, mas você também pode fazer isso agora com o mesmo tipo de idéia e promptcoisa.
precisa saber é o seguinte
m?m:1=>m||1
l4m2
4

JavaScript, 88 72 78 74 69 68

for (s = '', i = 2, m = n = prompt (); i <m; i ++) enquanto (! (n% i)) {if (i> 9) {alert (-1); E ( )} n / = i; s + = i} alerta (s)
4 caracteres a mais, mas na verdade um script executável (em oposição a uma função).

Edit: Usando idéias de outro JavaScript, posso reduzi-lo para isso:

for(s='',i=9,n=prompt();i>1;i--)for(;!(n%i);n/=i)s=i+s;alert(n-1?-1:s?s:1)

Finalmente! Uma solução de 69 caracteres, usa apenas 1 para loop;)

for(s='',i=9,n=prompt();i>1;n%i?i--:[n/=i,s=i+s]);alert(n-1?-1:s?s:1)

Ok, raspou uma vírgula.

for(i=9,n=prompt(s='');i>1;n%i?i--:[n/=i,s=i+s]);alert(n-1?-1:s?s:1)
Ry-
fonte
Mesmo problema que a solução GolfScript. Falha nas entradas 32, 432 e 1296. Há uma razão pela qual começo às 9 e volto para trás e concatenado da direita em vez da esquerda.
precisa saber é o seguinte
Também falha para a entrada 1. tem que fazer um caso especial para lidar com 1.
mellamokb
Perdi a parte "mínima", mudei.
Ry-
@ minitech: Ainda não funciona para a entrada '1'. lol, nossas respostas estão chegando a ser quase exatamente idêntica :-)
mellamokb
Ah, consegui torná-lo 2 caracteres mais curto que o seu! : D
Ry-
4

awk ( 63 61 59 58 57)

{for(i=9;i>1;$1%i?i--:($1/=i)<o=i o);print 1<$1?-1:o?o:1}
asoundmove
fonte
Estamos chamando o programa para apenas uma entrada. Várias entradas são fornecidas apenas para verificar a exatidão.
FR0DDY
3

Perl (75) (72)

$ d = shift; mapa {$ m = $ _. $ m, $ d / = $ _ até $ d% $ _} reverso 2..9; imprime $ d-1? -1: $ m || 1

inspirado no código javascript de mellamokb; destinado a ser executado com um parâmetro

gótico chinês do perl
fonte
Não seria mais curto se você usasse stdin em vez de um parâmetro?
Asoundmove
3

GolfScript ( 60 57)

~[{9,{)}%{\.@%!},)\;.@@/.9>2$1>&}do])[.])@@{1>},+\9>[-1]@if$

~{9,{)}%{\.@%!},)\;.@@/.9>2$1>&}do])[.])@@{1>},+$\9>-1@if

Editar

Ok, acho que esta versão fornece saída correta para todos os casos agora :-)

Editar 2

Raspou 3 caracteres por sugestões de @ Peter.

mellamokb
fonte
A razão pela qual comentei acima que 1dar 1é um caso de teste importante é que é um caso especial desagradável - o único número para o qual o dígito 1aparece na saída. E isso quebra seu código, receio.
31511 Peter
Ele também pausas para números divisíveis por primes maior que 9.
Peter Taylor
@ Peter: OK, tente novamente. Acho que esta versão funciona para todos os casos de teste agora.
precisa saber é o seguinte
Parece sim. Você pode salvar um caractere imediatamente removendo-o primeiro [- se você não tiver um [na pilha ao avaliar um ], leva tudo na pilha. E você provavelmente pode salvar dois caracteres perto do final, não agrupando -1em uma matriz e movendo a final $.
Peter Taylor
@ Peter: Obrigado, economizou mais 3 caracteres!
precisa saber é o seguinte
3

Haskell

f n=head([m|m<-[1..10^9],product(map(read.return)$show m)==n]++[-1])
Ming-Tang
fonte
Raspe um caractere alterando (show m)para $show m.
FUZxxl
11
não deveria ser m<-[1..9^9].... caso contrário, é uma lista infinita ... então -1nunca ocorrerá .... me corrija se eu estiver errado.
st0le
Eu não acho que ele pode trabalhar dentro 10secs ....
st0le
2

Windows PowerShell, 87

if(($n="$args")-le1){$n;exit}(-1,-join(9..2|%{for(;!($n%$_)){$_;$n/=$_}}|sort))[$n-eq1]
Joey
fonte
2

Perl (68)

$x=pop;map{$_-=11;$x/=$_,$@=-$_.$@until$x%$_}1..9;print!$x?-1:$@||1

Ele parece como o truque impressionante que usos @mellamokb em javascript para evitar o loop aninhado que traduzem bem para perl, mas ele sai muito mais detalhado, porque você não pode usar o foreachloop de estilo por mais tempo. Também é uma pena que o perl não pense que mapé um loop, caso contrário, redoseria útil.

Jasvir
fonte
2

scala 106 caracteres:

def p(n:Int,l:Int=9):List[Int]=if(n<=9)List(n)else
if(l<2)List(-1)else
if(n%l==0)l::p(n/l,l)else
p(n,l-1)

Teste e Invocação:

scala> val big=9*9*9*8*8*8*7*7*7*5*3 
big: Int = 1920360960

scala> p(big)                        
res1: List[Int] = List(9, 9, 9, 8, 8, 8, 7, 7, 7, 5, 3)

Tempo de resposta: imediatamente, <1s na CPU de 2Ghz.

Usuário desconhecido
fonte
2

Geléia , 18 13 10 bytes

×⁵RDP$€io-

Experimente online!

Solução de 13 bytes:

×⁵RDP$€iµ’¹¬?

Experimente online!

Explicação com entrada N:

׳R              create a range from 1 to N * 100 (replace ³ with ⁵ for a faster execution time)
   DP$           define a function ($) to get the product of the digits of a number,
      €          apply that function to each element in the list,
       iµ        get the index of the input N in the list (or 0 if it's not there), and yeild it as the input to the next link,
         ’¹¬?    conditional: if the answer is 0, then subtract one to make it -1, otherwise, yeild the answer

Solução de 18 bytes:

D×/
×⁵RÇ€i
Ç⁾-1¹¬?

Experimente online!

D×/        product of digits function, takes input M
D          split M into digits,
 ×/        reduce by multiplication (return product of digits)

×⁵RÇ€i     range / index function
×⁵R        make a range from 1 to N*10,
   ǀ      run the above function on each of the range elements,
     i     get the index of N in the result, or 0 if it's not there

Ç⁾-1¹¬?    main function:
Ç    ¬?    run the line above and check if the answer is null (0)
 ⁾-1       if it is, return "-1",
    ¹      otherwise, return the answer (identity function).

O último link é apenas para substituir 0 (valor falsey padrão de Jelly, como todas as listas são indexadas por um) por -1. Se você considerar 0 um valor falsey OK, o programa será 8 bytes .

atormentar
fonte
11
Algumas notas: (1) você usa cada link auxiliar apenas uma vez, portanto não há motivo para criar um link auxiliar. Basta usar o $ƊƲµ. (2) Como a string -1e o número -1são idênticos na saída, o uso do número economiza 2 bytes. (3) Pé uma abreviação de ×/. (4) Falha na entrada 3125.
User202729
@ user202729 Muito obrigado! Eu implementei (1), (2) e (3) e eles salvaram 6 bytes! Se eu alterasse o ⁵ para o ³, ele funcionaria na entrada 3125, mas somente após um atraso considerável. Você sabe se existe uma maneira melhor (e mais curta) ou a minha abordagem (que eu sei que definitivamente não é a mais rápida em termos de complexidade de tempo) é tão boa quanto possível?
Harry
11
Eu acho que _¬$deveria funcionar mais’¹¬?
dylnan
11
o-é ainda mais curto.
User202729
@ dylnan Obrigado - notei que, por causa do que µeu poderia usar sem o $que salvou 2 bytes! Mas então eu percebi que o-eu poderia simplesmente omitir µcompletamente e salvar 3 bytes!
Harry
1

Rubi (100)

n=gets.to_i;(d=1..9).map{|l|[*d].repeated_combination(l){|a|a.reduce(:*)==n&&(puts a*'';exit)}};p -1
Lars Haugseth
fonte
0

Python 2 , 89 bytes

f=lambda n,a=0,u=1,i=9:n<2and(a or 1)or-(i<2)or n%i<1and f(n/i,a+i*u,u*10)or f(n,a,u,i-1)

Experimente online!

Só porque ainda não há resposta em Python. É realmente doloroso não ter uma conversão implícita de tipo entre string e int.

Bubbler
fonte