Minus, Plus, Waktu, Eksponen?


26

Ini adalah CMC (tantangan mini obrolan) yang saya posting di chatroom kami, The Ninteenth Byte , beberapa waktu lalu.

Tantangan

Diberikan bilangan bulat positif x, tergantung pada 2 bit terakhir x, lakukan hal berikut:

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

Input output

Single Integer -> Single Integer  

Baris baru tambahan diizinkan dalam output. Tidak ada spasi putih lain yang diizinkan.

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

Ini adalah tantangan , jadi kode terpendek menang!


8
Tidak seharusnya 0kasus menjadi x + 2, melihat bagaimana yang lain x * 2, x ^ 2dan x ^^ 2(tetration)? : P
ETHproduksi

Apa output terbesar yang harus kita dukung (mengenai x ^ x)? 32-bit sudah tidak cukup untuk test case 11, dan 64-bit tidak cukup untuk test case 19.
Kevin Cruijssen

@KevinCruijssen Saya akan mengatakan bahwa Anda hanya perlu menangani kasus di mana input dan output berada dalam ruang lingkup bahasa Anda, selama program Anda secara teoritis akan bekerja mengingat ukuran angka tak terbatas.
HyperNeutrino

@HyperNeutrino Ok, dalam hal ini saya telah memperbaiki kode (Java 7) saya (untuk +72 byte .. xD)
Kevin Cruijssen

Jawaban:


13

Jelly , 8 byte

ị“+×*_”v

Cobalah online!

Bagaimana itu bekerja

Pertama, pemberitahuan yang x&3setara dengan x%4, di mana %modulo. Lalu, karena Jelly menggunakan pengindeksan modular ( a[n] == a[n+len(a)]), jadi kita bahkan tidak perlu menghadapinya.

Kemudian:

  • Jika x%4==0, kembali x_x(kurangi) (untuk konsistensi);
  • Jika x%4==1, kembali x+x;
  • Jika x%4==2, kembali x×x(multiplikasi);
  • Jika x%4==3, kembali x*x(eksponensial)

Perhatikan bahwa Jelly menggunakan pengindeksan 1, sehingga pengurangannya "_"dipindahkan ke akhir.

ị“+×*_”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 memiliki penyandian sendiri - lihat di sini , tapi saya tahu semua karakternya 1 byte.
Stephen

"8 byte". Bagaimana seharusnya byte dihitung? Jawaban ini terdiri dari delapan karakter, tetapi setidaknya dalam pengkodean stackexchange melayani halaman ini, dibutuhkan hingga 15 byte (dihitung menggunakan wc --bytes).
andrybak

Jika bahasa menafsirkannya dalam satu pengkodean, tidak masuk akal untuk menggunakan pengkodean lain untuk jumlah byte (imo)
Mackenzie McClane

@andrybak Kode yang disandikan dalam penyandian sehingga browser menunjukkannya dengan benar adalah 15 byte. Kode dalam pengkodean yang dipahami Jelly adalah 8 byte. Lihatlah github.com/DennisMitchell/jelly/wiki/Code-page jika Anda ingin tahu bagaimana kode tersebut dikodekan.
Etoplay


9

CJam , 12 byte

ri__"-+*#"=~

Cobalah online!

Penjelasan

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.

Menjalankan salah satu dari operasi berikut tergantung pada xnilai mod 4 (mod 4 setara dengan DAN 3).

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

6

Mathematica 25 Bytes

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

Disimpan 4 Bytes berkat @MartinEnder


4

Pyth, 8 byte

.v@"0y*^

Penerjemah


Ya saya sudah menguji ini dan itu berhasil. Dan tidak, saya tidak dapat menggunakan vbukan .v.
Erik the Outgolfer

Saya pikir cakupannya adalah lokal ... Saya pikir .vtidak dapat mengakses Q... Rupanya saya kalah dalam Pyth. +1 untuk Anda.
Leaky Nun

@ LeakyNun Tidak itu vyang memiliki cakupan lokal, .vhanya eval ekspresi.
Erik the Outgolfer

Saya harus banyak belajar ...
Leaky Nun

3
Itu indah! Benar-benar luar biasa! Saya tidak tahu itu mungkin. Untuk poin gaya, "0y*^bisa jadi "-+*^.
isaacg



3

Haskell, 28 27 byte

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

Cobalah online!

Sunting: Terima kasih kepada @ Ørjan Johansen selama 1 byte.


Hm saya sangat terlambat, tetapi Anda bisa mempersingkat byte ini dengan cycle.
Ørjan Johansen

