Chebyshev Dönme


36

Her hücrenin tam sayı koordinatlarına sahip olduğu normal bir ızgara düşünün. Hücreleri (kare şeklinde) "halkalar" halinde gruplayabiliriz; burada her bir halkadaki hücreler , kökenden aynı Chebyshev mesafesine (veya satranç tahtası mesafesine) sahiptir. Göreviniz böyle bir hücre koordinatını almak ve bu hücreyi halkasının içinde saat yönünün tersine bir konum döndürmek. Bu, aşağıdaki eşlemeyi uygular:

görüntü tanımını buraya girin

Mesela eğer girdi ise (3, -2)çıktı vermelisin (3, -1). (0, 0)Kendisiyle eşlenmesi gereken tek giriş olduğunu unutmayın .

kurallar

G / Ç formatı oldukça esnektir. İki ayrı sayı, bir çift / liste / dizi / sayı dizisi, tek bir karmaşık sayı, iki sayı içeren bir dize vb. Kullanabilirsiniz.

Bunu varsayabilirsin -128 < x,y < 128.

Bir program veya fonksiyon yazabilir ve standart girdi alma ve çıktı alma yöntemlerimizden herhangi birini kullanabilirsiniz .

Herhangi bir programlama dilini kullanabilirsiniz , ancak bu boşlukların varsayılan olarak yasak olduğunu unutmayın .

Bu , yani en kısa geçerli cevap - bayt cinsinden - kazanır.

Test Kılıfları

(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)

Girdi ve çıktı formatlarını karıştırabilir miyiz, örneğin bir tuple çekip karmaşık bir sayı çıkarabilir miyiz?
Dennis,

@Dennis evet iyi.
Martin Ender,

Yanıtlar:


16

JavaScript (ES6), 60 59 bayt

Karıştırma sözdizimi ile girdi alır (x)(y)ve bir dizi döndürür [new_x, new_y].

x=>y=>(x|y&&((z=x+(y<0))>-y?z>y?y++:x--:z>y?x++:y--),[x,y])

Nasıl çalışır

Asıl görevimiz hangi kadranda olduğumuzu belirlemek, böylece hangi yöne hareket edeceğimizi bilmek.

Bu formülü ilk yaklaşım olarak kullanabiliriz:

x > -y ? (x > y ? 0 : 1) : (x > y ? 2 : 3)

İşte aldığımız şey:

3 1 1 1 1 1 1 1 1
3 3 1 1 1 1 1 1 0
3 3 3 1 1 1 1 0 0
3 3 3 3 1 1 0 0 0
3 3 3 3 3 0 0 0 0
3 3 3 3 2 2 0 0 0
3 3 3 2 2 2 2 0 0
3 3 2 2 2 2 2 2 0
3 2 2 2 2 2 2 2 2

Neredeyse. Ancak halkaların sol alt ve sağ alt köşeleri geçersiz. Matrisin alt yarısını bir konum sola kaydırmalıyız, bu yüzden şöyle tanımlarız z:

z = y < 0 ? x + 1 : x

Ve yerini xile zbizim formülde:

z > -y ? (z > y ? 0 : 1) : (z > y ? 2 : 3)

Hangi yol açar:

3 1 1 1 1 1 1 1 1 
3 3 1 1 1 1 1 1 0 
3 3 3 1 1 1 1 0 0 
3 3 3 3 1 1 0 0 0 
3 3 3 3 3 0 0 0 0 
3 3 3 2 2 0 0 0 0 
3 3 2 2 2 2 0 0 0 
3 2 2 2 2 2 2 0 0 
2 2 2 2 2 2 2 2 0 

Artık bütün matris, [0, 0]ayrı ayrı ele alınması gereken özel durum (hiç hareket yok) hariç, artık doğrudur .

Test durumları


13

Jöle , 20 14 12 bayt

S;IṠN0n/¦Ạ¡+

Giriş ve çıkış diziler şeklindedir. Çevrimiçi deneyin! veya tüm test durumlarını doğrulayın .

Arka fon

