Melaksanakan Operator Biner INTERCAL

29

Bahasa Kompiler Tanpa Singkatan yang Dapat Diucapkan, disingkat INTERCAL , adalah bahasa pemrograman yang sangat unik. Di antara kualitasnya yang tidak dapat diproduksi adalah operator binernya.

Dua operator biner INTERCAL adalah interleave (juga dikenal sebagai mingle ), dan pilih . Interleave diwakili dengan perubahan (¢), dan pilih diwakili dengan sqiggle (~).

Interleave bekerja dengan mengambil dua angka dalam kisaran 0-65535 dan mengganti bit-bit mereka. Contohnya:

234 ¢ 4321
234   = 0000011101010
4321  = 1000011100001
Result: 01000000001111110010001001
Output: 16841865

Pilih karya dengan mengambil dua angka dalam kisaran 0-65535, mengambil bit di operan pertama yang berada di posisi yang sama dengan 1s di operan kedua, dan mengemas bit tersebut dengan benar.

2345 ~ 7245
2345  = 0100100101001
7245  = 1110001001101
Taken : 010   0  10 1
Result: 0100101
Output: 37

Dalam tantangan ini, Anda akan diberikan ekspresi biner menggunakan operasi interleave atau pilih. Anda harus menghitung hasilnya, menggunakan byte sesedikit mungkin.

Ekspresi akan diberikan sebagai string yang dipisahkan spasi, terdiri dari integer dalam 0-65535, spasi, salah satu ¢atau ~, spasi, dan integer dalam 0-65535.

Input dan output dapat melalui sistem standar apa saja (STDIN, fungsi, baris perintah, dll.). Celah standar dilarang.

Contoh:

5 ¢ 6
54

5 ~ 6
2

51234 ¢ 60003
4106492941

51234 ~ 60003
422

Ini adalah kode golf - byte terkecil menang. Semoga berhasil.

EDIT: Karena beberapa bahasa tidak mendukung simbol perubahan (¢) INTERCAL, Anda dapat menggunakan simbol uang besar ($) sebagai gantinya, dengan penalti 5 byte.

isaacg
sumber
10
Agak keras menghukum orang karena menggunakan tanda dolar. Itu adalah sesuatu yang tidak bisa dihindari.
Beta Decay
9
Saya baru menyadari bahwa CLWNPA benar-benar dapat diucapkan dalam bahasa Welsh. W diucapkan sebagai U dalam bahasa Spanyol atau OO dalam bahasa Inggris.
Level River St
9
Saya tidak mendapatkan penalti 5 byte. C-INTERCAL menggunakan $.
kirbyfan64sos
13
Apa yang kalian semua bantah? A $ jelas lebih mahal daripada ¢. Apa, Anda ingin 99 ¢ untuk apa-apa?
Maks
6
Saya tidak berpikir INTERCAL akan memungkinkan Anda untuk memasukkan angka dengan angka desimal. Bukankah kamu harus menulis FIVE ONE TWO THREE FOUR? Dan bukankah hasilnya harus dalam angka Romawi?
Nate Eldredge

Jawaban:

9

Pyth, 32 31 29 byte

isummFdG}\~zCm.[Z16jvd2%2cz)2

Cobalah online: Input Reguler / Test Suite

Terima kasih kepada @isaacg untuk bermain golf satu byte.

Penjelasan:

                         cz)   split input at spaces
                       %2      only take every second item (the numbers)
             m                 map each number d to:
                    vd           convert d to int
                   j  2          convert to base 2
              .[Z16              pad zeros at the left
            C                  zip
  u     }\~z                   apply the following function ("~" in input) times:
   m   G                         map each pair d to:
    mFd                          convert [x,0] to [] and [x,1] to [x]
 s                             take sum (unfold all lists)
