ล่องแก่งปัญหา (ตัวแปรเป้)


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สำหรับบางคนอย่างต่อเนื่อง, ฟังก์ชั่น valued เดียวf(y)ซึ่งเป็นบวกอย่างเคร่งครัดและมีบวกอย่างเคร่งครัดแรกและที่ไม่ใช่เชิงลบอนุพันธ์ที่สองสำหรับการบวกทั้งหมดyเรากำหนดปริมาณที่ไม่ใช่เชิงลบเป็นผลรวมของทั้งหมดF f(d(x)), 1 <= x <= rตัวเลือกใด ๆ ของการจัดสรรแพที่ตรงกับกฎสองข้อแรกและที่Fเท่ากับค่าต่ำสุดทั่วโลกจะเป็นไปตามกฎข้อที่สามด้วย


3
สำหรับการอ้างอิงในอนาคตคุณสามารถโพสต์ไปที่กล่องแซนด์บ็อกซ์ของเราเพื่อรับคำติชมเกี่ยวกับการท้าทายก่อนโพสต์
ข้าวสาลีตัวช่วยสร้าง

ยินดีต้อนรับสู่การเขียนโปรแกรมปริศนา & รหัสกอล์ฟ! ดูเหมือนว่าจะเป็นการท้าทายที่ดีเพราะรู้ว่าความท้าทายแรกของคุณคือ อย่างไรก็ตามในครั้งต่อไปอาจเป็นการดีกว่าที่จะโพสต์ความท้าทายในSandboxก่อนเพื่อให้ผู้คนสามารถให้คำแนะนำได้ จากนั้นเมื่อคุณคิดว่าความท้าทายเสร็จสิ้นคุณสามารถโพสต์ลงบนเว็บไซต์หลักได้ ขอบคุณสำหรับการอ่านและขอให้มีความสุขมาก ๆ ในวันนี้!
Matthew Roh

การวัดเท่า ๆ กันเป็นไปได้อย่างไร
เดนนิส

@Dennis; ฉันจะแนะนำวิธีในการกำหนดสิ่งนี้ในการแก้ไข อย่างไรก็ตามหากคุณมีวิธีการอื่นและสามารถพิสูจน์ได้สำหรับคำตอบของคุณนั่นก็ดี
Gwyn

1
การออกจากสิ่งต่างๆเพื่อนำไปใช้นั้นทำได้ดีตราบใดที่มันชัดเจนว่าอะไรที่ถูกต้องและอะไรที่ไม่ถูกต้องและการแก้ไขล่าสุดของคุณก็ประสบความสำเร็จเช่นกัน ฉันประหลาดใจนิดหน่อยที่เราไม่สามารถใช้งานได้g(y) = y(ศูนย์ที่สองมาก่อน) หรือg(y) = y²(ก่อนจะลดลงเหลือศูนย์เมื่อy = 0)
เดนนิส

คำตอบ:


2

Perl 6 , 163 158 bytes

{[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ถ้าคุณยกกำลังสองผลลัพธ์?
PurkkaKoodari

@ Pietu1998: ฉันไม่ได้จับได้ดี
smls

3

Haskell 226 228 234 268ไบต์

คำตอบที่ไร้เดียงสาใน Haskell

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 คำแนะนำที่ดีขอบคุณ!
walpen

0

Python3, 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))

ด้วย testcases:

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ฟังก์ชั่น แต่ฉันทำงานนี้เป็นเวลาหลายชั่วโมงแล้วดังนั้นที่นี่คุณไป

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.