บรรทัดนี้ผ่านจัตุรัสนั้นหรือไม่?


19

แบ่งจตุภาคแรก (รวมถึงแกน x บวก, แกน y บวกและต้นกำเนิด) เป็น 1x1 กริดโดยแต่ละตารางจะมีป้ายกำกับโดยพิกัดของมุมซ้ายล่างดังแสดงด้านล่าง:

โปรดทราบว่าแต่ละตารางมีขอบเขตและจุดยอด การใช้สัญลักษณ์ทางคณิตศาสตร์กริดที่มีป้ายกำกับ (m, n) จะเป็นตัวแทนของสแคว{(x,y) | m ≤ x ≤ m+1, n ≤ y ≤ n+1}ร์


กำหนดเส้นตรงในรูปแบบของax+by+c=0จำนวนเต็มa, bและ, และc, และแสดงโดยกริด(m,n), เอาท์พุทไม่ว่าจะเป็นเส้นผ่านตาราง, หรือไม่ว่าจุดใด ๆ ในตารางที่กำหนดอยู่บนบรรทัด.


a  b  c m n output
1  1  0 0 0 true
1  1  0 1 1 false
1  1  0 0 2 false
1  1 -3 0 1 true
1  1 -3 0 0 false
2 -1  0 1 1 true
2 -1  0 1 0 false
2 -1  0 0 2 true
2 -1  0 0 1 true
2 -1  0 1 2 true
2  0 -1 0 0 true
2  0 -1 0 1 true
2  0 -1 0 2 true
2  0 -1 1 0 false
2  0 -1 1 1 false
0  2 -1 0 0 true
0  2 -1 1 0 true
0  2 -1 2 0 true
0  2 -1 0 1 false
0  2 -1 1 1 false
1  0 -1 0 0 true
1  0 -1 0 1 true
1  0 -1 0 2 true
1  0 -1 1 0 true
1  0 -1 1 1 true

กรุณาแนะนำ testcase เพิ่มเติมในความคิดเห็น


นี่คือรหัสกอล์ฟคำตอบที่สั้นที่สุดในการชนะไบต์ ช่องโหว่มาตรฐานใช้


1
แน่นอนว่าเราควรจะสามารถสันนิษฐานได้ว่าไม่ใช่ทั้ง a และ b เป็น 0 ตั้งแต่นั้นถ้า c เป็นศูนย์จะมีเส้นไม่สิ้นสุดในขณะที่ถ้า c ไม่ใช่ศูนย์จะไม่มีบรรทัดเลย
Erik the Outgolfer

ฉันจะได้รับอินพุตเป็นสองอาร์เรย์ขึ้นไปพูด[a, b, c](เส้น) และ[m, n](สี่เหลี่ยมจัตุรัส) ได้หรือไม่
Erik the Outgolfer

@EriktheOutgolfer ฉันประหลาดใจที่ไม่มีใน meta
Leun Nun


คำตอบ:


5

Python 3, 84 66 ไบต์

กอล์ฟครั้งแรกล้มเหลวครั้งแรก (อาจ)

ขอบคุณ Rod สำหรับการโกนขนาด 18 ไบต์โดยใช้ฟังก์ชั่นแทนการป้อนข้อมูลโดยตรง

def f(a,b,c,m,n):f=-(a*m+c)/b;g=f-a/b;print(min(f,g)<=n<=max(f,g))

ลองออนไลน์!

คำอธิบาย:

โดยทั่วไปเราคำนวณค่าของฟังก์ชั่นบรรทัดสำหรับ m และ m + 1 ถ้า n อยู่ระหว่างค่าดังนั้นรายการจะต้องผ่านมันในบางจุด จะดีกว่ามากถ้าภาษามีวิธีที่ง่ายกว่าในการป้อนจำนวนเต็มหลายจำนวน



2
ยินดีต้อนรับสู่ PPCG!
betseg

1
สิ่งนี้ไม่จำเป็นต้องตรวจสอบกับ n + 1 รวมถึง m + 1 ใช่ไหม
Neil

3
หารด้วยศูนย์เมื่อเป็นb 0
Olivier Grégoire

นอกจากนี้ยังไม่ผ่านการทดสอบหลายกรณีที่เน้นโดย Leaky Nun
Olivier Grégoire

5

เยลลี่ 10 ไบต์