i                           2  convert back from base 2 and print
Jakube
sumber
Anda dapat menyimpan satu byte dengan mengubah hMfeTke smmFddan kemudian memindahkan duplikat sluar terner tersebut. Juga, kode Anda saat ini adalah 32 byte, bukan 33.
isaacg
@isaacg Wow. Saya tidak akan pernah berpikir bahwa golf pintar. Terima kasih. Dan ya, lakukan golf menit terakhir saat menulis penjelasan dan tidak memperbarui jumlah byte.
Jakube
2
Sangat menarik untuk melihat jawaban Pyth dan CJam, hampir selalu jumlah byte yang sama, tetapi Pyth sering kali mengalahkan CJam
Kametrixom
13

Python 2, 115 112 byte

x,y,z=input().split()
d=y<""
f=lambda a,b:a+b and(b%2+5&4-d)*f(a/2,b/2)+(a%2*2+b%2)/3**d
print f(int(x),int(z))

String pada baris kedua berisi karakter tunggal yang tidak dapat dicetak \x7d, karakter berikutnya setelahnya ~.

Semua harapan yang bagus, lambda tunggal dihancurkan oleh format input. Mungkin ada cara yang lebih baik untuk membaca input. Input suka "51234 ¢ 60003"via STDIN.

Fungsi ini fmenggabungkan dua fungsi rekursif berikut:

g=lambda a,b:a+b and 4*g(a/2,b/2)+a%2*2+b%2    # ¢
h=lambda a,b:a+b and(b%2+1)*h(a/2,b/2)+a*b%2   # ~

(-3 byte dengan bantuan @xnor)

Sp3000
sumber
1
+1 untuk jawaban Python pertama yang sangat kompetitif. Saya bertanya-tanya mengapa Anda repot-repot dengan lambda dan tidak hanya menggunakan ekspresi, tetapi sepertinya ada beberapa rekursi di sana? Saya tidak tahu Python, saya menantikan penjelasan.
Level River St
Beberapa bashing hebat! Saya melihat mengompresi ungkapan istilah konstan. Ekspresi (a%2*2+b%2)/3**dmenyimpan 3 karakter tetapi menggunakan komplemen d=1-c. Apakah Anda memiliki cara untuk melakukannya -~(3*c|b%2)dengan komplemen? Paling buruk itu kehilangan 2 karakter dengan 3-3*d. Juga, format and-~x+ybisa andy-~xsepanjang ydimulai dengan simbol atau angka.
xnor
@ xnor Paham (b%2+5&4-d),. Terima kasih!
Sp3000
11

CJam, 31 byte

rrc\r]{i2bF0e[}%(7=\zf{_)*?~}2b

Cobalah online di juru bahasa CJam .

Bagaimana itu bekerja

rr                              e# Read two tokens from STDIN.
  c\                            e# Cast the second to char and swap with the first.
    r                           e# Read a third token from STDIN.
     ]                          e# Wrap everything in an array.
      {       }%                e# For all three elements:
       i2b                      e#   Cast to int and convert to base 2.
          F0e[                  e#   Left-pad with zeroes to complete 15 digits.
                (               e# Shift out the first base 2 array.
                 7=             e# Select its eighth MSB (1 for '¢', 0 for '~').
                   \            e# Swap with the array of base 2 arrays.
                    z           e# Zip to transpose rows with columns.
                     f{     }   e# For each pair of base 2 digits:
                                e#   Push the bit, then the pair.
                       _        e#   Copy the pair.
                        )       e#   Pop the second digit.
                         *      e#   Repeat the first digit that many times.
                          ?     e#   Ternary if. Select the pair if the bit is
                                e#    truthy, the repeated first bit if it's falsy.
                           ~    e#   Dump the selected array on the stack.
                             2b e# Convert from base 2 to integer.
Dennis
sumber
8

JavaScript (ES6), 103 117 119 124

Edit sekarang bekerja dengan angka, bukan string

(tidak termasuk spasi, baris baru, dan komentar)

Tes menjalankan cuplikan pada peramban apa pun yang mendukung EcmaScript 6 (terutama bukan Chrome, bukan MSIE. Saya menguji pada Firefox, Safari 9 dapat berjalan)

I=s=>
  (i=>{
    for(m=r=0,[a,o,b]=s.split` `;i>0;i<<=1) // loop until bit 31 of i is set
      o>'~'?r+=(b&i)*i+(a&i)*2*i:b&i?r+=(a&i)>>m:++m
  })(1)||r


// TEST
out=x=>O.innerHTML+=x+'\n\n';

[ ['234 ¢ 4321', 16841865], ['2345 ~ 7245', 37]
, ['5 ¢ 6', 54], ['5 ~ 6', 2]
, ['51234 ¢ 60003',4106492941], ['51234 ~ 60003', 422]]
.forEach(([i,o,r=I(i)])=>{
  out('Test '+ (o==r?'OK':'Fail')+'\nInput:    '+ i+'\nResult:   '+r+'\nExpected: '+o)})
<pre id=O></pre>

edc65
sumber
5

Matlab, 119 113 byte

function f(s)
t=dec2bin(str2double(strsplit(s,{'¢' '~'}))');u=any(s>'~');[~u u]*bin2dec({t(1,t(2,:)==49) t(:)'})

