数字积


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 2011年

@ s-mark 26,嗯。最小的数字。
fR0DDY 2011年

我相信我们也应该测试明显的387420489(9 ^ 9)和1000000000的乐趣。
asoundmove 2011年

2
因为这是一个古老的问题,并且OP处于非活动状态,所以这只是对以后的帖子的注释:根据当前标准(在哪台计算机上,“ 10秒”不清楚)
user202729

Answers:


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如果我可以等待足够长的时间,也许也应该起作用。
YOU

@ S.Mark,谢谢。看起来我无法摆脱朴素的分解算法。
彼得·泰勒

@Peter:对于更复杂的情况给出错误的答案。32 - > 22222,应该是48 432 - > 2222333,应该是689 1296 - > 22223333,应该是2899.等
mellamokb

@mellamokb,好点。我想我必须重写和测试。
彼得·泰勒

哇,少了17个字符。我需要更好的算法,大声笑!
mellamokb 2011年

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:通过删除for循环中不需要的括号来保存2个字符。

编辑3:通过将while循环重写为if语句,节省了2个字符i++

编辑4:来回移动并减少对的操作,节省了2个字符i

编辑5:将if语句转换为三元格式,节省另外2个字符。

编辑6:通过移至i--三元数的真实部分来保存2个字符,删除++i


您已经为该功能计算了字符。这是完整的程序吗?你能在这里执行吗ideone.com
fR0DDY 2011年

1
貌似用的SpiderMonkey JavaScript的类似的输入在ideone他联系- ideone.com/samples#sample_lang_112
YOU

@ fR0DDY:好的,现在它是一个完整的程序:)
mellamokb

我最终将我的角色减少到69个字符,但是您现在也可以使用相同的构想和方法进行操作prompt
Ry- 2011年

m?m:1=>m||1
l4m2 '18年

4

JavaScript,88 72 78 74 69 68

for(s ='',i = 2,m = n = prompt(); i <m; i ++)而(!(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 2011年

也没有输入1.必须作出特殊情况处理1
mellamokb

我错过了“最小”部分,改变了。
Ry- 2011年

@minitech:对于输入“ 1”仍然无效。大声笑,我们的答案几乎是完全相同的:-)
mellamokb

啊,设法使它比您的字符短2个字符!:D
Ry- 2011年

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 2011年

3

Perl (75)(72)

$ d = shift; map {$ m = $ _。$ m,$ d / = $ _直到$ d%$ _}反转2..9; print $ d-1?-1:$ m || 1

受mellamokb的javascript代码启发;旨在与参数一起运行


如果使用stdin而不是参数,它会更短吗?
2011年

3

高尔夫脚本(60 57)

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

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

编辑

好的,我认为此版本现在可以为每种情况提供正确的输出:-)

编辑2

根据@Peter的建议,减少了3个字符。


我在上面评论说1给予1是一个重要的测试用例的原因是,这是一个令人讨厌的特殊情况-唯一的数字1出现在输出中。恐怕这会破坏您的代码。
彼得·泰勒

这也为数字比休息9整除素数更大
彼得·泰勒

@Peter:好的,再试一次。我认为此版本现在适用于所有测试用例。
mellamokb

似乎是的。您可以通过先删除一个字符来立即保存一个字符[-如果您[在评估时没有在堆栈上,那么]它将占用堆栈上的所有内容。通过不包装-1在数组中并移动最后一个字符,您可以在结尾处保存两个字符$
彼得·泰勒

@Peter:谢谢,节省了3个字符!
mellamokb 2011年

3

哈斯克尔

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

更改(show m)为,即可删除一个字符$show m
FUZxxl 2011年

1
不应该m<-[1..9^9]....否则它是一个无限列表...所以-1永远不会发生....如果我错了请纠正我。
st0le 2011年

我不认为它可以10secs内工作....
st0le

2

Windows PowerShell,87

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

2

佩尔(68)

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

看起来像真棒把戏在javascript @mellamokb用途,以避免嵌套循环会很好翻译成perl的,但它更详细的出来,因为你不能使用foreach样式循环下去。遗憾的是,perl不认为这map是一个循环,否则redo会派上用场。


2

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)

测试与调用:

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)

响应时间:立即,在2Ghz CPU上<1s。


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

最后一个链接只是将-1替换为0(Jelly的默认falsey值,因为所有列表都是一个索引)。如果将0视为OK假值,则程序为8个字节


1
一些注意事项:(1)每个辅助链接只能使用一次,因此没有理由建立辅助链接。只需使用即可$ƊƲµ。(2)由于字符串-1和数字-1在输出时相同,因此使用数字可以节省2个字节。(3)P是的简写×/。(4)输入失败3125
user202729

@ user202729非常感谢!我实现了(1),(2)和(3),它们节省了6个字节!如果将⁵更改为³,则它只能在输入3125上起作用,但要经过相当长的延迟后才能起作用。您是否知道有更好(更短)的方法,还是我的方法(就时间复杂性而言,我绝对不是最快的方法)会达到最佳效果吗?
哈利

1
我认为_¬$应该解决’¹¬?
迪南2018年

1
o-更短。
user202729 '18

@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的答案。在字符串和整数之间缺少隐式类型转换确实很痛苦。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.