Eksi, Artı, Kez, Üstatlık?


26

Bu bizim sohbet odamız olan The Ninteenth Byte'da biraz önce yayınladığım bir CMC (chat mini mücadelesi) .

Meydan okuma

Pozitif bir tamsayı verildiğinde x, son 2 bit'ine bağlı olarak x, aşağıdakileri yapın:

x & 3 == 0: 0
x & 3 == 1: x + x
x & 3 == 2: x * x
x & 3 == 3: x ^ x (exponentiation)

Giriş çıkış

Single Integer -> Single Integer  

Çıkışta izleyen bir yeni satıra izin verilir. Başka boşluk yok.

testcases

input       output
    1            2
    2            4
    3           27
    4            0
    5           10
    6           36
    7       823543
    8            0
    9           18
   10          100
   11 285311670611
   12            0

Bu bir mücadelesidir, bu yüzden en kısa kod kazanır!


8
Olmamalı 0durum x + 2diğerleri nasıl gibi görerek, x * 2, x ^ 2, ve x ^^ 2(tetrasyon)? : P
ETH Sunumlar

Desteklememiz gereken en büyük çıktı nedir x ^ x? 32 bit, test durumu için zaten yeterli değil 11ve 64 bit test durumu için yeterli değil 19.
Kevin Cruijssen

@KevinCruijssen Programın teorik olarak sonsuz sayıda boyutta çalışması koşuluyla, yalnızca giriş ve çıktının dilinizin kapsamındaki durumları ele almanız gerektiğini söyleyeceğim.
HyperNeutrino

@HyperNeutrino Tamam, bu durumda (Java 7) kodumu düzelttim (+72 bytes için .. xD)
Kevin Cruijssen

Yanıtlar:


13

Jöle , 8 bayt

ị“+×*_”v

Çevrimiçi deneyin!

Nasıl çalışır

Birincisi, duyuru x&3eşdeğerdir x%4, nerede %modülo olduğunu. Sonra Jelly, modüler indeksleme ( a[n] == a[n+len(a)]) kullandığından , bununla uğraşmamıza bile gerek kalmaz.

Sonra:

  • Varsa x%4==0, geri dönüş x_x(çıkarma) (tutarlılık için);
  • Eğer x%4==1döndüyse x+x;
  • Eğer x%4==2, geri dönüş x×x(çarpma);
  • Eğer öyleyse x%4==3, iade x*x(üs üs)

Jelly'in 1 indeksleme kullandığını, bu yüzden çıkarma "_"işleminin sonuna kadar taşındığını unutmayın.

ị“+×*_”v  example input: 10
ị“+×*_”   index 10 of the string “+×*_”, which gives "×"
       v  evaluate the above as a Jelly expression,
          with 10 as the argument, meaning "10×" is the
          expression evaluated. The dyad "×" takes the
          second argument from the only argument, effectively
          performing the function to itself.

2
@andrybak AFAIK Jelly'in kendi kodlaması var - buraya bakın , ancak tüm karakterlerinin 1 bayt olduğunu biliyorum.
Stephen

"8 bayt". Bayt nasıl sayılmalıdır? Bu cevap sekiz karakterden oluşuyor ancak en azından kodlamada stackexchange bu sayfaya hizmet ediyor, 15 bayt alıyor (kullanılarak sayılır wc --bytes).
andrybak

Dil bir kodlamada yorumlanırsa, bayt sayısı için başka bir kodlama kullanmanın anlamı yoktur (imo)
Mackenzie McClane

@andrybak Bir kodlamada kodlanmış kod, bu sayede tarayıcının doğru bir şekilde gösterdiği 15 byte Jelly'in anladığı bir kodlamadaki kod 8 bayttır. Nasıl kodlandığını bilmek istiyorsanız , github.com/DennisMitchell/jelly/wiki/Code-page adresine bakın .
Etoplay


9

CJam , 12 bayt

ri__"-+*#"=~

Çevrimiçi deneyin!

açıklama

ri            e# Read an int from input (call it x).
  __          e# Duplicate x twice.
    "-+*#"    e# Push this string.
          =   e# Get the character from the string at index x (mod 4).
           ~  e# Eval that char, using the two copies of x from before.

