Prodotto di cifre


10

Per un dato numero intero positivo N, scrivi un programma completo per trovare la M naturale minima in modo tale che il prodotto delle cifre di M sia uguale N. N sia inferiore a 1.000.000.000. Se non esiste una M, stampa -1. Il tuo codice non dovrebbe richiedere più di 10 secondi per ogni caso.

Sample Inputs
1
3
15
10 
123456789
32
432
1296

Sample Outputs
1
3
35
25
-1
48
689
2899

4
1dare 1è un caso di prova importante.
Peter Taylor,

1
Dovresti aggiungere casi più complessi, come i tre che ho usato di seguito: 32, 432, 1296. A meno che non lo lasci come esercizio per il programmatore.
mellamokb,

@ s-mark 26, eh. Numero più piccolo
fR0DDY,

Credo che dovremmo anche provare l'ovvio 387420489 (9 ^ 9) e 1000000000 per divertimento.
asoundmove,

2
Poiché questa è una vecchia domanda e l'OP è inattivo, questa è solo una nota per i post futuri: "10 sec" non è chiaro secondo lo standard corrente (su quale macchina?)
user202729

Risposte:


4

Golfscript, 45 43 40 caratteri

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

Sostituisce la versione che non ha raggruppato piccoli numeri primi in poteri e salva 8 caratteri mentre lo fa. Nota: 12 = piano (9 log 10 / log 5).

Ringraziamenti: due personaggi salvati da un trucco di @mellamokb; 3 salvato con un suggerimento da @Nabb.


1
Che cosa! Puoi scrivere Golfscript senza testarlo? +1, sembra buono, tranne 123456789, ci vuole più di 1 minuto sulla mia macchina e ho terminato il processo. 12345dammi -1, quindi potrebbe anche funzionare 123456789anche se potessi aspettare abbastanza a lungo.
TU

@ S.Mark, grazie. Sembra che non riesca a cavarmela con l'algoritmo ingenuo di fattorizzazione.
Peter Taylor,

@Peter: fornisce risposte errate per casi più complessi. 32 -> 22222, dovrebbe essere 48. 432 -> 2222333, dovrebbe essere 689. 1296 -> 22223333, dovrebbe essere 2899. ecc.
mellamokb,

@mellamokb, buon punto. Penso che dovrò riscrivere e testare.
Peter Taylor,

Wow, 17 caratteri in meno. Ho bisogno di un algoritmo migliore, 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/

Modifica: idea di input / output presa in prestito da un'altra soluzione e logica di output più breve.

Modifica 2: Salvato 2 caratteri rimuovendo le parentesi non necessarie in forloop.

Modifica 3: Salvato 2 caratteri riscrivendo il whileciclo come ifistruzione con i++.

Modifica 4: Hai salvato 2 caratteri spostandoti e riducendo le operazioni i.

Modifica 5: Converti l'istruzione if in formato ternario salvando altri 2 caratteri.

Modifica 6: salva 2 caratteri spostandoti i--nella parte vera del ternario, rimuovili ++i.


Hai contato i caratteri solo per la funzione. È un programma completo? Puoi eseguirlo qui ideone.com
fR0DDY

1
sembra che ci siano input simili per javascript con spidermonkey su ideone che ha collegato - ideone.com/samples#sample_lang_112
YOU

@ fR0DDY: OK, ora è un programma completo :)
mellamokb,

Alla fine ho ridotto il mio a 69 caratteri, ma puoi farlo anche adesso con lo stesso tipo di idea e la promptcosa.
Ry

m?m:1=>m||1
l4m2

4

JavaScript, 88 72 78 74 69 68

per (s = '', i = 2, m = n = prompt (); i <m; i ++), mentre {if (i ((n% i)!)> 9) {alert (-1); E ( )} n / = i; s + = i} alert (s)
4 caratteri più lunghi, ma in realtà uno script eseguibile (al contrario di una funzione).

Modifica: usando le idee dell'altro JavaScript, posso ridurlo a questo:

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! Una soluzione di 69 caratteri, utilizza solo 1 per il ciclo;)

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

Va bene, rasato una virgola.

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

Stesso problema della soluzione GolfScript. Non riesce sugli ingressi 32, 432 e 1296. C'è un motivo per cui inizio alle 9 e torno indietro e concateno da destra invece che da sinistra.
mellamokb,

Non riesce anche per l'input 1. Devono fare un caso speciale per gestire 1.
mellamokb

Ho perso la parte "minima", cambiata.
Ry,

