INTERCAL'in İkili Operatörlerini Uygulayın


29

INTERCAL olarak kısaltılmış olan , telaffuz edilebilir bir kısaltmaya sahip olmayan derleyici dili çok özel bir programlama dilidir. Yeniden üretilemez nitelikleri arasında ikili operatörleri bulunur.

INTERCAL'in iki ikili operatörü interleave ( karıştırıcı olarak da bilinir ), ve seçin . Interleave bir değişiklikle (¢) temsil edilir ve seçim bir kare (~) ile temsil edilir.

Interleave 0-65535 aralığında iki sayı alarak ve bitlerini değiştirerek çalışır. Örneğin:

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

0-65535 aralığında iki sayı alarak, ilk işlemdeki bitleri ikinci işlemselde 1s ile aynı konumda olan ve bu parçaları doğru şekilde paketleyen işleri seçin.

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

Bu zorlukta, interleave veya select işlemini kullanarak size ikili bir ifade verilecektir. Mümkün olan en az baytı kullanarak sonucu hesaplamanız gerekir.

İfade, 0-65535'te bir tam sayı, bir boşluk ya ¢da bir boşluk ve 0-65535'te bir tam sayıdan oluşan boşlukla ayrılmış bir dize olarak verilecektir ~.

Giriş ve çıkış herhangi bir standart sistemden (STDIN, fonksiyon, komut satırı vb.) Yapılabilir. Standart boşluklar yasaklandı.

Örnekler:

5 ¢ 6
54

5 ~ 6
2

51234 ¢ 60003
4106492941

51234 ~ 60003
422

Bu kod golf - en az bayt kazanır. İyi şanslar.

EDIT: Bazı diller INTERCAL'in değişim (¢) sembolünü desteklemediğinden, büyük para ($) sembolünü 5 bayt ceza ile kullanabilirsiniz.


10
Dolar işaretini kullandıkları için insanları cezalandırmak biraz zor. Bu yardım edilemeyecek bir şey.
Beta Çürüğü,

9
CLWNPA’nın Galce’de mükemmel bir şekilde telaffuz edildiğini fark ettim. W, İspanyolca olarak U veya İngilizce olarak OO olarak telaffuz edilir.
Level River St

9
5 baytlık ceza alamıyorum. C-INTERCAL kullanır $.
kirbyfan64sos

13
Hepiniz ne hakkında tartışıyorsunuz? Bir $ açıkça bir than daha pahalıdır. Ne, 99 ¢ boşuna mı istiyorsun?
Maksimum

6
INTERCAL'in sayıları ondalık sayılarla girmenize izin vereceğini düşünmemiştim. Eğer yazma gerekmiyor mu FIVE ONE TWO THREE FOUR? Ve çıktı Romen rakamlarında olmamalı mı?
Nate Eldredge,

Yanıtlar:


9

Pyth, 32 31 29 bayt

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

Çevrimiçi deneyin: Normal Giriş / Test Paketi

Bir bayt kapalı golf oynamak için @ isaacg teşekkürler.

Açıklama:

                         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

Sen değiştirerek bir bayt kaydedebilirsiniz hMfeTiçin smmFdve daha sonra yinelenen hareket sdışında ve üçlü. Ayrıca, geçerli kodunuz 33 değil, 32 bayttır.
isaacg 10:15

@ isaacg Vay. Bu akıllı golfü asla düşünemezdim. Teşekkürler. Ve evet, açıklama yazarken son dakikada bir golf oynadı ve bayt sayısını güncellemedi.
Jakube,

2
Pyth ve CJam'ın cevaplarını görmek ilginç, neredeyse her zaman aynı bayt sayılır, ancak Pyth sık sık CJam'ı birkaç kez yener
Kametrixom

13

Python 2, 115 112 bayt

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

İkinci satırdaki dize, bir \x7dsonraki karakterden sonra yazdırılamayan tek bir karakter içerir ~.

Güzel, tek bir lambanın tüm umutları giriş biçiminde eziliyor. Girdiyi okumak için muhtemelen daha iyi bir yol var. "51234 ¢ 60003"STDIN üzerinden giriş yapın .

İşlev faşağıdaki iki özyinelemeli işlevi birleştirir:

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

(@Xnor yardımı ile -3 bayt)


1
İlk gerçekten rekabetçi Python cevabı için +1. Neden lambda ile uğraştığınızı ve sadece bir ifade kullanmadığınızı merak ediyordum, ama orada bir neşe varmış gibi görünüyor? Python'u tanımıyorum, bir açıklama bekliyorum.
Level River St

