Produkt cyfr

10

Dla danej dodatniej liczby całkowitej N napisz pełny program, aby znaleźć minimalną naturalną M, tak że iloczyn cyfr M jest równy N. N jest mniejszy niż 1 000 000 000. Jeśli nie ma M, wydrukuj -1. W każdym przypadku Twój kod nie powinien zająć więcej niż 10 sekund.

Sample Inputs
1
3
15
10 
123456789
32
432
1296

Sample Outputs
1
3
35
25
-1
48
689
2899
fR0DDY
źródło
4
1dawanie 1jest ważnym przypadkiem testowym.
Peter Taylor
1
Powinieneś dodać bardziej złożone przypadki, takie jak trzy, których użyłem poniżej: 32, 432, 1296. Chyba że pozostawisz to jako ćwiczenie dla programisty.
mellamokb
@ s-mark 26, eh. Najmniejsza liczba.
fR0DDY,
Uważam, że dla zabawy powinniśmy również przetestować oczywiste 387420489 (9 ^ 9) i 1000000000.
asoundmove
2
Ponieważ jest to stare pytanie, a OP jest nieaktywny, jest to tylko uwaga na przyszłe posty: „10 sekund” jest niejasne zgodnie z obecnym standardem (na jakiej maszynie?)
202729

Odpowiedzi:

4

Golfscript, 45 43 40 znaków

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

Zastępuje wersję, która nie grupuje małych liczb pierwszych w potęgi i oszczędza przy tym 8 znaków. Uwaga: 12 = podłoga (9 log 10 / log 5).

Podziękowania: dwie postacie uratowane przez nickowanie lewy z @mellamokb; 3 zapisane z podpowiedzią @Nabb.

Peter Taylor
źródło
1
Co! Możesz pisać Golfscript bez testowania? +1, wygląda dobrze, z wyjątkiem 123456789, zajmuje to więcej niż 1 minutę na moim komputerze i zabiłem proces. 12345daj mi -1, więc może i powinno to działać, 123456789gdybym mógł czekać wystarczająco długo.
TY
@ S. Mark, dzięki. Wygląda na to, że nie mogę uciec od naiwnego algorytmu faktoryzacji.
Peter Taylor
@Peter: Udziela błędnych odpowiedzi w przypadku bardziej skomplikowanych przypadków. 32 -> 22222, powinna wynosić 48. 432 -> 2222333, powinna wynosić 689. 1296 -> 22223333, powinna wynosić 2899. itp.
mellamokb
@mellamokb, dobry punkt. Myślę, że będę musiał przepisać i przetestować.
Peter Taylor
Wow, 17 znaków mniej. Potrzebuję lepszego algorytmu, 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/

Edycja: pożyczony pomysł wejścia / wyjścia z innego rozwiązania i krótsza logika wyjścia.

Edycja 2: Zapisano 2 znaki, usuwając niepotrzebne nawiasy klamrowe w forpętli.

Edycja 3: Zapisano 2 znaki, przepisując whilepętlę jako ifinstrukcję za pomocą i++.

Edycja 4: Zapisano 2 znaki, przesuwając się i zmniejszając liczbę operacji i.

Edycja 5: Konwertuj instrukcję if na format potrójny, oszczędzając 2 dodatkowe znaki.

Edycja 6: Zapisz 2 znaki, przechodząc i--do prawdziwej części trójki, usuń ++i.

mellamokb
źródło
Policzyłeś znaki tylko dla funkcji. Czy to kompletny program? Czy możesz to zrobić
fR0DDY
1
wygląda na to, że istnieje podobny wkład do javascript ze spidermonkey w ideone, do którego on doprowadził - ideone.com/samples#sample_lang_112
TY
@ fR0DDY: OK, teraz jest to kompletny program :)
mellamokb
W końcu zmniejszyłem liczbę moich do 69 znaków, ale możesz to zrobić teraz z tym samym pomysłem i tym podobne prompt.
Ry-
m?m:1=>m||1
l4m2
4

JavaScript, 88 72 78 74 69 68

for (s = '', i = 2, m = n = zachęta (); i <m; i ++) while (! (n% i)) {if (i> 9) {alert (-1); E ( )} n / = i; s + = i} alert (y)
4 znaki dłuższe, ale w rzeczywistości skrypt wykonywalny (w przeciwieństwie do funkcji).

Edycja: Korzystając z pomysłów z innego JavaScript, mogę sprowadzić to do tego:

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

Wreszcie! 69-znakowe rozwiązanie, używa tylko 1 dla pętli;)

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

Okej, wygoliłem jeden przecinek.

for(i=9,n=prompt(s='');i>1;n%i?i--:[n/=i,s=i+s]);alert(n-1?-1:s?s:1)
Ry-
źródło
Ten sam problem, co rozwiązanie GolfScript. Nie działa na wejściach 32, 432 i 1296. Jest powód, dla którego zaczynam od 9 i wracam do tyłu i konkatenuję z prawej zamiast z lewej.
mellamokb
Również nie udaje się wprowadzić danych wejściowych 1. Muszę zrobić specjalny przypadek, aby obsłużyć 1.
mellamokb
Brakowało mi „minimalnej” części, zmieniłem się.
Ry- 30.04.11
@minitech: Nadal nie działa dla wejścia „1”. lol, nasze odpowiedzi
wydają
Ach, udało się uczynić go o 2 znaki krótszym niż twój! : 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
źródło
Program wywołujemy tylko dla jednego wejścia. Podano wiele danych wejściowych w celu sprawdzenia poprawności.
fR0DDY
3