xMod 4 değerine bağlı olarak aşağıdaki işlemlerden birini gerçekleştirir (mod 4, AND 3'e eşittir).

0:  -  Subtraction
1:  +  Addition
2:  *  Multiplication
3:  #  Exponentiation

6

Mathematica 25 Bayt

0[2#,#*#,#^#][[#~Mod~4]]&

@MartinEnder sayesinde 4 bayt kaydedildi


4

Pyth, 8 bayt

.v@"0y*^

yorumlayıcı


Evet bunu test ettim ve işe yarıyor. Ve hayır, vyerine kullanamam .v.
Outgolfer Erik

Kapsamın yerel olduğunu sanıyordum ... .verişemeyeceğimi sanıyordum Q... Görünüşe göre Pyth’a aşığım. +1 sizin için.
Sızdıran Rahibe

@LeakyNun Hayır vyerel kapsamı olan, .vsadece bir ifadeyi evrimleşiyor.
Outgolfer Erik,

Öğrenecek çok şeyim var ...
Leaky Nun

3
Bu çok güzel! Bu kesinlikle harika! Bunun mümkün olduğunu bile bilmiyordum. Stil noktaları için "0y*^olabilir "-+*^.
isaacg



3

Haskell, 28 27 bayt

f x=cycle[0,x+x,x*x,x^x]!!x

Çevrimiçi deneyin!

Düzenleme: 1 byte için @ Ørjan Johansen sayesinde.


Çok geç kaldım, ama bunu bir baytla kısaltabilirsin cycle.
Ørjan Johansen

@ ØrjanJohansen: hiç olmamasından daha iyi. Teşekkürler!
nimi


2

C, 63 veya 62 bayt

#include<math.h>
f(x){return(int[]){0,x+x,x*x,pow(x,x)}[x&3];}

Makrolara izin verilirse -1 bayt x, bunun gibi bir ifade olmadığını varsayar 3+5(önceliği bozar).

#include<math.h>
#define f(x)(int[]){0,x+x,x*x,pow(x,x)}[x&3]

@ceilingcat Doğru, bunu unuttum.
Tim,

MSVS2015'te derlenmez; Intellisense cast to incomplete array type "int[]" is not allowedderleyici dedi dedi error C4576: a parenthesized type followed by an initializer list is a non-standard explicit type conversion syntax; AYRICA! int f (int x) nerede? kod aslında en az 8 bayttır; ayrıca çok yavaş ve verimsizdir, çünkü her şeyi değerlendirir - tekrar etmeyin IRL)

@ xakepp35 Ne? 1) bir C derleyicide derlenmelidir . Çoğu (okuma: hemen hemen tüm MSVC hariç) C derleyicileri (int[])bu durum için bu sözdizimini destekler . 2) f(x)tamamen yasaldır C89. Ben standart belirtmedim. 3) Verimlilikle değil kod boyutuyla ilgilidir. Ve 4) Eğer patronluk yapacaksanız, en azından gerçek bir derleyici kullanın ve / veya gerçeklerinizi kontrol edin.
Tim,

@Tim Čas Ah evet, üzgünüm! C ++ kodu olarak derlemeye çalışıyordum. Bu benim suçum) Derler ve harika çalışır!

2

Java 7, 75 bayt

long c(int n){int x=n%4;return x<1?0:x<2?n+n:x<3?n*n:(long)Math.pow(n,n);}

Kurallara göre geçerli olmasına rağmen long, 64-bit, bu nedenle 19^19yukarıdaki ve üzerindeki üst deneme test durumları için başarısız olur . Bunu düzeltmek için bir BigDecimalyaklaşım kullanabiliriz :

148 146 bayt

import java.math.*;BigDecimal c(int n){int x=n%4;BigDecimal m=new BigDecimal(n);return x<1?m.subtract(m):x<2?m.add(m):x<3?m.multiply(m):m.pow(n);}

Açıklama (BigDecimal yaklaşımının):

import java.math.*;                // Import required for BigDecimal
BigDecimal c(int n){               // Method with integer parameter and BigDecimal return-type
  int x=n%4;                       //  Input modulo-4
  BigDecimal m=new BigDecimal(n);  //  Convert input integer to BigDecimal
  return x<1?                      //  If the input mod-4 is 0:
    m.subtract(m)                  //   Return input - input (shorter than BigDecimal.ZERO)
   :x<2?                           //  Else if the input mod-4 is 1:
    m.add(m)                       //   Return input + input
   :x<3?                           //  Else if the input mod-4 is 2:
    m.multiply(m)                  //   Return input * input
   :                               //  Else:
    m.pow(n);                      //   Return input ^ input
}                                  // End of method

