F olmayan bir tamsayılar için f (f (n)) = -n olacak şekilde bir f işlevi tanımlayın.


43

Bu zorluk, sık kullandığım bir programlama bloğundan esinlenmiştir. Lütfen orijinal yazıya bakınız: Bir Programlama Yapboz


Meydan okuma

Bir işlev tanımlayın f:Q->Qöyle ki f(f(n)) = -ntüm sıfırdan farklı tamsayılar için nve Qrasyonel sayılar kümesidir.

ayrıntılar

Ne olursa olsun tercih dil olarak tanımlar mısınız bir fonksiyon veya program fparametresi olarak kabul tek sayı nve getiri veya çıkışı bir numara f(n).

Diliniz için hangi mekanizma en doğal olursa olsun girdi sağlanabilir: işlev argümanı, STDIN'den okunan komut satırı argümanı, yığın konumu, ses girişi, çete işaretleri vb.

Çıktı bir fonksiyondan / programdan bir dönüş değeri olmalı veya STDOUT'a yazdırılmalıdır.

Program durumundan veya işlev dışından görülebilen genel bellekten / verilerden faydalanmayan işlevlerin yanıtlarını sınırlandırmak istiyorum f. Örneğin, bir sayacı bunun dışında tutmak fkaç kez fçağrıldığını sayar ve bu sayıya dayanarak sadece bir olumsuzlama yapmak hiç kimse için çok zor veya ilginç değildir. Alınan kararlar fsadece kendi fkapsamındaki verilere dayanmalıdır .

Bununla birlikte, bu kısıtlama, bazı yığın yönelimli diller veya bu tür veri veya kapsamları ayırt etmeyen diğer dil türleri için uygun değildir. Lütfen bu zorluğun ruhuna ayak uydurmak için en iyi kararınızı kullanın.


puanlama

Genel kod golf kuralları geçerlidir - puanınız kaynak kodunuzdaki bayt sayısıdır .

Asgari cevap, alanın ve alan adının frasyonellerin bir alt kümesi olmasını gerektirir Q. Etki alanınızı ve etki alanınızı ftamsayılarla sınırlarsanız Z, puanınız kaynak kodunuzdaki bayt sayısının% 90'ının tavanıdır .

Mola, tenis terimi

Beraberlik durumunda, aşağıdakiler sırayla kullanılacaktır:

  1. Kaynak kodunuzda en az sayıda yazdırılabilir boşluk olmayan simge var
  2. Yanıtın en erken tarihi ve saati

Düzenle

İsteğe bağlı büyüklükteki sayıları desteklemeniz gerekmez. Lütfen kümeleri Zve Qveri tiplerini seçtiğiniz dilde yorumlayınız (sırasıyla tam sayı ve kayan nokta).

Çözümünüz tamamen bir veri tipinin altında yatan yapıya veya bit desenine bağlıysa, lütfen sınırlamalarını ve nasıl kullanıldığını açıklayın.


20
f (n) = i * n - saf matematik: P
Johannes Kuhn

8
@JohannesKuhn bu yüzden etki alanı ve etki alanı rasyonellerle sınırlı
ardnew

Ne anlama f:Q->Qgeldiğini açıklayabilir misin ?
beary605

@ beary605 f, Q(rasyonel sayılar) üyelerini diğer üyelere (muhtemelen aynı) eşleyen bir fonksiyon anlamına gelir Q. bkz. en.wikipedia.org/wiki/Function_(mathematics)#Notation
ardnew

7
Bunu son zamanlarda gördüğümü biliyordum, ama nerede olduğunu hatırlamak biraz zaman aldı. Bir StackOverflow'daki az sıkı Belirtilen sürüm son zamanlarda kapatıldı. 100'den fazla cevap.
Peter Taylor

Yanıtlar:


12

J, 9 puan (10 karakter)

