Добуток цифр


10

Для заданого натурального цілого числа N складіть повну програму, щоб знайти мінімальний природний M таким, щоб добуток цифр M дорівнювало N. N менше 1 000 000 000. Якщо M не існує, надрукуйте -1. Ваш код не повинен займати більше 10 секунд для будь-якого випадку.

Sample Inputs
1
3
15
10 
123456789
32
432
1296

Sample Outputs
1
3
35
25
-1
48
689
2899

4
1давання 1- важливий тестовий випадок.
Пітер Тейлор

1
Вам слід додати більш складні випадки, як-от три, які я використав нижче: 32, 432, 1296. Якщо ви не залишите це як вправу для кодера.
mellamokb

@ s-марка 26, е. Найменше число.
fR0DDY

Я вважаю, що ми також повинні перевірити очевидні 387420489 (9 ^ 9) та 1000000000 для задоволення.
asoundmove

2
Оскільки це старе питання, і ОП неактивне, це лише примітка до майбутніх публікацій: "10 сек" незрозуміло відповідно до діючого стандарту (на якій машині?)
користувач202729

Відповіді:


4

Гольфскрипт, 45 43 40 символів

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

Замінює версію, яка не групувала невеликі лінійки у владу і економила 8 символів, роблячи це. Примітка: 12 = поверх (9 log 10 / log 5).

Подяка: два символи, збережені за допомогою трюку від @mellamokb; 3 збережено з підказкою від @Nabb.


1
Що! Можна написати Golfscript, не тестуючи його? +1, виглядає добре, окрім 123456789, на моїй машині потрібно більше 1 хвилини, і я вбив процес. 12345дай мені -1, то, може, це теж має працювати, 123456789якби я міг досить довго чекати.
ВИ

@ S.Mark, дякую. Схоже, я не можу піти з алгоритму наївної факторизації.
Пітер Тейлор

@Peter: дає неправильні відповіді на складніші випадки. 32 -> 22222, має бути 48. 432 -> 2222333, має бути 689. 1296 -> 22223333, має бути 2899. і т.д.
mellamokb

@mellamokb, хороший момент. Думаю, мені доведеться переписати і перевірити.
Пітер Тейлор

Нічого собі, на 17 символів менше. Мені потрібен кращий алгоритм, хаха!
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/

Редагувати: запозичена ідея введення / виведення з іншого рішення та скорочення логіки виводу.

Редагувати 2: збережено 2 символи, видаливши непотрібні дужки в forциклі.

Правка 3: збережено 2 символи, переписавши whileцикл як ifвисловлювання з i++.

Редагувати 4: Збережено 2 символи, переміщаючи та зменшуючи операції i.

Редагувати 5: Перетворити, якщо оператор у потрійний формат, заощадивши ще 2 символи.

Редагування 6: Збережіть 2 символи, перемістившись i--у справжню частину потрійного, видаліть ++i.


Ви порахували символи лише для функції. Це повна програма? Чи можете ви виконати його тут ideone.com
fR0DDY

1
схоже, є схожий вхід для javascript із павуковим ключем у ideone, який він пов’язав - ideone.com/samples#sample_lang_112
ВАС

@ fR0DDY: Гаразд, тепер це повна програма :)
mellamokb

Я нарешті скоротив мою до 69 символів, але ви можете зробити це теж зараз з такою ж ідеєю та promptріччю.
Ри-

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} попередження
На 4 символи довше, але насправді виконуваний сценарій (на відміну від функції).

Редагувати: Використовуючи ідеї з іншого JavaScript, я можу зменшити його до цього:

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

Нарешті! Рішення, що має 69 символів, використовує лише 1 для циклу;)

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

Гаразд, збрив одну кому.

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

Така ж проблема, як і рішення GolfScript. Збій на входах 32, 432 та 1296. Є причина, чому я починаю з 9 і йду назад, і з'єднуюся з правого, а не з лівого.
mellamokb

Також не вдається ввести 1. Доведеться зробити спеціальний випадок для обробки 1.
mellamokb

Я пропустив "мінімальну" частину, змінився.
Ри-

@minitech: все ще не працює для введення "1". хаха, наші відповіді майже точно ідентичні :-)
mellamokb

Ах, вдалося зробити його на 2 символи коротшим, ніж ваш! : D
Ри-

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}