@ ØrjanJohansen: lebih baik terlambat daripada tidak sama sekali. Terima kasih!
nimi


2

C, 63 atau 62 byte

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

-1 byte jika makro dibolehkan, dengan asumsi xbukan ekspresi seperti 3+5(karena itu akan mengacaukan prioritas):

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

@ceilingcat Benar, lupakan itu.
Tim Čas

tidak mengkompilasi pada MSVS2015; Intellisense berkata cast to incomplete array type "int[]" is not allowedCompiler berkata error C4576: a parenthesized type followed by an initializer list is a non-standard explicit type conversion syntax; JUGA! dimana int f (int x)? kode sebenarnya setidaknya 8 byte lebih lama; juga sangat lambat dan tidak efisien, karena mengevaluasi semua - jangan ulangi IRL)

@ xakepp35 Apa? 1) itu harus mengkompilasi dalam sebuah C compiler. Sebagian besar (baca: hampir semua kecuali MSVC) kompiler C mendukung (int[])sintaks ini untuk situasi ini. 2) f(x)C89 sangat legal. Saya tidak menentukan standar. 3) Ini tentang ukuran kode, bukan efisiensi. Dan 4) Jika Anda akan menggurui, setidaknya gunakan kompiler nyata dan / atau periksa fakta Anda.
Tim Čas

@Tim - Ah, ya, maaf! Saya mencoba mengkompilasinya sebagai kode C ++. Itu salah saya) Ini mengkompilasi dan bekerja hebat!

2

Java 7, 75 byte

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);}

Meskipun valid menurut aturan, longadalah 64-bit, sehingga gagal untuk kasus uji eksponensial ke 19^19atas. Untuk memperbaikinya kita dapat menggunakan BigDecimalpendekatan:

148 146 byte

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);}

Penjelasan (dari pendekatan BigDecimal):

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

Kode uji:

Coba di sini.

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) + "; ");
    }
  }
}

Keluaran:

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; 

Anda tidak perlu memperbaiki program dengan cara ini: P Jawaban lama akan berfungsi jika angka memiliki ukuran tak terbatas; program pertama akan valid berdasarkan spesifikasi saya. : P
HyperNeutrino

@HyperNeutrino Lalu saya tentukan dalam jawaban .. Ah well, Java tidak akan memenangkan tantangan kode-golf. ;)
Kevin Cruijssen

1
Ya, saya akan tentukan. Dan ya, itu Jawa, tidak akan menang. : D
HyperNeutrino

2
" Dan ya, itu Jawa, tidak akan menang.: D " Aku sudah terbiasa. : P Bahkan jawaban Java terpendek saya yang pernah 8 byte adalah panjang dibandingkan dengan jawaban golf. xD Meskipun itu adalah pertama kalinya saya mengalahkan jawaban Python dengan jawaban Java saya, yang harus dihitung untuk sesuatu yang saya kira. ;)
Kevin Cruijssen

2

x86 Assembler, Sintaks Intel, 192 byte

.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

Contoh berpura-pura untuk kecepatan kerja tercepat. Apakah adalah bagian program atau program, yang menggunakan konvensi panggilan cepat. Ini mengasumsikan variabel input xdalam register eax, dan mengembalikan hasil juga dalam eax. Ide dasarnya adalah menjauh dari menggunakan lompatan bersyarat, seperti dalam beberapa contoh di sini. Juga, ini bukan untuk mengevaluasi semuanya (seperti pada contoh C dengan array) tetapi untuk menggunakan array pointer ke functons dan membuat lompatan tanpa syarat lebih cepat (jmp / panggilan) sebagai analog "bahasa C switch () - case .." yang dioptimalkan. Teknik ini dapat juga berguna dalam jenis emulator finita automata - seperti prosesor, pelaksana dan sebagainya.

Pembaruan: untuk x64 gunakan "r" dalam nama register, bukan "e" (mis. raxBukannya eax, rcxbukan ecx). Ukuran tidak akan berubah, dan itu akan menggunakan kata-kata tak bertanda 64-bit.


Selamat datang di PPCG! Tujuan dari tantangan ini adalah membuat kode Anda sesingkat mungkin. Dalam hal ini, kode Anda dapat dengan mudah dipersingkat banyak dengan menggabungkan semua deklarasi fungsi tersebut. Anda juga dapat menghapus beberapa spasi putih.
HyperNeutrino

@HyperNeutrino asm itu sendiri agak "panjang" bahasa :) jadi saya tidak punya ide tentang bagaimana membuat ini lebih pendek. ada contoh-saran?