Perl (75) (72)

$ d = przesunięcie; mapa {$ m = $ _. $ m, $ d / = $ _ do $ d% $ _} odwróć 2..9; wydrukuj $ d-1? -1: $ m || 1

zainspirowany kodem javascript mellamokb; przeznaczony do uruchomienia z parametrem

goth perl chiński
źródło
Czy nie byłoby krótsze, gdybyś użył stdin zamiast parametru?
asoundmove
3

GolfScript ( 60 57)

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

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

Edytować

Ok, myślę, że ta wersja daje teraz prawidłowe wyjście dla każdego przypadku :-)

Edytuj 2

Ogoliłem 3 znaki na sugestie @ Petera.

mellamokb
źródło
Powodem, dla którego skomentowałem, że 1dawanie 1jest ważnym przypadkiem testowym, jest to nieprzyjemny przypadek specjalny - jedyna liczba, dla której cyfra 1pojawia się na wyjściu. Obawiam się, że łamie twój kod.
Peter Taylor
Łamie się również dla liczb podzielnych przez liczby pierwsze większe niż 9.
Peter Taylor
@ Peter: OK, spróbuj ponownie. Myślę, że ta wersja działa teraz dla wszystkich przypadków testowych.
mellamokb
Wydaje się, że tak. Możesz od razu uratować jedną postać, usuwając ją najpierw [- jeśli nie masz jej [na stosie podczas oceny ], bierze wszystko na stos. I prawdopodobnie możesz zapisać dwie postacie pod koniec, nie zawijając -1tablicy i nie przesuwając finału $.
Peter Taylor
@Peter: Dzięki, zapisane 3 kolejne znaki!
mellamokb
3

Haskell

f n=head([m|m<-[1..10^9],product(map(read.return)$show m)==n]++[-1])
Ming-Tang
źródło
Ogol jeden znak, zmieniając (show m)na $show m.
FUZxxl
1
nie powinno być m<-[1..9^9].... w przeciwnym razie jest to nieskończona lista ... więc -1nigdy nie nastąpi ... popraw mnie, jeśli się mylę.
st0le
Nie sądzę, że może działać w ciągu 10 sekund ....
st0le
2

Windows PowerShell, 87

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

Perl (68)

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

To wydaje się jak niesamowite sztuczki, które używa @mellamokb w javascript, aby uniknąć pętli zagnieżdżonych byłoby dobrze przekłada się na Perl ale wychodzi dużo bardziej gadatliwy, ponieważ nie można używać foreachpętli stylu dłużej. Szkoda też, że Perl nie uważa, że mapprzydałaby się inna pętla redo.

Jasvir
źródło
2

scala 106 znaków:

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 i wywołanie:

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)

Czas reakcji: natychmiast <1s na procesorze 2 Ghz.

nieznany użytkownik
źródło
2

Galaretka , 18 13 10 bajtów

×⁵RDP$€io-

Wypróbuj online!

13-bajtowe rozwiązanie:

×⁵RDP$€iµ’¹¬?

Wypróbuj online!

Objaśnienie z danymi wejściowymi 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

18-bajtowe rozwiązanie:

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

Wypróbuj 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).

Ostatni link służy tylko do zastąpienia 0 (domyślna wartość falsey galaretki, ponieważ wszystkie listy mają jeden indeks) wartością -1. Jeśli uznasz 0 za wartość OK falsey, program ma 8 bajtów .

Złupić
źródło
1
Kilka uwag: (1) używasz każdego linku pomocniczego tylko raz, więc nie ma powodu, aby tworzyć link pomocniczy. Po prostu użyj $ƊƲµ. (2) Ponieważ ciąg -1i liczba -1są identyczne, gdy są wypisywane, użycie liczby pozwala zaoszczędzić 2 bajty. (3) Pjest skrótem od ×/. (4) Nie można wprowadzić danych 3125.
user202729
@ user202729 Dziękuję bardzo! Zaimplementowałem (1), (2) i (3) i zapisali 6 bajtów! Jeśli zmieniłem ⁵ na ³, działało to na wejściu 3125, ale dopiero po znacznym opóźnieniu. Czy wiesz, czy istnieje lepszy (i krótszy) sposób, czy moje podejście (które, jak wiem, zdecydowanie nie jest najszybsze pod względem złożoności czasowej), jest tak dobre, jak to możliwe?
Harry
1
Myślę, że _¬$powinien działać’¹¬?
dylnan
1
o-jest jeszcze krótszy.
user202729
@dylnan Dziękuję - zauważyłem, że z powodu µmogłem po prostu korzystać bez tego, $który zapisał 2 bajty! Ale potem zdałem sobie sprawę, o-że mogę po prostu µcałkowicie pominąć i zaoszczędzić 3 bajty!
Harry
1

Rubinowy (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
źródło
0

Python 2 , 89 bajtów

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)

Wypróbuj online!

Tylko dlatego, że nie ma jeszcze odpowiedzi w języku Python. Naprawdę bolesne jest brak niejawnej konwersji typu między ciągiem a int.

Bubbler
źródło