เมทริกซ์ติดตามเมทริกซ์ใด ๆ ผ่าน ... การแรสเตอร์บรรทัดของ Bresenham


12

แรงบันดาลใจจากนี้

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

เนื่องจาก Agatha เป็นศิลปินเธอรู้วิธีวาดลายเส้นในโปรแกรมแก้ไขภาพที่เธอโปรดปรานและอันหลังนั้นใช้อัลกอริธึมของ Bresenham ในการพล็อตไลน์ เธอยังตรวจสอบ Wikipedia และพบรหัสปลอม:

ป้อนคำอธิบายรูปภาพที่นี่

 function line(x0, y0, x1, y1)
     real deltax := x1 - x0
     real deltay := y1 - y0
     real deltaerr := abs(deltay / deltax)    // Assume deltax != 0 (line is not vertical),
           // note that this division needs to be done in a way that preserves the fractional part
     real error := 0.0 // No error at start
     int y := y0
     for x from x0 to x1 
         plot(x,y)
         error := error + deltaerr
         while error ≥ 0.5 then
             y := y + sign(deltay) * 1
             error := error - 1.0

(โปรดทราบว่ารหัสเทียมนี้ทำงานได้เฉพาะกับความลาดชันน้อยกว่า 1; สำหรับกริดสูงควรทำการรักษาที่คล้ายกัน แต่มีการวนซ้ำyดูส่วนนี้สำหรับทั้งสองกรณี)

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

งาน

รับเมทริกซ์Aให้คืนค่าผลรวมขององค์ประกอบที่อยู่บนเส้นทแยงมุมหลัก rasterised (จากซ้ายไปขวาล่าง) ที่ซึ่งหลังถูกกำหนดโดยอัลกอริธึมบรรทัดของ Bresenham นั่นคือสมมติว่าเมทริกซ์แทนตาราง m × nวาดเส้นบนตารางจาก A [1, 1] ถึง A [m, n] โดยใช้อัลกอริทึมของ Bresenham และนำผลรวมขององค์ประกอบทั้งหมดในบรรทัด โปรดสังเกตว่าสำหรับเมทริกซ์1 × NและN × 1เมทริกซ์ทั้งหมดจะกลายเป็นเส้นทแยงมุมของตัวเอง (เพราะนี่คือวิธีที่เราวาดเส้นจากองค์ประกอบแรกของแถวแรกไปยังองค์ประกอบสุดท้ายของแถวสุดท้าย)

อินพุต:เมทริกซ์จริง (อาจเป็นเมทริกซ์ขนาด 1 × 1เมทริกซ์แถวเมทริกซ์คอลัมน์หรือเมทริกซ์สี่เหลี่ยม) ผลลัพธ์:ตัวเลข

ทราบว่าบางแหล่งที่มา (e. ก. วิกิพีเดียของ pseudocode ด้านบน) ใช้ตรวจสอบสภาพerror≥0.5ในขณะที่แหล่งอื่น ๆ error>0.5ที่ใช้ คุณควรใช้เดิมหนึ่ง ( error≥0.5) แต่ถ้าทางเลือกerror>0.5จะสั้นกว่าในรหัสของคุณแล้วคุณจะได้รับอนุญาตให้ใช้มัน (ตั้งแต่นี้เป็นรหัสกอล์ฟ) แต่พูดถึงมันอย่างชัดเจน ดูกรณีทดสอบ 4

กฏท้าทาย

  • รูปแบบ I / O มีความยืดหยุ่น เมทริกซ์สามารถเป็นตัวเลขจำนวนหนึ่งที่คั่นด้วยช่องว่างคั่นด้วยการขึ้นบรรทัดใหม่หรืออาร์เรย์ของเวกเตอร์แถวหรืออาร์เรย์ของเวกเตอร์คอลัมน์ ฯลฯ
  • นี่คือดังนั้นคำตอบที่สั้นที่สุดในหน่วยไบต์ชนะ
  • กฎมาตรฐานจะใช้สำหรับคำตอบของคุณดังนั้นคุณจึงได้รับอนุญาตให้ใช้ STDIN / STDOUT ฟังก์ชัน / เมธอดพร้อมพารามิเตอร์ที่เหมาะสมและชนิดผลตอบแทนโปรแกรมเต็มรูปแบบ
  • ช่องโหว่เริ่มต้นเป็นสิ่งต้องห้าม

กรณีทดสอบ

  1. [[1,2,3],[4,5,6],[7,8,9]]→การ→การส่งออก:1+5+915

กรณีทดสอบ 1

  1. [[1,2,3,4],[5,6,7,8]]→การ→การส่งออก:1+2+7+818

กรณีทดสอบ 2

  1. [[1,2,3,4,5,6],[7,8,9,10,11,12],[13,14,15,16,17,18],[19,20,21,22,23,24]]→การ→การส่งออก:1+8+9+16+17+2475

กรณีทดสอบ 3

  1. [[1,2,3,4,5],[6,7,8,9,10]]1+2+8+9+10(โดยใช้เงื่อนไขข้อผิดพลาด) 30→เอาท์พุท:

กรณีทดสอบ 4

อย่างไรก็ตามถ้ามันสั้นกว่าที่จะใช้ความไม่เท่าเทียมที่เข้มงวด>ในโค้ดของคุณเอาต์พุตที่ได้รับอนุญาตคือ1+2+3+9+10=25แต่คุณควรพูดถึงมันแยกกัน

