优化julia one-liner以使其与python一样快

时间:2016-04-18 12:47:31

标签: python julia

我在朱莉娅写了一个简单的单线来解决一个小数学问题:找到一个两位数字,A和一个三位数字B,这样他们的产品,A x B是一个五位数字,每一个数字来自0至9恰好在数字A,B和A x B中出现一次。例如,

54 x 297 = 16,038

这是我的julia代码,它找到了所有可能的解决方案:

println(filter(l -> length(unique(reduce(vcat, (map(digits, l))))) == 10, [[x, y, x*y] for x in Range(10:99), y in Range(100:999)]))

它解决了这个问题,但后来我尝试了python并提出了这个问题:

print filter(lambda y: len(set(''.join([str(x) for x in y])))==10, [[x, y, x*y] for x in range(10, 99) for y in range(100, 999)])

定时他们两个,我惊讶地发现python代码的运行速度是julia代码的两倍多。有关julia代码更快速处理的任何建议(最好将其保留为单行代码)?

除此之外:我知道我可以通过快速调整范围来改进 range(12, 98) range(102, 987)

更新

超越单行,我已经接受了循环可能比列表更快的建议,因此我比较了以下备选方案:

朱莉娅

ans = Array{Tuple{Int32, Int32, Int32}}(0)
for x in 12:98 
  for y in 102:987
    if length(unique(digits(x+y*100+x*y*100_000)))==10 push!(ans, (x, y, x*y) end
  end
end
println(ans)

的Python

ans = []
for x in range(12,98): 
  for y in range(102,987):
    if len(set(str(x+y*100+x*y*100000)))==10:
      ans.append((x, y, x*y))
print ans

python代码运行得更快(即使我更改了两者的代码,只是简单地在循环中打印出结果而不是在列表中收集它们)。我期待朱莉娅能有更好的表现。

另外,如果您感兴趣,完整的解决方案列表是

39 x 402 = 15,678
27 x 594 = 16,038
54 x 297 = 16,038
36 x 495 = 17,820
45 x 396 = 17,820
52 x 367 = 19,084
78 x 345 = 26,910
46 x 715 = 32,890
63 x 927 = 58,401

1 个答案:

答案 0 :(得分:6)

@simd for x in 10:99 for y in 100:999 length(unique(digits(x+y*100+x*y*100_000)))==10 && println(x,'*',y,'=',x*y) end end

在我的电脑中,此代码的速度约为原始速度的3倍。 (0.223902秒vs 0.680781秒)

关键是"avoid unnecessary arrays"。尽可能使用for循环或元组