Tidak Terkumpul:

function f(s)                                     % input s is a string
t = dec2bin(str2double(strsplit(s,{'¢' '~'}))');  % get the two numbers and convert to
                                                  % two-row char array of zeros of ones
u = any(s>'~');                                   % 1 indicates '¢'; 0 indicates '~'
[~u u]*bin2dec({t(1,t(2,:)==49) t(:)'})           % compute both results and display
                                                  % that indicated by u

Contoh:

>> f('234 ¢ 4321')
ans =
    16841865

>> f('2345 ~ 7245')
ans =
    37
Luis Mendo
sumber
5

R, 145 byte

s=scan(,"");a=as.double(c(s[1],s[3]));i=intToBits;cat(packBits(if(s[2]=="~")c(i(a[1])[i(a[2])>0],i(0))[1:32] else c(rbind(i(a[2]),i(a[1]))),"i"))

Penjelasan + tidak dikumpulkan:

# Read a string from STDIN and split it on spaces
s <- scan(, "")

# Convert the operands to numeric
a <- as.double(c(s[1], s[3]))

o <- if (s[2] == "~") {
    # Get the bits of the first operand corresponding to ones in
    # the second, right pad with zeros, and truncate to 32 bits
    c(intToBits(a[1])[intToBits(a[2]) == 1], intToBits(0))[1:32]
} else {
    # Interleave the arrays of bits of the operands
    c(rbind(intToBits(a[2]), intToBits(a[1])))
}

# Make an integer from the raw bits and print  it to STDOUT
cat(packBits(o, "integer"))
Alex A.
sumber
5

Python 3, 174 166 148 126

Cukup mudah, operasi string, lalu konversi kembali ke integer.

Terbatas pada angka yang dalam biner memiliki 99 digit (maks. 2 ^ 99-1 = 633825300114114700748351602687).

Terima kasih, Sp3000 dan Vioz!

a,o,b=input().split()
print(int(''.join([(i+j,i[:j>'0'])[o>'~']for i,j in zip(*[bin(int(j))[2:].zfill(99)for j in(a,b)])]),2))

Atau 165 karakter, tanpa batas:

a,o,b=input().split()
a,b=[bin(int(j))[2:]for j in(a,b)]
print(int(''.join([(i if j=='1'else'')if o=='~'else i+j for i,j in zip(a.zfill(len(b)),b.zfill(len(a)))]),2))

Tidak Terkumpul:

a, op, b = input().split()
a, b = [bin(int(j))[2:] for j in(a,b)] #convert to int (base 10), then to binary, remove leading '0b'
m = max(len(a), len(b))
a = a.zfill(m) #fill with leading zeroes
b = b.zfill(m)
if op == '~':
    ret = [i if j=='1' else'' for i, j in zip(a, b)]
else:
    ret = [i + j for i, j in zip(a, b)]
ret = ''.join(ret) #convert to string
ret = int(ret, 2) #convert to integer from base 2
print(ret)
Trang Oul
sumber
2
Anda dapat menggunakan zfillsebagai ganti rjustuntuk melapisi dengan angka nol
Sp3000
Input maksimal keluar pada 16 bit, dan output pada 32 bit. 99 bit lebih dari cukup.
isaacg
Saya tahu, tetapi karena '99' mengambil karakter sebanyak '16', tidak ada manfaatnya membatasi.
Trang Oul
1
Beberapa lagi: 1) Anda tidak perlu menabung a,b, cukup masukkan zipdengan *percikan, 2) (i if j=='1'else'') -> i[:j>'0']3) Anda dapat menggunakan tip ini untuk menghemat yang lainif/else
Sp3000
1
Solusi saya akhirnya terlalu dekat dengan Anda, jadi ini yang saya bisa dapatkan (126 byte).
Kade
4