Hangi yöne hareket etmemiz gerektiğine karar vermek için, başlangıç ​​noktasının kadran bisektörleri olan x + y = 0 (mavi) ve x - y = 0 (kırmızı) göreceli konumunu gözlemleyebiliriz .

diyagram

  • Kökeni sabittir. Başlangıç ​​noktasına [0, 0] ekleyerek ilerliyoruz .

  • En üstteki üçgendeki puanlar - ilk kadranın bisektörü dahil - pozitif toplam ve negatif olmayan delta ( y - x ) değerine sahiptir . Başlangıç ​​noktasına [-1, 0] ekleyerek ilerliyoruz .

  • En soldaki üçgendeki noktalar - ikinci kadranın iki parçacığını içeren - pozitif olmayan toplam ve pozitif deltaya sahiptir. Başlangıç ​​noktasına [0, -1] ekleyerek ilerliyoruz .

  • En alt üçgendeki puanlar - üçüncü kadranın bisector'ı dahil - negatif toplam ve pozitif olmayan deltalara sahiptir. Başlangıç ​​noktasına [1, 0] ekleyerek ilerliyoruz .

  • En sağdaki üçgenin içindeki noktalar - dördüncü kadranın iki parçasını içerir - negatif olmayan toplam ve negatif deltaya sahiptir. Başlangıç ​​noktasına [0, 1] ekleyerek ilerliyoruz .

Doğru yönü bulmak için , sadece dokuz olası sonucu olan [-sign (x + y), -sign (y - x)] değerini hesaplıyoruz .

Aşağıdaki tablo, hangi sonuçların hangi yönlerle eşleştirilmesi gerektiğini göstermektedir.

    sign(x+y) |  sign(y-x) | -sign(x+y) | -sign(y-x) |     Δx     |     Δy
  ------------+------------+------------+------------+------------+------------
        0     |      0     |      0     |      0     |      0     |      0
        1     |      0     |     -1     |      0     |     -1     |      0
        1     |      1     |     -1     |     -1     |     -1     |      0
        0     |      1     |      0     |     -1     |      0     |     -1
       -1     |      1     |      1     |     -1     |      0     |     -1
       -1     |      0     |      1     |      0     |      1     |      0
       -1     |     -1     |      1     |      1     |      1     |      0
        0     |     -1     |      0     |      1     |      0     |      1
        1     |     -1     |     -1     |      1     |      0     |      1

Bu üç durumda bırakır.

  • İşaretlerden en az biri 0 ise , [Δx, Δy] = [-sign (x + y), -sign (yx)] .

  • İşaretler eşit ve sıfır değilse, [Δx, Δy] = [-sign (x + y), 0] .

  • Eğer işaretler farklıysa ve sıfır değilse, [Δx, Δy] = [0, -sign (yx)] .

Nasıl çalışır

S;IṠN0n/¦Ạ¡+  Main link. Argument: [x, y] (pair of integers)

S             Sum; compute x + y.
  I           Increments; compute [y - x].
 ;            Concatenate; yield [x + y, y - x].
   Ṡ          Sign; compute [sign(x + y), sign(y - x)].
    N         Negate; yield [-sign(x + y), -sign(y - x)].
          ¡   Do n times:
         Ạ      Set n to all([-sign(x + y), -sign(y - x)]), i.e., 1 if the signs
                are both non-zero and 0 otherwise.
        ¦       Conditional application:
      n/          Yield 1 if the signs are not equal, 0 if they are.
     0            Replace the coordinate at 1 or 0 with a 0.
              This returns [Δx, Δy].
           +  Add; yield  [Δx + x, Δy + y].


5

Python, 55 bayt

lambda x,y:(x-(-y<x<=y)+(y<=x<-y),y+(~x<y<x)-(x<y<=-x))

Dört diyagonal kadranı algılar ve uygun koordinatı kaydırır.


4

Haskell, 77 71 69 bayt

x#y|y>=x,-x<y=(x-1,y)|y>x=(x,y-1)|y< -x=(x+1,y)|y<x=(x,y+1)|1>0=(0,0)

