राफ्टिंग समस्या (नॅप्सैक वैरिएंट)


20

मेरी ओर से पहली पहेली, सुधार के सुझाव खुशी से मिले!

परिदृश्य है; आप एक वाइटवॉटर राफ्टिंग कंपनी के लिए एक प्रबंधक के रूप में काम करते हैं। हर सुबह, आपको बुकिंग की एक सूची दी जाती है, और आपको उन्हें भार भार में क्रमबद्ध करना होता है। अपनी चुनी हुई भाषा में एक प्रोग्राम या फ़ंक्शन लिखें जो आपके लिए ऐसा करता है।

प्रत्येक बेड़ा अधिकतम nग्राहक रखता है, और प्रत्येक बुकिंग 1 और nलोगों (समावेशी) के समूह के लिए है । निम्नलिखित नियमों का पालन किया जाना चाहिए;

  • कोई समूह विभाजित नहीं किया जा सकता है। यदि वे एक साथ बुक करते हैं, तो वे सभी एक ही बेड़ा में होना चाहिए।

  • राफ्ट की संख्या कम से कम होनी चाहिए।

  • दो पूर्ववर्ती नियमों के अधीन, समूहों को राफ्ट के बीच यथासंभव फैलाया जाना चाहिए।

इनपुट। संख्या n(आप मान सकते हैं कि यह एक सकारात्मक पूर्णांक है), और सभी बुकिंग का आकार। यदि आपकी भाषा ऐसी चीजों का समर्थन करती है तो यह एक सरणी, सूची या समान डेटा संरचना हो सकती है। ये सभी 1 और के बीच सकारात्मक पूर्णांक होंगे n। बुकिंग का क्रम परिभाषित नहीं है, न ही यह महत्वपूर्ण है।

आउटपुट। बुकिंग नंबरों की एक सूची, जिन्हें भार भार में वर्गीकृत किया गया है। समूहीकरण को स्पष्ट रूप से इंगित किया जाना चाहिए, जैसे;

  • एक सूची, या सारणी की सारणी।
  • प्रत्येक बेड़ा के लिए एक अल्पविराम से अलग सूची। प्रत्येक बेड़ा के बीच की नई रेखा।

आप तीसरे नियम को कैसे लागू करते हैं, यह आप पर निर्भर करता है, लेकिन इसमें औसतन अधिभोग का पता लगाना, और इससे यथासंभव विचलन को कम करना शामिल हो सकता है। यहाँ कुछ परीक्षण मामले हैं।

n  Bookings       Output
6  [2,5]          [5],[2]
4  [1,1,1,1,1]    [1,1,1],[1,1]
6  [2,3,2]        [2,2],[3]
6  [2,3,2,3]      [2,3],[2,3]
6  [2,3,2,3,2]    [2,2,2],[3,3]
12 [10,8,6,4,2]   [10],[8,2],[6,4]
6  [4,4,4]        [4],[4],[4]
12 [12,7,6,6]     [12],[7],[6,6]

मानक नियम लागू होते हैं, सबसे छोटा कोड जीतता है। मज़े करो!

संपादित; तीसरे नियम के लिए जितना संभव हो उतना परिभाषित करने का सुझाव दिया गया तरीका ।

एक बार राफ्ट की संख्या rनिर्धारित हो जाने के बाद (दूसरे नियम के अधीन), औसत अधिभोग की aगणना बुकिंग के दौरान योग करके, और विभाजित करके की जा सकती है r। प्रत्येक बेड़ा के लिए, औसत अधिभोग से विचलन का उपयोग करके पाया जा सकता है d(x) = abs(n(x)-a), जहां n(x)प्रत्येक बेड़ा में लोगों की संख्या है और 1 <= x <= r। कुछ निरंतर, एकल-मूल्यवान फ़ंक्शन के लिए f(y), जो सख्ती से सकारात्मक है और सभी सकारात्मक के लिए एक सख्ती से सकारात्मक पहला और गैर-नकारात्मक दूसरा डेरिवेटिव है y, हम Fसभी के योग के रूप में, एक गैर-नकारात्मक मात्रा को परिभाषित करते हैं f(d(x)), 1 <= x <= r। बेड़ा आवंटन का कोई भी विकल्प जो पहले दो नियमों को संतुष्ट करता है, और जहां Fवैश्विक न्यूनतम के बराबर है, तीसरे नियम को भी संतुष्ट करेगा।


