ยืดอาร์เรย์


13

ก่อนหน้านี้ฉันกำหนดกระบวนการในการบดขยี้อาร์เรย์

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

ตัวอย่างเช่นที่นี่เป็นกระบวนการของการบดขยี้อาร์เรย์ต่อไปนี้

[5,2,2,4]
 ^
[5,2,2,4]
   ^
[5,2,2,4]
     ^
[5,4,4]
   ^
[5,4,4]
     ^
[5,8]
   ^

โปรดทราบว่าองค์ประกอบเดียวกันสามารถยุบได้หลายครั้ง ในตัวอย่าง2,2,4ถูกยุบลง8ในรอบเดียว

ตอนนี้การบดย่อยอาร์เรย์เป็นเรื่องง่ายอะไรที่ยากคือการบดขยี้พวกเขา งานของคุณคือการใช้อาร์เรย์ของจำนวนเต็มบวกเป็นอินพุทและเอาท์พุทอาเรย์ที่ใหญ่ที่สุดที่สามารถสร้างรูปแบบการป้อนข้อมูลเมื่อบดซ้ำ ๆ ยกตัวอย่างเช่นอาร์เรย์[4]จะเกิดขึ้นโดยเด็ดขาดซึ่งเป็นในทางกลับกันที่เกิดขึ้นจากการบด[2,2] [1,1,1,1]เนื่องจากเราไม่สามารถมีค่าที่ไม่ใช่จำนวนเต็ม[1,1,1,1]ไม่สามารถ unrushed ใด ๆ เพิ่มเติมและเป็นคำตอบของเรา

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

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

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

กรณีทดสอบ

[] -> []
[5] -> [5]
[6] -> [3,3]
[8] -> [1,1,1,1,1,1,1,1]
[4,8] -> [1,1,1,1,1,1,1,1,1,1,2]
[2,8] -> [1, 1, 1, 1, 2, 1, 1, 1, 1]
[4,4] -> [1,1,1,1,1,1,1,1]

1
ขออภัย แต่ฉันยังไม่เข้าใจกฎ ทำไม[1,1,1,1,1,1,1,1,1,1,2]ผลิต[4, 8]แทน[8, 4]? นี้ควรจะเป็น[1,>1,1,1,1,1,1,1,1,1,2], [2,1,>1,1,1,1,1,1,1,2], [2,>2,1,1,1,1,1,1,2], [4,1,>1,1,1,1,1,2], [4,2,1,>1,1,1,2], [4,2,>2,1,1,2], [4,>4,1,1,2], [8,1,>1,2], [8,2,>2], [8,4]?
tsh

2
@tsh ฉันคิดว่าคุณมีความเข้าใจผิดในวิธีการทำงานที่บด นี่คือเส้นทางที่ใช้ในครั้งแรกผ่าน: [1,>1,1,1,1,1,1,1,1,1,2], [2,>1,1,1,1,1,1,1,1,2], [2,1,>1,1,1,1,1,1,1,2], [2,2,>1,1,1,1,1,1,2], [2,2,1,>1,1,1,1,1,2], [2,2,2,>1,1,1,1,2], [2,2,2,1,>1,1,1,2], [2,2,2,2,>1,1,2], [2,2,2,2,1,>1,2], [2,2,2,2,2,>2], [2,2,2,2,4>], [2,>2,2,2,4]ผ่านที่สอง: [4,>2,2,4], [4,2,>2,4], [4,4,>4], [4,8>], หวังว่าจะล้างมันออก หากคุณต้องการรหัสเพื่อดูคำถามก่อนหน้านี้มีคำตอบที่ใช้ฟังก์ชั่นการบด
Ad Hoc Garf Hunter

มันจะโอเคไหมถ้าฉันเอาท์พุทตัวเลขแต่ละอันคั่นด้วยบรรทัดใหม่?
กอตติเนต์

@scottinet นั่นเป็นวิธีที่สมเหตุสมผลในการแสดงรายการ ไปข้างหน้า
Ad Hoc Garf Hunter

[4, 4]ควรลบกรณีทดสอบออกเนื่องจากเราไม่สามารถหาอาเรย์นั้นได้หลังจากลำดับการยืด => crush เนื่องจากมันจะจบลงด้วย[8]
scottinet

คำตอบ:


2

JavaScript (Node.js) , 237 221 213 186 ไบต์

