রাফটিং সমস্যা (ন্যাপস্যাক বৈকল্পিক)


20

আমার কাছ থেকে প্রথম ধাঁধা, উন্নতির জন্য পরামর্শ আনন্দের সাথে গৃহীত হয়েছে!

দৃশ্যটি হ'ল; আপনি একটি হোয়াইটওয়াটার রাফটিং সংস্থার পরিচালক হিসাবে কাজ করেন। প্রতিদিন সকালে, আপনাকে বুকিংয়ের একটি তালিকা দেওয়া হবে এবং আপনাকে সেগুলি রাফ্ট লোডগুলিতে বাছাই করতে হবে। আপনার নির্বাচিত ভাষায় এমন একটি প্রোগ্রাম বা ফাংশন লিখুন যা এটি আপনার জন্য করে।

প্রতিটি ভেলাটি সর্বাধিক nক্লায়েন্টকে ধারণ করে এবং প্রতিটি বুকিং 1 এবং nলোকের মধ্যে (অন্তর্ভুক্ত) একটি গোষ্ঠীর জন্য । নিম্নলিখিত নিয়মগুলি অবশ্যই পালন করা উচিত;

  • কোনও গোষ্ঠী বিভক্ত নাও হতে পারে। যদি তারা একসাথে বুকিং দেয় তবে তাদের অবশ্যই সবাইকে একই ভেলাতে থাকতে হবে।

  • রাফসের সংখ্যা অবশ্যই হ্রাস করতে হবে।

  • দুটি পূর্ববর্তী নিয়মের সাপেক্ষে, দলগুলিকে ভেলাগুলির মধ্যে যথাসম্ভব সমানভাবে ছড়িয়ে দিতে হবে।

ইনপুট। সংখ্যা n(আপনি ধরে নিতে পারেন এটি ইতিবাচক পূর্ণসংখ্যা) এবং সমস্ত বুকিংয়ের আকার। আপনার ভাষা যদি এ জাতীয় জিনিসগুলিকে সমর্থন করে তবে এটি কোনও অ্যারে, তালিকা বা অনুরূপ ডেটা কাঠামো হতে পারে। এই সমস্ত 1 এবং 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; আমি একটি সম্পাদনায় এটি সংজ্ঞায়িত করার জন্য একটি প্রস্তাবিত উপায় রাখব। তবে আপনার যদি আলাদা পদ্ধতি থাকে এবং আপনার উত্তরের জন্য এটি ন্যায়সঙ্গত করতে পারেন তবে তা ঠিক।
Gwyn

1
কোনটি কার্যকর এবং কোনটি নয় এবং আপনার সর্বশেষ সম্পাদনাটি সেই ইমো অর্জন করবে ততক্ষণ তা বাস্তবায়ন পর্যন্ত জিনিস ফেলে রাখা ভাল। আমি কিছুটা surpised যে আমরা ব্যবহার করতে পারি না g(y) = y(দ্বিতীয় g(y) = y²ডেরিভেট শূন্য ) বা (প্রথমে শূন্য যখন derviate 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ফলাফল বর্গক্ষেত্র করা উচিত?
পূর্বকুডারী

@ পিটু ১৯৯৮: আমি ভাল ধরছি না।
স্মিল

3

হাস্কেল 226 228 234 268 বাইট

হাস্কেলের নিষ্পাপ উত্তর

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

কিছু পরীক্ষার মামলা দিয়ে With

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]]

সম্পাদন করা

পরামর্শের জন্য @ ফ্লোয়ার এবং @ নিমিকে ধন্যবাদ।

pকিছুটা স্কোয়াশ করেছে।

এক জোড়া বাইট বন্ধ


1
আপনি সেট পারে s=sumএবং তারপর ব্যবহার sপরিবর্তে sum, এবং সম্ভবত আপনার কাছে প্রতিস্থাপন করতে পারে fst$ ...সঙ্গে ...!!0
flawr

1
আপনি ফাংশনটি minimumBy(c s)দিয়ে প্রতিস্থাপন head.sortOn sএবং মুছে ফেলতে পারেন c। এছাড়াও: \t->sum t<=nহয় (<=n).sum
নিমি

@ ফ্লোয়ার, ভাল পরামর্শ, ধন্যবাদ!
walpen

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ফাংশন কেবল একটি প্রদত্ত তালিকার সমস্ত পার্টিশন (সমস্ত সম্ভাব্য উপায় sublists সেটিকে ভাগ করা) তৈরি করে। 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ফাংশন, তবে আমি ইতিমধ্যে কয়েক ঘন্টা ধরে এটি কাজ করেছি, তাই আপনি এখানে যান।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.