เลิกรวมรายการ


14

บทนำ

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

function merge(A, B):
  C = []
  while A is not empty or B is not empty:
    if A is empty:
      C.append(B.pop())
    else if B is empty or A[0] ≤ B[0]:
      C.append(A.pop())
    else:
      C.append(B.pop())
  return C

ความคิดที่จะให้ popping ขนาดเล็กขององค์ประกอบแรกของAและจนทั้งสองรายการที่ว่างเปล่าและรวบรวมผลการลงไปB Cถ้าAและมีทั้งที่เรียงแล้วเพื่อให้เป็นBC

ตรงกันข้ามถ้าCเป็นรายการที่เรียงลำดับและเราแยกมันออกเป็นสอง subsequences AและBแล้วAและยังมีการเรียงลำดับและB merge(A, B) == Cที่น่าสนใจสิ่งนี้ไม่จำเป็นต้องถือถ้าCไม่เรียงซึ่งนำเราไปสู่ความท้าทายนี้

อินพุต

การป้อนข้อมูลของคุณคือการเปลี่ยนแปลงในครั้งแรก2*nจำนวนเต็มไม่เป็นลบ[0, 1, 2, ..., 2*n-1]สำหรับบางคนให้เป็นรายการn > 0C

เอาท์พุต

ผลลัพธ์ของคุณจะเป็นค่าจริงหากมีสองรายการAและBความยาวnเช่นนั้นC == merge(A, B)และค่าเท็จเป็นอย่างอื่น เนื่องจากอินพุตไม่มีการซ้ำซ้อนคุณจึงไม่ต้องกังวลกับความสัมพันธ์ที่ขาดในmergeฟังก์ชั่น

กฎและโบนัส

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

โปรดทราบว่าคุณไม่จำเป็นต้องคำนวณรายการAและBในกรณี "ใช่" แต่ถ้าคุณจริงส่งออกรายการคุณได้รับโบนัส 20% ในการรับโบนัสนี้คุณจะต้องส่งออกรายการเดียวเท่านั้นไม่ใช่ความเป็นไปได้ทั้งหมด เพื่อให้โบนัสนี้ง่ายขึ้นในการอ้างสิทธิ์ในภาษาที่พิมพ์อย่างรุนแรงได้รับอนุญาตให้ส่งออกรายการคู่ที่ว่างเปล่าในอินสแตนซ์ "no"

การบังคับให้เดรัจฉานไม่ได้รับอนุญาต แต่มีโบนัส -10%สำหรับการคำนวณกรณีทดสอบสี่ครั้งล่าสุดทั้งหมดไม่เกิน 1 วินาที

กรณีทดสอบ

มีเพียงหนึ่งเอาต์พุตที่เป็นไปได้ที่กำหนดในอินสแตนซ์ "ใช่"

[1,0] -> False
[0,1] -> [0] [1]
[3,2,1,0] -> False
[0,3,2,1] -> False
[0,1,2,3] -> [0,1] [2,3]
[1,4,0,3,2,5] -> False
[4,2,0,5,1,3] -> [4,2,0] [5,1,3]
[3,4,1,2,5,0] -> [4,1,2] [3,5,0]
[6,2,9,3,0,7,5,1,8,4] -> False
[5,7,2,9,6,8,3,4,1,0] -> False
[5,6,0,7,8,1,3,9,2,4] -> [6,0,8,1,3] [5,7,9,2,4]
[5,3,7,0,2,9,1,6,4,8] -> [5,3,7,0,2] [9,1,6,4,8]
[0,6,4,8,7,5,2,3,9,1] -> [8,7,5,2,3] [0,6,4,9,1]
[9,6,10,15,12,13,1,3,8,19,0,16,5,7,17,2,4,11,18,14] -> False
[14,8,12,0,5,4,16,9,17,7,11,1,2,10,18,19,13,15,6,3] -> False
[4,11,5,6,9,14,17,1,3,15,10,12,7,8,0,18,19,2,13,16] -> [4,17,1,3,15,10,12,7,8,0] [11,5,6,9,14,18,19,2,13,16]
[9,4,2,14,7,13,1,16,12,11,3,8,6,15,17,19,0,10,18,5] -> [9,4,2,16,12,11,3,8,6,15] [14,7,13,1,17,19,0,10,18,5]