Bazı büyük dayak! Sabit terim ifadesini sıkıştırmaya bakıyorum. İfade (a%2*2+b%2)/3**d3 karakter kaydeder ancak tamamlayıcıyı kullanır d=1-c. -~(3*c|b%2)Tamamlayıcı ile yapmanın bir yolu var mı? En kötüsü ile 2 karakter kaybeder 3-3*d. Ayrıca, biçim bir sembol veya sayı ile başlayan sürece and-~x+yolabilir . andy-~xy
xnor,

@xnor Anladım (b%2+5&4-d). Teşekkürler!
Sp3000

11

CJam, 31 bayt

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

CJam tercümanında çevrimiçi olarak deneyin .

Nasıl çalışır

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.

8

JavaScript (ES6), 103 117 119 124

Düzenle şimdi sayıların yerine dizeleri ile çalışan

(baştaki boşlukları, yeni satırları ve yorumları saymaz)

Snippet'i EcmaScript 6 uyumlu bir tarayıcıda çalıştırma testi (özellikle MSIE değil Chrome değil. Firefox'ta test ettim, Safari 9 gidebilirdi)

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>


5

Matlab, 119 113 bayt

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

Ungolfed:

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

Örnekler:

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

>> f('2345 ~ 7245')
ans =
    37

5

R, 145 bayt

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

Ungolfed + açıklama:

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

5

Python 3, 174 166 148 126

Oldukça basit, string işlemleri, daha sonra tamsayıya dönüş.

İkilik sayılarda 99 rakam olan numaralarla sınırlıdır (en fazla 2 ^ 99-1 = 633825300114114700748351602687).

Teşekkürler, Sp3000 ve 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))

Veya 165 karakter, limitsiz:

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

Ungolfed:

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)

2
zfillrjust
Sıfırlama

Girişler 16 bit'te maksimuma çıkarılır ve 32 bit'te çıkışlar. 99 bit, fazlasıyla yeterli.
isaacg

Biliyorum ama '99', '16' kadar karakter aldığı için, onu sınırlandırmanın faydası yok.
Trang Oul

1
Birkaç tane daha: 1) Tasarruf etmenize gerek yok a,b, sadece zipbir *uyarıyla birlikte koyun , 2) (i if j=='1'else'') -> i[:j>'0']3) Bu ucu diğerinden tasarruf etmek için kullanabilirsinizif/else
Sp3000

1
Benim çözümüm bu yüzden, çok yakın sizinkine olmak sona erdi burada seninkini (126 bayt) alabilir olduğunca kısa.
Kade

4

Pyth, 43 bayt

Bir parçam isaacg'ın sorusu üzerine böylesine uzun bir Pyth cevabı göndermekten korkuyor ...: oP

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

Açıklama:

                                               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

4
Profil resmini seviyorum! :)
kirbyfan64sos

2
@ kirbyfan64sos Mavi Kirby en iyisi Kirby: o)
Sok

3

C, 127 123 bayt + 5 penaltı = 128

scanfunicode sembolünü, işleri karmaşık hale getiren birden fazla karakter olarak sayar, bu yüzden 5 baytlık bir ceza kullanıyorum $.

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

Orijinal versiyondaki değişiklikler:

-S $ veya ~ testi, ile q&2değiştirildi q%7. Bu, doğru / yanlış değerleri tersine çevirir ve $ operatörünün kodunun önce girmesine izin verir. : bu, parantez kümesinin ortadan kaldırılabileceği anlamına gelir.

-Döngü işimdi 2 olan, artık daha uzun olan, ancak >>bunun yerine/ bazı parantezlerin ve bazı parantezleri saklayan .

Orijinal sürüm 127 bayt

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

İki döngünün üstünden kaçınmak için içinde şartlı olan tek bir döngü ile gittim. Her iki durumda da, işlenenlerin bitlerini 1'inin bitine düşürürüm ve sonucu, en önemliden en az anlamlı bit'e kadar yükseltirim, sonucu ilerledikçe (2 veya 4 ile çarparak) değiştiririm.


Sizin için golf oynamıştım: ana (a, b, q, x, i) {scanf ("% d% c% d", & a, & q, & b); (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)} >> i & 1 bölümlerinden uzaklaşıp golf oynamaya çalıştım, ancak bunu yapmanın uygun maliyetli bir yolunu bulamadım. Değişken tanımlarını main'e ekleyerek 1 karakter kaydedebildim. Not: denenmemiş.
LambdaBeta,

@LamdaBeta teşekkürler, >> i & 1 için bir makro bulamadım ancak başka bir şekilde golf oynamayı başardım. Değişkenleri makinemde bozulacak mainnedenlerin argümanları olarak koymak q, bu garip. Asıl problemin beraber olduğunu umuyorum scanfama bu yüzden onları normal beyanlar olarak bıraktım.
Level River St

