रूबी (135 पात्र)
a=(0..48).map{rand(9)+1}
([0,0,j=8]*3).each{|l|a[j]=[0,1,6,7,8].inject{|s,e|s+a[j+e]+a[j-e]};j+=l+2}
a.each_slice(7){|r|puts"%-3s"*7%r}
नमूना उत्पादन
2 1 6 9 4 5 1
9 34 4 37 2 31 3
7 2 3 1 8 1 7
5 42 4 40 2 47 9
3 9 9 4 9 4 7
3 44 4 41 2 47 4
6 9 1 5 7 6 8
टूट - फूट
यह बहुत स्पष्ट नहीं है कि यह कैसे काम करता है, इसलिए यहां एक त्वरित ब्रेकडाउन है। नोट: आप संभवत : इनमें से कुछ चरणों को छोड़ सकते हैं और छोटे संस्करणों पर अधिक तेज़ी से कूद सकते हैं, लेकिन मुझे लगता है कि यह अलग-अलग तरीकों से देखने के लिए पर्याप्त रूप से शैक्षिक है, विशेष रूप से मैं 2-अंकीय संख्याओं को 1-अंकीय संस्करणों में बदलने के लिए शाब्दिक रूप से पैटर्न को खोलकर। ।
नैवेद्य संस्करण
दो-आयामी सरणी पर भरोसा करने वाले अन्य रूबी समाधानों के विपरीत , आप 1-आयामी सरणी के साथ शुरू करके और ऑफसेट मूल्यों के साथ काम करके एक छोटा संस्करण प्राप्त कर सकते हैं, क्योंकि पैटर्न दोहराते हैं।
ary=(0..48).map { rand(9) + 1 }
offsets = [-8,-7,-6,-1,1,6,7,8]
3.times do |i|
[8,10,12].each do |j|
ary[j + 14*i] = ary.values_at(*offsets.map { |e| j+14*i + e }).inject(:+)
end
end
ary.each.with_index do |e,i|
$> << ("%-3s" % e)
$> << ?\n if i % 7==6
end
यहां मुख्य सिद्धांत यह है कि हम 8, 10, 12 के सूचकांक पदों पर काम कर रहे हैं, केवल 14. के गुणकों से ऑफसेट। पदों 8, 10 और 12 3x3 ग्रिड के केंद्र हैं जिन्हें हम समेट रहे हैं। नमूना उत्पादन में 34 स्थिति 8, 42 8 + 14 * 1, आदि की स्थिति है हम साथ 34 पदों के द्वारा स्थिति 8 से ऑफसेट स्थिति 8 की जगह [-8,-7,-6,-1,1,6,7,8]
- दूसरे शब्दों में 34 = sum(ary[8-8], ary[8-7], ..., ary[8+8])
। [8 + 14*i, 10 + 14*i, 12 + 14*i]
पैटर्न के दोहराव के बाद से यह सिद्धांत सभी मूल्यों के लिए है।
इसका अनुकूलन कर रहे हैं
सबसे पहले, कुछ त्वरित अनुकूलन:
- इसके बजाय
3.times { ... }
, और j + 14*i
हर बार गणना करते हुए, पदों को "इनलाइन" करें [8,10,12,22,24,26,36,38,40]
।
offsets
सरणी एक बार प्रयोग किया जाता है, तो शाब्दिक साथ चर बदलें।
- के
do ... end
साथ बदलें {...}
और मुद्रण के चारों ओर स्विच करें $> << foo
। (यहाँ एक चाल है जिसमें शामिल है puts nil
और() == nil
।)
- छोटे चर नाम।
इसके बाद का कोड 177 अक्षर है:
a=(0..48).map{rand(9)+1}
[8,10,12,22,24,26,36,38,40].each{|j|a[j]=a.values_at(*[-8,-7,-6,-1,1,6,7,8].map{|e|j+e}).inject(:+)}
a.map.with_index{|e,i|$><<"%-3s"%e<<(?\nif i%7==6)}
अगली कटौती के लिए, ध्यान दें कि inject
ऑफ़सेट सरणी को क्रम में रखने की आवश्यकता नहीं है। हम या तो [-8,-7,-6,-1,1,6,7,8]
या कुछ अन्य आदेश दे सकते हैं, क्योंकि इसके अलावा सराहनीय है।
तो पहले सकारात्मकता और पाने के लिए नकारात्मक जोड़ी [1,-1,6,-6,7,-7,8,-8]
।
अब आप छोटा कर सकते हैं
[1,-1,6,-6,7,-7,8,-8].map { |e| j+e }.inject(:+)
सेवा
[1,6,7,8].flat_map { |e| [j+e, j-e] }
इसका परिणाम यह होगा
a=(0..48).map{rand(9)+1}
[8,10,12,22,24,26,36,38,40].each{|j|a[j]=a.values_at(*[1,6,7,8].flat_map{|e|[j+e,j-e]}).inject(:+)}
a.map.with_index{|e,i|$><<"%-3s"%e<<(?\nif i%7==6)}
जो 176 अक्षर है।
8 से शिफ्ट करें और अंतर पर जाएं
दो-वर्ण शाब्दिक मान ऐसा लगता है कि उन्हें छोटा किया जा सकता है, इसलिए लूप की शुरुआत में अद्यतन [8,10,12,22,24,26,36,38,40]
करके सब कुछ नीचे ले जाएं और शिफ्ट करें । (ध्यान दें कि ऑफसेट मूल्यों को अद्यतन करने की आवश्यकता से बचा जाता है ।)8
j
+=8
1,6,7,8
a=(0..48).map{rand(9)+1}
[0,2,4,14,16,18,28,30,32].each{|j|j+=8;a[j]=a.values_at(*[1,6,7,8].flat_map{|e|[j+e,j-e]}).inject(:+)}
a.map.with_index{|e,i|$><<"%-3s"%e<<(?\nif i%7==6)}
यह 179 है, जो बड़ा है, लेकिन j+=8
वास्तव में हटाया जा सकता है।
पहला बदलाव
[0,2,4,14,16,18,28,30,32]
मतभेदों की एक सरणी के लिए:
[2,2,10,2,2,10,2,2]
और इन मूल्यों को प्रारंभिक रूप से जोड़ते हैं j=8
। यह अंततः समान मूल्यों को कवर करेगा। (हम शायद पहले 8 से शिफ्ट करने के बजाय इसे सीधे छोड़ सकते हैं।)
ध्यान दें कि हम भी की एक डमी मूल्य जोड़ देंगे 9999
मतभेद सरणी के अंत तक, और करने के लिए जोड़ j
पर अंत देंगे , लूप की शुरुआत नहीं । औचित्य यह है कि भयानक रूप से वही 3 नंबर दोहराए जाने के करीब 2,2,10,2,2,10,2,2
दिखाई देता है 3 बार, और j+difference
लूप के अंत में कंप्यूटिंग करके , 9999
वास्तव में आउटपुट को प्रभावित नहीं करेगा, क्योंकि a[j]
कॉल नहीं है, जहां j
कुछ मूल्य है खत्म हो गया 10000
।
a=(0..48).map{rand(9)+1}
j=8
[2,2,10,2,2,10,2,2,9999].each{|l|a[j]=a.values_at(*[1,6,7,8].flat_map{|e|[j+e,j-e]}).inject(:+);j+=l}
a.map.with_index{|e,i|$><<"%-3s"%e<<(?\nif i%7==6)}
इस अंतर सरणी के साथ, j+=8
अब बस है j=8
, ज़ाहिर है, अन्यथा हम बार-बार 8
बहुत अधिक जोड़ देंगे । हमने ब्लॉक वेरिएबल को से भी बदल दिया j
है l
।
इसलिए चूंकि 9999
तत्व का आउटपुट पर कोई प्रभाव नहीं है, इसलिए हम इसे बदल सकते हैं 10
और सरणी को छोटा कर सकते हैं ।
a=(0..48).map{rand(9)+1}
j=8
([2,2,10]*3).each{|l|a[j]=a.values_at(*[1,6,7,8].flat_map{|e|[j+e,j-e]}).inject(:+);j+=l}
a.map.with_index{|e,i|$><<"%-3s"%e<<(?\nif i%7==6)}
यह 170 अक्षर है।
लेकिन अब j=8
थोड़ा सा भद्दा लग रहा है, और आप आसानी से असाइनमेंट के लिए उपयोग कर सकते हैं 2 अक्षरों [2,2,10]
को 2 से नीचे स्थानांतरित करके बचा 8
सकते हैं। यह भी j+=l
बनने की जरूरत है j+=l+2
।
a=(0..48).map{rand(9)+1}
([0,0,j=8]*3).each{|l|a[j]=a.values_at(*[1,6,7,8].flat_map{|e|[j+e,j-e]}).inject(:+);j+=l+2}
a.map.with_index{|e,i|$><<"%-3s"%e<<(?\nif i%7==6)}
यह 169 अक्षर है। 7 वर्णों को निचोड़ने का एक गोल-गोल तरीका है, लेकिन यह साफ-सुथरा है।
अंतिम मोड़
values_at
कॉल निरर्थक की वास्तव में तरह है, और हम एक इनलाइन कर सकते हैं Array#[]
कॉल। इसलिए
a.values_at(*[1,6,7,8].flat_map{|e|[j+e,j-e]}).inject(:+)
हो जाता है
[1,6,7,8].flat_map{|e|[a[j+e],a[j-e]]}.inject(:+)
आप यह भी देख सकते हैं flat_map
सरणी में प्रारंभिक के साथ + j+e/j-e
+ inject
अधिक प्रत्यक्ष योग में घटाया जा सकता है 0
।
इससे आपका साथ छूट जाता है 152 वर्णों के :
a=(0..48).map{rand(9)+1}
([0,0,j=8]*3).each{|l|a[j]=[0,1,6,7,8].inject{|s,e|s+a[j+e]+a[j-e]};j+=l+2}
a.map.with_index{|e,i|$><<"%-3s"%e<<(?\nif i%7==6)}
आखिरकार:
map.with_index
बन सकता है each_slice
।
- मुद्रण दृष्टिकोण बदलें।
135 :
a=(0..48).map{rand(9)+1}
([0,0,j=8]*3).each{|l|a[j]=[0,1,6,7,8].inject{|s,e|s+a[j+e]+a[j-e]};j+=l+2}
a.each_slice(7){|r|puts"%-3s"*7%r}