Ми викликаємо програму лише для одного входу. Кілька входів даються лише для перевірки правильності.
fR0DDY

3

Perl (75) (72)

$ d = shift; карта {$ m = $ _. $ m, $ d / = $ _ до $ d% $ _} зворотній 2..9; надрукуйте $ d-1? -1: $ m || 1

натхненний кодом javascript mellamokb; призначений для запуску з параметром


Чи не буде коротше, якби замість параметра ви використовували stdin?
asoundmove

3

GolfScript ( 60 57)

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

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

Редагувати

Гаразд, я думаю, що ця версія дає правильний вихід для кожного випадку зараз :-)

Редагувати 2

Поголив 3 символи на пропозиції @ Петра.


Причина, про яку я коментував вище, що 1давання 1є важливим тестовим випадком, полягає в тому, що це неприємний спеціальний випадок - єдине число, для якого цифра 1відображається у висновку. І це зламає ваш код, я боюся.
Пітер Тейлор

Він також розбивається на числа, що поділяються на прості більше 9-х.
Пітер Тейлор

@Peter: Добре, спробуйте ще раз. Я думаю, що ця версія працює зараз для всіх тестових випадків.
mellamokb

Здається, так. Ви можете зберегти один символ відразу, видаливши його спочатку [- якщо у вас немає [стека, коли ви оцінюєте а, ]це займе все на стеку. І, ймовірно, ви можете зберегти два символи до кінця, не загорнувшись -1у масив і не перемістивши остаточний $.
Пітер Тейлор

@Peter: Спасибі, зберегли ще 3 символи!
mellamokb

3

Хаскелл

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

Поголіть одну табличку, змінивши (show m)на $show m.
FUZxxl

1
чи не повинно бути m<-[1..9^9].... інакше це нескінченний список ... так -1ніколи не трапиться .... виправте мене, якщо я помиляюся.
st0le

Я не думаю, що це може спрацювати протягом 10 секунд ....
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

Це , здається , як дивовижний трюк , який @mellamokb використовує в JavaScript , щоб уникнути вкладеного циклу б добре перевести на Perl , але це виходить набагато більш багатослівним , тому що ви не можете використовувати foreachцикл стилю більше. Шкода також, що Perl не думає map, що цикл ще redoстане у нагоді.


2

Шкала 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)

Тест та виклик:

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)

Час відповіді: негайно, <1 в процесорі 2 ГГц.


2

Желе , 18 13 10 байт

×⁵RDP$€io-

Спробуйте в Інтернеті!

13-байтне рішення:

×⁵RDP$€iµ’¹¬?

Спробуйте в Інтернеті!

Пояснення із введенням 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-байтне рішення:

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

Спробуйте в Інтернеті!

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

Останнє посилання лише замінити 0 (значення Falsey за замовчуванням Jelly, оскільки всі списки одноіндексовані) на -1. Якщо ви вважаєте 0 значенням ОК фальси, програма становить 8 байт .


1
Деякі зауваження: (1) ви використовуєте кожне допоміжне посилання лише один раз, тому немає ніяких причин робити допоміжне посилання. Просто використовуйте $ƊƲµ. (2) Оскільки рядок -1і число -1є однаковими при виведенні, за допомогою числа зберігається 2 байти. (3) Pє скороченим для ×/. (4) Помилка введення 3125.
користувач202729

@ user202729 Дуже дякую! Я реалізував (1), (2) і (3), і вони зберегли 6 байт! Якщо я змінив ⁵ на ³, він працював на вході 3125, але лише після значної затримки. Чи знаєте ви, чи існує кращий (і коротший) спосіб, чи мій підхід (який я знаю, безумовно, не найшвидший за часовою складністю) такий хороший, як це вийде?
Гаррі

1
Думаю, _¬$слід попрацювати над’¹¬?
dylnan

1
o-ще коротше.
користувач202729

@dylnan Дякую - я помітив, що через те, що µя міг просто використовувати, без $якого зберегли 2 байти! Але тоді я зрозумів, o-що міг просто опустити µцілу і зберегти 3 байти!
Гаррі


0

Python 2 , 89 байт

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)

Спробуйте в Інтернеті!

Просто тому, що ще немає відповіді Python. Дуже боляче бракує неявного перетворення типу між рядком та int.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.