Produit de chiffres

10

Pour un nombre entier positif donné N, écrivez un programme complet pour trouver le M naturel minimal tel que le produit des chiffres de M soit égal à N. N est inférieur à 1 000 000 000. Si aucun M n'existe, imprimez -1. Dans tous les cas, votre code ne devrait pas prendre plus de 10 secondes.

Sample Inputs
1
3
15
10 
123456789
32
432
1296

Sample Outputs
1
3
35
25
-1
48
689
2899
fR0DDY
la source
4
1donner 1est un important test.
Peter Taylor
1
Vous devriez ajouter des cas plus complexes, comme les trois que j'ai utilisés ci-dessous: 32, 432, 1296. À moins que vous ne laissiez cela comme exercice pour le codeur.
mellamokb
@ s-mark 26, eh. Le plus petit nombre.
fR0DDY
Je crois que nous devrions également tester les 387420489 (9 ^ 9) et 1000000000 évidents pour le plaisir.
asoundmove du
2
Parce que c'est une vieille question et que l'OP est inactif, ce n'est qu'une note pour les prochains messages: "10 sec" n'est pas clair selon la norme actuelle (sur quelle machine?)
user202729

Réponses:

4

Golfscript, 45 43 40 caractères

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

Remplace la version qui ne regroupait pas les petits nombres premiers en pouvoirs et enregistre 8 caractères en le faisant. Remarque: 12 = étage (9 log 10 / log 5).

Remerciements: deux personnages sauvés en exécutant une astuce de @mellamokb; 3 enregistré avec un indice de @Nabb.

Peter Taylor
la source
1
Quoi! Vous pouvez écrire Golfscript sans le tester? +1, semble très bien, sauf 123456789, cela prend plus d'une minute sur ma machine et j'ai tué le processus. 12345donnez-moi -1, alors ça devrait aussi marcher 123456789si je pouvais attendre assez longtemps.
VOUS
@ S.Mark, merci. On dirait que je ne peux pas m'en tirer avec l'algorithme de factorisation naïf.
Peter Taylor
@Peter: donne de mauvaises réponses pour les cas plus complexes. 32 -> 22222, devrait être 48. 432 -> 2222333, devrait être 689. 1296 -> 22223333, devrait être 2899. etc.
mellamokb
@mellamokb, bon point. Je pense que je vais devoir réécrire et tester.
Peter Taylor
Wow, 17 caractères de moins. J'ai besoin d'un meilleur algorithme, lol!
mellamokb
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/

Edit: idée d'entrée / sortie empruntée à une autre solution et logique de sortie plus courte.

Édition 2: enregistrement de 2 caractères en supprimant les accolades inutiles en forboucle.

Edit 3: 2 caractères enregistrés en réécrivant la whileboucle en tant ifqu'instruction avec i++.

Édition 4: enregistrement de 2 caractères en se déplaçant et en réduisant les opérations i.

Edit 5: Convertir l'instruction if au format ternaire en économisant 2 caractères supplémentaires.

Edit 6: Enregistrez 2 caractères en vous déplaçant i--dans la vraie partie du ternaire, supprimez ++i.

mellamokb
la source
Vous avez compté des caractères uniquement pour la fonction. S'agit-il d'un programme complet? Pouvez-vous l'exécuter ici ideone.com
fR0DDY
1
semble qu'il existe une entrée similaire pour javascript avec spidermonkey chez ideone qu'il a lié - ideone.com/samples#sample_lang_112
VOUS le
@ fR0DDY: OK, maintenant c'est un programme complet :)
mellamokb
J'ai finalement réduit le mien à 69 caractères, mais vous pouvez aussi le faire maintenant avec le même genre d'idée et la promptchose.
Ry-
m?m:1=>m||1
l4m2
4

JavaScript, 88 72 78 74 69 68

for (s = '', i = 2, m = n = prompt (); i <m; i ++) while (! (n% i)) {if (i> 9) {alert (-1); E ( )} n / = i; s + = i} alerte (s)
4 caractères de plus, mais en fait un script exécutable (par opposition à une fonction).

Edit: En utilisant des idées de l'autre JavaScript, je peux le réduire à ceci:

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

Finalement! Une solution à 69 caractères, n'utilise que 1 pour la boucle;)

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

D'accord, rasé une virgule.

for(i=9,n=prompt(s='');i>1;n%i?i--:[n/=i,s=i+s]);alert(n-1?-1:s?s:1)
Ry-
la source
Même problème que la solution GolfScript. Échoue sur les entrées 32, 432 et 1296. Il y a une raison pour laquelle je commence à 9 et que je recule et que je concatène de la droite au lieu de la gauche.
mellamokb
Échoue
J'ai raté la partie "minimale", changée.
Ry-
@minitech: ne fonctionne toujours pas pour l'entrée '1'. lol, nos réponses sont presque identiques :-)
mellamokb
Ah, j'ai réussi à faire 2 caractères plus courts que le vôtre! : 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
la source
Nous appelons le programme pour une seule entrée. Plusieurs entrées sont données juste pour vérifier l'exactitude.
fR0DDY
3