Yığın akışı cevabına göre :

   (*-[*_1&^)

İlk fikir (13 karakter):

   ((-*)-2&|*+:)

   ((-*)-2&|*+:) _10 _9 _8 _7 _6 _5 _4 _3 _2 _1 0 1 2 3 4 5 6 7 8 9 10
_9 10 _7 8 _5 6 _3 4 _1 2 0 _2 1 _4 3 _6 5 _8 7 _10 9

   ((-*)-2&|*+:) _9 10 _7 8 _5 6 _3 4 _1 2 0 _2 1 _4 3 _6 5 _8 7 _10 9
10 9 8 7 6 5 4 3 2 1 0 _1 _2 _3 _4 _5 _6 _7 _8 _9 _10

Bu, tamsayı girişi için çalışır, ancak bu kayan nokta değerleri için hayali çıktı üretir (işlev, teknik özelliklere göre rasyonel girdi için rasyonel çıktı üretmelidir)
Volatility

5
@Volatility, spec ifadesiyle kafa karıştırıcı, ancak okuduğumda etki alanı ve alan adının tamsayıları kısıtlamasına izin veriyor.
Peter Taylor

Parantezlere mi ihtiyacınız var?
Cyoce

14

Python: 61 34 30 29 27 puan

f: S -> S

matematikte:

       | 0.5-x   if x is in Q \ Z
f(x) = |
       | x+0.5   if x is in Z

Python'da:

f=lambda x:.5+[x,-x][x%1>0]

ile test edildi

filter(lambda n: n[0] != -n[1], map(lambda n:(n,f(f(n))),range(0,50)))

bunun arkasındaki mantık:

Bir tamsayı alıp niçine koyduğunuzda falırsınız x+0.5. Bu artık bir tamsayı değil, bu yüzden bir sonraki uygulama 0.5-(x+0.5)hangisi olacak -x.

Kredi

Sayesinde

  • Bakuriu , 61 karakterden 34 karaktere kadar şeritleme işlemi için.
  • Kod boyutunu 30 karaktere kadar azaltmak için uçuculuk .
  • kod boyutunu 29 karaktere küçültmek için kopyalayın (ve olası bir kayan nokta sorununu düzeltin).
  • aditsu , yukarıdaki değişikliklerle gelen bir tutarsızlıktan bahsettiği için.

notlar

İlk önce bunun iyi olacağını düşündüm

f = lambda n: 1j*n

fakat f: N-> C ve buna izin verilmiyor: - /


1
Aşağı doğru sıyrılabilir: f=lambda x:x%1>0and(-x+x%1)or x+.1yalnızca 34 karakter uzunluğunda.
Bakuriu

f=lambda x:[x+.1,x%1-x](x%1>0)sadece 30
Volatility

1
Bir kısa Char: f=lambda x:[x+.5,.5-x][x%1>0]. Hassas konular etrafında almak için .5 yerine .1 kullanımına dikkat
copy

1
@AJMansfield 1.48 bir tam sayı değil.
Martin Thoma

1
Hayır, bu demek değil. Bunu söylerse, "bütün rasyonel sayıları" yazmalıydı. f:Q->Qbu sadece, rasyonel sayıları rasyonel sayılarla eşleştirdiği anlamına gelir. Benim tanımımın yaptığı gibi.
Martin Thoma

11

C, 41 puan (41 veya 45 karakter)

Hem 32 hem de 64 bit kullanarak çalışır.

f : Z -> Z(hariç INT_MAX):

f(n){return (abs(n)%2*2-1)*n+n?(-n<n)*2-1:0;}

0Dahil etmek zorunda değilsek, bazı karakterleri tıraş edebiliriz (41 karakter):

f : Z -> Z( 0& hariç INT_MAX):

f(n){return (abs(n)%2*2-1)*n+(-n<n)*2-1;}

Bu fonksiyon tüm tam sayıları işaret ve paritelerine göre 4 gruba ayırarak çalışır.

Yani 4 farklı kombinasyonumuz var:

+ even, + odd, - even, - odd

İki işareti geçtikten sonra sayı işaretini değiştirmemiz gerektiğinden, ancak eşliği değiştirmememiz gerektiğinden, iki farklı olası dizilim elde ediyoruz:

  + even -> - odd -> - even -> + odd -\
^-------------------------------------/

  + even -> + odd -> - even -> - odd -\
^-------------------------------------/

Bu örnekte ilkini seçtim.

Öncelikle, tüm pozitif pozitif tamsayıları garip negatif tamsayılarla eşlememiz gerekir. Bunu, işareti değiştirerek ve sayıyı artırarak yaparız (bunun yerine sayıyı düşürmeyi de seçebilirsiniz):

f1(n) = -n + 1

O zaman tüm garip negatif tam sayılarını, negatif tam sayılarla eşleştirmemiz gerekir. Şunlardan emin olmalıyız f2(f1(n)) = -n:

f2(f1(n)) = -n
f2(-n + 1) = -n
f2(-n) = -n - 1
f2(n) = n - 1

Bulduğumuz aynı yöntemleri kullanarak f3ve f4:

f3(n) = -n - 1
f4(n) =  n + 1

Bu işlevleri tek bir işlevde birleştirmek için, her zamanın nişaretini değiştirdiğimizin bile olduğunu nve her zamanın npozitif olduğunu, aksi halde bir azaldığımızı gözlemliyoruz :

f1(n) = -n + 1 (+ even)
f2(n) =  n - 1 (- odd)
f2(n) = -n - 1 (- even)
f4(n) =  n + 1 (+ odd)

Bu şekilde şöyle yazılabilir:

f(n) = odd(n) * n + sign(n)

nerede odd(n)döner 1tek sayı ve -1çift sayılar için.

Toplam 4 çözüm var:

f(n) = odd(n) * n + sign(n)  (edge cases: f(f(0))  -> -2, f(f(INT_MAX))   -> -8)
f(n) = even(n) * n - sign(n) (edge cases: f(f(0))  -> -2, f(f(INT_MIN+1)) -> -6)
f(n) = odd(n) * n - sign(n)  (edge cases: f(f(1))  -> -3, f(f(INT_MIN))   -> -5)
f(n) = even(n) * n + sign(n) (edge cases: f(f(-1)) -> -1, f(f(INT_MIN))   -> -5)

INT_MIN-INT_MIN == INT_MIN= 4 olarak her dört fonksiyonda da daima bir uç durum olarak kabul edilebilir f(f(INT_MIN)) = INT_MIN.


Bu aslında GolfScript cevabımla aynıdır (daha iyi açıklanması dışında). Bu 0 için çalışıyor mu?
Ben Reich

@BenReich Cevabında belirtildiği gibi 0ve 3 başka numara için çalışmıyor .
Tyilo

1
@Tylio şimdi görüyorum. Mantıklı. ZEn azından 0 alırsan bonusu almalısın .
Ben Reich

@BenReich Bonusu düzeltene kadar kaldırıldı.
Tyilo

9

İşte benim gidiyorum.

long f(int i){return i;}
int f(long i){return -i;}

Canlı örnek :

int main()
{
  for(int i=-10; i<10; i=i+3)
    std::cout << f(f(i)) << "\n";
}

Cn giriş tipleri isteğe bağlı olarak ihtiyaçlarınıza göre uyarlanabilir. Bu sürüm 2 ^ 32-1'den küçük tam sayı değişmezleri için çalışıyor.


2
Sorun söyledi f:Q->Q, değil f:Z->Z.
AJMansfield

@AJMansfield spec puanlama bölümünde tanımlanan işlevleri için teklif bonus puan gerekiyordu f:Z->Z, üzgünüm kafa karıştırıcı ifadeler için
ardnew

6
Bu cevaba göre sorun iki ayrı fonksiyon tanımlamak gibi görünmekle birlikte, sadece bir tanım tanımlamanızı gerektirir. ama yine de çok düşünceli bir çözüm, bir semantik tartışma başlatmak istemem
ardnew

@ardnew, oh haklısın. SO sohbeti Lounge <C ++> ile paylaşmadan sadece birkaç saniye önce bu geçerli itiraza işaret ettim. Derleyiciden bunun ne yaptığını merak ediyorum (çağrıları satır içi yapmazsa), ancak montajım berbat.
rubenvb

1
Sanırım boşlukları kaldırabilirsinizreturn -i
Cyoce

6

JavaScript, 18

f=n=>n%1?.5-n:n+.5

Yeni yağ oku gösterimini kullanma (Firefox 22).

Diğer versiyon (18):

f=n=>n%1?-.5/n:.5/n

Önceki sürüm (20):

f=n=>n-~~n?.5-n:n+.5

Örnek:

> [-3,-2,-1,1,2,3].map(f).map(f)
[3, 2, 1, -1, -2, -3]

10
Javascript CoffeeScript'e dönüşüyor gibi görünüyor.
Peter Taylor

4

Mathematica 18

f=#+1/2-4#(#-⌊#⌋)&

İşte ⌊...⌋kat işlevi. Sadece rasyonel sayılar kullanır (listeler değil, karmaşık sayılar vb.)

f[10]
f[f[10]]

21/2

-10

f[-5]
f[f[-5]]

-9/2

5


3

x86 derleme dili (FASM). Argüman ve sonuç eax register'ındadır.

-2 ^ 30 için düzgün çalışıyor <N <+ 2 ^ 30-1

16 bayt çalıştırılabilir kod.

        use32

f_n:
        lea     edx, [2*eax]
        xor     edx, eax
        btc     eax, 30
        shl     edx, 1
        jnc     .end
        neg     eax
.end:
        retn

Sayılarını nitelemek; 2E30 2 * 10 ^ 30 olur, 2 ^ 30 değil, sanırım istediğiniz gibi.
Nick T,

@NickT Benim hatam. Sabit.
johnfound

Kaynak koddaki baytları saymanız gerektiğinden eminim.
nyuszika7h

3

Ortak Lisp: 35 bayt

(defun f(x)(/(if(> 1 x)-1/2 1/2)x))

Şema (ve Raket): 36 bayt

(define(f x)(/(if(> 1 x)-1/2 1/2)x))

Yorum ve açıklama ile Ungolfed:

(define (f x)
  (/             ;; divide
     (if (> 1 x) ;; if x is below 1 
         -1/2    ;; then -1/2 (the fraction)
         1/2)    ;; else 1/2 (the fraction)
      x))        ;; gets divided with x

Herhangi bir sayı için xde kesir dönüşecek her iki dilde gerçek tam sayıdır.[1,->]if1/2

Böylelikle bölünme kısmı (/ 1/2 x), kesir 1/(x*2)her zaman aşağıda olan olacak 1. İçin 1öyle olacak 1/2, için 2bu kadar 1/4vb

1'in altındaki herhangi bir sayı ifiçin -1/2, bu, fonksiyonun yaptığı işlevi yapan kesriye dönüşecektir (/ -1/2 x), -1/(2*x)ancak değerin, önceki çalışmanın sonucu olmasını bekleyebileceğimizden, 1 / (x * 2) 'nin çift uygulama yapması için x yerine koyabiliriz.-1/((1/(x*2))*2) = -x

Örneğin ikinci uygulamaya 1dönüştüğünden1/2(/ -1/2 1/2) ==> -1


Bu nasıl çalışıyor?
AJMansfield

@AJMansfield bazı bilgiler ekledi. Sadece net olmayan bir şey olup olmadığını sorun. Eğer öğrenmediyseniz LISP sözdizimini okumak Yunanca gibidir ve alışması biraz zaman alır.
Sylwester

3

C, 60 (⌈66 *, 9⌉)

int f(int x){if(!x&1||!~x)return ~x;if(x<0)return x-1;return x+1;}

İşte yoğunlaşmamış bir versiyon:

int f(int x){
    if(!x&1 || !~x) return ~x;
    if(x<0) return x-1;
    return x+1;
}

Bu yöntem sadece tam sayıları kullanarak çalışır, bu yüzden% 90 puan bonusu alır. Başlangıçta java'da yazıyordum ancak bu programın özellikle C tarzı mantıksal operatörlerden faydalanabileceğini fark ettim.

Buna karşılık gelen bir tamsayı olmadığından -INT_MIN, bunun yerine f(f(INT_MIN))döner INT_MIN.

Temel haritalama cebirsel olarak oldukça basittir. İfadeyi çalıştırmak x=f(x)x ile değiştirilir:

  • x+1, eğer xolumlu ve tuhafsa
  • -x+1, eğer xolumlu ve hatta
  • x-1, eğer xnegatif ve tuhafsa
  • -x-1, eğer xolumsuz ve hatta

Her durumun sonucu, işlev bir daha x'e uygulandığında bir sonraki durumun altına düşecektir.

Gördüğünüz gibi, bir olayı takip eden bir dava ile hazırlamak -x.

Kod, ikisinin tamsayı tamsayısının bit yapısından yararlanmak için fonksiyonun akıllıca basitleştirilmesinin bir sonucudur.


3

> <> , 21 + 3 = 24 bayt, 22 puan

:0)$:0($:1$2%2*-*+-n;

Kullanım resmi Python yorumlayıcısı ve kullanımı -v3 bayt bir maliyetle, giriş girmek için komut satırı seçeneği.

Bunun daha iyi olabileceği hissine sahibim - bakmaya devam edip golf oynamaya çalışacağım.

Verilen girdi n, program çıktıları

(n>0) - ((n<0) + n * (1 - 2*(n%2)))

Boole'lar nerede (n>0)ve (n<0). Bu Gelatin'in Python cevabına eşittir

(n>0) - (n<0) - n * (-1)**n

ancak ><>yerleşik bir üs işletmecisine sahip değiliz, bu yüzden (1 - 2*(n%2))yerine kullanırız (-1)**n.

Ardından matematik teorisi var - eğer ilgilenirseniz (ve eğer ilgilenirseniz) okuyun:

Herhangi bir fonksiyonu göz önüne alındığında f: Z -> Zböyle f(f(n)) = -nherkes için nin Z, bunu hemen bakın f(f(f(f(n)))) = nveya başka bir deyişle, f^4kimlik fonksiyonudur. Özellikle, fters çevrilebilir ve ters işlevidir f^3. Bu nedenle fbir permütasyon Zve o zamandan beri f^4 = Id, her bir yörünge (veya bir) izler fboyutu ya sahip 1, 2ya da 4.

Sonra bunu görüyoruz f(0) = 0. Dayanıklı: f(0) = f(-0) = f(f(f(0))) = -f(0)bu yüzden f(0) = 0, arzu edilen. Bunun aksine, diyelim ki xuzunlukta bir döngüsü içinde 1veya 2bu yüzden f(f(x)) = x. Öyleyse -x = xöyleyse x = 0.

Bu nedenle f, adresindeki sabit nokta (1-döngü) hariç, tamamen 4-döngüden oluşur 0.

Ayrıca, her 4 döngüsü formu olmalı (x, y, -x, -y)ve biz varsayabiliriz etrafında döngüsünü çevirerek xve yher ikisi de olumludur. Tersine, sıfır olmayan tamsayıları bölen 4-döngüden oluşan her bir ürün bir seçimini belirler f.

Bu nedenle, her bir seçim f, köşeleri pozitif tamsayılar olan yönlendirilmiş bir grafiğe tekabül eder, öyle ki her köşe girişte ya da çıkarken tam olarak bir oka gelir. Daha doğrusu, alttaki yönlendirilmemiş grafikte, her köşe tam olarak dereceye sahiptir 1. (Her bir 4-döngü (x y -x -y)ile xve yok pozitif karşılık gelir x --> y.)

Bu yanıt (ve burada birkaç diğer yanıtlar) olarak işlev grafik tekabül 1 --> 2, 3 --> 4ve genel olarak 2k-1 --> 2k.

Bu grafikler sipariş çiftlerinin sonsuz sekansları ile bir eşleşme (a_n, p_n)her a_nbir pozitif tamsayıdır ve her bir p_nya da bir 0ya da 1bir sekans verilen: (a_1, p_1), (a_2, p_2), (a_3, p_3), ..., ilk çifti 1ile 1 + a_1, ve daha sonra ok oluşturabilir; 1 --> 1 + a_1veya oku 1 + a_1 --> 1bağlı olarak p_1bir 0ya da 1. Temel olarak, ok paritesine bağlı olarak, bir <işaret ya da >işarettir p_1.

Daha sonra, en küçük eşleşmemiş pozitif bir tamsayı almak kve yukarı saymak ktam olarak a_2zaten bir şeyler ile eşleştirilmiş herhangi bir sayıda ATLAMASI adımlar. Sonucu kile eşleştirin ve p_2yukarıdaki gibi bağlı olarak ok yönünü ayarlayın . Ardından (a_3, p_3), vb. İle tekrarlayın .

Her ok sonunda bu şekilde belirlenir, bu yüzden süreç iyi tanımlanmıştır. Bu cevaptaki işlev, diziye karşılık gelir (1,0), (1,0), (1,0), ..., çünkü en nküçük eşleşmemiş tamsayı adımda 2n-1hiçbir 2n-1şeyle eşleştirilenden daha büyük tam sayı olmadığından ve 2n-1 --> 2nher biri için elde ettiğimizden n(oklar bu şekilde yönlendirilir çünkü her biri p_neşittir 0).

Bu setin asallığı , bu cevabın(N*2)^N = N^N son paragrafına göre, gerçek sayıların asallığına eşittir .2^N


Komut satırı seçenekleri genellikle birer bayttır.
kedi

@ cat Bu meta gönderinin "Özel çağrılar" bölümüne bakın .
mathmandan

2

Önceki J cevabını düzeltmek için (orijinali yorumlayacak kadar itibarım yok):

(*+[*1-~2*2|])

Sadece tam tersi işareti veren _1&^ile değiştirir 1-~2*2|]. Değiştim Yani -bir karşı +(ki sadece girişindeki önemli 1ve _1).

