Gerçek Chebyshev Dönüşü


15

Bu Chebyshev Rotation'dan esinlenilen bir meydan okuma . Bu meydan okumadan ilham almak için oradaki cevaplara bakmanızı öneririm.

Kalkış ve kesiştiği nokta (ortalanmış benzersiz bir kare (eşit kenarları olan bir dikdörtgen) vardır düzlem üzerindeki bir nokta verilen etkileşimli demo ):

resim açıklamasını buraya girin

Bir noktaya verilen p ve bir mesafe d , mesafe hareket ile elde edilen dönüş noktasının d den p , saat yönünün tersine (ve negatif için saat yönünde d kare çevresi boyunca), kesişen menşe merkezli p . Cevabınız en az 4 ondalık basamağa kadar doğru olmalıdır.

testcases:

(0, 0), 100 -> (0, 0)
(1, 1), 81.42 -> (-0.4200, 1.0000)
(42.234, 234.12), 2303.34 -> (-234.1200, 80.0940)
(-23, -39.234), -234.3 -> (39.2340, -21.8960)

Aşağıdaki test senaryoları Martin Ender'in orijinal meydan okumasından kaynaklanmaktadır ve hepsi d = 1'dir :

(0, 0)       -> (0, 0)
(1, 0)       -> (1, 1)
(1, 1)       -> (0, 1)
(0, 1)       -> (-1, 1)
(-1, 1)      -> (-1, 0)
(-1, 0)      -> (-1, -1)
(-1, -1)     -> (0, -1)
(0, -1)      -> (1, -1)
(1, -1)      -> (1, 0)
(95, -12)    -> (95, -11)
(127, 127)   -> (126, 127)
(-2, 101)    -> (-3, 101)
(-65, 65)    -> (-65, 64)
(-127, 42)   -> (-127, 41)
(-9, -9)     -> (-8, -9)
(126, -127)  -> (127, -127)
(105, -105)  -> (105, -104)

Bunların neredeyse tamamı diğer zorluktan biraz değiştirilemez mi? Bu gereksiz bir ekleme gibi görünüyor.
ATaco

1
@ATaco Hayır, biraz daha karmaşık.
orlp

Mesafe p'de başlayan çevre boyunca hesaplanmalı mıdır?
Gábor Fekete

@ GáborFekete Başka ne var?
orlp

Evet, test senaryoları bunu ima ediyor, ancak açıkça belirtilmiyor. İlk başta x eksenindeki pozitif kavşakta başlayacağını düşündüm.
Gábor Fekete

Yanıtlar:


4

Piton 2, 363 335 296 266 262 258 256 233 bayt

Woo, 130 bayt kaybetti! Neil'e 4 bayt kaydettiği için teşekkürler, Nathan Merrill 2 bayt kaydettiği için ve xnor gülünç 23 bayt kaydettiği için!

Genel fikir şudur: Meydanın çevresine karşı onun modülünü alarak kat edilen mesafeyi azaltabiliriz. Çevre, iki koordinatın en büyüğünün 8 katı olarak tanımlanır, çünkü nokta üzerinde durmalıdır. Daha sonra, modül alındıktan sonra hiçbir çakışma olmayacağımız garanti edilir. Ayrıca, modülün olumlu bir sonuç verdiği için sadece saat yönünün tersine hareket etmemiz gerektiğini garanti eder.

Oradan, nerede olduğumuzu bulmak için verilen x ve y koordinatlarından bildiklerimi kullanıyorum: üst, alt, sol, sağ veya bir köşede ve aşağıdakilerden biri olabilen yönü belirle 0, 1, 2, 3:

0 --> we are on the 'top', moving 'left'
1 --> we are on the 'left', moving 'down'
2 --> we are on the 'bottom', moving 'right'
3 --> we are on the 'right', moving 'up'

Bundan sonra, hala seyahat etmek için mesafemiz varken döngü yapmak kadar basittir ve uygun koordinatı çıkardığımız veya eklediğimiz yöne bağlı olarak ve döngüye bir sonraki adımda ne yapacağımızı söyleyin.

