แก้ปริศนาโรงละคร BattleBlock


13

เกมBattleBlock ละครบางครั้งมีปริศนาซึ่งเป็นรุ่นทั่วไปของไฟออก คุณมีบล็อกที่อยู่ติดกันสามบล็อกซึ่งแต่ละบล็อกระบุระดับระหว่าง 1 ถึง 4 ที่รวมกับแท่งเช่น:

|
||||
||

หากคุณสัมผัสบล็อกบล็อกนั้นและบล็อกที่อยู่ติดกันจะเพิ่มระดับของบล็อกนั้น (ย้อนกลับจาก 4 เป็น 1) ปริศนาดังกล่าวได้รับการแก้ไขเมื่อบล็อกทั้งสามแสดงระดับเดียวกัน (ไม่สำคัญว่าระดับใด) เนื่องจากลำดับที่คุณสัมผัสบล็อกในนั้นไม่สำคัญเราจึงแสดงวิธีแก้ปัญหาโดยแตะแต่ละบล็อกบ่อยครั้ง ทางออกที่ดีที่สุดสำหรับอินพุตด้านบนจะเป็น201:

|    --> || --> |||     |||
||||     |      ||      |||
||       ||     ||  --> |||

เกมนี้สามารถวางบล็อกได้อย่างง่ายดายแม้ว่าจะมีตัวเลขบางตัว แต่การตั้งค่าบางอย่างนั้นไม่สามารถแก้ไขได้

ความท้าทาย

เมื่อได้รับลำดับของระดับบล็อกให้ส่งกลับความถี่ที่แต่ละบล็อคต้องสัมผัสเพื่อไขปริศนา เช่นตัวอย่างข้างต้นจะได้รับ142และสามารถให้201ผล หากไม่มีวิธีแก้ปัญหาให้ส่งคืนผลลัพธ์ที่คุณเลือกที่สอดคล้องซึ่งสามารถแยกได้จากโซลูชันที่อาจเกิดขึ้นทั้งหมด-1หรือสตริงว่าง

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

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

นี่คือรหัสกอล์ฟดังนั้นคำตอบที่สั้นที่สุด (เป็นไบต์) ชนะ

ตัวอย่าง

การแก้ปัญหาไม่ใช่เรื่องแปลกดังนั้นคุณอาจได้ผลลัพธ์ที่แตกต่างกัน

Input                          Output

1                              0
11                             00
12                             No solution
142                            201
434                            101
222                            000
4113                           0230
32444                          No solution
23432                          10301
421232                         212301
3442223221221422412334         0330130000130202221111
22231244334432131322442        No solution
111111111111111111111222       000000000000000000000030
111111111111111111111234       100100100100100100100133
412224131444114441432434       113013201011001101012133

เท่าที่ฉันรู้มีโซลูชั่น 4 ข้อสำหรับแต่ละอินพุตที่จำนวนบล็อกคือ 0 mod 3 หรือ 1 mod 3 และมี 0 หรือ 16 โซลูชันซึ่งเป็น 2 mod 3


คุณต้องการแสดงทางออกที่ดีที่สุดหรือไม่?
xnor

@xnor ไม่คุณทำไม่ได้
Martin Ender

เราต้องพิมพ์วิธีการแก้ปัญหาเดียวหรือเราสามารถพิมพ์ทั้งหมดหรือไม่
Jakube

@ Jakube หนึ่งโปรด ฉันควรจะเพิ่มโบนัสสำหรับทุก / ทางออกที่ดีที่สุด แต่ฉันไม่ได้คิดว่าเร็วพอดังนั้นวิธีการแก้ปัญหาใด ๆ (หนึ่ง)
Martin Ender

คำตอบ:


10

Python 2, 115 ไบต์

n=input()
for F in range(4):
 t=[F];b=0;exec"x=(-n[b]-sum(t[-2:]))%4;t+=x,;b+=1;"*len(n)
 if x<1:print t[:-1];break

นี่เป็นโปรแกรมรุ่นที่ฉันเขียนขณะคุยเรื่องปัญหากับ Martin