@minitech: non funziona ancora per l'ingresso "1". lol, le nostre risposte sono quasi identiche :-)
mellamokb

Ah, sono riuscito a rendere 2 personaggi più corti dei tuoi! : 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}

Stiamo chiamando il programma per un solo input. Vengono forniti più ingressi solo per verificare la correttezza.
fR0DDY,

3

Perl (75) (72)

$ d = shift; mappa {$ m = $ _. $ m, $ d / = $ _ fino a $ d% $ _} indietro 2..9; stampa $ d-1? -1: $ m || 1

ispirato al codice javascript di mellamokb; intendeva essere eseguito con un parametro


Non sarebbe più breve se si usasse stdin invece di un parametro?
asoundmove,

3

GolfScript ( 60 57)

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

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

modificare

Ok, penso che questa versione dia l'output corretto per ogni caso ora :-)

Modifica 2

Rasato 3 caratteri per i suggerimenti di @ Peter.


La ragione per cui ho commentato sopra che 1dare 1è un caso di test importante è che si tratta di un brutto caso speciale, l'unico numero per il quale 1appare la cifra nell'output. E rompe il tuo codice, temo.
Peter Taylor,

Si rompe anche per numeri divisibili per numeri primi maggiori di 9.
Peter Taylor,

@Peter: OK, riprova. Penso che questa versione funzioni ora per tutti i casi di test.
mellamokb,

Sembra di si. Puoi salvare immediatamente un personaggio rimuovendolo per primo [- se non ne hai uno [in pila quando lo valuti ], prende tutto in pila. E probabilmente puoi salvare due personaggi verso la fine non avvolgendo -1un array e spostando il finale $.
Peter Taylor,

@Peter: Grazie, hai salvato altri 3 caratteri!
mellamokb,

3

Haskell

f n=head([m|m<-[1..10^9],product(map(read.return)$show m)==n]++[-1])

Radere un carattere cambiando (show m)in $show m.
FUZxxl,

1
non dovrebbe essere m<-[1..9^9]... altrimenti è un elenco infinito ... quindi -1non accadrà mai .... correggimi se sbaglio.
st0le

Non credo che possa funzionare entro 10 secondi ...
st0le

2

Windows PowerShell, 87

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

2

Perl (68)

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

E sembra come il trucco impressionante che usi @mellamokb in javascript per evitare il ciclo nidificato si tradurrebbe ben al perl, ma si esce molto più dettagliata, perché non è possibile utilizzare laforeach anello stile più. È anche un peccato che Perl non pensi che mapun ciclo altrimenti redosarebbe utile.


2

caratteri scala 106:

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 e invocazione:

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 di risposta: immediatamente, <1s su CPU da 2 Ghz.


2

Gelatina , 18 13 10 byte

×⁵RDP$€io-

Provalo online!

Soluzione a 13 byte:

×⁵RDP$€iµ’¹¬?

Provalo online!

Spiegazione con input 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

Soluzione a 18 byte:

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

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

L'ultimo link serve solo a sostituire 0 (il valore di falso predefinito di Jelly, poiché tutti gli elenchi sono indicizzati uno) con -1. Se consideri 0 un valore di falso OK, il programma è di 8 byte .


1
Alcune note: (1) usi ogni collegamento ausiliario una sola volta, quindi non c'è motivo di creare un collegamento ausiliario. Basta usare il $ƊƲµ. (2) Poiché la stringa -1e il numero -1sono identici durante l'output, l'utilizzo del numero consente di risparmiare 2 byte. (3) Pè una scorciatoia per ×/. (4) Errore per input 3125.
user202729,

@ user202729 Grazie mille! Ho implementato (1), (2) e (3) e hanno salvato 6 byte! Se ho cambiato ⁵ in ³, ha funzionato sull'ingresso 3125 ma solo dopo un considerevole ritardo. Sai se esiste un modo migliore (e più breve) o il mio approccio (che so sicuramente non è il più veloce in termini di complessità temporale) è buono come sarà?
Harry,

1
Penso che _¬$dovrebbe funzionare’¹¬?
Dylnan

1
o-è ancora più breve.
user202729,

@dylnan Grazie - ho notato che a causa del µpotevo semplicemente usare senza il $quale ho salvato 2 byte! Ma poi ho capito o-che potevo semplicemente omettere del µtutto e salvare 3 byte!
Harry,

1

Rubino (100)

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

0

Python 2 , 89 byte

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)

Provalo online!

Solo perché non esiste ancora una risposta Python. È davvero doloroso mancare di una conversione di tipo implicita tra stringa e int.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.