f=a=>a.map(b=>{for(i=1;~b%2;b/=2)i*=2;return Array(i).fill(b)}).reduce((t,c,i,s)=>{b=c.slice();if(i)r=2*s[--i].length,b.length>=r&&b[0]==s[i][0]?b[r-2]+=b.pop():b;return t.concat(b)},[])

ลองออนไลน์!

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

ตัวอย่างเช่น

[1, 1, 1, 1, 1, 1]ให้[4,2]บดครั้งเดียว แต่[1, 1, 1, 1, 2]ผลลัพธ์ใน[2, 4]

ความท้าทายคือการกำหนดว่าควรวางตำแหน่งตัวบล็อกการบีบอัดเพื่อให้การเรียงลำดับผลลัพธ์เป็นผลลัพธ์ที่ถูกต้องหรือไม่:

  • ตัวบล็อกการบีบอัดจะต้องถูกวางไว้เฉพาะในกรณีที่หมายเลขที่ยืดออกก่อนหน้านี้เท่ากับจำนวนที่มีอยู่ในปัจจุบันและหากลำดับการยืดออกในปัจจุบันนั้นดีกว่าครั้งก่อนมาก ตัวอย่างเช่น[2, 4]ต้องใช้ตัวบล็อกการบีบอัด (จำนวนที่ยืดคือ1ซ้ำและ[1, 1]สั้นกว่า[1,1,1,1]) แต่[4, 2]และ[2, 6]ไม่ต้องการ
  • หากเราเรียกnลำดับที่ยืดออกก่อนหน้านี้และหากเงื่อนไขข้างต้นได้รับการตรวจสอบแล้วลำดับปัจจุบันคือการทำซ้ำของnลำดับ ในการขัดจังหวะลำดับการบดของหมายเลขก่อนหน้าเราจำเป็นต้องวาง crush blocker ที่ส่วนท้ายของnลำดับที่สองของหมายเลขปัจจุบันเพื่อยืด ตัวอย่าง: [2, 8] => [(1, 1)=n, (1, 1) + (2) + (1, 1) + ...]หรือ[4, 8] => [(1, 1, 1, 1)=n, (1, 1, 1, 1) + (1, 1, 2) + ...]


1

Python 2 , 230 228 226 ไบต์

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

แก้ไข: -2 ไบต์โดยการลบifในฟังก์ชั่นหลัก

แก้ไข: -2 ไบต์โดยการลบวงเล็บเหลี่ยมที่ไม่จำเป็นออกสองตัว

lambda x:max((c(z[:],x),len(z),z)for z in b(sum(x)))[2]
def c(x,y):
 i=e=1
 while x[i:]:
	if x[~-i]==x[i]:del x[i];i-=1;x[i]*=2;e=2
	i+=1
 return x==y or~-e and c(x,y)
b=lambda s:[z+[-~i]for i in range(s)for z in b(s+~i)]+[[]]

ลองออนไลน์!

คำอธิบาย

หน้าที่หลักรับผิดชอบในการค้นหาวิธีแก้ไขที่เป็นไปได้ทั้งหมดและเลือกโซลูชันที่ยาวที่สุด

lambda x:max((c(z[:],x),len(z),z)for z in b(sum(x)))[2]

ฟังก์ชัน Crush, ตรวจสอบว่า y เท่ากับหนึ่งใน crushes หรือไม่

def c(x,y):
 i=e=1
 while x[i:]:
	if x[~-i]==x[i]:del x[i];i-=1;x[i]*=2;e=2
	i+=1
 return x==y or~-e and c(x,y)

สร้างพีชคณิตที่เป็นไปได้ทั้งหมดด้วยผลรวมที่กำหนด

b=lambda s:[z+[-~i]for i in range(s)for z in b(s+~i)]+[[]]

0

05AB1E , 41 37 ไบต์

vy[DÉ#2÷]DYQX©NoDU‹&sDV¸X∍sić·®·Íǝ}»,

ลองออนไลน์!

พอร์ตของโซลูชัน Javascript ของฉัน

คำอธิบาย:

vy                   for each member of the list
[DÉ#2÷]              divide by 2 until odd: stack = stretched value, N = iterations
DYQ                  stetched value equal to the previous one?
X©NoDU‹              previous size < current one? (+store the new size in X)
&                    AND on the 2 previous tests
sDV¸X∍s              build a list of the new stretched value repeated X times
                      (+store the new stetched value in Y)
ić·®·Íǝ}             if the previous tests are true:
                       reduce the result list size by 1
                       multiply by 2 the number at the crush block position
»,                   join by newline + print the list
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.