อินพุตเป็นรายการผ่าน STDIN เอาท์พุทเป็นรายการที่แสดงถึงการแก้ปัญหาล่าสุดที่พบว่ามีวิธีการแก้ปัญหาหรือศูนย์ถ้าไม่มี ตัวอย่างเช่น:

>>>
[1, 4, 2]
[2, 1, 1]
>>>
[1, 2]
0
>>>
map(int,"3442223221221422412334")
[2, 3, 3, 2, 1, 3, 2, 0, 0, 2, 1, 3, 2, 2, 0, 0, 2, 2, 3, 1, 1, 3]

Pyth, 32 29 ไบต์

V4J]NVQaJ%_+s>J_2@QN4)I!eJPJB

พอร์ตบังคับ ขอบคุณ @Jakube สำหรับการบันทึก 3 ไบต์

วิธีการป้อนข้อมูลเป็นเช่นเดียวกับข้างต้นลองออนไลน์


คำอธิบาย (ยาวและเต็มไปด้วยตรรกะ!)

ครั้งแรกที่สองข้อสังเกตพื้นฐาน:

  • การสังเกต 1:มันไม่สำคัญว่าคุณจะแตะบล็อกไหน

  • การสังเกตที่ 2:ถ้าคุณสัมผัสบล็อก 4 ครั้งมันเทียบเท่ากับการสัมผัสหนึ่งครั้ง

กล่าวอีกนัยหนึ่งหากมีวิธีการแก้แล้วมีวิธีแก้ปัญหาที่จำนวนสัมผัสอยู่ระหว่าง 0 และ 3 รวม

เนื่องจากโมดูโล่ 4 นั้นดีมากเรามาทำกับบล็อกด้วย สำหรับคำอธิบายที่เหลือบล็อกระดับ 0 เทียบเท่ากับบล็อกระดับ 4

ทีนี้เราa[k]มาดูกันว่าระดับของบล็อกในปัจจุบันkและx[k]เป็นจำนวนครั้งที่เราสัมผัสบล็อคkในโซลูชัน ยังให้nเป็นจำนวนรวมของบล็อก ดังที่ @Jakube ได้ระบุไว้วิธีการแก้ปัญหาต้องเป็นไปตาม:

  a[0]   + x[0] + x[1]
= a[1]   + x[0] + x[1] + x[2]
= a[2]          + x[1] + x[2] + x[3]
= a[3]                 + x[2] + x[3] + x[4]
...
= a[n-1]                                     ...  + x[n-2] + x[n-1] + x[n]
= a[n]                                       ...           + x[n-1] + x[n]
= C

ซึ่งCเป็นระดับสุดท้ายบล็อกทั้งหมดจบลงระหว่าง 0 และ 3 รวม (จำไว้ว่าเรากำลังรักษาระดับ 4 เป็นระดับ 0) และสมการข้างต้นทั้งหมดเป็น congruences modulo 4 จริง ๆ

ตอนนี้นี่คือส่วนที่สนุก:

  • สังเกต 3 : หากการแก้ปัญหาที่มีอยู่, 0 <= C <= 3การแก้ปัญหาที่มีอยู่ในระดับบล็อกใด

มีสามกรณีขึ้นอยู่กับจำนวนของบล็อกโมดูโล 3 คำอธิบายสำหรับแต่ละของพวกเขาจะเหมือนกัน - สำหรับจำนวนของบล็อกใด ๆ ที่มีอยู่ส่วนหนึ่งของบล็อกซึ่งถ้าคุณสัมผัสแต่ละคนครั้งเดียวเพิ่มระดับบล็อกทั้งหมดโดย 1.

0 mod 3 (touch every third block starting from the second):
    .X. / .X. / .X.

1 mod 3 (touch every third block starting from the first):
    X. / .X. / .X. / .X

2 mod 3 (touch every third block starting from either the first or second):
    X. / .X. / .X. / .X.
    .X. / .X. / .X. / .X

นี้อธิบายว่าทำไมมี 4 โซลูชั่นสำหรับการ0 mod 3และ1 mod 3และมักจะ 16 2 mod 3โซลูชั่นสำหรับ หากคุณมีวิธีแก้ไขปัญหาอยู่แล้วการสัมผัสบล็อกดังกล่าวจะเป็นการแก้ปัญหาอื่นซึ่งจบลงที่ระดับบล็อกที่สูงขึ้น (ล้อมรอบ)