Test kodu:

Burada dene.

import java.math.*;
class M{
  static BigDecimal c(int n){int x=n%4;BigDecimal m=new BigDecimal(n);return x<1?m.subtract(m):x<2?m.add(m):x<3?m.multiply(m):m.pow(n);}

  public static void main(String[] a){
    for (int i = 1; i <= 25; i++) {
      System.out.print(c(i) + "; ");
    }
  }
}

Çıktı:

2; 4; 27; 0; 10; 36; 823543; 0; 18; 100; 285311670611; 0; 26; 196; 437893890380859375; 0; 34; 324; 1978419655660313589123979; 0; 42; 484; 20880467999847912034355032910567; 0; 50; 

Programı bu şekilde düzeltmenize gerek yok: P Eğer sayılar sonsuz boyutta olsaydı eski cevap işe yarayacaktı; ilk program benim şartnameme göre geçerli olurdu. : P
HyperNeutrino

@HyperNeutrino Daha sonra cevabını belirtiyorum .. Ah, Java, herhangi bir kod-golf mücadelesinde kazanamayacak. ;)
Kevin Cruijssen

1
Evet, belirtirim. Ve evet, bu Java, kazanmayacak. : D
HyperNeutrino

2
Ve evet, bu Java, kazanmayacak.: D ” Buna alışkınım. : P 8 bayttan en kısa Java cevabım bile , golf cevaplarına kıyasla çok uzun sürüyor. xD Her ne kadar ilk defa Java cevabımla bir Python cevabı yemiş olmama rağmen, sanırım bir şeyi hesaba katmalı. ;)
Kevin Cruijssen

2

x86 Assembler, Intel sözdizimi, 192 bayt

.data
f dw @q,@w,@e,@r
.code
mov ecx, eax
and ecx, 3
mov edx,dword ptr f[ecx*4]
call [edx]
ret
q:
xor eax,eax
ret
w:
add eax,eax
ret
e:
mul eax,eax
ret
r:
mov ecx,eax
t:
mul eax,eax
loop t
ret

Örnek en hızlı çalışma hızı gibi görünüyor. Fastcall kongre kullanan bir program veya program parçasıdır. xKayıt değişkeninde giriş değişkenini varsayareax ve sonucu da döndürür eax. Temel fikir, burada bazı örneklerde olduğu gibi koşullu atlama kullanmaktan uzak durmaktır. Ayrıca, her şeyi değerlendirmek (dizilerdeki C örneğinde olduğu gibi) değil, functonlar için işaretçiler dizisini kullanmak ve en iyi duruma getirilmiş "C dil anahtarı () - durum .." analogu olarak koşulsuz atlamaları (jmp / call) daha hızlı yapmaktır. Bu teknik aynı zamanda finita otomata benzeri işlemci emülatörleri, uygulayıcılar vb.

Gnc: x64 kullanımı (ör yerine "e" nin kayıt adlarında "r", için raxyerine eax, rcxyerine ecx). Boyut değiştirilmeyecek ve 64-bit işaretsiz sözcükleri kullanacaktır.


PPCG'ye Hoşgeldiniz! Bu zorluğun amacı, kodunuzu mümkün olduğu kadar kısa yapmaktır. Bu durumda, kodunuz tüm bu işlev bildirimlerini birleştirerek bir demet kolayca kısaltılabilir. Bazı boşlukları da kaldırabilirsiniz.
HyperNeutrino

@HyperNeutrino asm kendisi tür "uzun" bir dildir :) bu yüzden bu kısaltmanın nasıl yapılacağı hakkında bir fikrim yok. herhangi bir örnek önerileri?

Üzgünüm, C cevabınızla ilgili yorumumu bu yazıya kopyalamış olmalıyım. ASM'de nasıl programlandığını bilmiyorum ama bazı boşlukları silme potansiyeli var mı?
HyperNeutrino

