优化julia单线以使其与python一样快

Optimising a julia one-liner to make it as fast as python

我在julia中写了一个简单的一线代码来解决数学上的一个小问题:找到一个两位数的数字A和一个三位数的数字B,这样他们的乘积A x B是一个五位数的数字,并且每个数字从0到9在数字A,B和A x B中只出现一次。例如,

1
54 x 297 = 16,038

这是我的茱莉亚代码,可以找到所有可能的解决方案:

1
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并提出了以下建议:

1
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)的范围来改善两者。

更新资料

除了单行之外,我还建议循环可以比列表快,因此我比较了以下几种选择:

朱莉亚

1
2
3
4
5
6
7
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

1
2
3
4
5
6
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代码的运行速度要快得多(即使我更改了两者的代码也只是将结果打印在循环中而不是将它们收集在列表中)。我期待朱莉娅表现更好。

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

1
2
3
4
5
6
7
8
9
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


@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秒和0.680781秒)

关键是"避免不必要的数组"。 尽可能使用for循环或元组