ดังนั้นสิ่งนี้หมายความว่าอย่างไร เราสามารถเลือกระดับบล็อกสุดท้ายที่Cเราต้องการได้! มาเลือกC = 0กันเพราะจะช่วยประหยัดเป็นไบต์

ตอนนี้สมการของเรากลายเป็น:

0 = a[0] + x[0] + x[1]
0 = a[1] + x[0] + x[1] + x[2]
0 = a[2] + x[1] + x[2] + x[3]
0 = a[3] + x[2] + x[3] + x[4]
...
0 = a[n-1] + x[n-2] + x[n-1] + x[n]
0 = a[n] + x[n-1] + x[n]

และจัดเรียงใหม่:

x[1] = -a[0] - x[0]
x[2] = -a[1] - x[0] - x[1]
x[3] = -a[2] - x[1] - x[2]
x[4] = -a[3] - x[2] - x[3]
...
x[n] = a[n-1] - x[n-2] - x[n-1]
x[n] = a[n] - x[n-1]

ดังนั้นสิ่งที่เราเห็นคือถ้าเรามีx[0]แล้วเราสามารถใช้สมการทั้งหมดยกเว้นอันสุดท้ายเพื่อหาx[k]กัน สมการสุดท้ายเป็นเงื่อนไขเพิ่มเติมที่เราต้องตรวจสอบ

สิ่งนี้ทำให้เรามีอัลกอริทึม:

  • ลองใช้ค่าทั้งหมดสำหรับ x[0]
  • ใช้สมการข้างต้นเพื่อหาผลเฉลยอื่น ๆ ทั้งหมด x[k]
  • ตรวจสอบว่าเงื่อนไขสุดท้ายเป็นที่พอใจ ถ้าเป็นเช่นนั้นบันทึกวิธีแก้ปัญหา

ที่ให้ทางออกข้างต้น

ดังนั้นทำไมบางครั้งเราถึงไม่มีทางออก2 mod 3? ลองดูที่สองรูปแบบเหล่านี้อีกครั้ง:

X. / .X. / .X. / .X.
.X. / .X. / .X. / .X

ทีนี้ลองพิจารณาสมการที่ตำแหน่งเหล่านั้นเช่นสำหรับอันแรก:

0 = a[0] + x[0] + x[1]
0 = a[3] + x[2] + x[3] + x[4]
0 = a[6] + x[5] + x[6] + x[7]
0 = a[9] + x[8] + x[9] + x[10]

เพิ่มขึ้น:

0 = (a[0] + a[3] + a[6] + a[9]) + (x[0] + x[1] + ... + x[9] + x[10])

สำหรับคนที่สอง:

0 = a[1] + x[0] + x[1] + x[2]
0 = a[4] + x[3] + x[4] + x[5]
0 = a[7] + x[6] + x[7] + x[8]
0 = a[10] + x[9] + x[10]

เพิ่มขึ้นอีกครั้ง:

0 = (a[1] + a[4] + a[7] + a[10]) + (x[0] + x[1] + ... + x[9] + x[10])

ดังนั้นหาก(a[1] + a[4] + a[7] + a[10])และ(a[0] + a[3] + a[6] + a[9])ไม่เท่ากันเราก็ไม่มีทางออก แต่ถ้าพวกมันเท่ากันเราจะได้คำตอบ 16 ข้อ สำหรับn = 11กรณีนี้ แต่แน่นอนว่านี่เป็นการสรุปจำนวนใด ๆ นั่นคือ2 mod 3- นำผลรวมของทุกองค์ประกอบที่สามเริ่มต้นจากที่สองและเปรียบเทียบกับผลรวมขององค์ประกอบที่สามที่เริ่มต้นจากที่หนึ่ง

ในที่สุดก็เป็นไปได้หรือไม่ที่จะคิดออกว่าx[0]จะต้องทำอะไรแทนที่จะเป็นไปได้ทั้งหมด? ท้ายที่สุดเนื่องจากเรา จำกัด ระดับเป้าหมายของเราCเป็น 0 จึงมีเพียงระดับเดียวเท่านั้นx[0]ที่ให้วิธีแก้ปัญหาในกรณี0 mod 3หรือ1 mod 3(ตาม4 solutions / 4 final levels = 1 solution for a specific final level)