p,d=input()
x,y=p
s=max(x,y,-x,-y)
d=d%(s*8or 1)
r=[(y<s)*[2,[3,x>-s][x<s]][y>-s],[2*(y<0),3*(y<=0)][x>0]][y*y==x*x]
while s>0<d:f=1-2*(r<2);m=abs(f*s-p[r%2]);j=d>m;p[r%2]=[p[r%2]+f*d,f*s][j];r=-~r%4;d=(d-m)*j
print"%.4f "*2%tuple(p)

Oldukça uzun olsa da, kesinlikle işe yarıyor. İşte bazı örnek G / Ç:

[0, 0], 100 --> 0.0000 0.0000
[1, 1], 81.42 --> -0.4200 1.0000
[42.234, 234.12], 2303.34 --> -234.1200 80.0940
[-23, -39.234], -234.3 --> 39.2340 -21.8960

Çevrimiçi deneyin veya test senaryoları çalıştırın .


Mu s=max(x,y,-x,-y)iş?
Neil

@Neil Öyle, bir demet teşekkürler!
Kade

(s>0)*(d>0)olduğunu s>0<d. Çıktı olabilir "%.4f "*2%tuple(p). if s:d=d%(8*s)olabilir d%(s*8or 1). (r+1)olabilir ~-r. 1*(x>-s)sadece olabilir (x>-s). abs(y)==abs(x)olabiliry*y==x*x
xnor

@xnor Vay canına, teşekkürler! Sadece değiştirdiğim ikizler (x>-s)parantez ve ~-razalmaya ihtiyaç duymadı, bu yüzden kullandım -~r.
Kade

3

JavaScript (ES6), 147 bayt

f=(x,y,d,s=Math.max(x,y,-x,-y),c=(d/8%s+s)%s*8,v=0,w=x+y>0?1:-1,b=(v?x:y)*w+c-s)=>c?b>0?f(v?s*w:x,v?y:s*w,d,s,b,!v,v?w:-w):[x+c*w*v,y+c*w*!v]:[x,y]

Açıklama: Karenin sınırları dahilinde tutarak yön vektörünü eklemeye çalışır. Herhangi bir aşma, 90 ° döndürülerek yön saat yönünün tersine döndürülür. Yön aslında dikey bir bayrak vve bir birim kullanılarak kodlanır, wböylece (1, 0), (0, 1), (-1, 0) ve (0, -1) vektörleri 0, 1, 0 ile kodlanır v. 1 ve w1, 1, -1, -1'dir. Yön vektörü başlangıçta uygun bir yönü göstermeyebilir, ancak asla geriye bakmaz, böylece sonunda kullanılabilir bir yöne dönecektir.

f=(x,y,d,                   Input parameters
 s=Math.max(x,y,-x,-y),     Calculate half the side of the square
 c=(d/8%s+s)%s*8,           Reduce the distance modulo the perimeter
 v=0,                       Initial vertical flag
 w=x+y>0?1:-1,              Initial direction
 b=(v?x:y)*w+c-s)=>         Will we overshoot the corner?
  c?b>0?f(v?s*w:x,v?y:s*w,  Advance to the next corner
          d,s,b,!v,v?w:-w): Rotate the direction
        [x+c*w*v,y+c*w*!v]: Advance the remaining amout
    [x,y]                   Nothing to do, zero input

Bunun nedeni tarayıcımın (Opera 40.0.2308.81) olabilir, ancak f(42.234, 234.12, 2303.34) -> [-234.12, 80.09399999999988]4 basamaklı bir hassasiyeti olmadığı için biraz yuvarlama hatasına sahip olduğu anlaşılıyor. Belki bazı çıktı biçimlendirmeleri eklemek bu sorunu çözebilir? Güzel cevap olsa! :)
Kade

@Shebang Teknik olarak çıktı biçimlendirmesi yuvarlama gerektirir ve bu nedenle potansiyel bir yuvarlama hatası oluşturur. Oluşturulan sayılar, rastgele ondalık gösterimler için kesin sonuçlar vermesi beklenmeyen, kayan nokta aritmetiği sınırları içinde mümkün olan en yakın değerlerdir. Kesin cevaplar istiyorsanız ikili kesirlere sadık kalın.
Neil
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.