Bu sadece bu eğimli kadranların her birini kontrol etmek ve girişi buna göre değiştirmek. Boşlukların gerekli olduğuna dikkat edin, aksi takdirde örneğin >-bir operatör olarak anlaşılır (tanımlanmamış).

Birkaç byte daha sildiğiniz için teşekkür ederiz!


,&&İlk nöbetçi yerine bir bayt kazandırır. Ve sonra ikinci karşılaştırmayı -x<ybaşka bir baytla değiştirebilirsin.
nimi

Teşekkürler, farkında değildim ,!
kusur

4

Ruby, 68

Lambda işlevi karmaşık sayıyı argüman olarak alır, karmaşık sayıyı döndürür.

->z{k=1
4.times{z*=?i.to_c
x,y=z.rect
y*y>=x*x&&y<-x&&(z+=k;k=0)}
z} 

Noktayı çarparak 90 derece 4 kez döndürüyoruz i. Bu nedenle, 4 kadranın hepsinden de geçer ve değişmeden geri gönderilir - belirli bir tanedeyken değiştirdiğimiz gerçeği dışında. Aynı kadranda her zaman değiştirilmiş olması, değişikliği kolaylaştırır.

zSağ kadrandayken değiştirirsek takip etmek en kolay yoldur . bu durumda biz y, 1 ile koordine artırmak gerekir (yani, ekleme iiçin z).

Biz kontrol x.abs>=y.abskarelerini karşılaştırarak xve y. Bu bize, noktanın yukarı ya da aşağı değil, sağ ya da sol kadranda olduğunu söyler. O sağ taraftaki kadranda aslında kontrol etmek daha ileri kontrol x>y(biz davayı dışlamak istiyorum, çünkü kesinlikle daha x=y"üst" kadranda aittir.) Bu Eklemek doğrudur Nerede ietmek z.

Golf nedeniyle, ekleme iarzu edilmez. Bunun yerine, sayıyı alt kadrandayken değiştiriyoruz, bu durumda xkoordinata 1 eklemeliyiz (1 ila z.). Bu durumda y*y>=x*xkontrol etmek için üst veya alt kadranda olup olmadığını test ediyoruz . Alt kadranda olduğundan emin olmak için kontrol etmemiz gerekir y<-x(kesinlikle sağ alt köşedeki durum hariç y=-x.)

Bu kontrolün bir avantajı 0,0 koordinatı için özel bir durum olmamasıdır. Maalesef, noktayı hareket ettirmenin onu farklı bir kadranda değiştirebileceği bulundu ve bu, ikinci kademe hareketinin bastırılması gerektiği anlamına geliyor, ki bu da, kadranın tekrar kontrol edilmesi durumunda, ki bu da muhtemelen avantajı engelliyor.

örnek 1

Input                                        95,-12
Rotate 90deg                                 12,95    
Rotate 90deg                                -95,12    
Rotate 90deg                                -12,-95 
Rotate 90deg                                 95,-12
y.abs>=x.abs=TRUE, y<-x=TRUE, increase x     95,-11

The check and alteration of the coordinate is done AFTER the rotation.
Thus in this case it gets done in the 4th iteration of the loop, not the 1st.
If the code were rewritten to do the check and alteration BEFORE the rotation, 
it would be done in the 1st iteration instead of the 4th.

Örnek 2

Input                                        -1,0
Rotate 90deg                                  0,-1
y.abs>=x.abs=TRUE, y<-x=TRUE, increase x      1,-1
Rotate 90deg                                  1,1
Rotate 90deg                                  1,-1
Rotate 90deg                                 -1,-1
y.abs>=x.abs?=TRUE, y<-x=TRUE but DO NOT CHANGE x!

This is an unusual situation due to the fact that the first move caused the
point to advance by one quadrant. We do NOT want to move it again, for this
reason we need to set k to 0 the first time it is moved.

Test programında

f=->z{k=1                   #amount to be added to coordinate
4.times{z*=?i.to_c          #iterate 4 times, rotating point by 90deg till it reaches the original orientation
x,y=z.rect                  #separate out x and y for testing
y*y>=x*x&&y<-x&&(z+=k;k=0)} #if y.abs>=x.abs and y negative and not equal -x, move the point and zero k.
z}                          #return z