คำตอบคือ ... ใช่! เราสามารถทำสิ่งนี้เพื่อ0 mod 3:

 .X..X
.X..X.

ซึ่งแปลเป็น:

0 = a[2] + x[1] + x[2] + x[3]   -> 0 = (a[2] + a[5]) + (x[1] + ... + x[5])
0 = a[5] + x[4] + x[5]          /


0 = a[1] + x[0] + x[1] + x[2]   -> 0 = (a[1] + a[4]) + (x[0] + x[1] + ... + x[5])
0 = a[4] + x[3] + x[4] + x[5]   /

การลบให้:

x[1] = (a[2] + a[5]) - (a[1] + a[4])

ในทำนองเดียวกันสำหรับ1 mod 3เราสามารถทำรูปแบบนี้:

 .X..X.
X..X..X

ซึ่งจะช่วยให้:

x[0] = (a[2] + a[5]) - (a[0] + a[3] + a[6])

หลักสูตรเหล่านี้พูดคุยโดยการขยายดัชนีโดยเพิ่มทีละ 3

สำหรับ2 mod 3เนื่องจากเรามีชุดย่อยสองชุดที่ครอบคลุมทุกบล็อคเราจึงสามารถเลือกx[0]ได้ ในความเป็นจริงนี้เป็นจริงสำหรับx[0], x[1], x[3], x[4], x[6], x[7], ...(โดยทั่วไปดัชนีใด ๆ ไม่สอดคล้องกัน2 mod 3ตามที่พวกเขาจะไม่ครอบคลุมโดยส่วนย่อยทั้งสอง)

ดังนั้นเราจึงมีวิธีเลือกx[0]แทนที่จะพยายามเป็นไปได้ทั้งหมด ...

... แต่ข่าวร้ายก็คือว่ามันไม่ได้บันทึกเป็นไบต์ (124 ไบต์):

def f(n):s=[];L=len(n);B=sum(n[~-L%3::3])-sum(n[-~L%3::3]);x=A=0;exec"s+=B%4,;A,B=B,-n[x]-A-B;x+=1;"*L*(L%3<2or B<1);print s

ฉลาด. คุณสามารถบันทึก 1 อักขระโดยใช้JแทนHและ 2 ตัวอักษรหากคุณปรากฏองค์ประกอบสุดท้ายPJแทนการแบ่งส่วน <J_1. V4J]NVQaJ%_+s>J_2@QN4)I!eJPJB
Jakube

@Jakube Ah ขอบคุณ เมื่อฉันอ่านป๊อปฉันคิดว่ามันเหมือนกับ Python pop ที่ส่งคืนองค์ประกอบสุดท้ายในขณะที่ลบออกจากรายการ ตอนนี้ฉันเห็นว่าไม่ใช่กรณี
Sp3000

4

Pyth, 72 76 73 66 39 38 ตัวละคร

Ph+f!eTmu+G%+&H@G_3-@QH@QhH4UtQd^UT2]Y

แก้ไข 4:ตระหนักว่าการคำนวณQ[N]-Q[N+1]+solution[-3]และQ[-2]-Q[-1]+solution[-3]ระบุ ดังนั้นฉันคำนวณมากเกินไปแก้ปัญหาโดย 1 และกรองการแก้ปัญหาที่รายการสุดท้ายคือ 0 จากนั้นฉันป๊อปอัพรายการสุดท้าย โชคดีที่กรณีพิเศษไม่ต้องการการดูแลเป็นพิเศษด้วยวิธีนี้ อักขระ -27

แก้ไข 3:ใช้เทคนิคการตีกอล์ฟจาก FryAmTheEggman: -7 ตัวอักษร

แก้ไข 2:การใช้ตัวกรอง, ลดและแผนที่: ตัวละคร -3

แก้ไข 1:ในรุ่นแรกของฉันฉันไม่ได้พิมพ์อะไรเลยถ้าไม่มีวิธีแก้ปัญหา ฉันไม่คิดว่ามันจะได้รับอนุญาตดังนั้นตัวละคร +4

