Bu çizgi o kareden mi geçiyor?


19

İlk çeyreği (pozitif x ekseni, pozitif y ekseni ve başlangıç ​​noktası dahil) 1x1 ızgaralara bölün, her ızgara aşağıda gösterildiği gibi sol alt köşesinin koordinatları tarafından etiketlenir:

Her ızgaranın sınırlarını ve köşelerini içerdiğini unutmayın. Matematiksel semboller kullanıldığında (m, n) etiketli ızgara kareyi temsil eder {(x,y) | m ≤ x ≤ m+1, n ≤ y ≤ n+1}.


Şeklinde düz bir çizgi dikkate alındığında ax+by+c=0tamsayılar ile a, bve c, ve ile temsil edilen bir ızgara (m,n)hattı şebekesine, bir deyişle belirli bir ızgara herhangi bir nokta çizgi üzerinde olup olmadığı geçer olup çıkış.


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

Lütfen yorumlarda daha fazla testcase önerin.


Bu . Bayt cinsinden en kısa cevap kazanır. Standart boşluklar geçerlidir.


1
Tabii ki hem a hem de b'nin 0 olmadığını varsayabiliriz, çünkü c sıfırsa sonsuz çizgiler olabilir, c sıfır değilse, hiç çizgi olamaz.
Outgolfer Erik

[a, b, c](Satır) ve [m, n](kare) gibi iki veya daha fazla dizi olarak girdi alabilir miyim ?
Outgolfer Erik

@EriktheOutgolfer Metada olmadığına şaşırdım.
Leaky Nun


Yanıtlar:


5

Python 3, 84 66 bayt

İlk golf, ilk başarısız (belki).

Doğrudan giriş yerine bir işlev kullanarak 18 bayt tıraş etmek için Rod sayesinde.

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

Çevrimiçi deneyin!

Açıklama:

Temel olarak, m ve m + 1 için çizgi işlevinin değerini hesaplıyoruz, eğer n değerler arasında olursa, liste bir noktada onu geçmelidir. Dilin birden fazla tamsayı girmek için daha basit bir yolu olsaydı çok daha iyi olurdu.



2
PPCG'ye Hoşgeldiniz!
17'de

1
Bunun m + 1 kadar n + 1'e karşı kontrol etmesi gerekmez mi?
Neil

3
Sıfıra takım zaman bolduğu 0.
Olivier Grégoire

Ayrıca, Leaky Nun tarafından vurgulanan birkaç test vakasını geçmez .
Olivier Grégoire

5

Jöle , 10 bayt

ż‘{Œpæ.ṠE¬

Çevrimiçi deneyin!

Arka fon

Benden önceki diğer cevaplar gibi, bu da düz bir çizginin uçağı iki yarı düzleme böldüğü gerçeğine dayanır. Dikdörtgen ya bu yarı düzlemlerden birinde bulunur (çizgi ile kesişme olmaz) ya da her iki yarı düzlemle (ve böylece onları ayıran çizgiyle kesişir).

Nasıl çalışır

ż‘{Œ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 bayt

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

Çevrimiçi deneyin!

Bir noktanın işaretiyle çizginin hangi tarafının olduğunu söyleyebiliriz a*x+b*y+c. Dört köşenin (m,n),(m,n+1),(m+1,n),(m+1,n+1)tümü kesinlikle çizginin aynı tarafında değilse, çizgi kareden geçer (dokunma sayımı) . Bu değerleri, a*m+b*n+cdördünde de görünen sabiti bir özete ekleyebiliriz :

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

Bu nedenle, bu dört değerin tümü pozitif veya tümü negatif olmadığı sürece çizgi kareden geçer. Bu nedenle, minimum <=0ve maksimum olmaları yeterlidir >=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+cHer parçadan ortak çıkarılması kodu verir.

Biraz daha uzun bir yaklaşım, işaret kümesinin (+, 0, -) en az 2 uzunluğuna sahip olup olmadığını kontrol etmektir.

Python 2 , 62 bayt

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

Çevrimiçi deneyin!


3

Mathematica, 60 55 bayt

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

-MartinEnder'e -5 bayt thanx

giriş formu

[A, b, c, m, n]


2
Ah, keşke her dilin bir Solveişlevi olsaydı ...
Outgolfer Erik

3

Toplu, 66 bayt

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

Açıklama: Denklem tarafından hücrenin dört köşesinde alınan değerleri dikkate alıyoruz. Çizgi hücreyle kesişmiyorsa, dört değerin hepsi aynı işarete sahiptir, ancak hücreyle kesişirse, en az bir değer sıfır veya ters işaret olacaktır. Karşılık, zıt köşelerin çiftlerinin çarpımı ile basitleştirilir, o zaman her iki değer de pozitifse, çizgi hücreyle kesişmez. Bazı bit-twiddling daha sonra çarpmaları genel bir sonuca dönüştürür.


1

Mathematica, 50 bayt

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

Çevrimiçi deneyin!

Alır m, n, c, a, bbu sırayla girdi olarak.

Açıklama: Tuples@{{#,#+1},{#2,#2+1}}daha sonra nokta ürün alarak, kare dört köşesinden bir koordinat listesi yapar .{##4}(ki vasıtasıyla {#4, #5}) ve ekleme +#3hesaplar ax + by + ciçin x,yher bir köşede. Çizgi noktadan geçerse, bu sıfırdır; eğer çizgi başlangıç ​​noktasından uzaksa, negatiftir; ve çizgi orijine daha yakınsa, pozitiftir - bu nedenle Signbu dört değerin s'lerini kontrol ederiz . Yalnızca dört değer 1 veya dördü de -1 ise çizgi karenin dışından geçer, bu nedenle toplamlarının kesinlikle -4 ile 4 arasında olduğunu kontrol ederiz.

(Bu cevap belirsiz bir şekilde bu soruya verdiğim yanıttan esinlenmiştir .)



1

Python , 54 bayt

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

Çevrimiçi deneyin!

(Test komut dosyası için xnor'a teşekkürler.)

Nasıl çalışır

Çizgi sadece ve sadece 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⋅ by .

Bu bazıları için mümkündür | x |, | y | ≤ 1/2 ise ve sadece | 2⋅ ( am + bn + c ) + a + b | ≤ | a | + | b |.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.