3
भविष्य के संदर्भ के लिए आप पोस्ट करने से पहले एक चुनौती पर प्रतिक्रिया प्राप्त करने के लिए हमारे सैंडबॉक्स पर पोस्ट कर सकते हैं ।
गेहूं जादूगर

प्रोग्रामिंग पहेलियाँ और कोड गोल्फ में आपका स्वागत है! यह एक अच्छी चुनौती की तरह लग रहा है, यह जानकर कि यह आपकी पहली चुनौती है। अगली बार, हालांकि, पहले सैंडबॉक्स में चुनौती पोस्ट करना बेहतर हो सकता है , इसलिए लोग वहां सुझाव दे सकते हैं। फिर जब आपको लगता है कि चुनौती पूरी हो गई है, तो आप इसे मुख्य साइट पर पोस्ट कर सकते हैं। पढ़ने के लिए धन्यवाद, और आपका दिन शुभ हो!
मैथ्यू रो

कैसे संभव के रूप में समान रूप से मापा जाता है?
डेनिस

@Dennis; मैं इसे संपादित करने के लिए एक सुझाया गया तरीका रखूँगा। हालाँकि अगर आपके पास एक अलग तरीका है, और आप अपने जवाब के लिए इसे सही ठहरा सकते हैं, तो यह ठीक है।
ग्विन

1
कार्यान्वयन तक की चीजों को छोड़ना ठीक है, जब तक यह स्पष्ट है कि क्या मान्य है और क्या नहीं, और आपका नवीनतम संपादन उस imo को प्राप्त करता है। मैं थोड़ा सर्पोटेड हूं कि हम g(y) = y(दूसरा शून्य शून्य) या g(y) = y²(पहले कब शून्य शून्य) का उपयोग नहीं कर सकते y = 0
डेनिस

जवाबों:


2

पर्ल 6 , 163 158 बाइट्स

{[grep $^n>=*.all.sum,map ->\p{|map {p[0,|$_ Z..^|$_,p]},(1..^p).combinations},$^s.permutations].&{.grep: .map(+*).min}.min({.map((*.sum-$s.sum/$_)**2).sum})}

इसे ऑनलाइन आज़माएं!

यह काम किस प्रकार करता है

  • map ->\p{|map {p[0,|$_ Z..^|$_,p]},(1..^p).combinations},$^s.permutations

    इनपुट सरणी के सभी क्रमपरिवर्तन के सभी संभावित विभाजन उत्पन्न करता है।

  • grep $^n>=*.all.sum,

    फिल्टर करता है, जहां कोई बेड़ा नहीं है।

  • .&{.grep: .map(+*).min}

    राफ्ट की संख्या न्यूनतम है, जहां लोगों को फिल्टर करता है।

  • .min({.map((*.sum-$s.sum/$_)**2).sum})}

    न्यूनतम ∑ (n x -a) 2 के साथ पहले वाले को प्राप्त करता है ।

-4 बाइट्स @ Pietu1998 के लिए धन्यवाद


.absयदि आपको परिणाम को चौकोर करना है, तो आपको क्या करने की आवश्यकता है ?
पुरकाकूदरी

@ Pietu1998: मैं नहीं, अच्छी पकड़।
smls

3

हास्केल 226 228 234 268 बाइट्स

हास्केल में Naive जवाब

import Data.List
o=map
u=sum
p=foldr(\x t->o([x]:)t++[(x:y):r|(y:r)<-t>>=permutations])[[]]
m x=foldl(\[m,n]x->[m+(x-m)/(n+1),n+1])[0,0]x!!0
a!z=abs$u z-a
s t=(length t,u$o((m$o u t)!)t)
a n=head.sortOn s.filter(all$(<=n).u).p

या अनगढ़