คาดว่ารายชื่อของจำนวนเต็มเป็นใส่[1,4,2]และผลการแก้ปัญหาที่ถูกต้องถ้ามีคนมิฉะนั้นรายการที่ว่างเปล่า[2,0,1][]

คำอธิบาย:

อนุญาตQเป็นรายการ 5 ระดับและYรายการวิธีแก้ปัญหา สมการต่อไปนี้ต้องถือ:

  Q0 + Y0 + Y1 
= Q1 + Y0 + Y1 + Y2
= Q2      + Y1 + Y2 + Y3
= Q3           + Y2 + Y3 + Y4
= Q4                + Y3 + Y4

ดังนั้นถ้าเราใช้ใด ๆY0และY1เราสามารถคำนวณY2, Y3และY4ในทางดังต่อไปนี้

Y2 = (Q0 - Q1     ) mod 4
Y3 = (Q1 - Q2 + Y0) mod 4
Y4 = (Q2 - Q3 + Y1) mod 4

กว่าทุกระดับที่ผ่านมามีระดับเท่ากัน (เพราะเราไม่ได้ใช้สมการ= Q4 + Y3 + Y4เพื่อตรวจสอบว่าอันสุดท้ายนี้เท่ากับระดับอื่น ๆ หรือไม่เราสามารถตรวจสอบได้(Q3 - Q4 + Y2) mod 4 == 0) สังเกตว่าส่วนที่เหลือจะเป็นค่าY5ถ้าฉันคำนวณส่วนที่ 6 ของการแก้ปัญหาฉันสามารถตรวจสอบได้ว่าเป็นศูนย์หรือไม่

ในแนวทางของฉันฉันเพียงแค่วนซ้ำไปตามการเริ่มต้นที่เป็นไปได้ทั้งหมด ( [0,0], ถึง[3,3]) และคำนวณความยาว (อินพุต) -1 รายการเพิ่มเติมและกรองโซลูชันทั้งหมดที่ลงท้ายด้วยศูนย์

mu+G%+&H@G_3-@QH@QhH4UtQd^UT2   generates all possible solutions

มันเป็นพื้นต่อไปนี้:

G = start value           //one of "^UT2", [0,0], [0,1], ..., [9,9]
                          //up to [3,3] would be enough but cost 1 char more
for H in range(len(Q)-1): //"UtQ"
   G+=[(H and G[-3])+(Q(H)-Q(H+1))%4] //"+G%+&H@G_3-@QH@QhH4"
   //H and G[-3] is 0, when H is empty, else G[-3]

จากนั้นฉันกรองโซลูชันที่เป็นไปได้เหล่านี้สำหรับรายการที่ถูกต้อง:

f!eT //only use solutions, which end in 0

ในรายการโซลูชันนี้ฉันจะเพิ่มรายการว่างเพื่อเพิ่มรายการนั้นอย่างน้อยหนึ่งรายการ

 +....]Y

และใช้วิธีแก้ปัญหาแรกhปรากฏองค์ประกอบสุดท้ายpและพิมพ์

 Ph

โปรดสังเกตว่าสิ่งนี้ยังใช้งานได้หากมีบล็อกเดียวเท่านั้น ในแนวทางของฉันฉันได้รับตำแหน่งเริ่มต้น [0,0] และไม่ขยายออก เนื่องจากรายการสุดท้ายคือ 0 จึงพิมพ์วิธีแก้ไข [0]

กรณีพิเศษที่สอง (2 ช่วงตึก) นั้นไม่พิเศษเลย ไม่แน่ใจว่าทำไมก่อนหน้านี้ฉันจึงซับซ้อนเกินไป


ฉันคิดว่าการพิมพ์ไม่เป็นไรหากไม่มีวิธีแก้ปัญหาหากเป็นกรณีเดียวที่คุณไม่พิมพ์อะไรเลย อาจต้องได้รับ @ MartinBüttnerเพื่อยืนยันว่า
Sp3000