Eh, maaf, saya harus menyalin komentar saya pada jawaban C Anda ke dalam posting ini. Saya tidak tahu cara memprogram dalam ASM tetapi dapatkah Anda berpotensi menghapus spasi kosong?
HyperNeutrino

@HyperNeutrino, maaf .. tapi sepertinya tidak) harus kode terpanjang antara lain, saya hanya bisa memotong windows crlf ke format linux sehingga 209-> 192 byte, perubahan tidak terlihat)

Ah. Sayang sekali. Tapi pengajuan yang bagus terlepas dari! :)
HyperNeutrino

2

C #, 39 byte

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

Penjelasan

Perhatikan bahwa:

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

Solusi ini menciptakan sebuah array, mengindeks ke dalamnya dan kemudian mengalikan hasilnya dengan x:

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

Versi alternatif:

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

(39B, semua perkalian yang dilakukan dalam array, x%4ganti x&3)

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

(39B, sama dengan jawaban @ MetaColon tetapi x%2*2*xdiganti x*x%4<1?0:2)


1

Sebenarnya , 12 byte

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

Cobalah online!

Penjelasan:

;;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 byte

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

Cobalah online!

Bagaimana itu bekerja

Perhatikan bahwa x&3itu setara dengan x%4, di mana %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 adalah bahasa berbasis tumpukan di mana setiap karakter adalah perintah.



1

C #, 42 Bytes

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

Sebenarnya itu adalah C # yang normal, tetapi karena Anda tidak dapat menjalankannya sebagai keseluruhan program dan Anda harus mengetiknya di interaktif, saya kira Anda dapat menyebutnya C # interaktif .

Penjelasan :

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)

Saya tidak tahu apakah ini varian terpendek, ada saran yang dihargai.


Saya pikir itu tidak valid. Anda biasanya harus mengirimkan program atau fungsi . Cuplikan tidak diizinkan secara default.
Cyoce

@Cyoce Ini adalah program. Anda hanya perlu menjalankannya melalui interaktif, yang akan menafsirkan program.
MetaColon

Ketika saya menjalankan ini secara interaktif, saya mendapatkan kesalahan karena xtidak didefinisikan. Itu menjadikan ini cuplikan, bukan program lengkap.
Cyoce

@Cyoce Dalam tantangan yang dikatakannya, akan ada variabel x yang didefinisikan.
MetaColon

Bukan itu artinya. "Diberikan bilangan bulat positif x" berarti Anda diberikan x melalui metode input standar (yaitu, fungsi atau program).
Cyoce




1

C, 115 byte

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

Contoh adalah fungsi int f(int x)

Ini berpura-pura untuk kecepatan kerja tercepat karena menjauhkan CPU dari menggunakan lompatan bersyarat. Dan ini hanya cara optimalisasi kecepatan yang benar untuk tugas ini. Juga, ia mencoba untuk tidak mengevaluasi semuanya, seperti pada contoh array C return(int[]){0,x+x,x*x,pow(x,x)}[x%4];Tetapi tetapi dengan bijak menggunakan array pointer ke functons, untuk membuat lompatan tanpa syarat yang jauh lebih cepat (jmp / panggilan) dengan aritmatika alamat yang jauh lebih cepat, sebagai versi yang dioptimalkan dari " switch () - case .. ". Teknik ini bisa juga berguna dalam beberapa jenis finita automata - seperti emulator prosesor, pelaksana, pengurai aliran perintah, dan sebagainya - di mana masalah kecepatan dan kode suka switch(x%4) case(0):... case(1):... tidak cocok karena menghasilkan beberapa instruksi cmp / jnz; dan ini adalah operasi yang mahal untuk CPU

Program uji paling sederhana dan tersingkat (dalam kondisi default) untuk kasus ini adalah sebagai berikut:

D(main,f(x))

Ini akan menambah hanya 12 byte payload dan akan total ukuran kita menjadi 127 byte;

Tetapi Anda sebaiknya memberi tahu linker untuk menggunakan ffungsi sebagai titik masuk, alih-alih main. Itulah caranya, jika kami bertujuan untuk mendapatkan biner yang berfungsi paling cepat untuk tugas ini dari kode terpendek ;-) Ini terjadi karena pustaka C menambahkan kode init / shutdown tambahan sebelum memanggil fungsi utama () Anda.

Kode mengkompilasi pada Komunitas MSVS 2015 tanpa ada trik dan masalah dan menghasilkan hasil yang benar. Saya belum mengujinya dengan gcc, tapi saya yakin itu akan berfungsi dengan baik juga.


