सबसे पहले, कुछ शब्दावली है: तो तुम एक सहायक समारोह, कि एक सूची में डॉट्स जोड़ता है लिख सकते हैं : किसी दिए गए पंक्ति के लिए, उदाहरण के लिए ["some", "more", "random", "words"]
, हम पंक्ति में "दिए गए शब्दकोष" पंक्ति में दिए गए शब्द की अनुक्रमणिका को कॉल करेंगे। इस प्रकार "more"
में उस पंक्ति में तार्किक कॉलम 1
है; और "words"
में लॉजिकल कॉलम 3
है।एक बार जब हम प्रत्येक शब्द के लिए स्थिति चुन लेते हैं, तो हमारे पास "भौतिक कॉलम" भी होगा जो कहता है कि पंक्ति को प्रस्तुत करते समय उसके सामने कितने अक्षर (बिंदु या अन्य शब्द वर्ण) दिखाई दे सकते हैं।
के एक सरल बनाने धारणा (समस्या काफी कठिन भी सरलीकृत है) करते हैं: अंतिम लेआउट में, पंक्ति r
पर एक शब्द, तार्किक स्तंभ c
शब्दों के बीच में पंक्ति r+1
, तार्किक कॉलम c
और c+1
पर होना चाहिए। इस समस्या से निपटने के लिए
एक विचार स्तंभ की एक तिहाई तरह जोड़ने के लिए, चलो यह एक "बिसात स्तंभ" कहते हैं, एक मध्यवर्ती कदम के रूप में जाने है। नीचे से भी कई चरणों में पंक्तियों में उनके सभी शब्द चेकरबोर्ड कॉलम में होंगे, और पंक्तियों की एक अजीब संख्या में पंक्तियों में उनके सभी शब्द अजीब चेकरबोर्ड कॉलम में होंगे। फिर प्रत्येक चेकरबोर्ड कॉलम के लिए चौड़ाई चुन सकते हैं, और एक शब्द के भौतिक कॉलम को छोटे से चेकरबोर्ड कॉलम की चौड़ाई के योग के रूप में सेट कर सकते हैं।
बहरहाल, यह एक मामूली समस्या है; इस बिसात, जहां मैं स्पष्ट रूप से बिसात स्तंभ सीमाओं बाहर चिह्नित किया है पर विचार करें:
| | |aa| | |
| | b| |c| |
|d| |e | |f|
g| |hh| |i| |j
क्योंकि हम प्रत्येक बिसात स्तंभ की चौड़ाई को चुना है, अलग अलग बिसात कॉलम में शब्द कभी नहीं ओवरलैप कर सकते हैं। इस के बाद एक तरह समाधान है, जो थोड़ा परिमित हैं बाहर नियम:
aa
b c
d e f
g hh i j
ध्यान दें कि aa
और hh
ओवरलैप - हालांकि वे सन्निकट पंक्तियों पर नहीं हैं, तो यह ठीक है।
4
3 7
2 6 9
1 5 8 10
जब किसी दिए गए शब्द बिछाने, हम तो बस छोटी से छोटी शारीरिक स्तंभ इसके लिए चुन सकते हैं कि देख कर नियमों का उल्लंघन नहीं करता है:
एक अन्य समाधान इस क्रम में शब्द बाहर रखना है ऊपर/बाएं और नीचे/बाईं ओर वाले शब्दों की स्थिति और लंबाई (जो पहले ही गणना की जाएगी)। मैं इस एल्गोरिथ्म, जो मैं (प्रति होमवर्क के बारे में साइट दिशा-निर्देश) कुछ ही दिनों में यह जवाब देने के लिए जोड़ देगा के एक कार्यान्वयन है, लेकिन यह संकेत पर्याप्त होना चाहिए आप अपने आप को बहुत यह की तरह कुछ पुन: पेश करने के लिए। मेरी कार्यान्वयन की दिलचस्प एल्गोरिथम बिट प्रकार Map (Row, LogicalColumn) String -> Map (Row, PhysicalColumn) String
की एक दस लाइन समारोह है, और मैं तुम्हें एक इसी तरह टाइप किया समारोह में एक प्रयास कर सलाह देते हैं। इनपुट सूचियों के एक चतुर ट्रैवर्सल के साथ ऐसा करना संभव होना चाहिए (इसलिए किसी भी मैप इंडेक्सिंग लागत को समाप्त करना), लेकिन मैं इसके चारों ओर अपने सिर को लपेट नहीं पाया। हम प्रेरण से साबित कर सकते हैं (जहां हम जिस चर को शामिल कर रहे हैं वह वह क्रम है जिसे हम शब्दों को लिखते हैं) कि यह दृष्टिकोण न्यूनतम चौड़ाई के साथ समाधान उत्पन्न करता है।
के रूप में वादा किया था, कोड मैं के साथ आया था:
import Control.Applicative
import Data.List
import Data.Map hiding (empty, map)
import Data.Ord
type Row = Int
type PhysicalColumn = Int
type LogicalColumn = Int
layout :: Map (Row, LogicalColumn) [a] -> Map (Row, PhysicalColumn) [a]
layout m = munge answer where
answer = mapWithKey positionFor m
positionFor (r, c) as = maximumBy (comparing snd) . concat $
[ [(as, 0)]
, addLength as <$> lookup (r+1, c ) answer
, addLength as <$> lookup (r-1, c-1) answer
]
addLength as (v, p) = (as, p + length v)
lookup k m = maybe empty pure (Data.Map.lookup k m)
munge = fromAscList . map (\((r, _), (w, c)) -> ((r, c), w)) . toAscList
parse :: String -> Map (Row, LogicalColumn) String
parse = fromList
. enumerate
. map words
. lines
enumerate :: [[a]] -> [((Row, LogicalColumn), a)]
enumerate xss = concat . zipWith (\i xs -> [((i, j), x) | (j, x) <- xs]) [0..] . map (zip [0..]) $ xss
groups :: Eq b => (a -> (b, c)) -> [a] -> [(b, [c])]
groups f
= map (\pairs -> (fst . head $ pairs, map snd pairs))
. groupBy ((==) `on` fst)
. map f
flatten :: Map (Int, Int) [a] -> [(Int, [(Int, [a])])]
flatten
= map (\(r, pairs) -> (r, map (concat <$>) (groups id pairs)))
. groups (\((r, c), a) -> (r, (c, a)))
. toAscList
pad :: a -> [(Int, [a])] -> [a]
pad blank = go 0 where
go n ((target, v):rest) = replicate (target-n) blank ++ v ++ go (target+length v) rest
go _ [] = []
pprint = unlines . map (pad ' ' . snd) . flatten
allTogetherNow = putStr . pprint . layout . parse
शायद उदाहरण थोड़ा सही नहीं है? दुनिया के डब्ल्यू के नीचे एक मीटर है, और नियमों के मुताबिक इसकी अनुमति नहीं दी जानी चाहिए। इसके अलावा केवल डॉट्स का पूरा कॉलम है जिसे हटाया जा सकता है। (और इसे स्पष्ट करने के लिए +1 यह होमवर्क है) – chi
हां, यह गलत है, इसे इंगित करने के लिए धन्यवाद। मैंने इसे संपादित किया है। – b3036667
यह समस्या आश्चर्यजनक रूप से सूक्ष्म है! उदाहरण के लिए, '[["aa"], ["b", "c"], ["d", "e", "ff"] '" \ "के लिए एक सही उत्तर है। Aa \ nbc। \ nd.e ... \ n .... एफएफ "'। नोट 'aa'' c' के दाएं * के लिए है, और उत्तर '" ..aa ... \ nb.c .. \ nnd.e .... \ n ..... ff "' जो 'बी' और' सी' के बीच 'aa' रखता है और अधिक बिंदु है (इसलिए आपके spec के अनुसार गलत है)। क्या यह जानबूझकर है? –