puts f[Complex(0, 0)]       # (0, 0)
puts f[Complex(1, 0)]       # (1, 1)
puts f[Complex(1, 1)]       # (0, 1)
puts f[Complex(0, 1)]       # (-1, 1)
puts f[Complex(-1, 1)]      # (-1, 0)
puts
puts f[Complex(-1, 0)]      # (-1, -1)
puts f[Complex(-1, -1)]     # (0, -1)
puts f[Complex(0, -1)]      # (1, -1)
puts f[Complex(1, -1)]      # (1, 0)
puts f[Complex(95, -12)]    # (95, -11)
puts f[Complex(127, 127)]   # (126, 127)
puts
puts f[Complex(-2, 101)]    # (-3, 101)
puts f[Complex(-65, 65)]    # (-65, 64)
puts f[Complex(-127, 42)]   # (-127, 41)
puts f[Complex(-9, -9)]     # (-8, -9)
puts f[Complex(126, -127)]  # (127, -127)
puts f[Complex(105, -105)]  # (105, -104)

Diyagram

Aşağıdaki resimde (mavi) x*x>=y*y, (sarı) alanların y<-xve (yeşil) bunların kesiştiği alan gösterilmektedir, bu da doğru dönüşümün 1 ila 5 eklenmiş olduğu bölgedir z.

görüntü tanımını buraya girin


1
Üzgünüm, açıklamayı takip etmiyorum. Bir örnek veya şema ekler misiniz?
Martin Ender,

@ Martin açıklaması eklendi. Bu ilginç bir yaklaşımdı, ancak ilk hareket ettiklerinde kadranı değiştiren noktaların çifte hareketini bastırma ihtiyacı nedeniyle, umduğum kadar zarif olmadı.
Level River St

4

Python, 52 bayt

h=lambda z:z and 1j*h(z/1j)if'-'in`z*1j-z-1`else z+1

Karmaşık giriş ve çıkış. Noktayı alt diyagonal kadranda bulunduğunu test etmek için, önce saat yönünün tersine, saat yönünün tersine döndürerek o kadranı (x> 0, y> 0) standart kadrana getirin ve sonucun dize gösteriminde eksi simgesi olup olmadığını test edin. 1 çıkarma, önce sınır koşulunu sağlar.

O kadranda değilse, tüm sorunu 90 derece döndürün. Girdi sıfırdır, özellikle çıktısını almak için kullanılır.

Karmaşık sayılarla yapılan diğer girişimler:

## 56 bytes
## Coordinate input, complex output
q=lambda x,y:(y<=x<-y)*(1j*y-~x)or x+1j*y and 1j*q(y,-x)

## 60 bytes
h=lambda z:(z+1)*(z.imag<=z.real<-z.imag)or z and 1j*h(z/1j)