1
Selamat datang di PPCG! Tujuan dari tantangan ini adalah membuat kode Anda sesingkat mungkin. Dalam hal ini, kode Anda dapat dengan mudah dipersingkat banyak dengan menggabungkan semua deklarasi fungsi tersebut. Anda juga dapat menghapus beberapa spasi putih.
HyperNeutrino

Saya suka ide menggunakan pointer ke fungsi
RosLuP

@ROSLuP kamu, tetapi hampir dua kali lebih lama dari versi 60 byte Anda. tetapi bekerja lebih cepat, sepadan dengan ukurannya.

@Hutper Neutrino Oke. Saya telah mengompres lebih banyak. Sepertinya, ini adalah versi final! Tidak ada bug, semua tes lulus 8-)

@ xakepp35 apakah Anda mengukur lebih cepat dari saya?
RosLuP

1

R, 47 42 byte

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

Berlaku fungsi -, +, *, atau ^berdasarkan modulus xuntuk xdan x.

-adalah satu-satunya (agak) hal yang cerdas, karena x-xselalu 0.

R, 33 byte

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

Metode yang sama seperti yang digunakan orang lain. Meskipun lebih pendek, saya tidak terlalu menyukainya.


0

Pyth , 12 byte

.vjd,+@"-+*^

Cobalah online!

Bagaimana itu bekerja

Pertama, pemberitahuan yang x&3setara dengan x%4, di mana %modulo. Kemudian, karena Pyth menggunakan pengindeksan modular ( a[n] == a[n+len(a)]), jadi kita bahkan tidak perlu berurusan dengan itu.

Kemudian:

  • Jika x%4==0, kembali x-x(untuk konsistensi);
  • Jika x%4==1, kembali x+x;
  • Jika x%4==2, kembali x*x;
  • Jika x%4==3, kembali x^x.

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

Lebih lanjut tentang notasi Polandia: Wikipedia (terlalu buruk jika Anda berada di Turki).


Hah? Ini sepertinya terlalu banyak bagi saya. Lihat jawaban saya untuk detailnya.
Erik the Outgolfer

0

Japt , 13 byte

Ov"^+*p"gU +U

Cobalah online!

Ini menggunakan metode yang sama dengan jawaban eval lainnya, kecuali program -Uhanya meniadakan U, jadi kami menggunakan ^(bitwise XOR) sebagai gantinya.


0

Vim, 50 byte

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

Di sini, ^Vmewakili a Ctrl+V, ^Rmewakili Ctrl-Rdan ^[mewakili esckuncinya

Bekerja dengan terlebih dahulu membangun ekspresi dan kemudian membiarkan bcmengevaluasinya. Mengharapkan input pada baris pertama dalam buffer kosong.

Penjelasan:

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.

Ketika saya mengetiknya ^Vhanya menempelkan apa yang saya miliki di clipboard saya, bukan nomor ...
Leaky Nun

1
Cobalah online! Selain itu, Anda dapat melakukan Dalih - alihd$
DJMcMayhem

0

Pyth, 9 byte

@[0yQ*QQ^

Suite uji

Tidak ada yang terjadi di sini, hanya menghitung empat nilai, dan pilih satu dengan pengindeksan modular.

@[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

Batch, 135 byte

@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%

Saya berharap untuk membuat eksponensial dengan membangun dan mengevaluasi string bentuk [0+...+0, 2+...+2, x+...+x, x*...*x]tergantung pada dua bit terakhir xtapi sayangnya kode untuk memilih operasi terlalu lama untuk diekspresikan karena saya tidak dapat menggunakan *sebagai forparameter, tapi saya setidaknya dapat menggunakan beberapa tipuan jatuh-jatuh untuk bermain golf beberapa byte.


0

Retina , 87 byte

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

Cobalah online! (Tautan termasuk test suite.)

Penjelasan: Dua baris pertama mengubah input menjadi unary dan menduplikatnya (jadi sekarang kita miliki x;x). Dua baris berikutnya mencari x&3dari salah satu 0atau 1dan berubah x;xmenjadi x;0atau x;2tepat. Dua baris berikutnya mencari x&3==3dan perubahan x;xke x;x;x;...;x;1;x( x xs). Ini berarti bahwa kita harus baik x;0, x;2, x;x, atau x;...;xdan masih kalikan semuanya bersama-sama dan mengkonversi kembali ke desimal. (Kode multiplikasi didasarkan pada yang ada di Retina wiki tetapi diubah untuk menangani perkalian dengan nol.)

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.