Pyth, 43 byte

Sebagian diriku merasa gugup memposting jawaban Pyth yang panjang pada pertanyaan isaacg ...: oP

J.(Kczd1Am.BvdKiu?qJ\~u+G?qeH\1hHk+VGHk.iGH2

Penjelasan:

                                               Implicit: z=input(), k='', d=' '
   Kczd                                        Split z on spaces, store in K
J.(    1                                       Remove centre element from K, store in J
         m    K                                For each d in K
          .Bvd                                 Evaluate as int, convert to binary string
        A                                      Store pair in G and H
                                               ~ processing:
                                 +VGH          Create vectorised pairs ([101, 110] -> [11, 01, 10])
                     u               k         Reduce this series, starting with empty string
                        ?qeH\1                 If 2nd digit == 1...
                              hHk              ... take the 1st digit, otherwise take ''
                      +G                       Concatenate
                                      .iGH     ¢ processing: interleave G with H
                ?qJ\~                          If J == ~, take ~ processing, otherwise take ¢
               i                          2    Convert from binary to decimal
Sok
sumber
4
Saya suka foto profil Anda! :)
kirbyfan64sos
2
@ kirbyfan64sos Blue Kirby adalah yang terbaik Kirby: o)
Sok
3

C, 127 123 byte + 5 penalti = 128

scanfmenghitung simbol unicode sebagai lebih dari satu karakter yang menyulitkan banyak hal, jadi saya menerapkan hukuman 5-byte untuk digunakan $.

a,b,q,x,i;main(){scanf("%d %c %d",&a,&q,&b);for(i=65536;i/=2;)q%7?x=x*4|a/i*2&2|b/i&1:b/i&1&&(x=x*2|a/i&1);printf("%u",x);}

Perubahan dari versi aslinya adalah:

-Tes untuk $ atau ~ telah direvisi dari q&2menjadi q%7. Ini membalikkan nilai true / false, memungkinkan kode untuk $ operator untuk pergi sebelum :yang berarti satu set tanda kurung dapat dihilangkan.

-Lingkaran isekarang dihitung dalam kekuatan 2 yang lebih panjang, tetapi memungkinkan >>untuk diganti oleh /dan menyimpan beberapa tanda kurung.

Versi asli 127 byte

a,b,q,x,i;
main(){
  scanf("%d %c %d",&a,&q,&b);
  for(i=16;i--;)
    q&2?
      b>>i&1&&(x=x*2|a>>i&1):    // ~ operator. && used as conditional: code after it is executed only if code before returns truthy.
      (x=x*4|(a>>i&1)*2|b>>i&1); // $ operator
  printf("%u",x);
}

Aku pergi dengan satu loop dengan persyaratan di dalam untuk menghindari overhead dua loop. Dalam kedua kasus saya hakhift bit dari operan ke bit 1, dan membangun hasil dari bit yang paling signifikan hingga paling signifikan, meninggalkan hasilnya (mengalikan dengan 2 atau 4) saat aku pergi.