Bunu düşünmemiştim. Haklısın, q bozulmuş olacak. Bunun nedeni, ana sistemin iki argüman aldığını, komut satırı argümanlarının sayısının ve bir argüman dizisinin kendisinin bir dizi olduğunu öğrenmemize rağmen, çoğu sistem aslında ortamı kodunu tanımlayan üçüncü bir argüman (genellikle char * envp [] olarak adlandırılır) sağlar. (EG: çevre değişkenlerine erişim izni) çalıştırıldı. Bu yüzden, ana ünitedeki üçüncü değer sistem tarafından da bir değer olarak verilebilir, bu kez scanf masumdur.
LambdaBeta,

@ steveverill 5 bayt cezasını da kaldırabileceğinizi düşünüyorum. Kodunuzu henüz test ettim (+ yapmak için ALT + 155 kullanarak) ve düzgün çalışıyor gibi görünüyor. :)
LambdaBeta

@LambdaBeta aslında deneme, ikisinin bir kombinasyonunu gösteriyor. Normal bildirimin qsıfır olması garanti edilir ancak işlev parametresi bildirgesiyle q32 bit çöp içerir. Ben eğer bir sorun olmaz atanan bir değer q, ancak scanfbirlikte "%c"sadece tanımsız diğer 24 bırakarak çöp az önemli 8 bit üzerine yazar. Başka bir derleyicide şanslı olabilirim!
Seviye Nehri St

3

K5, 53 52 bayt

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

53 bayt sürümü:

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

Hala biraz daha golf oynamak istiyor.



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

Giriş, fonksiyonlara / operatörlere giriş uygulanarak verilir ?ve¢ Haskell bir operatör tanımlayamazsınız (kodunda tanımlanan~ teknik nedenlerden dolayı).

temelde eski özyinelemeli yaklaşımı çalışır.


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

bir satır girdi bekliyor

girdi, EOF ile olan yeni satırdan sonra sonlanacak


2

Javascript ES6 (3 bağımsız değişkenler) 141 138 136 121 119 bayt

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

Ölçek:

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

Javascript ES6 (1 bağımsız değişken) 135 133 bayt

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')`)

Ölçek:

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

Not: Yeni satır, değiştirilebildiği için 1 bayt olarak sayılır ;.


1
0x10000 == 65536 (2 karakter kaydet)
edc65 21

@ edc65, cevabı güncelledim.
Qwertiy

2
65536 | x önlemek için ~ ~
edc65 10:15

Yalnızca ikinci sürüme izin verilir - giriş, boşlukla ayrılmış bir dize biçiminde olmalıdır.
isaacg

@isaacg, tamam. Ancak ilk sebeplerden dolayı ilkini silmek istemiyorum.
Qwertiy

2

Python 3, 157 bayt

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

Tam ve açıklayıcı versiyonu pastebinimde bulunabilir .


'==' operatörü etrafındaki boşlukları kaldırarak, 'if' öncesi ve 'base' 'i konumsal argüman olarak geçirerek birkaç karakter de kullanabilirsiniz.
Trang Oul

Teşekkürler, o ve bazı diğerleri 15 karakter kurtardı! ancak dönüşü biçimlendirmenin iki katına varan yolu hala çok fazla.
Oliver Friedrich

Ayrıca, girinti başına 4 boşluk kullanıyor musunuz? Bir (veya sekme) yeterli.
Trang Oul

2
@BeowulfOF Aksi belirtilmediği sürece, tam bir program veya bir işlev gönderebilirsiniz. Genellikle, hangisi daha kısa ise, dilinizin zorluk için özel girdiyi ayrıştırma yöntemine bağlı olacaktır (örneğin yakut stdin'den gelen sayılarla şaşırtıcı derecede sakar). Çıktı için iki olası yönteminiz de var: her ikisi için de geçerli olan stdout veya return değeri (programlardan gelen dönüş değerleri nadirdir.)
Level River St

1
Sadece bir ekez kullanıyor görünüyorsun , sadece satır içi yapamaz mısın?
Kevin Brown

0

Mathematica, 155 bayt

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"}]&

Dizeyi girdi olarak alan adsız bir işlevi değerlendirir. Netlik için satır sonları eklendi.

fve gtabandan / tabandan 2. dönüştürün. Riffletam olarak ne araya koymak gerekiyorsa yapar. Ben kullanmak istedim Selectiçin seçme ama Casesdaha iyi ne yazık olduğunu. Son satır biraz kandırmacadır; ~Mathematica'nın infix operatörü olan boşluklar değiştirilir , daha sonra string değerlendirilir.

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.