İşte testler:

   (*+[*1-~2*2|])6 3 _9 _8 1r2 _4.6 0 1 _1
7 _2 8 _9 1 7.28 0 2 _2
   (*+[*1-~2*2|])7 _2 8 _9 1 7.28 0 2 _2
_6 _3 9 8 0 _10.3568 0 _1 1

   NB. f^:2 = f@:f
   (*+[*1-~2*2|])^:(2)6 3 _9 _8 1r2 _4.6 0 1 _1
_6 _3 9 8 2 _5.0832 0 _1 1

Görebildiğiniz gibi, etki alanı ve aralığı tüm gerçek sayılardır, ancak yalnızca tam sayılar için çalışır (0 dahil).

Açıklama:

(   *     + [ *  1-~    2*     2|]    )
 signum n + n * pred (twice (n mod 2))

2

GolfScript ceiling(26*.9)=24

Golfscript sadece tamsayıları işler, bu yüzden Zbonusu toplam 24 puan için uygulayın:

.{..0>2*(\)2%!2*(@*+}{ }if

Özel 0 durumu, 8 karakterden oluşuyor. 0'ı yok sayarak, 17 puanlık bir cevabımız olabilir:

..0>2*(\)2%!2*(@*+

Bu kod x, yığının en üstünde bir tam sayı için aşağıdakileri yapar :

  • Eğer x0, dan ayrıldığı 0yığını üzerinde ve daha fazla kural geçerlidir.
  • Eğer xinkâr bile olduğunu x.
  • Eğer xolumlu, ekleyin 1.
  • Eğer xnegatifse, çıkartın 1.

Bu, döngüsel olarak 4 sayı kümesini birbirine bağlar, burada döngünün föğelerini çaprazlar ve döngünün karşıt köşeleri birbirinin negatifleridir. Her tamsayı, özel kasalı olan 0 hariç, tam olarak bu tür bir döngünün parçasıdır. Örneğin, şunun için {-8, -7, 7, 8}:

  • 7 f -> 8
  • 8 f -> -7
  • -7 f -> -8
  • -8 f -> 7

Aklıma gelebilecek tek ilgili test vakaları, olumsuz, tek, negatif, pozitif, tek, pozitif 0, ve sonra attım -1ve 1yakınlıklarından dolayı 0sorunlara neden olmuş olabileceğim için:

[-10 -5 -1 0 1 5 10]
{.{..0>2*(\)2%!2*(@*+}{ }if}:f;
{f f}%
-> [10,5,1,0,-1,-5,-10]

Gerçek GolfScript'in biraz geliştirilebileceğinden eminim. 26 karakter alması gerektiğini düşünmüyor! Bazı önerileri duymak isterim.


2

Java, sadece eğlence için

İşte ℤ ve ℤ² arasında gerçek bir önyükleme yapan ve aynı zamanda tek bir işlev olan bir uygulama (g (-x) == -g (x)). Karşılık gelen element² elemanını karmaşık bir sayı olarak ele alır ve onu "i" ile çarpar, sonra tekrar conver değerine dönüştürür.

f (x) = g⁻¹ (ig (x))
f (f (x)) = g⁻¹ (-g (x)) = - x

İşlev O (1) ile çalışır.

public class Ffn {
    public static int f(int n) {
        if (n == 0) {
            return 0;
        }
        // adjust sign
        int s = n > 0 ? 1 : -1;
        int m = n * s;
        // calculate square "radius"
        int r = (int) (Math.sqrt(2 * m - 1) + 1) / 2;
        int q = r * 2;
        // starting point
        int x = r, y = r;
        int k = q * (r - 1) + 1;

        if (m - k < q) {
            // go left
            x -= m - k;
        }
        else {
            // go left
            x -= q;
            // go down
            y -= m - k - q;
        }

        // multiply by i
        int x2 = -y * s, y2 = x * s;
        // adjust sign
        s = y2 < x2 || y2 == x2 && x2 < 0 ? -1 : 1;
        x2 *= s;
        y2 *= s;

        if (y2 == r) {
            // go left
            k += r - x2;
        }
        else {
            // go left and down
            k += q + r - y2;
        }
        return k * s;
    }

    public static void main(final String... args) {
        for (int i = 0; i < 1000000; ++i) {
            if (f(f(i)) != -i || f(f(-i)) != i) {
                System.out.println(i);
            }
        }
    }
}

PS Yeni Yılınız Kutlu Olsun!


Boşluğun gereksiz olduğuna inanıyorum.
pppery

2

Python 3 - 38

@ Moose'nin cevabına benzer, ancak f(n) == n. Tüm tamsayı değerleri için çalışır.

f=lambda x:x*(isinstance(x,int)*2.0-1)

2

Perl, 33 (boşluksuz)

sub f{($=)=@_;$=-$_[0]?-$=:"$=.1"}

Düzenle:

  • $=.".1"kısaltıldı "$=.1"(teşekkür ederim).

Matematik:

Matematik

Ungolfed:

# script.pl
sub f {
  ($=) = @_;   # short for $= = int($_[0]); 
               # "int" is implicit in assignments to $=;
               # ($=) can be prepended by "local" to get
               # the function free of side effects.

  $= - $_[0] ? # short for $= != $_[0], check if input is integer
    -$=        # input is not an integer  
  : $= . ".1"  # input is integer
}  

# Testing
chomp;
$_ = sprintf "f(f($_)) = f(%s) = %s\n", f($_), f(f($_));

Örnekler:

perl -p script.pl
7
f(f(7)) = f(7.1) = -7
2
f(f(2)) = f(2.1) = -2
0
f(f(0)) = f(0.1) = 0
-1
f(f(-1)) = f(-1.1) = 1
-10
f(f(-10)) = f(-10.1) = 10
-1.23
f(f(-1.23)) = f(1) = 1.1
3.4
f(f(3.4)) = f(-3) = -3.1
1.0
f(f(1.0)) = f(1.1) = -1

Sağlam çözüm - demonte ettiğiniz kayan nokta test durumları, spesifikasyon başına talep edilmez (bunun için bonus puan vermiş olmalı!). işte aynı algoritma, 22 karakterde bir kaç temizleme işlemi ile birlikte:sub f{yzxzzc?-$_:x.$_}
ardnew

1
@ardnew: Teşekkürler. Ancak çözümünüzün aynı algoritmayı kullanması konusunda aynı fikirdeyim. Algoritma sub f{yzxzzc?-$_:x.$_}olduğu değil o değişkeni yoluyla bir devlet kullanır, devlet ücretsiz $_. Bu nedenle, fartık bir işlev değildir (matematiksel anlamda), duruma bağlı olarak aynı girdi değeri için farklı değerler mümkündür (hava durumu ya da $_içermez x). Algoritmam bir durum kullanmıyor, bilgi çıktı değerinde kodlanmış. Tamsayılar ekleyerek gerçek sayılara dönüştürülür .1. Ve gerçek sayılar, işaret açıkken tam sayılara geri dönüştürülür.
Heiko Oberdiek

ilginç-hiçbir devlet verileri uygulanmasında kullanılan çünkü ilk atama değil çünkü bazı özel mülkiyet $=?
ardnew

Ben de bu karaktere göre kendi ftanımlamamı ( tanımlanmış olan Q->Q) başarısız olduğumu bilmiyordum x. ayrıca $=.".1"kısaltılabilir"$=.1"
ardnew

@ardnew: Özelliği $=sadece tam sayı almasıdır. Aynı sıradan değişkeni kullanılarak sağlanabilir: $a=int$_[0]. Ancak bu fonksiyon nedeniyle üç ek bayt maliyeti int.
Heiko Oberdiek

2

Julia, 26

julia> f(n::Int)=n//1
f (generic function with 1 method)
julia> f(n)=int(-n)
f (generic function with 2 methods)
julia> f(f(4))
-4

Süper rekabetçi değil, ancak çok sayıda gönderime dayandığından dolayı çok Julian. Eğer bu bir int ise na, ya da başka bir şeyse eksi işaretli bir int olur. Biri bunun 2 işlev olduğunu itiraz edebilir, ancak Julia bunu iki yöntemle bir işlev olarak görür ve bir işlevi türünün üzerinde if if statüsü ile tanımlamaya eşdeğerdir n.


Bir matematikçinin bir işlev dediği şey bu değil: Julia'da 3==3//1geri döner trueama f(3//1)==f(3)geri döner false.
Omar

2

Şeker , 20 18 bayt

3 -> 4 -> -3 -> -4 -> 3 numaralarını kullanır.

~A2%{|m}1A0>{+|-}.

Çağırmak için yorumlayıcıdaki -i anahtarını kullanın

İkili çağrı örneği:

$ candy -i 7 -e '~A2%{|m}1A0>{+|-}.'
program length: 18
>>> 8
$ candy -i 8 -e '~A2%{|m}1A0>{+|-}.'
program length: 18
>>> -7
$ candy -i -7 -e '~A2%{|m}1A0>{+|-}.'
program length: 18
>>> -8
$ candy -i -8 -e '~A2%{|m}1A0>{+|-}.'
program length: 18
>>> 7

Uzun formu:

peekA
pushA
digit2
mod          # even/odd
if
else
  negate     # negate even numbers
endif
digit1
pushA
digit0
greater      # positive/negative
if
  add        # add two numbers from stack (original stack value, and delta)
else
  sub        # diff two numbers from stack (original stack value, and delta)
endif
retSub

2

Dyalog APL, 9 puan

×-⍨⊢ׯ1*⊢

Kaynak 9 bayt uzunluğundadır ve bonus için hak kazanır (hiç bir faydası yoktur). Aynı zamanda en üst SO cevabındaki formülü kullanır.




1

Java, 113 bayt

Yaklaşım oldukça basittir. Beklediğimden daha fazla bayt bitti, ancak belki de biraz golf oynayabilir.

public class F{public static int f(int x){if(x<0)x+=-2147483647-++x;x+=1073741824;return x<0?-2147483647-++x:x;}

Temel olarak x'in 4 farklı "alanı" yaratır ve Java'nın değişkenlerin etrafını sarmasını sağlar. Beklenenden daha büyük olan ana neden olan negatif sayılar için bazı zor dönüşümler yapmak zorunda kaldım.

-2147483648 dışında tüm x için çalışır.


1

Golfscript cevap olarak aynı sayı dizisi (3, 4, -3, -4, 3 ...), ancak perl (beyaz boşluk çıkarıldıktan sonra 42 karakter) uygulanır

sub f{($_[0]%2?1:-1)*$_[0]+($_[0]<0?-1:1)}

Daha okunaklı olmak:

sub f { ($_[0] % 2 ? $_[0] : -$_[0] ) + ( $_[0] < 0 ? -1 : 1 ) }

Ya da daha okunaklı bir şekilde:

sub f {
  my $n = shift;
  my $sign = $n >= 0 ? 1 : -1;
  # note that in perl $n % 2 is the same as int($n) % 2
  if( $n % 2 ) {
    # odd: add one to magnitude
    return $n + $sign
  } else {
    # even: subtract one from magnitude then invert
    return -($n - $sign)
  }
}

Çıktı:

ski@anito:~/mysrc/.../acme$ echo 3 | perl -e 'sub f{($_[0]%2?1:-1)*$_[0] + ($_[0]<0?-1:1)}; my $x = <>; for(0..10) { print "$_: $x\n"; $x = f($x); }'
0: 3
1: 4
2: -3
3: -4
4: 3
5: 4
6: -3
7: -4
8: 3
9: 4
10: -3

Yukarıdakiler ayrıca tam sayı olmayanlar için de geçerlidir: ski @ anito: ~ / mysrc /.../ acme $ echo 1.1234 | perl -e 'alt f {($ _ [0]% 2 - 1: -1) * $ _ [0] + ($ _ [0] <0 - -1: 1)}; $ x = <>; (0..4) için {"$ _: $ x \ n" yazdır; $ x = f ($ x); } '0: 1.1234 1: 2.1234 2: -1.1234 3: -2.1234 4: 1.1234
skibrianski

1

Sed, 25 bayt.

|sed s/0+/0-/|sed s/^/0+/

Kullanımı:

$ echo 1.23 |sed s/0+/0-/|sed s/^/0+/
0+1.23
$ echo 0+1.23 |sed s/0+/0-/|sed s/^/0+/
0+0-1.23

1

Matlab, 26 karakter

f=@(n) (n<0)-(n<0)-n*(-1)^n

2
Bu geçerli bir cevap değildir, çünkü işlevin etki alanı ve etki alanı karmaşık olmamalıdır.
Wrzlprmft

ah, özür dilerim ... Sadece başlığı okudum ve o kadar dikkatli değildim ... Bakalım bunu biraz düzenleyebilir miyim
bla

1

C ++ - 63 55,8

Kod böyle görünüyor:

int f(int n){return (n&45056?n^45056:n|45056)*(n&45056?-1:1);}

Dördüncü baytı 0xB'ye eşit olan tamsayılar üzerinde çalışmaz, bu değerleri geçişleri takip etmek için kullanır. Aksi takdirde, sıfır dahil, herhangi bir Z üyesi üzerinde çalışır.


bunu açıklar mısın? İlk incelemede f, statik bir değişkenle yapılan aramaların bir sayacını tuttuğunuz görülüyor. ama sonra ne anlamı var sqrt?
ardnew

Soruyu yanlış anlamış gibiyim; statik bir değişkenin tamam olduğunu düşündüm çünkü C ++ yığın yönelimli bir dil, ancak kodu düzelteceğim. Aksi halde, niçin bir sqrttür döküm ile yuvarlandığından neden gerekli olduğumu bilmiyorum . Statik değişken olmadan çalışabilmesi için refactor yapıcam.
Darkgamma

Nereden geldiğini bilmiyorum 55.8ama şu anki kodun 62 byte. Düzenleme: Boş ver, soruyu doğru okumamıştım.
nyuszika7h

Dördüncü baytın 0xB'ye eşit olamayacağı kısıtı maalesef bu, (en azından) tüm tamsayılarda çalışmasını gerektiren zorluğa geçerli bir cevap değildir.
pppery

1

Synthetica tarafından sağlanan fonksiyonla güncellendi (açıkçası bunun için kredi alması gereken)

Dil: Python

Karakter sayısı: 41 boşluk dahil

f=lambda x:-float(x) if str(x)==x else`x`

Lütfen kullandığınız dilin adını da sağlayın ve karakter sayısını belirtin.
ProgramFOX

Bunun integer olmayanlarla da çalışmasını seviyorum. Aferin. :)
cjfaure

f=lambda x:-float(x) if str(x)==x else`x`biraz daha kısa: boşluklar dahil 41
25ıɐɔuʎs

Teşekkürler Synthetica, backticks hilesini bile bilmiyordum! : D
HolySquirrel

Tamsayılarda fbir dize döndürür; şartname rasyonel bir sayı döndürmesi gerektiğini söylüyor.
Omar

1

Prolog, 36 bayt

Kod:

X*Y:-X//1=:=X,Y is 0.5+X;Y is 0.5-X.

Açıklaması:

Dyadic predicate which converts integers to floats and floats back to negated integers.

Örnek:

10*X.
X = 10.5

10*Y,Y*X.
X = -10,
Y = 10.5


1

Fare-2002 , 21 19 12 bayt

$A1%[1%_|1%]

Bir işlevi tanımlar A; gibi diyoruz #A,#A,?;;(herhangi bir numarayı girmek için kullanıcı için bekleyeceği olan). Alternatif olarak, böyle diyoruz #A,#A,n;;nerede nherhangi bir sayıdır.


1

Julia, 21

f(x)=(1-2(1>x>-1))/2x

Sonra

julia> f(f(12//1))
-12//1

p // q, Julia'nın gerçek rasyonel sayılar gösterimidir.

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.