## 63 bytes
from cmath import*
h=lambda z:z and 1j**(phase(z*1j-z)*2//pi)+z

3

Mathematica, 34 bayt

±0=0
±z_:=z+I^Floor[2Arg@z/Pi+3/2]

Bu tekli operatör tanımlayan ±bileşenler temsil karmaşık sayı alır ve döner xve y.

Lynn şimdi karmaşık sayı çözümünü açıkladı ve Dennis benim puanımı aştı, golfe atıfta bulunduğum başvurumu gönderdiğim için kendimi kötü hissetmiyorum. :) (Lynn'in cevabı ile neredeyse aynı olduğu ortaya çıktı.)


Bu yardımcı olur mu? ± 0 = 0 ⁢ ± z_: = z + I ^ ⌊ 2 ⁢ Arg @ z / Pi + 3/2 ⌋ (belki de zemin braketleri için farklı bir karakter ile)
DavidC

@DavidC ne yazık ki çünkü o zaman UTF-8 kodlaması kullanmam gerekecek ve ardından ± her biri 2 bayta mal olacaktı.
Martin Ender

Bu 7 yerine 4 bayt olmaz mı, yani 3 baytlık bir ekonomi veriyor mu?
DavidC

@DavidC hayır, zemin destekleri her biri 3 byte olacaktır.
Martin Ender,

Bunun farkında değildim. Ancak yine de 1 bayttan tasarruf etmelisiniz.
DavidC,

3

MATL , 19 17 bayt

t|?JGJq*X/EYP/k^+

Bu giriş ve çıkış olarak karmaşık sayıları kullanır.

Çevrimiçi deneyin! Veya tüm test durumlarını doğrulayın .

açıklama

-127+42jÖrnek olarak girdi alalım.

t|       % Implicit input. Duplicate and take absolute value
         % STACK: -127+42j, 133.764718816286
?        % If nonzero
         % STACK: -127+42j
  J      %   Push j (imaginary unit)
         %   STACK: -127+42j, j
  GJq*   %   Push input multiplied by -1+j. This adds 3*pi/4 to the phase of the input
         %   STACK: -127+42j, j, 85-169i
  X/     %   Phase of complex number
         %   STACK: -127+42j, j, -1.10478465600433
  EYP/   %   Divide by pi/2
         %   STACK: -127+42j, j, -0.703327756220671
  k      %   Round towards minus infinity
         %   STACK: -127+42j, j, -1
  ^      %   Power
         %   STACK: -127+42j, -j
  +      %   Add
         %   STACK: -127+41j
         % Implicit end
         % Implicit display

3

Ruby, 51 bayt

Orijinal form

->x,y{d=x*x-y*y
[x+(d>0?0:-y<=>x),y+(d<0?0:x<=>y)]}

Her Xnor'ın yorumuna göre alternatif form

->x,y{[x+(x*x>y*y ?0:-y<=>x),y+(x*x<y*y ?0:x<=>y)]}

Diğer cevabımla aynı tip eşitsizlikleri kullanır, fakat farklı bir şekilde kullanır.

Test programında

f=->x,y{d=x*x-y*y
[x+(d>0?0:-y<=>x), #if y.abs>=x.abs: x+=1 if -y>x, x-=1 if -y<x 
y+(d<0?0:x<=>y)]}  #if x.abs>=y.abs: y+=1 if  x>y, y-=1 if  x<y

p f[0, 0]       # (0, 0)
p f[1, 0]       # (1, 1)
p f[1, 1]       # (0, 1)
p f[0, 1]       # (-1, 1)
p f[-1, 1]      # (-1, 0)
puts
p f[-1, 0]      # (-1, -1)
p f[-1, -1]     # (0, -1)
p f[0, -1]      # (1, -1)
p f[1, -1]      # (1, 0)
p f[95, -12]    # (95, -11)
p f[127, 127]   # (126, 127)
puts
p f[-2, 101]    # (-3, 101)
p f[-65, 65]    # (-65, 64)
p f[-127, 42]   # (-127, 41)
p f[-9, -9]     # (-8, -9)
p f[126, -12]   # (127, -127)
p f[105, -105]  # (105, -104)

datama değer o? Sadece karşılaştırabilir gibi görünüyor x*x>y*y.
xnor

@ Xnor ne yazık ki Ruby arasında bir boşluk olması gerekir y*yve ?bu yüzden tam olarak aynı uzunluk. Senin tarzının daha iyi olduğunu düşündüğüm gibi dahil ettim. Sanırım Ruby, y?yasal bir işlev adı olacak gibi geçmeye çalışıyor .
Level River St

3

Julia, 38 34 bayt

!z=z==0?0:z+im^int(2angle(z)/pi+1)

Dennis dört byte kurtardı. Teşekkürler!

Çevrimiçi deneyin!


Ben karışık gibi görünüyor int 'in (benim savunmasında olduğu Julia farklı sürümleri arasında davranış korkunç tutarsız). Julia 0.4 (TIO'daki sürüm) yarıya eşit şekilde yuvarlar, bu nedenle bu çalışmaz. Julia 0.3'te, int(2angle(z)/pi+5)aynı bayt sayısı için kullanabilirsiniz (negatif güçler, herhangi bir nedenle bir hataya neden olur).
Dennis,

Ayrıca, bir bayt ile !z=z+(z!=0)im^...tüm sürümlerinde kaydedebilirsiniz .
Dennis,

