การค้นหากำลังเดินสแควร์


9

Marching Squaresเป็นอัลกอริธึมจากคอมพิวเตอร์กราฟิกส์ซึ่งใช้ในการกู้คืน isocontours 2D จากตารางตัวอย่าง (ดูเพิ่มเติมที่Marching Cubes Cubesสำหรับการตั้งค่า 3D) แนวคิดคือการประมวลผลแต่ละเซลล์ของกริดอย่างอิสระและกำหนดรูปทรงที่ส่งผ่านเซลล์นั้นตามค่าที่มุมของมัน

ขั้นตอนแรกในกระบวนการนี้คือการกำหนดว่าขอบใดที่เชื่อมต่อกันด้วยรูปทรงโดยพิจารณาจากมุมที่สูงหรือต่ำกว่าค่าของเส้นขอบ เพื่อความง่ายเราจะพิจารณาเฉพาะส่วนที่มีค่าตามรูปร่าง0ซึ่งเราสนใจว่ามุมนั้นเป็นมุมบวกหรือลบ มีหลายกรณีที่จะแยกแยะ:24 = 16

ป้อนคำอธิบายรูปภาพที่นี่
แหล่งที่มาของภาพ: Wikipedia

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

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

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

ความท้าทาย

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

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

อินพุตอาจถูกใช้ในรูปแบบสตริงหรือรายการที่สะดวก

16 รายจะถูกนำเสนอในรูปแบบ ASCII โดยใช้บล็อก 5x5 อย่างใดอย่างหนึ่งต่อไปนี้:

o---o  o---o  o---o
|   |  |   |  | | |
|   |  |---|  | | |
|   |  |   |  | | |
o---o  o---o  o---o

o---o  o---o  o---o  o---o
|/  |  |  \|  |   |  |   |
|   |  |   |  |   |  |   |
|   |  |   |  |\  |  |  /|
o---o  o---o  o---o  o---o

o---o  o---o
|/  |  |  \|
|   |  |   |
|  /|  |\  |
o---o  o---o

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

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

กรณีทดสอบ

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

[1, 2, 1, 3]
[-9, -2, -2, -7]

[4, 5, -1, -2]
[-1, -2, 3, 4]

[7, -7, 7, -7]
[-5, 5, -5, 5]

[1, -6, -4, -1]
[-2, 3, 3, 4]

[-1, 6, -4, -1]
[2, -3, 3, 4]   

[-1, -6, 4, -1]
[2, 3, -3, 4]

[-1, -6, -4, 1]
[2, 3, 3, -4]

[3, -8, -9, 2]
[-3, 8, 9, -2]

[8, -3, -2, 9]
[-8, 3, 2, -9]

นอกจากนี้กรณีทดสอบต่อไปนี้อาจส่งคืนจุดอาน (ทั้งตัวเลือก):

[1, -4, -2, 5]
[-1, 4, 2, -5]

คำตอบ:


5

ทับทิม, 201 180 176

นี่คือฟังก์ชั่นแลมบ์ดานิรนามที่จะถูกเรียกในแบบที่แสดงในตัวอย่างที่ไม่ดี

sนี้มีตัวแปรไม่มี ในเวอร์ชันที่ไม่ได้ลงนามนิพจน์ที่ซับซ้อนจะถูกกำหนดให้sเพื่อความชัดเจนก่อนที่จะใช้ 4 ไบต์จะถูกบันทึกไว้ในเวอร์ชัน golfed โดยวางไว้ในบรรทัด ข้อแตกต่างอื่น ๆ ระหว่างรุ่นคือช่องว่างและข้อคิดเห็น

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

->a{p=t=0
4.times{|i|t+=a[i]*=a[3];p+=a[i]>>9&1<<i}
q=p==6&&t>0?19:'@AC@P*10'[p].ord
puts c='o---o',(0..2).map{|i|b=p*i==3?'|---|':'|   |';b[q%4]='|/|\|/'[q%4+(i&2)];q/=4;b},c}

ฉันมีความสุขกับการแยกอาร์เรย์ แต่ฉันคิดว่าอาจมีวิธีที่สั้นกว่าในการสร้างเอาต์พุต

องค์ประกอบทั้งสี่ของอาร์เรย์ที่ป้อนเข้าจะถูกคูณด้วยองค์ประกอบสุดท้าย สิ่งนี้รับประกันได้ว่าองค์ประกอบสุดท้ายเป็นบวกและลดจำนวนคดีจาก 16 ลงเหลือ 8 องค์ประกอบได้รับการเลื่อนตำแหน่ง 9 ตำแหน่งเพื่อให้ตัวเลขบวกทั้งหมดกลายเป็น 0 และจำนวนลบทั้งหมดกลายเป็น -1 (อย่างน้อยในช่วงของอินพุต ที่ได้รับในกรณีทดสอบ) จากนั้นพวกเขาจะได้รับ1<<array indexเลขฐานสอง 3 บิตเพื่อระบุรูปแบบ (จริง ๆ แล้ว 4 บิต แต่เนื่องจากองค์ประกอบสุดท้ายเป็นบวกเสมอบิตที่ 4 จะเป็นศูนย์เสมอ)

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

วิธีการแสดงผลของเอาต์พุตนั้นชัดเจนจากความคิดเห็นในโค้ด

ungolfed ในโปรแกรมทดสอบ

f=->a{p=t=0
  4.times{|i|                      #for each number in the input
    t+=a[i]*=a[3];                   #multiply each number by a[3]; totalize the sum in t
    p+=a[i]>>9&1<<i                  #shift right to find if negative; AND with 1<<i to build index number for pattern 
  }                                #q is a 3-digit base 4 number indicating which character of each line is non-whitespace (if any). 
  q=p==6&&t>0?19:'@AC@P*10'[p].ord #It's encoded in the magic string, except for the case of saddles with a positive total, which is encoded by the number 19.
  s=(0..2).map{|i|                 #build an array of 3 strings, indexes 0..2
    b=p*i==3?'|---|':'|   |';        #IF p is 3 and we are on row 1, the string is |---| for the horizontal line case. ELSE it is |   |.
    b[q%4]='|/|\|/'[q%4+(i&2)];      #The numbers in q indicate which character is to be modified. The characters in the string indicate the character to replace with.
    q/=4;                            #If q%4=0, the initial | is replaced by | (no change.) i&2 shifts the string index appropriately for the last row.
    b                                #divide q by 4, and terminate the loop with the expression b so that this is the object loaded into array s.  
  }
puts c='o---o',s,c}                #print the array s, capped with "o---o" above and below.


[[1, 2, 1, 3],
[-9, -2, -2, -7],

[4, 5, -1, -2],
[-1, -2, 3, 4],

[7, -7, 7, -7],
[-5, 5, -5, 5],

[1, -6, -4, -1],
[-2, 3, 3, 4],

[-1, 6, -4, -1],
[2, -3, 3, 4],

[-1, -6, 4, -1],
[2, 3, -3, 4],

[-1, -6, -4, 1],
[2, 3, 3, -4],

[3, -8, -9, 2],
[-3, 8, 9, -2],

[8, -3, -2, 9],
[-8, 3, 2, -9],

[1, -4, -2, 5],
[-1, 4, 2, -5]].each{|k|f.call(k)}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.