2016-04-18 7 views
5

जितना तेज़ बनाने के लिए अनुकूलित करना मैंने थोड़ा गणित समस्या हल करने के लिए जुलिआ में एक साधारण एक-लाइनर लिखा है: दो अंकों की संख्या, ए और एक तीन अंकों की संख्या बी खोजें जैसे कि उनका उत्पाद , एक एक्स बी, 0 से 9 तक की संख्या ठीक एक बार ए, बी और एक एक्स बी उदाहरण के लिए के बीच में प्रकट होता है एक पांच अंकों की संख्या और हर अंकों हैएक जूलिया वन-लाइनर को इसे पाइथन

54 x 297 = 16,038 

यहाँ जो सभी संभव पाता मेरी जूलिया कोड है समाधान:

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

यह समस्या हल करता है लेकिन फिर मैंने अजगर में कोशिश की और इसके साथ आया:

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

दोनों को समय देना, मुझे यह जानकर आश्चर्य हुआ कि पाइथन कोड जूलिया कोड के जितना तेज़ से अधिक चला गया है। जूलिया कोड के लिए एक तेज दृष्टिकोण के लिए कोई सुझाव (अधिमानतः इसे एक लाइनर में रखते हुए)?

एक तरफ: मैं जानता हूँ कि मैं दोनों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) 

पायथन

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 

पायथन कोड बहुत तेज़ चलता है (भले ही मैं दोनों को सूची में उन्हें इकट्ठा करने के बजाय लूप में परिणामों को मुद्रित करने के लिए कोड बदलूं)। मैं जुलिआ से बेहतर प्रदर्शन की उम्मीद कर रहा था।

इसके अलावा, मामले में आप रुचि रखते हैं, समाधान की पूरी सूची

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 
+0

मैं कमांड लाइन पर 'टाइम' के साथ इन्हें समय दे रहा था। जूलिया में '@ टाइम' और पायथन में 'टाइमिट' का उपयोग करने से पता चलता है कि पाइथन कोड डबल से अधिक की तुलना में केवल 65% तेज है, लेकिन यह अभी भी एक महत्वपूर्ण अंतर है। – seancarmody

+4

बस '[x, y, x * y] 'से' (x, y, x * y)' को प्रतिस्थापित करें, 30% सुधार प्राप्त कर सकते हैं। आप अपने कोड को छोटा करने के लिए 'रेंज (10:99) '' 10: 99' के साथ भी बदल सकते हैं। –

+0

धन्यवाद। दिलचस्प है कि सूचियों के बजाय टुपल्स में बदलना जूलिया के लिए महत्वपूर्ण सुधार देता है लेकिन पाइथन के लिए नगण्य है। – seancarmody

उत्तर

5

@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

अपने कंप्यूटर में इस कोड को 3x के बारे में मूल एक की गति है। (0.223902 सेकंड बनाम 0.680781 सेकेंड)

कुंजी "avoid unnecessary arrays" है। for लूप या टुपल का उपयोग करें जब संभव हो

+0

अच्छा समाधान, मेरे पास एक सवाल है ... इस उदाहरण पर @simd का उद्देश्य क्या है और आप इसका उपयोग कब करते हैं? – Esteban

+0

@Esteban यह [जुलिआ डॉक्टर] से है (http://docs.julialang.org/en/release-0.4/manual/performance-tips/#performance-annotations), लेकिन ईमानदार होने के लिए यह इस उदाहरण में थोड़ा सुधार करता है –

+0

सुझाव के लिए धन्यवाद - बेहद तेज़। दिलचस्प बात यह है कि मैंने अजगर की बजाय उपयोग लूप के समान पाइथन कोड को भी संशोधित किया और परिणाम जूलिया कोड से काफी तेज है। माना जाता है कि व्हाइटस्पेस स्वरूपण आवश्यकता का अर्थ है कि पायथन कोड चार लाइनों में से एक नहीं है। – seancarmody