ทริกเกอร์ปล่องและป้องกันแจ็คพอต


23

คุณจะเข้าร่วมในเกมอย่างไร หนึ่งในความท้าทายทำงานดังนี้:

  • ห้องแรกมีลูกบอลเหมือนกันจำนวนมาก
  • ห้องที่สองมีชุดของรางซึ่งแต่ละห้องมีเซ็นเซอร์ซึ่งนับจำนวนลูกบอลที่ถูกวางไว้ในนั้น ลูกบอลที่วางในรางไม่สามารถกู้คืนได้
  • รางแต่ละอันจะทริกเกอร์หลังจากมีการวางลูกจำนวนหนึ่ง ( จำนวนการเรียกใช้ทริกเกอร์ ) เมื่อมันก่อให้เกิดการกระพริบไฟเสียงและทำให้คุณไม่ต้องสงสัยเลยว่ามันได้ถูกทริกเกอร์
  • คุณต้องเปิดใช้งานNปล่องเพื่อดำเนินการท้าทายต่อไป
  • คุณรู้ว่าจำนวนการเรียกทริกเกอร์ แต่ไม่ใช่การโต้ตอบระหว่างการนับและการเปลี่ยนราง
  • คุณมีโอกาสหนึ่งที่จะเอาลูกบอลจากห้องแรกไปสู่ห้องที่สอง เมื่อคุณวางลูกบอลลงในรางคุณจะไม่สามารถกลับไปเล่นลูกอื่นได้อีก
  • ลูกบอลแต่ละลูกที่คุณนำมาหักเงินจากแจ็คพอต

เห็นได้ชัดว่าคุณต้องการให้แน่ใจว่าคุณจะผ่านการท้าทาย แต่คุณต้องการลดการสูญเสียเงินแจ็คพอต เขียนโปรแกรมฟังก์ชั่นคำกริยา ฯลฯ เพื่อบอกจำนวนลูกบอลที่คุณต้องการ

ตัวอย่าง

สมมติว่าจำนวนทริกเกอร์คือ 2, 4 และ 10 และคุณต้องทริกเกอร์ 2 ตัวเพื่อผ่าน มีกลยุทธ์ในการส่งต่อด้วย 10 ลูกคือ: วางได้ถึง 4 ลูกในรางแรก, ถึง 4 ลูกในรางที่สอง, และมากถึง 4 ลูกในรางที่สาม เนื่องจากหนึ่งในสามของรางจะเริ่มทำงานหลังจากเพียง 2 ลูกคุณจะใช้ทั้งหมด 10 ลูกเท่านั้นไม่มีกลยุทธ์ใดที่รับประกันว่าจะทำงานได้น้อยกว่า 10 ดังนั้นนั่นคือผลลัพธ์ที่ถูกต้อง

อินพุต

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

คุณอาจสันนิษฐานว่าอินพุตทั้งหมดมีค่ามากกว่าศูนย์และจำนวนของ chutes ที่ต้องถูกทริกเกอร์ไม่เกินจำนวน chutes

คุณอาจจะคิดว่าจำนวนนั้นถูกจัดเรียง (ขึ้นหรือลง) ตราบใดที่คุณระบุไว้อย่างชัดเจนในคำตอบของคุณ

เอาท์พุต

ผลลัพธ์ควรเป็นจำนวนเต็มเดียวโดยกำหนดจำนวนลูกที่ต้องการโดยกลยุทธ์ที่เหมาะสม

กรณีทดสอบ

รูปแบบ: N counts solution

1 [2 4 10] 6
2 [2 4 10] 10
3 [2 4 10] 16
1 [3 5 5 5 5 5 5 5 5 5] 5
2 [1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 8 11] 8
2 [1 2 6 6 6 6 6 6 6 10] 16
2 [1 2 3 3 4 4 6 6 6 11] 17
3 [1 2 3 4 5 5 6] 16
3 [2 4 7 7 7 7 7 7 7] 21
5 [1 2 2 3 3 3 3 3 5 9 9 11] 27
2 [5 15 15] 25
1 [4 5 15] 10
3 [1 4 4 4] 10
2 [1 3 4] 6
2 [1 3 3 8] 8