?**lQ]0qhQeQ<lQ3h+f!%-+ePQ@T_3eQ4mu+G]%+&H@G_3-@QH@QhH4UttQd^UT2]Yคือ 66 ไบต์ การแสดงนั้นออกมาเล็กน้อย แต่มันก็ยังคงเป็นกรณีทดสอบที่ใหญ่ที่สุดใน <1 วินาทีสำหรับฉัน ปิงฉันถ้าคุณต้องการคำอธิบายของสนามกอล์ฟ; มีพื้นที่ไม่เพียงพอในความคิดเห็นนี้;) หวังว่าคุณจะเพลิดเพลินกับการใช้
Pyth

+<list><int>มีผลเหมือนกับ+<list>]<int>คุณจึงสามารถลบออกก่อน]ได้ นอกจากนี้ทางออกที่ดีมาก
isaacg

@isaacg เหมือนกันจริง~หรือ? ดูเหมือนจะไม่เป็นเมื่อฉันพยายาม
Sp3000

@ SP3000 เพียงแทนที่~ด้วยa- เทียบเท่ากับ~<list>]<int> คือในขณะที่isa<list><int>~+=a.append()
isaacg

3

Ruby, 320 313 ตัวอักษร

m=gets.chop.chars.map{|x|x.to_i-1}
a=m.map{0}
t=->n{m[n]+=1
m[n-1]+=1if n>0
m[n+1]+=1if n<m.size-1
m.map!{|x|x%4}
a[n]=(a[n]+1)%4}
t[0]until m[0]==1
(2...m.size).map{|n|t[n]until m[n-1]==1}
r=0
while m.uniq.size>1&&m[-1]!=1
(0...m.size).each_with_index{|n,i|([1,3,0][i%3]).times{t[n]}}
(r+=1)>5&&exit
end
$><<a*''

สามารถตีกอล์ฟได้มากกว่านี้อย่างแน่นอน แสดงผลใด ๆ สำหรับปริศนาที่แก้ไม่ตก

เวอร์ชันที่ไม่ถูกปรับแต่ง:

#!/usr/bin/ruby

nums = gets.chomp.chars.map {|x| x.to_i-1 }
touches = nums.map {0}

# our goal: make all the numbers 1
# utility function
touch = ->n {
    nums[n] += 1
    nums[n-1] += 1 if n > 0
    nums[n+1] += 1 if n < (nums.length-1)
    nums.map! {|x| x % 4 }
    touches[n] = (touches[n] + 1) % 4
}

# first, start with the very first number
touch[0] until nums[0] == 1

# then, go from index 2 to the end to make the previous index right
(2...nums.length).each {|n|
    touch[n] until nums[n-1] == 1
}

iters = 0
if nums.uniq.length != 1
    # I have no idea why this works
    while nums[-1] != 1
        (0...nums.length).each_with_index {|n, i|
            ([1, 3, 0][i % 3]).times { touch[n] }
        }
        if (iters += 1) > 5
            puts -1
            exit
        end
    end
end

puts touches * ''

โอเคอันนี้สนุกแล้ว นี่คืออัลกอริธึมพื้นฐานโดย{n}แสดง n "touch" es บนหมายเลขด้านบนnดังที่แสดงในตัวอย่างหนึ่งตัวอย่าง:

we want each number to be a 1
first make the first number a 1
3442223221221422412334
2}
1242223221221422412334
 {3} now keep "touch"ing until the number to the left is a 1
1131223221221422412334
  {2}
1113423221221422412334
   {2}
1111243221221422412334
... (repeat this procedure)
1111111111111111111110

ฉันนิ่งงันมานิดนึง ฉันจะเปลี่ยน111...1110เป็นชุดหมายเลขเดียวกันได้อย่างไร ดังนั้นฉันจึงเปรียบเทียบโซลูชันของฉันกับโซลูชันที่ถูกต้อง (หมายเหตุ: การนับ "สัมผัส" ทั้งหมดมีค่ามากกว่าที่ควรจะเป็นเพราะอินพุตมีการจัดทำดัชนี 1 ขณะที่เอาต์พุตเป็น 0 ดัชนี):

3033233103233301320210
0330130000130202221111

