Продукт цифр


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-mark 26, а. Наименьшее число.
fR0DDY

Я считаю, что мы должны также проверить очевидные 387420489 (9 ^ 9) и 1000000000 для развлечения.
Asoundmove

2
Поскольку это старый вопрос, а OP неактивен, это всего лишь примечание к будущим сообщениям: «10 секунд» неясно в соответствии с текущим стандартом (на каком компьютере?)
user202729

Ответы:


4

Golfscript, 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тоже сработает, если я смогу подождать достаточно долго.
ВЫ

@ С.Марк, спасибо. Похоже, я не могу сойти с рук с наивным алгоритмом факторизации.
Питер Тейлор

@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: преобразовать оператор if в троичный формат, сохранив еще 2 символа.

Редактировать 6: Сохранить 2 символа, перейдя i--в истинную часть троичной, удалить ++i.


Вы посчитали символы только для функции. Это полная программа? Можете ли вы выполнить это здесь ideone.com
fR0DDY

1
Похоже, что есть аналогичные входные данные для javascript с spidermonkey на ideone, который он связал - ideone.com/samples#sample_lang_112
ВЫ

@ fR0DDY: Хорошо, теперь это полная программа :)
mellamokb

Наконец-то я уменьшил количество своих персонажей до 69, но теперь вы можете сделать то же самое с той же идеей и тем же prompt.
Ry-

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

4

JavaScript, 88 72 78 74 69 68

для (S = '', I = 2, т = п = строке (); я <м; я ++), в то время как {если (я ((п% я)!)> 9) {оповещения (-1); Е ( )} п / = I, s + = я} оповещения (ы)
На 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.
Необходимо

Я пропустил «минимальную» часть, поменял.
Ry-

@minitech: по-прежнему не работает для ввода «1». лол, наши ответы оказываются практически идентичными :-)
mellamokb

Ах, удалось сделать его на 2 символа короче вашего! : 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}

Мы вызываем программу только для одного входа. Несколько входов даны только для проверки правильности.
fR0DDY

3

Perl (75) (72)

$ d = shift; map {$ 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

Haskell

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

Я не думаю , что он может работать в 10secs ....
st0le


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 (значение по умолчанию для Jelly по умолчанию, поскольку все списки имеют один индекс) на -1. Если вы считаете 0 допустимым значением Falsey, программа занимает 8 байт .


1
Некоторые примечания: (1) вы используете каждую вспомогательную ссылку только один раз, поэтому нет необходимости создавать вспомогательную ссылку. Просто используйте $ƊƲµ. (2) Поскольку строка -1и число -1идентичны при выводе, использование числа экономит 2 байта. (3) Pявляется сокращением для ×/. (4) Сбой для ввода 3125.
user202729

@ user202729 Спасибо большое! Я реализовал (1), (2) и (3), и они сохранили 6 байтов! Если я изменил ⁵ на ³, он работал на входе 3125, но только после значительной задержки. Знаете ли вы, есть ли лучший (и более короткий) путь, или мой подход (который, я знаю, определенно не самый быстрый с точки зрения сложности времени) настолько хорош, насколько это возможно?
Гарри

1
Я думаю, что _¬$должен работать над’¹¬?
Dylnan

1
o-еще короче.
user202729

@dylnan Спасибо - я заметил, что из-за µя мог просто использовать без того, $который сэкономил 2 байта! Но потом я понял, что o-могу просто µполностью опустить и сохранить 3 байта!
Гарри


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.