partition' :: [a] -> [[[a]]]
partition' [] = [[]]
partition' (x:xs) = [[x]:ps     | ps <- partition' xs]
                 ++ [(x:p):rest | ps <- partition' xs, (p:rest) <- permutations ps]

-- from Data.Statistics
mean :: [Double] -> Double
mean xs = fst $ foldl (\(m, n) x -> (m+(x-m)/n+1, n+1)) (0, 0) xs

diff :: Double -> [Double] -> Double
diff avg xs = abs $ sum xs - avg

rawScore :: [[Double]] -> Double
rawScore xs = sum . map (diff avg) $ xs where avg = mean . map sum $ xs

score :: [[Double]] -> (Int, Double)
score xs = (length xs, rawScore xs)

-- from Data.Ord
comparing :: (Ord b) => (a -> b) -> a -> a -> Ordering
comparing p x y = compare (p x) (p y)

candidates :: Double -> [Double] -> [[[Double]]]
candidates n xs = filter (all (\ ys -> sum ys <= n)) . partition' $ xs

answer :: Double -> [Double] -> [[Double]]
answer n xs = minimumBy (comparing score) $ candidates n xs

कुछ परीक्षण मामलों के साथ

import Text.PrettyPrint.Boxes

testCases :: [(Double, [Double])]
testCases = [(6 , [2,5])
            ,(4 , [1,1,1,1,1])
            ,(6 , [2,3,2])
            ,(6 , [2,3,2,3])
            ,(6 , [2,3,2,3,2])
            ,(12, [10,8,6,4,2])
            ,(6 , [4,4,4])
            ,(12, [12,7,6,6])]

runTests tests = transpose 
                 $ ["n", "Bookings", "Output"]
                 : map (\(n, t) -> [ show . floor $ n
                                   , show . map floor $ t
                                   , show . map (map floor) $ a n t]) tests

test = printBox 
     . hsep 3 left . map (vcat top) . map (map text) . runTests $ testCases

जहां testपैदावार होती है

n    Bookings       Output
6    [2,5]          [[2],[5]]
4    [1,1,1,1]      [[1,1],[1,1,1]]
6    [2,3,2]        [[2,2],[3]]
6    [2,3,2,3]      [[2,3],[2,3]]
6    [2,3,2,3,2]    [[2,2,2],[3,3]]
12   [10,8,6,4,2]   [[10],[8,2],[6,4]]
6    [4,4,4]        [[4],[4],[4]]
12   [12,7,6,6]     [[12],[7],[6,6]]

संपादित करें

सलाह के लिए @flawr और @nimi को धन्यवाद।

pथोड़ा सा खिसका ।

एक दो बाइट्स शेव की।


1
आप सेट कर सकते हैं s=sumऔर उसके बाद का उपयोग sकरने के बजाय sum, और शायद आप भी बदल सकते fst$ ...के साथ ...!!0
दोष

1
आप बदल सकते हैं minimumBy(c s)के साथ head.sortOn sऔर समारोह को दूर c। भी: \t->sum t<=nहै (<=n).sum
nimi

@flawr, अच्छा सुझाव, धन्यवाद!
11

0

पायथन 3, 224 बाइट्स

def p(c):
 if len(c)==1:yield[c];return
 for s in p(c[1:]):
  for n,u in enumerate(s):yield s[:n]+[[c[0]]+u]+s[n+1:]
  yield[[c[0]]]+s
s=sum
r=lambda n,b:min(p(b),key=lambda c:s(abs(s(x)-s(b)/(s(b)//n+1))for x in c))

वृषण के साथ:

tc = [[6,[2,5]],[4,[1,1,1,1,1]],[6,[2,3,2]],[6,[2,3,2,3]],[6,[2,3,2,3,2]],[12,[10,8,6,4,2]],[6,[4,4,4]],[12,[12,7,6,6]]]
for case in tc:
    print(str(case[0]).ljust(3),str(case[1]).ljust(16),"|",r(*case))

यह कैसे काम करता है?

pसमारोह बस एक दी गई सूची में से सभी विभाजनों (हर संभव तरीके उप-सूचियों में विभाजित करने के लिए) उत्पन्न करता है। s=sumबस राशि फ़ंक्शन का नाम बदल देता है, इसलिए अंतिम पंक्ति सभी काम करती है।

r=lambda n,b:min(p(b),key=lambda c:s(abs(s(x)-s(b)/(s(b)//n+1))for x in c))
r=lambda n,b:                                                               Initialize the lambda
                 p(b)                                                       Calculate all possible raft arrangements
                     ,key=lambda c:                                         Map the following lambda onto the list:
                                              s(b)/(s(b)//n+1)              Calculate the ideal average amount of people per raft
                                     abs(s(x)-                )             Calculate how close is the current raft
                                                               for x in c   For each raft in the partition
                                   s(                                    )  Sum it (the sum is a score of how close to ideal the function is),
             min(                                                         ) And find the lowest valued partition.

मुझे यकीन है कि इसे आगे बढ़ाया जा सकता है, विशेष रूप से pकार्य, लेकिन मैंने इस पर पहले से ही घंटों तक काम किया है, इसलिए यहां आप जाते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.