/ / मुद्रण 2D ट्रायल्स की सूची से ग्रिड - हैस्केल

त्रिगुणों की सूची से 2 डी ग्रिड मुद्रण - हैस्केल

मैं एक पंक्ति में त्रिकोणीय की सूची को लाइन से प्रिंट करना चाहता हूंतौर तरीका। सूची में ऐसे त्रिगुण होते हैं जो त्रिगुणों के प्रत्येक पहले तत्व को दूसरे और तीसरे तत्वों के रूप में दिए गए निर्देशांक में रखा जाना चाहिए। ग्रिड (0,0) निर्देशांक से शुरू होता है। नीचे एक 2x2 ग्रिड उदाहरण है:

generateGrid [("a",0,0),("b",0,2),("c",1,1), ("d",2,2)]
-> a - b
- c -
- - d

मेरे पास इस फ़ंक्शन को उत्पन्न करने के लिए एक दृष्टिकोण है लेकिनमैं कोड में सब कुछ नहीं डाल सकता था। मैंने त्रिगुणों में अधिकतम संख्या ज्ञात करने और उसके बढ़े हुए मूल्य से ग्रिड बनाने की कोशिश की। इस तरह मैं कोआर्डिनेट (0,0) से शुरू कर सकता था। फिर, मैं सभी त्रिगुणों के ऊपर जाना चाहता था और संबंधित समन्वय में पहला तत्व रखता था। मैं इसे कैसे बना सकता हूं?

नीचे मेरा कोड है:

gridMax ((p1, p2, p3):xs) = max (maximum(secList ((p1, p2, p3):xs))) (maximum(thirdList ((p1, p2, p3):xs)))

secList [] = []
secList ((p1, p2, p3):xs) = [p2] ++ secList xs

thirdList [] = []
thirdList ((p1, p2, p3):xs) = [p3] ++ thirdList xs

इस तरह से मुझे ग्रिड की अधिकतम मिली जिसका अर्थ है कि मुझे (0,0) से शुरू होने वाली एक (अधिकतम + 1) X (अधिकतम + 1) ग्रिड बनानी चाहिए। मैं बाकी कोड नहीं मिला।

उत्तर:

उत्तर № 1 के लिए 1

हास्केल के आलस्य के कारण, हम कर सकते हैंमान लें कि हमारे पास एक अनंत ग्रिड है, इसलिए हम इस ग्रिड पर कोशिकाओं को एक-एक करके तर्कों में दिए गए निर्देशांक के अनुसार सेट कर सकते हैं, और इस प्रक्रिया में परिणाम ग्रिड के आकार को रिकॉर्ड कर सकते हैं। जब हम समाप्त कर लेते हैं, हम उस अनंत ग्रिड से केवल परिणाम ग्रिड ले सकते हैं।

इस विचार का कार्यान्वयन इस प्रकार है:

setVal :: Int -> a -> [a] -> [a]
setVal idx val lst = h ++ (val : tail t)
where (h, t) = splitAt idx lst

setCell :: (Char, Int, Int) -> [[Char]] -> [[Char]]
setCell (c, x, y) grid = setVal x xl grid
where xl = setVal y c $ grid !! x

generateGrid :: [(Char, Int, Int)] -> [[Char]]
generateGrid cs = take (mx+1) $ map (take (my+1)) grid
where (mx, my, grid) = foldr step (0, 0, g) cs
g = repeat $ repeat "-"
step co@(c, x, y) (mx, my, g) =
let g" = setCell co g
mx" = max x mx
my" = max y my
in
(mx", my", g")

इस तरह परीक्षण किया जा सकता है:

*Main> let cs = [("a",0,0),("b",0,2),("c",1,1), ("d",2,2)] :: [(Char, Int, Int)]
*Main> putStr $ unlines $ generateGrid cs
a-b
-c-
--d

जवाब के लिए 0 № 2

बस मज़े के लिए, यहाँ हास्केल वन-लाइनर है:

generateGrid :: [((Int, Int), Char)] -> String
generateGrid xs =
unlines $ map (map snd) $ groupBy ((==) `on` fst . fst) $ assocs $ accumArray (const id) "-" ((0,0), (maximum $ map (fst . fst) xs, maximum $ map (snd . fst) xs)) xs

यहाँ क्या हो रहा है यह डिकोड करें:

generateGrid :: [((Int, Int), Char)] -> String
generateGrid xs =
unlines .
map (map snd) .
groupBy ((==) `on` fst . fst) .
assocs .
accumArray (const id)
"-"
((0,0), (maximum $ map (fst . fst) xs, maximum $ map (snd . fst) xs))
$ xs

पहली चीज़ जो हम करते हैं वह है एक सरणी का उपयोग करना accumArray :: (e -> a -> e) -> e -> (i, i) -> [(i, a)] -> Array i e। यह यहां "डिफ़ॉल्ट" तत्व लेता है "-" ज़ाहिर कारणों की वजह से; एक संयोजन समारोह, यहाँ const id - जो सिर्फ दूसरा तत्व लौटाता है, जो सूची से निकाले गए तत्व होंगे; एक सीमा, पर शुरू (0,0) और अधिकतम मूल्यों पर समाप्त; और अंत में, xs इनपुट सूची, जो चाबियों की एक सूची है (Int, Int) मूल्यों के साथ जुड़े: Char.

इसका पूरा बिंदु खाली स्थानों को "भरना" है ((x,y),"-"). accumArray यह करने का एक बहुत ही आसान तरीका है।

तब हम उपयोग करते हैं assocs सरणी से वापस सूची प्राप्त करने के लिए।

अगला फ़ंक्शन संघों की सूची ले जाएगा और उन्हें उप-सूची में समूहित करेगा - प्रत्येक उप-सूची जिसमें एक पंक्ति होगी।

अब हमारे पास पंक्तियों की एक सूची है - हम उठते हैं "किसी भी समय सूचकांक में दिलचस्पी नहीं है, इसलिए map (map snd) उनसे छुटकारा मिलता है। आखिरकार, unlines न्यूलाइन्स द्वारा अलग की गई एक स्ट्रिंग में पंक्तियों को जोड़ती है।