@HyperNeutrino, üzgünüm .. ama hayır gibi görünüyor) diğerleri arasında en uzun kod olmalı, ben sadece windows crlf'i linux formatına böylelikle 209-> 192 bayt, değişiklikler görülemiyor)

Ah. Bu çok kötü. Ama ne olursa olsun güzel teslim! :)
HyperNeutrino

2

C #, 39 bayt

x=>new[]{0,2,x,Math.Pow(x,x-1)}[x&3]*x;

açıklama

Bunu gözlemle:

(xx, x + x, x * x, x ^ x) == (0, 2, x, x ^ (x-1)) * x

Çözüm bir dizi oluşturur, dizine endeksler ve ardından sonucu çarparak x:

x => new[] { 0, 2, x, Math.Pow(x,x-1) }[x&3] * x;

Alternatif versiyonlar:

x=>new[]{0,x+x,x*x,Math.Pow(x,x)}[x%4];

(39B, dizide yapılan tüm çarpma x%4yerine geçer x&3)

x=>x%4<2?x%2*2*x:Math.Pow(x,x%4<3?2:x);

(39B, @ MetaColon'un cevabı ile aynı, ancak x%2*2*xdeğiştirme x*x%4<1?0:2)


1

Aslında , 12 bayt

;;3&"-+*ⁿ"Eƒ

Çevrimiçi deneyin!

Açıklama:

;;3&"-+*ⁿ"Eƒ
;;            two copies of input (so 3 total)
  3&          bitwise AND with 3
    "-+*ⁿ"E   index into this string
           ƒ  call the respective function



1

Oasis , 25 bayt

mn4%3Q*nkn4%2Q*nxn4%1Q*++

Çevrimiçi deneyin!

Nasıl çalışır

x&3Eşdeğer olduğuna dikkat edin x%4, nerede %modulo.

mn4%3Q*nkn4%2Q*nxn4%1Q*++  input is n
mn4%3Q*                    (n**n)*((n%4)==3)
       nkn4%2Q*            (n**2)*((n%4)==2)
               nxn4%1Q*    (n*2)*((n%4)==1)
                       +   add the above two
                        +  add the above two

Oasis, her karakterin komut olduğu yığın tabanlı bir dildir.



1

C #, 42 Bayt

x=>x%4<2?x*x%4<1?0:2:Math.Pow(x,x%4<3?2:x)

Aslında bu normal bir C #, ama bütün bir program olarak çalıştıramayacağınız ve onu interaktif olarak yazmanız gerektiği için sanırım C # interaktif diyebilirsiniz .

Açıklama :

x => (x % 4) < 2     //If the bits are smaller than 2 (1 or 0)
? x *           //multiply x with
    (x % 4) < 1 //if the bits are 0
    ? 0         //0 (results in 0)
    : 2         //or else with 2 (results in 2*x or x+x)
: Math.Pow(x,   //otherwise power x by
    (x % 4) < 3 //if the bits are 2
    ? 2         //2 (results in x^2 or x*x)
    : x);       //or else x (results in x^x)

Bunun en kısa değişken olup olmadığını söyleyemem, önerileriniz takdir edilir.


Bunun geçerli olduğunu sanmıyorum. Genelde bir program veya işlev sunmalısınız . Snippet'lere varsayılan olarak izin verilmez.
17'de

@Cyoce Bu bir programdır. Sadece programı yorumlayacak olan etkileşimli üzerinden geçirmeniz gerekiyor.
MetaColon

Bunu etkileşimli olarak çalıştırdığımda, xtanımlanmadığı için hata alıyorum . Bu bir pasaj yapar, tam bir program değil.
Cyoce

@Cyoce Söylediği mücadelede, tanımlanmış bir x değişkeni olacağını söyledi.
MetaColon

Bunun anlamı bu değil. "Olumlu bir tamsayı verildiğinde x", standart bir giriş yöntemiyle (yani, işlev veya program) verildiği anlamına gelir x.
Cyoce




1

C, 115 bayt

#include<math.h>
#define D(K,L)K(x){return L;}
D(q,0)D(w,x+x)D(e,x*x)D(r,pow(x,x))(*g[])()={q,w,e,r};D(f,g[x%4](x))

Örnek bir fonksiyondur int f(int x)

İşlemciyi koşullu sıçrama kullanmaktan uzak tuttuğu için en hızlı çalışma hızı gibi görünüyor. Ve bu, bu görev için yalnızca doğru hız optimizasyon yöntemidir. Ayrıca, dizi C örneğinde olduğu gibi her şeyi değerlendirmeye return(int[]){0,x+x,x*x,pow(x,x)}[x%4];çalışmaz, ancak çok daha hızlı adres aritmetiğine sahip daha hızlı koşulsuz atlamalar (jmp / call) yapmak için optimize edilmiş bir sürüm olarak koşulsuz atlamalar (jmp / call) yapmak için functons için işaretçi dizisini akıllıca kullanın. " yer değiştir..". Bu teknik aynı zamanda birkaç finita otomata gibi - işlemci emülatörleri, uygulayıcılar, komut akışı ayrıştırıcıları ve benzerlerinde - hızın önemli olduğu kod gibi yerlerde yararlı olabilir.switch(x%4) case(0):... case(1):... uygun olmadığı, çünkü çoklu cmp / jnz komutları; ve bunlar CPU için pahalı işlemlerdir

Durum için en basit ve en kısa test programı (varsayılan koşullarda) aşağıdaki gibi olacaktır:

D(main,f(x))

Sadece 12 baytlık bir veri yükü ekleyecek ve büyüklüğümüzü 127 bayta çıkaracak;

Ama linker'a kullanması gerektiğini söylemelisin. f yerine fonksiyonu giriş noktası olarak .main . Bu, bu görev için mümkün olan en hızlı şekilde çalışan ikili dosyayı en kısa koddan elde etmeyi amaçlıyorsak ;-) Bu, C kütüphanesinin main () işlevinizi çağırmadan önce fazladan giriş / kapatma kodu eklemesi nedeniyle oluşur.

Kod, hileler ve sorunlar olmadan MSVS Community 2015'te derlenir ve doğru sonuçlar elde edilir. Bunu gcc ile test etmedim, ancak bunun da iyi olacağından eminim.


1
PPCG'ye Hoşgeldiniz! Bu zorluğun amacı, kodunuzu mümkün olduğu kadar kısa yapmaktır. Bu durumda, kodunuz tüm bu işlev bildirimlerini birleştirerek bir demet kolayca kısaltılabilir. Bazı boşlukları da kaldırabilirsiniz.
HyperNeutrino


@RosLuP siz, ancak 60 bayt sürümünüzden neredeyse iki kat daha uzun. ama çok daha hızlı çalışıyor, boyutuna değer.

@Hyper Neutrino Tamam. Daha fazla sıkıştırdım. Görünüşe göre bu son versiyon! Hata yok, tüm testler 8

@ xakepp35 ölçünüzü aldın mı benden daha hızlı?
RosLuP

1

R, 47 42 bayt

x=scan();c(`-`,`+`,`*`,`^`)[[x%%4+1]](x,x)

Fonksiyon uygular -, +, *, veya ^modülü dayalı xetmek xve x.

-tek (biraz) akıllı şey, çünkü x-xher zaman 0'dır.

R, 33 bayt

pryr::f(c(0,2*x,x^2,x^x)[x%%4+1])

Diğer insanların kullandığı yöntem. Daha kısa olmasına rağmen, neredeyse kadar sevmiyorum.


0

Pyth , 12 bayt

.vjd,+@"-+*^

Çevrimiçi deneyin!

Nasıl çalışır

Birincisi, duyuru x&3eşdeğerdir x%4, nerede %modülo olduğunu. Öyleyse, Pyth modüler indeksleme ( a[n] == a[n+len(a)]) kullandığından , bununla uğraşmamız gerekmiyor.

Sonra:

  • Eğer x%4==0dönerseniz x-x(tutarlılık için);
  • Eğer x%4==1döndüyse x+x;
  • Eğer x%4==2döndüyse x*x;
  • Eğer x%4==3dönersen x^x.

.vjd,+@"-+*^  example input: 10
      @"-+*^  "-+*^"[10], which is "*"
     +        "*10"
    ,         ["*10","10"]
  jd          "*10 10"
.v            evaluate as Pyth expression
              (Pyth uses Polish notation)

Lehçe notasyonu hakkında daha fazlası: Vikipedi (eğer Türkiye'de iseniz çok kötü).


Ha? Bu sadece bana çok fazla görünüyor. Ayrıntılar için cevabımı gör.
Outgolfer Erik,

0

Japt , 13 bayt

Ov"^+*p"gU +U

Çevrimiçi deneyin!

Bu, diğer değerlendirme cevaplarıyla aynı yöntemi kullanır, program -Usadece olumsuzlar dışında U, bu yüzden biz ^(bitwise XOR) kullanırız.


0

Vim, 50 bayt

y$o^R"A-+*^^V^[0^R"lx0"_Dp^[0D@"kJ0"ad$:r!echo ^R"^R0|bc^<Enter>

Burada, ^Vtemsil eder Ctrl+V, ^Rtemsil ederCtrl-R ve ^[temsil ederesc anahtarı

Önce ifadeyi oluşturarak ve sonra bırakarak çalışır bc değerlendirerek çalışarak çalışır. İlk satırdaki girişi aksi halde boş bir tamponda bekler.

Açıklama:

y$o^R"                                                          Copies the input into register " and pastes it on the second line
      A-+*^^V^[0^R"lx0"_Dp                                      Enters that text after the input on the second line
                          ^[0D@"                                Executes the second line as a Vim command.
                                                                For example, if the input is 12, the second line would be 12A-+*^^[012lx0"_Dp, which means:
                                                                  12A-+*^^[           Insert the text -+*^ 12 times
                                                                           012lx0"_Dp Go 12 chars to the right and remove everything except for that.
                                                                If effect, this basically just selects the appropriate operation.
                                kJ0"ad$                         Put the operator after the number, cut it into register a
                                       :r!                      Execute the following shell command and put the result into the buffer:
                                          echo ^R"^R0|bc<Enter> The shell command "echo [contents of register a][contents of registers 0]|bc. As said above, register a contains the input and the operator, and register 0 contains the input. The <enter> then executes this command.

Ben yazarken ^Vsadece ... numara yerine, benim panoya ben ne yapıştırır it
Çatlak Rahibe

1
Çevrimiçi deneyin! Ayrıca, Dyerined$
DJMcMayhem

0

Pyth, 9 bayt

@[0yQ*QQ^

Test odası

Burada hiçbir şey olmaz, sadece dört değeri hesaplayın ve modüler indeksleme ile bir tane seçin.

@[0yQ*QQ^
@[0yQ*QQ^QQ)Q    Implicit variable introduction
@           Q    Modularly index into the following list
 [0        )     0
   yQ            Q*2
     *QQ         Q*Q
        ^QQ      Q^Q

0

Toplu, 135 bayt

@set/an=%1*2^&6
@goto %n%
:6
@set n=1
@for /l %%i in (1,1,%1)do @set/an*=%1
@goto 0
:4
@set n=%1
:2
@set/an*=%1
:0
@echo %n%

Ben formun bir dize birikmesini ve değerlendirerek üs oluşturmak için umuyordum [0+...+0, 2+...+2, x+...+x, x*...*x]son iki bit bağlı xkullanamıyorum çünkü ifade etmek çok uzun sürdü işlemini seçmek için ama maalesef kod *bir şekilde forparametre, ama ben en azından bazı baytları uzaklaştırmak için düşünse aldatmaca kullanabileceksiniz.


0

Retina , 87 bayt

.+
$*1;$&$*
;((1111)*)(1?)$
;$3$3
1(?=1.*;((1111)*111)$)
$1;
+`\G1(?=.*;(1*))|;1*$
$1
1

Çevrimiçi deneyin!(Bağlantı test takımı içerir.)

Açıklama: İlk iki satır girdiyi birliğe çevirir ve çoğaltır (yani şimdi elimizde x;x). Sonraki iki satır bir aramaya x&3ya 0ya da 1değişimin x;xiçine x;0ya da x;2uygun bir şekilde. Sonraki iki satır bakmak x&3==3ve değişim x;xiçine x;x;x;...;x;1;x( x xs). Bu araçlar sahip olduğumuz ya x;0, x;2, x;x, veya x;...;xve çarpın birlikte her şey ve ondalık dönüştürmek arkasına kalır. (Çarpma kodu, Retina wiki'ninkine dayanır, ancak çarpma işlemini sıfırla işlemek için değiştirilir.)

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.