คำตอบ:


3

Pyth, 39 * 0.9 * 0.8 = 28.08

#aY->QxQeS-QsY&YsY)KfqylTlQmsdty_Y%tlKK

โปรแกรมนี้จับสองโบนัสทั้งหมด มันพิมพ์คู่ของรายการหากยกเลิกการผสานเป็นไปได้อื่นเป็นรายการที่ว่างเปล่าซึ่งเป็นค่าเท็จใน Pyth (และ Python)

Input:  [5,3,7,0,2,9,1,6,4,8]
Output: ([9, 1, 6, 4, 8], [5, 3, 7, 0, 2])
Input:  [5,7,2,9,6,8,3,4,1,0]
Output: [] (falsy value)

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

อาจเป็น (หนึ่งใน) เป็นครั้งแรกวิธีการแก้ปัญหา Pyth ใช้ข้อยกเว้นอย่างแข็งขัน(มันบันทึกอย่างน้อย 1 ถ่าน) มันใช้แนวคิดเดียวกันกับโซลูชันของ Peter Taylor

                         preinitialisations: Q = input(), Y = []
#                 )     while 1: (infinite loop)
        eS-QsY             finds the biggest, not previous used, number
      xQ                   finds the index
    >Q                     all elements from ... to end
   -          &YsY         but remove all used elements
 aY                        append the resulting list to Y

When all numbers are used, finding the biggest number fails, 
throws an exception and the while loop ends.  
This converts [5,3,7,0,2,9,1,6,4,8] to [[9, 1, 6, 4, 8], [7, 0, 2], [5, 3]]

        msdty_Y  combine the lists each for every possible subset of Y (except the empty subset)
 fqylTlQ         and filter them for lists T with 2*len(T) == len(Q)
K                and store them in K

%tlKK        print K[::len(K)-1] (prints first and last if K, else empty list)

Pyth, 30 * 0.9 = 27.0

ฉันไม่ได้ลองแก้ไขโดยไม่พิมพ์รายการผลลัพธ์ แต่นี่เป็นวิธีแก้ปัญหาอย่างรวดเร็วโดยยึดตามรหัสข้างต้น

#aY->QxQeS-QsY&YsY)fqylsTlQtyY

โดยทั่วไปแล้วฉันเพิ่งลบคำสั่งพิมพ์ เอาท์พุทค่อนข้างน่าเกลียดว่า

Input:  [0,1,2,3]
Output: [[[3], [2]], [[3], [1]], [[2], [1]], [[3], [0]], [[2], [0]], [[1], [0]]] (truthy value)
Input:  [5,7,2,9,6,8,3,4,1,0]
Output: [] (falsy value)

ลองมันออนไลน์


คุณอาจพบว่าแทนที่จะพิมพ์(K[0], Q-K[0])คุณสามารถพิมพ์(K[0], K[-1])ได้ ฉันไม่รู้ว่าจะช่วยให้ประหยัดได้หรือไม่
ปีเตอร์เทย์เลอร์

@PeterTaylor ขอบคุณบันทึก 2 ตัวอักษร
Jakube

@PeterTaylor และอีก 2 ตัวอักษรถ้าฉันพิมพ์ K[::len(K)-1]ตัวอักษรมากขึ้นถ้าฉันพิมพ์
Jakube

4

GolfScript (35 * 0.9 = 31.5)

{.$-1>/~,)\.}do;]1,\{{1$+}+%}/)2/&,

การสาธิตออนไลน์ค่อนข้างช้า: บนคอมพิวเตอร์ของฉันมันรันการทดสอบทั้งหมดภายใน 0.04 วินาทีดังนั้นฉันจึงขอลด 10%

คำอธิบาย

คำต่อท้ายของ C ซึ่งเริ่มต้นด้วยตัวเลขที่มากที่สุดใน C ต้องมาจากรายการเดียวกัน จากนั้นเหตุผลนี้สามารถนำไปใช้กับ (ส่วนต่อท้าย C) เพื่อให้ปัญหาลดลงเป็นผลรวมย่อย


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