Level River St
sumber
Saya memasukkannya untuk Anda: main (a, b, q, x, i) {scanf ("% d% c% d", & a, & q, & b); untuk (i = 16; i -;) q & 2? b >> i & 1 && (x = x * 2 | a >> i & 1) :( x = x * 4 | (a >> i & 1) * 2 | b >> i & 1); printf ("% u", x);} Saya mencoba bermain golf di bagian >> i & 1, tetapi tidak menemukan cara yang efektif untuk melakukannya. Saya dapat menyimpan 1 karakter namun dengan meletakkan definisi variabel di utama. Catatan: belum diuji.
LambdaBeta
@LamdaBeta terima kasih, saya tidak dapat menemukan makro untuk >> i & 1 tetapi saya telah berhasil bermain golf dengan cara lain. Menempatkan variabel sebagai argumen mainpenyebab qrusak pada mesin saya, yang aneh. Saya berharap masalah sebenarnya adalah dengan scanf, tetapi karena itu saya telah meninggalkan mereka sebagai deklarasi normal.
Level River St
Saya tidak memikirkan itu. Anda benar, q akan rusak. Alasannya adalah bahwa sementara kita mengetahui bahwa main mengambil dua argumen, hitungan argumen baris perintah dan array argumen itu sendiri, sebagian besar sistem sebenarnya menyediakan argumen ketiga (biasanya disebut char * envp []) yang menggambarkan lingkungan kode dijalankan (memberikan akses ke EG: variabel lingkungan). Jadi nilai ketiga pada main juga dapat diberi nilai oleh sistem, scanf tidak bersalah saat ini.
LambdaBeta
@steveverill Saya pikir Anda juga dapat menghapus penalti 5 byte. Saya baru saja menguji kode Anda (menggunakan ALT + 155 untuk membuat ¢) dan sepertinya berfungsi dengan baik. :)
LambdaBeta
@LambdaBeta sebenarnya eksperimen menunjukkan kombinasi keduanya. Dengan deklarasi normal qdijamin menjadi nol, tetapi dengan deklarasi sebagai parameter fungsi qberisi 32-bit sampah. Itu tidak akan menjadi masalah jika saya memberikan nilai q, tetapi scanfdengan "%c"hanya menimpa 8 bit paling signifikan dari sampah, meninggalkan 24 lainnya tidak terdefinisi. Saya mungkin beruntung di kompiler lain!
Level River St
3

K5, 53 52 byte