ฉันสังเกตเห็นว่าแต่ละหมายเลขอยู่ห่างจากหมายเลขที่ถูกต้องmod 4ดังนั้นฉันจึงทำเครื่องหมายด้วย+s, -s และ=s:

3033233103233301320210 original program output
+-=+-=+-=+-=+-=+-=+-=+ amount to modify by (+1, -1, or 0 (=))
4334534404534602621511 result (the correct answer)

0330130000130202221111 (the original solution, digits equal to result mod 4)

ที่ทำงานในขณะที่จนผมสังเกตเห็นว่าบางครั้งผลสุดท้ายเป็น111...11112หรือ11...1113เช่นกัน! โชคดีที่ใช้สูตรเวทย์มนตร์ซ้ำ ๆ ที่ไม่สมเหตุสมผล แต่ก็ใช้งานได้เช่นกัน

ดังนั้นคุณมีมัน โปรแกรมที่เริ่มมีเหตุผล แต่ลดระดับลงไปสู่ความแฮ็คที่น่าเกลียดมากขึ้นเรื่อย ๆ ฉันคิดว่าเป็นเรื่องธรรมดาสำหรับรหัสกอล์ฟ :)


1
ฉันชอบความคิดเห็นล่าสุดในรหัสของคุณ :) คุณสามารถบันทึกตัวอักษร 2 โดยการเปลี่ยนไปexit if (r+=1)>5 (r+=1)>5&&exitนอกจากนี้ไวยากรณ์สั้นกว่า(code)while cond while cond \n code \n end
Cristian Lupascu

2

Python 2, 294,289,285,281 273 ไบต์

n=input();l=len(n);s=[0]*l
for i in range(2,l):
 a=(n[i-2]-n[i-1])%4;s[i]+=a;n[i-1]+=a;n[i]+=a
 if i+1<l:n[i+1]+=a
 n=[a%4for a in n]
if l%3>1 and n!=[n[0]]*l:print"x"
else:
 for i in range(l%3,l-1,3):s[i]+=(n[l-1]-n[l-2])%4
 m=min(s);s=[(a-m)%4 for a in s];print s

การสาธิต

ฉันแน่ใจว่านี้สามารถเล่นกอล์ฟต่อไป ..

นี่คือผลลัพธ์จากกรณีทดสอบ:

[1]
-> [0]

[1,1]
-> [0, 0]

[1,2]
-> x

[1,4,2]
-> [2, 0, 1]

[4,3,4]
-> [1, 0, 1]

[2,2,2]
-> [0, 0, 0]

[4,1,1,3]
-> [0, 2, 3, 0]

[3,2,4,4,4]
-> x

[2,3,4,3,2]
-> [0, 0, 3, 3, 1]

[4,2,1,2,3,2]
-> [2, 0, 2, 3, 3, 1]

[3,4,4,2,2,2,3,2,2,1,2,2,1,4,2,2,4,1,2,3,3,4]
-> [0, 3, 3, 0, 1, 3, 0, 0, 0, 0, 1, 3, 0, 2, 0, 2, 2, 2, 1, 1, 1, 1]

[2,2,2,3,1,2,4,4,3,3,4,4,3,2,1,3,1,3,2,2,4,4,2]
-> x

[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2]
-> [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0]

[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,3,4]
-> [1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 3, 3]

[4,1,2,2,2,4,1,3,1,4,4,4,1,1,4,4,4,1,4,3,2,4,3,4]
-> [1, 0, 3, 0, 0, 3, 2, 3, 1, 0, 0, 1, 0, 3, 1, 1, 3, 1, 0, 0, 2, 1, 2, 3]

อัลกอริทึมแรกทำให้แน่ใจว่าค่าของบล็อกทั้งหมดยกเว้นบล็อกสุดท้ายจะเหมือนกัน (โดยวนซ้ำและเพิ่มใน "จำนวนสัมผัส" ของบล็อกทั้งหมดยกเว้น 2 แรก) จากนั้นหากจำนวนบล็อกอนุญาตให้มัน ( (num_of_blocks - 1) % 3 != 1) กลับไปและตรวจสอบให้แน่ใจว่าค่าของบล็อกที่เหลือตรงกับบล็อกสุดท้าย พิมพ์xหากไม่มีวิธีแก้ไข

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