คำเตือน: อย่าพยายามนินจา!
Erik the Outgolfer

1
คุณช่วยอธิบายได้ไหมว่าทำไมกรณีทดสอบครั้งสุดท้ายถึงให้ 10 ไม่ใช่สถานที่เดียวอย่างน้อย 4 แห่งเพื่อให้แน่ใจว่ามีทริกเกอร์อย่างน้อยหนึ่งตัวใช่หรือไม่ ฉันอาจจะโง่เกินไปและอ่านคำถามไม่ดี แต่ฉันไม่เข้าใจ
Mr. Xcoder

2
@Rod คุณจะต้องวาง 5 ในสองของพวกเขาก่อนที่จะรับประกันว่าจะเรียก 5 * 2 = 10
H.PWiz

3
@ H.PWiz ขอบคุณตอนนี้รับแล้ว ความท้าทายดูเหมือนซับซ้อนยิ่งขึ้นในขณะนี้ ....
Mr. Xcoder

1
@ Mr.Xcoder ใช่ แต่คุณต้องมั่นใจในความสำเร็จในกรณีที่เลวร้ายที่สุด
Peter Taylor

คำตอบ:


4

Python 222 198 ไบต์

def S(G,P,T=0):
 T=T or[0]*len(P);r=[0]*(sum(t>=p for t,p in zip(T,P))>=G)
 for i,t in enumerate(T):
    if t<max(P):a=next(p for p in P if p>t)-t;T[i]+=a;r+=[a+S(G,P,sorted(T))];T[i]-=a
 return min(r)

S(2, (2, 4, 10))การใช้งาน

ในการทดสอบโปรแกรมนี้ด้วยความเร็วที่เหมาะสมให้เพิ่มการบันทึกความจำโดยใส่คำสั่งนี้หลังจากนิยามฟังก์ชัน:

old_s = S
mem = {}
def S(G, P, T=0):
    k = (G, tuple(P), T and tuple(T) or 0)
    if k in mem: return mem[k]
    r = old_s(G, P, T)
    mem[k] = r
    return r

เราทำการเขียนโปรแกรมแบบไดนามิกบนอาเรย์ T ที่มีจำนวนลูกบอลที่เราโยนลงไปในแต่ละรางโดยเริ่มจากศูนย์ทั้งหมด โดยอ้างหลักฐานที่เข้มงวดฉันอ้างว่าเราสามารถจัดเรียง T ตลอดเวลานั่นคือสมมติว่าเรามักจะโยนลูกบอลมากที่สุดในรางสุดท้ายซึ่งในทางกลับกันเราจะถือว่าเป็นรางที่ใหญ่ที่สุด

ถ้า T นั้นเมื่อจับคู่องค์ประกอบสำหรับองค์ประกอบด้วย P (ซึ่งเป็นปัญหาของเรา) มีอย่างน้อย G (ซึ่งเป็นเป้าหมายของเรา) องค์ประกอบที่ใหญ่กว่าเราพบวิธีแก้ปัญหาแล้วเราคืน 0 เพราะเราต้องโยน 0 ลูกบอลเพิ่มเติมเพื่อค้นหาวิธีแก้ไข ซึ่งหมายความว่าถ้า G เป็น 1 โยนอย่างน้อยที่สุดของเราลงในรางจะต้องมีจำนวนเท่ากับหรือมากกว่าจำนวนของความต้องการรางเล็กที่สุดและอื่น ๆ สำหรับกรัมที่ใหญ่กว่า

มิฉะนั้นสำหรับแต่ละตำแหน่งเราโยนลูกบอลให้มากพอที่จะอัพเกรดเป็นความต้องการทางรางต่อไป (ทุกสิ่งที่อยู่ระหว่างนั้นจะไม่สามารถสังเกตได้) และรับคืน จากนั้นเราจะคืนค่าการโทรซ้ำขั้นต่ำเหล่านี้


215 ไบต์continueโดยการเอา
Mr. Xcoder

1
195 ไบต์โดยลบออกenumerate
Felipe Nardi Batista

4

Haskell, 124 117 100 98 91 80 78 ไบต์

บันทึก 11 ไบต์ขอบคุณ @Peter Taylor