2

C ++, 94 bayt

#define a(x) (x>0?x:-(x))
#define f(x,y) y>a(x-.5)?x--:-y>a(x+.5)?x++:x>a(y+.5)?y++:x|y?y--:x;

Ungolfed:

#define a(x) (x>0?x:-(x))  //shorter than std::abs from <cmath>
#define f(x,y) 
    y>a(x-.5)?      // shift absolute value function by 0.5 to the right to get upper fourth
        x--:
        -y>a(x+.5)? //same for lower fourth
            x++:
            x>a(y+.5)? //same for right fourth
                y++:
                x|y? //only left fourth and 0 are left
                    y--:
                    x; //can't be empty, just does nothing

Kullanımı:

#include <iostream>
void test(int x, int y, int rx, int ry){
    std::cout << "(" << x << ", " << y << ")=>";
    f(x,y);
    std::cout << "(" << x << ", " << y << ") - " << ((x==rx&&y==ry)?"OK":"FAILURE") << std::endl;
}

//Using the test cases from the question
int main() {
    test(0, 0, 0, 0);
    test(1, 0, 1, 1);
    test(1, 1, 0, 1);
    test(0, 1, -1, 1);
    test(-1, 1, -1, 0);
    test(-1, 0, -1, -1);
    test(-1, -1, 0, -1);
    test(0, -1, 1, -1);
    test(1, -1, 1, 0);
    test(95, -12, 95, -11);
    test(127, 127, 126, 127);
    test(-2, 101, -3, 101);
    test(-65, 65, -65, 64);
    test(-127, 42, -127, 41);
    test(-9, -9, -8, -9);
    test(126, -127, 127, -127);
    test(105, -105, 105, -104);

    return 0;
}

Çevrimiçi deneyin


Ben eminim (x>0?x:-(x))olabilir (x>0?x:-x).
Yytsi

Ne yazık ki hayır, çünkü x belirteci x ile değiştirilecek, çünkü x + .5 olacak.
Anedar

Peki. Parantezsiz olumsuzlamaların işaretini çevirdiği bir zihniyet vardı: D
Yytsi

