2016-12-09 7 views
8

मैं पिछले कुछ वर्षों में AdventOfCode समाधानों को देखकर मुझे कुछ F # सीखने की कोशिश कर रहा था। मैं इस neat peice of code, जो मैं बिल्कुल पार्स नहीं कर सकता भर में आया था:डिबगिंग Seq.sumBy

i 1|>Seq.sumBy(" (".IndexOf) 

ध्यान दें, मेरा मानना ​​है कि मैं पहले लाइन (लिंक में) को समझते हैं:

let i n=System.IO.File.ReadAllText(sprintf "%s/input/input%d.txt"__SOURCE_DIRECTORY__ n) 

कौन सा एक समारोह i कि एक लेता है बनाता है integer n और फ़ाइल inputN.txt को पढ़ता है और इसे एक स्ट्रिंग के रूप में देता है। इसलिए i 1 एक स्ट्रिंग के रूप में input1.txt देता है।

फिर |> सिर्फ स्ट्रिंग पाइप (या वर्ण की सरणी?) अगले समारोह के लिए सबसे पहले परम है, जो है Seq.sumBy

लेकिन फिर चीजें टूट शुरू के रूप में ...

sumBy सीधे लगता है आगे पर्याप्त:

सूची के प्रत्येक तत्व में फ़ंक्शन को लागू करके उत्पन्न परिणामों का योग देता है।

लेकिन स्ट्रिंग " (" के IndexOf ने मुझे परेशान किया है।

अब, मुझे वास्तव में कोई मछलियों को नहीं चाहिए, मैं यह जानना चाहता हूं कि यह क्या है। इस विदेशी भाषा के लिए नौसिखिया के रूप में, जैसा कि मैं एफ # के अधिक बिट्स काम करना सीखता हूं, मैं इस कोड का टुकड़ा कैसे ले सकता हूं और इसे समझने के लिए इसे छोटे टुकड़ों में विघटित कर सकता हूं कि क्या हो रहा है? यह मुझे पागल कर रहा है कि मेरे पास समाधान है, google/so है, और मैं अभी भी इस कोड को समझ नहीं पा रहा हूं।

क्या कोई मुझे कुछ छोटे स्निपेट दिखा सकता है ताकि मैं स्वयं जवाब खोज सकूं?

+0

मैं शुरू में रीड का जवाब है, जो मुझे बेहद मदद मिली स्वीकार कर लिया। लेकिन मार्क का जवाब एफएसआई में अपने वर्णनात्मक उदाहरणों के साथ शानदार रूप से "मेरी मदद डीबग" पर हिट हुआ। दोनों उत्कृष्ट हैं। और मेरी मदद करने के लिए एक महान एफ # समुदाय क्या है। एक बातचीत से दूर चलना मजेदार है! इस समुदाय में हर किसी के लिए महान काम। धन्यवाद! –

उत्तर

7

FSI से मेल खाता है तुम्हारा दोस्त है मैं अक्सर इसका इस्तेमाल को समझने के लिए काम करता है तोड़ा जा सकता है आप FSI में अभिव्यक्ति " (".IndexOf पेस्ट करते हैं तो पहली नजर में यह नहीं दिखता है जैसे कि यह मदद करता है।।:

> " (".IndexOf;; 

    " (".IndexOf;; 
    ^^^^^^^^^^^^ 

stdin(12,1): error FS0041: A unique overload for method 'IndexOf' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: System.String.IndexOf(value: char) : int, System.String.IndexOf(value: string) : int 

आप पहले से ही खोज निकाला है के रूप में, " (" एक स्ट्रिंग है, और IndexOfstring पर एक विधि है। वास्तव में, वहाँ है कि विधि का quite a few overloads हैं, लेकिन केवल दो arity के साथ 1.

इन भार के में से एक इनपुट के रूप में एक char लेते हैं, और अन्य एक string इनपुट के रूप में लेता है।

अभिव्यक्ति " (".IndexOf यदि कोई फ़ंक्शन। यह fun x -> " (".IndexOf x का संक्षिप्त रूप है।

तुम भी पहले से ही पहचान कर रहे हैं कि string लागू करता char seq, इसलिए जब आप इस पर Seq मॉड्यूल का उपयोग, आप अनुक्रम के प्रत्येक तत्व को देख रहे हैं। इस मामले में, प्रत्येक तत्व char है, इसलिए यहां उपयोग में अधिभार एक ऐसा होना चाहिए जो इनपुट के रूप में चार लेता है।

अब जब कि तुम समझ गए होंगे जो ओवरलोड उपयोग में है, तो आप FSI में इसके साथ प्रयोग करने के लिए शुरू कर सकते हैं:

> " (".IndexOf '(';; 
val it : int = 1 
> " (".IndexOf 'f';; 
val it : int = -1 
> " (".IndexOf 'o';; 
val it : int = -1 
> " (".IndexOf ' ';; 
val it : int = 0 

जाहिर है, समारोह " (" में प्रत्येक इनपुट char के सूचकांक ढूंढता है, इसलिए हर बार जब आप '(' में पास करते हैं तो आपको 1 (क्योंकि यह शून्य-अनुक्रमित है) मिलता है, और जब इनपुट ' ' होता है, तो वापसी मान 0 है। अन्य सभी मूल्यों के लिए, वापसी मूल्य -1 है।

"(foo bar)" जैसे इनपुट स्ट्रिंग भी char seq है। इसके बजाय एक sumBy करने का, आप इसे पाइप को Seq.map में क्रम में समझने के लिए कैसे तत्वों में से प्रत्येक के अनुवाद किया जा रहा है की कोशिश कर सकते हैं:

> "(foo bar)" |> Seq.map (" (".IndexOf) |> Seq.toList;; 
val it : int list = [1; -1; -1; -1; 0; -1; -1; -1; -1] 

अब, Seq.map केवल अनुवाद करता है, लेकिन Seq.sumBy उन सभी नंबरों को लेता है और उन्हें एक साथ जोड़ता है :

> "(foo bar)" |> Seq.sumBy (" (".IndexOf);; 
val it : int = -6 

मैं अभी भी अनुमान लगा सकते हैं नहीं क्या उद्देश्य है, लेकिन फिर, मैं कभी इनपुट स्ट्रिंग देखा है ...

+1

मार्क, आपका उत्तर भी शानदार है। धन्यवाद। माता-पिता या कॉमा के बिना यह ढीली हंसमुख भाषा सिर्फ मुझे मार रही है !-) लेकिन आपकी व्याख्या ने स्पष्टीकरण में मदद की है। आपके विस्तृत उत्तर के लिए धन्यवाद (और सामान्य रूप से शिक्षण में आपके कई योगदान! –

8

तो, हम इसे टुकड़ों में तोड़ सकते हैं।

i 1|>Seq.sumBy(" (".IndexOf) 

आप i 1 अनुभाग के बारे में सही हैं। यह input1.txt पढ़ेगा, और आपको पूरे पाठ को string के रूप में देगा।

तो, पहली कुंजी यह है कि String implements IEnumerable<char> (char seq), जिसका अर्थ है कि यह कुछ ऐसा है जिसे समझाया जा सकता है।

आगे, कोष्ठक के अंदर भाग पर ध्यान दें:

" (".IndexOf 

पहले भाग सिर्फ एक स्ट्रिंग है: " (", और IndexOf स्ट्रिंग पर एक विधि है। यह एक विशिष्ट चरित्र की शून्य आधारित अनुक्रमणिका देता है, या -1 यदि यह अस्तित्व में नहीं है।

यह एक तरीका है के रूप में, आप इसे एक समारोह के रूप में उपयोग कर सकते हैं - तो " (".IndexOf तरह के बारे में सोचा जा सकता है:

(fun someChar -> 
       let str = " (" 
       str.IndexOf(someChar)) 

जब तक आप पूर्ण जवाब चाहिए --------- यहाँ बंद करो विस्तार से समझाया गया --------

 

 

 

 

 

 

 

 

 

 

इस मामले में, यदि इनपुट चरित्र ' ' है, यह 0 वापस आ जाएगी, अगर यह '(' है, यह 1 आरंभ कर देंगे, और अगर यह कुछ और है, यह -1 वापस आ जाएगी।

Seq.sumBy इनपुट स्ट्रिंग के प्रत्येक अक्षर को लेता है और इसे इस फ़ंक्शन में पाइप करता है, फिर परिणामस्वरूप रकम करता है। इसका मतलब है कि प्रत्येक इनपुट '(' 1 जोड़ देगा, प्रत्येक इनपुट ' ' 0 जोड़ देगा, और कुछ और -1 जोड़ देगा (जो इस मामले में ')' वर्ण हैं। "()" जैसे स्ट्रिंग 1 जोड़ देगा, फिर -1 जोड़ें, जिसके परिणामस्वरूप । 0, जो goal of the day 1 advent challenge

+2

मुझे लगता है कि यह "" ("इंडेक्सऑफ' आखिरकार मुझे फेंक रहा था। तथ्य यह है कि आप 'कई' वर्णों का एक सूचकांक कर सकते हैं। और आपके 'मजेदार' ने प्रकाश लाया! बाकी सब एक साथ फिट बैठता है। दिन 1, भाग 2 देखें! धन्यवाद रीड। (और इसके लिए धन्यवाद - यहां रुकें --- ;-) –

संबंधित मुद्दे