0#_=0
n#a=minimum$zipWith(\x y->x*y+(n-1)#(snd.splitAt y$a))a[1..length a-n+1]

ลองออนไลน์!

(#) รับจำนวนเต็มและรายการจำนวนเต็มเรียงจากมากไปน้อยเป็นอาร์กิวเมนต์

การใช้งานคือ 1#[10,4,2]

ชี้แจง:

สำหรับแต่ละค่า x ในตำแหน่ง i (1-idexed) ในรายการกลยุทธ์ที่ดีที่สุดในการลบองค์ประกอบนั้น (หรือจำนวนองค์ประกอบน้อยกว่าหรือเท่ากับ x) คือการเทลูกบอล x ลงใน i chutes

สำหรับแต่ละองค์ประกอบ x ในตำแหน่ง i ในรายการ (n #) คำนวณ x * i + ((n-1) #) ของรายการที่เกินกว่าตำแหน่ง i (จนถึง n คือ 0) จากนั้นจะใช้เวลาน้อยที่สุดในการตรวจสอบความเป็นไปได้ทั้งหมด


3

Haskell , 54 ไบต์

(%)0
(p%l)n|h:t<-l=p+min(p%t$n)(h%t$n-1)|n<1=p|1>0=1/0

ลองออนไลน์!

ใช้รายการตามลำดับจากน้อยไปหามาก


หมายเหตุถึงตนเอง: ครั้งต่อไปยืนยันว่าผลลัพธ์ควรเป็นประเภทจำนวนเต็ม
Peter Taylor

1
ฉันไม่รู้จัก Haskell มากพอที่จะเข้าใจสิ่งนี้คุณสามารถเพิ่มคำอธิบายได้ไหม?
orlp

2

Python ขนาด 73 ไบต์

f=lambda n,c:n and min(c[i]*-~i+f(n-1,c[-~i:])for i in range(len(c)-n+1))

พอร์ตของ H.PWiz คำตอบของ Haskell ต้องป้อนข้อมูลให้อยู่ในลำดับถัดลงมา


1

CJam (35 ไบต์)

{:A,,e!f<{$__(;A,+.-\Af=.*1bz}%:e<}

การสาธิตออนไลน์

รับอินพุตเป็นN countsสมมติว่าcountsเรียงลำดับจากน้อยไปหามาก

การผ่า

แสดงการนับในลำดับจากมากไปน้อยเป็นอาร์เรย์ 1 ที่จัดทำดัชนีC(ดังนั้นองค์ประกอบที่สองของCคือการนับที่ใหญ่ที่สุดที่สอง) C[a_0], C[a_1], ... C[a_{N-1}]สมมติว่าเราจะจบลงด้วยการชนะโดยเรียกปล่อง จากนั้นในกรณีที่เลวร้ายที่สุดสำหรับแต่ละC[a_i]เราได้ใส่อย่างน้อยC[a_i]ลูกลงไปในแต่ละปล่องไป1 a_iดังนั้นเราจึงใส่C[a_{N-1}]ลูกบอลลงไปในa_{N-1}ปล่อง, อีกC[a_{N-2}]ลูกเข้าไปa_{N-2}...

ในแต่ละช่วงของการNนับซึ่งทำให้เราได้ผลรวมที่น้อยที่สุด? จากนั้นเราควรตั้งเป้าหมายที่จะชนะด้วยส่วนย่อยของค่า

NB รหัสใช้จำนวนจริงตามลำดับจากน้อยไปมาก แต่ฉันคิดว่าลำดับจากมากไปน้อยนั้นง่ายกว่า

{         e# Define a block
  :A      e#   Store the sorted counts as A
  ,,e!f<  e#   Get all N-element subsets of A's indices
  {       e#   Map over these subsets S:
    $__   e#     Sort the subset and get a couple of copies
    (;A,+ e#     Remove the first element from one copy and append len(A)
    .-    e#     Pointwise subtraction, giving [S[0]-S[1] S[1]-S[2] ...]
    \Af=  e#     Get the counts [A[S[0]] A[S[1]] ...]
    .*    e#     Pointwise multiplication
    1bz   e#     Sum and take absolute value, giving the worst case score
  }%
  :e<     e#   Select the minimum worst case score
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.