{b/({,/x,'y};{x@&y})[*"~"=y][b\.x;(b:20#2)\.z]}." "\

Versi 53-byte:

{b/({,/x,'y};{x@&y})[*"¢~"?y][b\.x;(b:20#2)\.z]}." "\

Masih perlu sedikit lebih banyak bermain golf.

kirbyfan64sos
sumber
3

CJam, 61 50 46 41 34 byte

Terima kasih @Dennis karena menunjukkan golf 4 byte.

rrc'~=:X;r]{i2bF0e[}/.{X{{;}|}&}2b

Cobalah online .

Andrea Biondo
sumber
1
]{}/adalah noop.
Dennis
1
@Dennis Terima kasih. Saya mungkin harus tidur ...
Andrea Biondo
3

Haskell, 77

g=(`mod`2)
h=(`div`2)
0¢0=0
a¢b=g a+2*b¢h a
a?0=0
a?b=g a*g b+(1+g b)*h a?h b

input diberikan dengan menerapkan input ke fungsi / operator ?dan ¢didefinisikan dalam kode (Haskell tidak dapat mendefinisikan operator ~karena alasan teknis).

pada dasarnya bekerja dengan pendekatan rekursif lama.

haskeller bangga
sumber
2

J, 173

f=:|."1@(>@(|.&.>)@(#:@{:;#:@{.))
m=:2&#.@:,@:|:@:|.@:f
s=:2&#.@#/@:f
a=:{&a.@-.
(1!:2)&2(s@".@:a&126)^:(126 e.i)((m@".@:a&194 162)^:(1 e.194 162 E.i)i=._1}.(a.i.((1!:1)3)))

mengharapkan satu baris input

input diharapkan berakhir setelah baris baru dengan EOF

protista
sumber
2

Javascript ES6 (3 argumen) 141 138 136 121 119 byte

b=x=>(65536|x).toString`2`
f=(x,o,y)=>+eval(`'0b'+(b(y)+b(x)).replace(/^1|${o=='~'?1:'(.)'}(?=.{16}(.)())|./g,'$2$1')`)

Uji:

;[f(234,'¢',4321),f(2345,'~',7245)]=="16841865,37"

Javascript ES6 (1 argumen) 135 133 byte

b=x=>(65536|x).toString`2`
f=s=>([x,o,y]=s.split` `)|eval(`'0b'+(b(y)+b(x)).replace(/^1|${o=='~'?1:'(.)'}(?=.{16}(.)())|./g,'$2$1')`)

Uji:

;[f('234 ¢ 4321'),f('2345 ~ 7245')]=="16841865,37"

PS: Baris baru dihitung sebagai 1 byte karena dapat diganti oleh ;.

Qwertiy
sumber
1
0x10000 == 65536 (simpan 2 karakter)
edc65
@ edc65, saya sudah memperbarui jawabannya.
Qwertiy
2
65536 | x untuk menghindari ~~
edc65
Hanya versi kedua yang diizinkan - input harus dalam bentuk string yang dibatasi ruang.
isaacg
@isaacg, oke. Tapi saya tidak ingin menghapus yang pertama karena alasan historis.
Qwertiy
2

Python 3, 157 byte

a,x,y=input().split()
i=int
b=bin
print(i(''.join(([c for c,d in zip(b(i(a)),b(i(y)))if d=='1'],[c+d for c,d in zip(b(i(a))[2:],b(i(y))[2:])])['¢'==x]),2))

Versi lengkap dan jelas dapat ditemukan di pastebin saya .

Oliver Friedrich
sumber
Anda dapat menyamakan beberapa karakter dengan menghapus spasi di sekitar operator '==', sebelum 'jika' dan dengan melewatkan 'basis' sebagai argumen posisi.
Trang Oul
Terima kasih, itu dan beberapa yang lain telah menyelamatkan 15 karakter! tetapi cara menggandakan memformat pengembalian masih banyak.
Oliver Friedrich
Juga, apakah Anda menggunakan 4 spasi per indent? Satu (atau tab) sudah cukup.
Trang Oul
2
@BeowulfOF Kecuali ditentukan lain, Anda dapat mengirimkan program atau fungsi lengkap. Secara umum, mana yang lebih pendek akan tergantung pada cara bahasa Anda mem-parsing input spesifik untuk tantangan (ruby secara mengejutkan canggung dengan angka dari stdin misalnya). Anda juga memiliki dua cara yang mungkin untuk menghasilkan: stdout atau nilai pengembalian, yang berlaku untuk keduanya (meskipun nilai pengembalian dari program jarang.)
Level River St
1
Anda hanya terlihat menggunakan esekali, tidak bisakah Anda hanya sebaris itu?
Kevin Brown
0

Mathematica, 155 byte

f=IntegerDigits[#,2,16]&;
g=#~FromDigits~2&;
¢=g[f@#~Riffle~f@#2]&;
s=g@Cases[Thread@{f@#,f@#2},{x_,1}->x]&;
ToExpression@StringReplace[#,{" "->"~","~"->"s"}]&

Mengevaluasi fungsi anonim dengan mengambil string sebagai input. Jeda baris ditambahkan untuk kejelasan.

fdan gmengkonversi ke / dari basis 2. Rifflemelakukan apa yang seharusnya dilakukan interleave . Saya ingin menggunakan Selectuntuk pilih tetapi Casessayangnya lebih baik. Baris terakhir adalah sedikit tipu daya; spasi diubah menjadi ~operator infiks Mathematica, lalu string dieval'd.

jcai
sumber