Açıkçası, C önişlemcisini kullandınız (kuşkusuz C ++ 'ın bir parçası, ancak aynı zamanda diğer C çeşitleri ve torunları ile paylaşılıyor)
tucuxi

2

R, 131 110 bayt

İki tamsayıyı alan ve işlevi x,ystdout'a yazan bir fonksiyon . Çözüm @Dennis'in kontrol akış şemasını takip ediyor ancak muhtemelen golf oynayabilirdi.

EDIT: @ JDL'nin önerilerini temel alarak kod güncellendi ve bir sürü bayt kaydedildi.

function(x,y){X=sign(x+y);Y=sign(y-x);if(!X|!Y){x=x-X;y=y-Y}else if(X==Y&X&Y)x=x-X else if(X-Y&X)y=y-Y;c(x,y)}

Ungolfed

f=function(x,y){
    X=sign(x+y)                 # calculate sign 
    Y=sign(y-x)                 #  =||=
    if(!X|!Y){x=x-X;y=y-Y}      # if at least one is 0: subtract sign
    else if(X==Y&X&Y)x=x-X      # if signs are equal and non-zero: add sign to x
    else if(X-Y&X)y=y-Y         # if signs are not equal and non-zero: add sign to y
    c(x,y)                      # print to stdout
}

1
Bence bazı mantıksal koşullar kısaltılabilir: as.logical(-1)öyle TRUE, öyle X==0|Y==0olabilir !X|!Yve koşul if(X!=Y...)olabilir if(X-Y). Ayrıca, eğer X==Yve X!=0sonra Y!=0gereksizdir. Aslında, tüm !=0parçalar gereksizdir; if(X!=0)eşittir if(X).
JDL

1
Ayrıca, "G / Ç formatı oldukça esnek" olduğu göz önüne alındığında, bunun c(x,y)yerine örtük olarak çıktı almak adil bir oyundur cat(x,y).
JDL

@JDL Bunlar, hiç düşünmediğim çok yararlı golf ipuçları. Cevap güncellendi.
Billywob

2

JavaScript (ES6), 57 bayt (55–63 †)

Bir [x, y] dizisini kabul eder, yerinde değiştirir ve geri döndürür.

c=>([x,y]=c,i=x>y|x==y&x<0,c[i^x<-y|x==-y]-=-i|!!(x|y),c)

Nasıl çalışır

c=>(

Bu, returnserbest özlü bir gövdeye sahip tek parametreli bir ok işlevidir .

[x,y]=c

Parametre derhal xve ydeğişkenler halinde tahrip olur .

,

Virgül operatörü, sonuncunun sonucunu kullanarak birden fazla ifadeyi bir olarak birleştirir.

i=x>y|x==y&x<0

iArttırma ve azaltma durumlarını ayırt etmek için kullanılır. Büyüktür x, yya alt ya da sağ kadrandayız ve bir boyutta ilerlememiz gerekir ( i=1boolean-sayı zorlamasıyla). Aynı şekilde, x = y köşegenlemesinin negatif kısmının üzerindeyken . Diğer tüm durumlarda - başlangıç ​​noktası dahil - herhangi bir artış gerekmez ( i=0).

c[i^x<-y|x==-y]

Hangi dizi indeksinin ayarlanacağını kontrol etmek için biraz benzer bir ifade kullanıyoruz. Biz artan olup sol ve alt kadranlarda (ya da zaman zaman değil artırma ve de sol ya da alt), daha sonra bit-bazında XOR üretecek 1ve ayarlayacaktır y değeri. Aynı şekilde, x = -y köşegeninde (orijin dahil) bölenler için de geçerlidir. Diğer tüm durumlarda, dizin 0( x ) olacaktır.

-=-i|!!(x|y)

Olduğu zaman i, 1belirtilen değere ekleyeceğiz. Ne zaman i, eğer0 başlangıçta değilsek ve eğer olmasaydık 1 değerini çıkarırız . Sonuncusu x|ysıfır vermeyerek tespit edilir , bool zorlama ile {0, 1} 'e kesilir ve ihmal edilmemesi ibize mantıksal olarak bitsel OR kullanmamıza izin verir (çünkü -1sıfır bit yoktur, değişiklikten güvenlidir).

c

Dizi son, bu yüzden döndürülecek.

Test yapmak

† Varyasyonları

Anlamlı bir geri dönüş değeri atlayarak ve yalnızca giriş mutasyonunu kullanarak iki bayttan daha tasarruf edebiliriz :

c=>([x,y]=c,i=x>y|x==y&x<0,c[i^x<-y|x==-y]-=-i|!!(x|y))

… Ya da girdi mutasyonunu atlayabilir ve tüm değişkenleri, altı bayt pahasına, saf bir işlev için yerel yapabiliriz:

([x,y],i=x>y|x==y&x<0,c=[x,y])=>(c[i^x<-y|x==-y]-=-i|!!(x|y),c)

1

JavaScript (ES6), 80 76 bayt

(x,y,s=Math.max(x,y,-x,-y))=>(s?x+s?y-s?x-s?x++:y++:x--:y+s?y--:x++:0,[x,y])

1

Haskell, 53 bayt

0%0=(0,0)
x%y|y>=0-x,y<x=(x,y+1)|(p,q)<-(-y)%x=(q,-p)

İki sayı alır, bir sonuç verir. Nokta doğu bölümündeyse -x<=y<x, ikinci koordinatı 1 ile artırın. Aksi takdirde, giriş noktasını 90 derece döndürerek, üzerine işlevi çağırarak sonra geri döndürerek kadranları çevirin.


1

Raket 191 bayt

(cond[(= 0 x y)(list x y)][(= x y)(if(> x 0)(list(sub1 x)y)(list(add1 x)y))][(> x y)(if(>= x(abs y))
(list x(add1 y))(list(add1 x)y))][(< x y)(if(> y(abs x))(list(sub1 x)y)(list x(sub1 y)))])

Ungolfed (herhangi bir ara formül kullanmadan doğrudan şekil talimatlarını koda çevirerek)

(define(f x y)
  (cond
    [(= 0 x y) (list x y)]
    [(= x y)
     (if (> x 0)
         (list (sub1 x) y)   ; left
         (list (add1 x) y))] ; right
    [(> x y)
     (if (>= x (abs y))
         (list x (add1 y))   ; up
         (list (add1 x) y))] ; right
    [(< x y)
     (if (> y (abs x))
         (list (sub1 x) y)   ; left
         (list x (sub1 y)))] ; down
    ))

Test yapmak:

(f 0  0)      
(f 1  0)     
(f 1  1)     
(f 0  1)     
(f -1  1)    
(f -1  0)    
(f -1  -1)   
(f 0  -1)    
(f 1  -1)    
(f 95  -12)  
(f 127  127) 
(f -2  101)  
(f -65  65)  
(f -127  42) 
(f -9  -9)    
(f 126  -127) 
(f 105  -105) 

Çıktı:

'(0 0)
'(1 1)
'(0 1)
'(-1 1)
'(-1 0)
'(-1 -1)
'(0 -1)
'(1 -1)
'(1 0)
'(95 -11)
'(126 127)
'(-3 101)
'(-65 64)
'(-127 41)
'(-8 -9)
'(127 -127)
'(105 -104)

1

Aslında , 16 bayt

Bu girdi olarak karmaşık bir sayı alır ve başka bir karmaşık sayı çıkarır. Golf önerileri hoş geldiniz! Çevrimiçi deneyin!

;`₧╦@/τuLïⁿ+0`╬X

Ungolfing

         Implicit input z.
;        Duplicate z.
`...`╬   If z is non-zero (any a+bi except 0+0j), run the following function.
           Stack: z, z
  ₧        Get phase(z).
  ╦@/      Divide phase(z) by pi.
  τuL      Push floor(2*phase(z)/pi + 1).
  ïⁿ       Push 1j ** floor(2*phase(z)/pi + 1).
  +        And add it to z. This is our rotated z.
  0        Push 0 to end the function.
X        Discard either the duplicate (0+0j) or the 0 from the end of function.
         Implicit return.

0

Scala, 184 bayt

val s=math.signum _
(x:Int,y:Int)=>{val m=x.abs max y.abs
if(x.abs==y.abs)if(s(x)==s(y))(x-s(x),y)else(x,y-s(y))else
if(x.abs==m)(x,y+Seq(0,x).indexOf(m))else(x-Seq(0,y).indexOf(m),y)}

Ungolfed:

import math._

(x: Int, y: Int) => {
  val max = max(x.abs, y.abs)
  if (x.abs == y.abs)
    if (signum(x) == signum(y))
      (x - signum(x), y)
    else
      (x, y - signum(y))
  else
    if (x.abs == max)
      (x, y + Seq(0, x).indexOf(max))
    else
      (x - Seq(0, y).indexOf(max), y)
}

Açıklama:

val s=math.signum _             //define s as an alias to math.signum
(x:Int,y:Int)=>{                //define an anonymous function
  val m=x.abs max y.abs           //calculate the maximum of the absolute values,
                                  //which is 1 for the innermost circle and so on.
  if(x.abs==y.abs)                //if we have a cell at a corner of a circle
    if(s(x)==s(y))                  //if it's at the top-left or bottom-right, we need to
                                    //modify the x value
      (x-s(x),y)                      //if x is positive (bottom-right),
                                      //we need to return (x+1,y),
                                      //(x-1,y) If it's at the top-left.
                                      //This can be simplified to (x-s(x),y)
    else                            //for top-right and bottom-left, 
      (x,y-s(y))                      //modify y in the same way.
  else                            //we don't have a corner piece
    if(x.abs==m)                    //if we're at the left or right edge of the square
      (x,y+Seq(0,x).indexOf(m))       //if it's a piece from the right edge, add one
                                      //to y, else subtract 1
    else                            //it's a piece from the top or bottm edge
      (x-Seq(0,y).indexOf(m),y)       //subtract 1 from x if it's from the top edge,
                                      //else subtract -1
}
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.