Perl (75) (72)

$ d = shift; map {$ m = $ _. $ m, $ d / = $ _ jusqu'à $ d% $ _} reverse 2..9; print $ d-1? -1: $ m || 1

inspiré par le code javascript de mellamokb; destiné à être exécuté avec un paramètre

perl chinois goth
la source
Ne serait-il pas plus court si vous utilisiez stdin au lieu d'un paramètre?
asoundmove
3

GolfScript ( 60 57)

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

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

Éditer

Ok, je pense que cette version donne maintenant une sortie correcte pour chaque cas :-)

Modifier 2

Rasé 3 caractères selon les suggestions de @ Peter.

mellamokb
la source
La raison pour laquelle j'ai commenté ci-dessus que 1donner 1est un cas de test important est qu'il s'agit d'un cas spécial désagréable - le seul numéro pour lequel le chiffre 1apparaît dans la sortie. Et ça casse votre code, je le crains.
Peter Taylor
Il casse également pour les nombres divisibles par des nombres premiers supérieurs à 9.
Peter Taylor
@Peter: OK, réessayez. Je pense que cette version fonctionne maintenant pour tous les cas de test.
mellamokb
Semble, oui. Vous pouvez enregistrer un personnage tout de suite en le supprimant d'abord [- si vous n'en avez pas [sur la pile lorsque vous évaluez un, ]il faut tout sur la pile. Et vous pouvez probablement enregistrer deux caractères vers la fin en n'encapsulant pas -1dans un tableau et en déplaçant la finale $.
Peter Taylor
@Peter: Merci, vous avez enregistré 3 caractères supplémentaires!
mellamokb
3

Haskell

f n=head([m|m<-[1..10^9],product(map(read.return)$show m)==n]++[-1])
Ming-Tang
la source
Raser un char en changeant (show m)pour $show m.
FUZxxl
1
ne devrait-il pas être m<-[1..9^9].... sinon c'est une liste infinie ... donc -1ne se produira jamais .... corrigez-moi si je me trompe.
st0le
Je ne pense pas que cela puisse fonctionner dans les 10 secondes ....
st0le
2

Windows PowerShell, 87

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

Perl (68)

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

Il semble que l'astuce géniale que @mellamokb utilise en javascript pour éviter la boucle imbriquée se traduise bien en perl mais elle sort beaucoup plus verbeuse car vous ne pouvez plus utiliser la foreachboucle de style. Il est également dommage que perl ne pense pas mapqu'une boucle redoserait utile.

Jasvir
la source
2

scala 106 caractères:

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)

Test et invocation:

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)

Temps de réponse: immédiatement, <1 s sur CPU 2Ghz.

Utilisateur inconnu
la source
2

Gelée , 18 13 10 octets

×⁵RDP$€io-

Essayez-le en ligne!

Solution à 13 octets:

×⁵RDP$€iµ’¹¬?

Essayez-le en ligne!

Explication avec entrée 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

Solution à 18 octets:

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

Essayez-le en ligne!

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).

Le dernier lien consiste uniquement à remplacer 0 (la valeur de falsey par défaut de Jelly, car toutes les listes sont indexées) par -1. Si vous considérez 0 comme une valeur de falsey OK, le programme est de 8 octets .

Harry
la source
1
Quelques remarques: (1) vous n'utilisez chaque lien auxiliaire qu'une seule fois, il n'y a donc aucune raison de créer un lien auxiliaire. Utilisez simplement le $ƊƲµ. (2) Comme la chaîne -1et le nombre -1sont identiques lors de la sortie, l'utilisation du nombre économise 2 octets. (3) Pest un raccourci pour ×/. (4) Échec d'entrée 3125.
user202729
@ user202729 Merci beaucoup! J'ai implémenté (1), (2) et (3) et ils ont économisé 6 octets! Si j'ai changé le ⁵ en ³, cela a fonctionné sur l'entrée 3125 mais seulement après un délai considérable. Savez-vous s'il existe un moyen meilleur (et plus court), ou mon approche (qui, je le sais, n'est certainement pas la plus rapide en termes de complexité temporelle) est-elle aussi bonne que possible?
Harry
1
Je pense que ça _¬$devrait marcher’¹¬?
dylnan
1
o-est encore plus court.
user202729
@dylnan Merci - j'ai remarqué qu'en raison du µje pouvais juste l'utiliser sans avoir $économisé 2 octets! Mais je me suis alors rendu compte que o-je pouvais tout simplement omettre le µtout et économiser 3 octets!
Harry
1

Rubis (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
la source
0

Python 2 , 89 octets

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)

Essayez-le en ligne!

Tout simplement parce qu'il n'y a pas encore de réponse Python. Il est vraiment pénible de ne pas avoir de conversion de type implicite entre chaîne et int.

Bubbler
la source