กรณีทดสอบ 5

  1. [[1,2,3],[4,5,6],[7,8,9],[10,11,12]]→การ→การส่งออก:1+5+8+1226

กรณีทดสอบ 5

  1. [[-0.3,0.5]]0.2→เอาท์พุท:

  2. [[3.1],[2.9]]6→เอาท์พุท:

  3. [[-5]]-5→เอาท์พุท:

ข้อมูลเพิ่มเติมเกี่ยวกับอัลกอริทึมของ Bresenham


[[1,2,3,4,5],[6,7,8,9,10]]กรณีทดสอบที่ขอ:
user202729

@ user202729 เพิ่มไว้เพื่อแก้ไขความกำกวม
Andreï Kostyrka

เราสามารถรับกรณีทดสอบที่สูงกว่ากว้างได้ไหม กดไลค์[[1,2],[3,4],[5,6],[7,8],[9,10]]
จูเซปเป้

@Giuseppe Catch ดูกรณีที่ 5 ตอนนี้ สำหรับตัวอย่างของคุณคำตอบควรจะ28(พร้อมกับการนำไปใช้ที่คาดหวัง) หรือ 27 (พร้อมกับ>การนำไปปฏิบัติเสริม)
Andreï Kostyrka

โปรแกรมสามารถสนับสนุนเมทริกซ์ไม่เกินขนาดที่กำหนด (พูด, 500 × 500) ได้หรือไม่?
user202729

คำตอบ:



3

SmileBASIC, 101 99 ไบต์

DEF D A,W,H
GCLS
GTRI.,0,0,0,W-1,H-1FOR I=0TO W*H-1=I MOD W
S=S+A[I/W,M]*!!GSPOIT(M,I/W)NEXT?S
END

ตอนแรกฉันคิดว่าการใช้ฟังก์ชัน GLINE เพื่อวาดเส้น แต่มันไม่ปรากฏว่าใช้อัลกอริทึมที่ถูกต้อง อย่างไรก็ตาม GTRI ไม่ดูเหมือนจะทำงาน

กรณีทดสอบ 4 เอาต์พุต 30

อินพุตเป็นอาร์เรย์ 2D ในรูปแบบ [Y, X] พร้อมกับความกว้าง / ความสูง (ไม่มีวิธีตรวจสอบขนาดของอาร์เรย์เพียงจำนวนองค์ประกอบทั้งหมดเท่านั้น)


1

JavaScript (ES6), 110 103 ไบต์

เอาต์พุต25สำหรับกรณีทดสอบครั้งที่ 4

a=>(X=a[x=y=0].length-1,Y=1-a.length,g=e=>a[y][x]+(x-X|y+Y&&g(e+(e*2>Y&&++x&&Y)+(e*2<X&&++y&&X))))(X+Y)

ลองออนไลน์!

หรือ88 ไบต์หากถ่ายขนาดของเมทริกซ์เมื่ออนุญาตอินพุต


1

Python 3.X, 269 ไบต์

ด้วยการป้อนข้อมูลเป็นแถวที่คั่นด้วยจุลภาคของตัวเลขที่คั่นด้วยช่องว่าง

import math;c=math.ceil;a=[[float(k)for k in q.split(" ")]for q in input().split(",")];_=len;m=lambda f,t,x,y,e,d:sum(x[0]for x in a)if 2>_(a[0])else m(*[0]*4,*[(_(a)-1)/(_(a[0])-1)]*2)if f else m(f,t+a[y][x],x+1,y+c(e-0.5),e+d-c(e-0.5),d)if x<_(a[0])else t;m(1,*[0]*5)

Pre-กอล์ฟ:

def line(a):
   if len(a[0])<2: return sum([x[0] for x in a])
   e = d = abs((len(a)-1)/(len(a[0])-1))
   y=t=0
   for x in range(len(a[0])): 
       t += a[y][x]
       f = ceil(e-0.5)
       y += f
       e += d-f
   return t

ดูเหมือนว่าc=math.ceilจะทำให้โปรแกรมใช้เวลานานขึ้น ...
user202729

นอกจากนี้คุณไม่จำเป็นต้องระหว่าง[] มักจะมี sum(..)a if c else bc and a or b
user202729

input("")input()สามารถ
user202729

นอกจากนี้ ... รูปแบบอินพุต / เอาท์พุตคืออะไร? พิมพ์ไปยังหน้าจอ?
user202729

1

FMSLogo , 136 ไบต์

make 1 rl
setxy -1+count :1 -1+count last :1
pu home
make 9 0
foreach :1[foreach ?[if
0=last pixel[make 9 :9+?]fd 1]setxy xcor+1 0]pr :9

โปรแกรมเต็มรูปแบบแจ้งให้ผู้ใช้ป้อนข้อมูล (ป๊อปอัพกล่องโต้ตอบ) จากนั้นพิมพ์ผลลัพธ์ไปที่หน้าจอ

เพียงแค่วาดเส้นบนหน้าจอและคำนวณผลลัพธ์ ใช้ความไม่เท่าเทียมที่เข้มงวด


รองรับเฉพาะขนาดเมทริกซ์ขนาดผ้าใบสูงสุดถึง FMSLogo (ประมาณ 500 × 500)

รหัสไม่ได้รับการตอบกลับ:

Make "input ReadList
SetXY (-1+Count :input) (-1+Count Last :input)
PenUp
Home
Make "sum 0
ForEach :input[
    ForEach ?[
        If 0=Last Pixel[
            Make "sum :sum+?
        ]
        Forward 1
    ]
    SetXY XCor+1 0
]
Print :sum
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.