ż‘{Œpæ.ṠE¬

ลองออนไลน์!

พื้นหลัง

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

มันทำงานอย่างไร

ż‘{Œpæ.ṠE¬  Main link. Left argument: [m, n]. Right argument: [a, b, c]

 ‘{         Increment left; yield [m+1, n+1].
ż           Zipwith; yield [[m, m+1], [n, n+1]].
   Œp       Cartesian product; yield [[m, n], [m, n+1], [m+1, n], [m+1, n+1]].
     æ.     Take the dot products with [a, b, c], mapping each [x, y] to ax+by+c.
       Ṡ    Take the signs.
        E   Test the signs for equality.
         ¬  Logical NOT.

4

Python 2 , 59 ไบต์

lambda a,b,c,m,n:min(0,a,b,a+b)<=-a*m-b*n-c<=max(0,a,b,a+b)

ลองออนไลน์!

a*x+b*y+cเราสามารถบอกได้ที่ด้านข้างของเส้นจุดโดยสัญลักษณ์ของ เส้นผ่านจัตุรัส (การสัมผัสนับ) เว้นแต่ว่าจุดยอดทั้งสี่(m,n),(m,n+1),(m+1,n),(m+1,n+1)นั้นอยู่บนด้านเดียวกันของเส้นอย่างเคร่งครัด เราสามารถเสียบค่าเหล่านี้ในการแยกค่าคงa*m+b*n+cที่ที่ปรากฏในทั้งสี่:

a*m+b*n+c
a*m+b*n+c+a
a*m+b*n+c+b
a*m+b*n+c+a+b

ดังนั้นเส้นผ่านจตุรัสยกเว้นค่าทั้งสี่นี้เป็นค่าบวกหรือลบทั้งหมด ดังนั้นจึงพอเพียงอย่างน้อยพวกเขาจะและสูงสุดที่จะเป็น<=0>=0

min(a*m+b*n+c,a*m+b*n+c+a,a*m+b*n+c+b,a*m+b*n+c+a+b)<=0<=max(a*m+b*n+c,a*m+b*n+c+a,a*m+b*n+c+b,a*m+b*n+c+a+b)

การลบทั่วไปa*m+b*n+cจากแต่ละส่วนให้รหัส

วิธีที่ยาวกว่าเล็กน้อยคือการตรวจสอบว่าชุดสัญญาณ (+, 0, -) มีความยาวอย่างน้อย 2 หรือไม่

Python 2 , 62 ไบต์

lambda a,b,c,m,n:len({cmp(a*m+b*n+c,-d)for d in(0,a,b,a+b)})>1

ลองออนไลน์!


3

Mathematica, 60 55 ไบต์

Solve[m#+n#2==-#3&&#4<=m<=#4+1&&#5<=n<=#5+1,{m,n}]!={}&

-5 ไบต์ thanx ถึง @MartinEnder

แบบฟอร์มการป้อนข้อมูล

[A, B, C, m, n]


2
อ่าฉันหวังว่าทุกภาษาจะมีSolveฟังก์ชั่น ...
Erik the Outgolfer

3

แบตช์ 66 ไบต์

@cmd/cset/a"q=%1*%4+%2*%5+%3,((-(q+%1)*(q+%2)&-q*(q+%1+%2))>>31)+1

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


1

Mathematica, 50 ไบต์

-4<Tr@Sign[Tuples@{{#,#+1},{#2,#2+1}}.{##4}+#3]<4&

ลองออนไลน์!

ใช้m, n, c, a, bเป็นอินพุตในลำดับนั้น

คำอธิบาย: Tuples@{{#,#+1},{#2,#2+1}}สร้างรายการพิกัดของมุมทั้งสี่ของสี่เหลี่ยมจัตุรัสจากนั้นนำผลคูณของจุดด้วย.{##4}(ซึ่งหมายถึง{#4, #5}) และเพิ่มการ+#3คำนวณax + by + cสำหรับx,yแต่ละมุม หากเส้นผ่านจุดนี้เป็นศูนย์; ถ้าเส้นนั้นห่างจากจุดกำเนิดมากขึ้นก็จะเป็นลบ และถ้าเส้นใกล้ต้นกำเนิดมันก็เป็นบวก - ดังนั้นเราตรวจสอบSigns ของค่าทั้งสี่นี้ เส้นผ่านนอกจตุรัสหากและถ้าค่าทั้งสี่เป็น 1 หรือทั้งสี่คือ -1 ดังนั้นเราตรวจสอบว่าผลรวมของพวกเขาอยู่ระหว่าง -4 และ 4 อย่างเคร่งครัด

(คำตอบนี้ได้แรงบันดาลใจจากคำตอบของคำถามนี้ )



1

Pythonขนาด 54 ไบต์

lambda a,b,c,m,n:abs(2*(a*m+b*n+c)+a+b)<=abs(a)+abs(b)

ลองออนไลน์!

(ขอบคุณ xnor สำหรับสคริปต์ทดสอบ)

มันทำงานอย่างไร

เส้นผ่านm + 1/2 + x , n + 1/2 + yถ้าหากว่าเท่านั้น

a ⋅ ( m + 1/2 + x ) + b ⋅ ( n + 1/2 + y ) + c = 0
⇔2⋅ ( am + bn + c ) + a + b = −2⋅ ax - 2⋅ ⋅ Y

นี่เป็นไปได้สำหรับบางคน | x |, | y | ≤ 1/2 ถ้าหาก | 2⋅ ( am + bn + c ) + a + b | ≤ | a | + | b |


1

Java (OpenJDK 8) , 71 ไบต์

(a,b,c,x,y)->(0<a?0:a)+(0<b?0:b)<=(x=-a*x-b*y-c)&x<=(0>a?0:a)+(0>b?0:b)

ลองออนไลน์!

พอร์ตของโซลูชัน Python ของ xnor

โซลูชันดั้งเดิมโดยใช้การแยกรูปร่าง / เส้นใน Java (108 ไบต์)

(a,b,c,x,y)->b==0?x<=-c/a&-c/a<=x+1:new java.awt.Rectangle(x,y,1,1).intersectsLine(x,c=(c+a*x)/-b,x+1,c-a/b)

ลองออนไลน์!

เครดิต

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