Wdrożenie operatorów binarnych INTERCAL


29

Język kompilatora bez wyraźnego akronimu, w skrócie INTERCAL , jest bardzo unikalnym językiem programowania. Wśród jego niepowtarzalnych cech znajdują się operatory binarne.

Dwa operatory binarne INTERCAL są przeplatane (znane również jako mingle ) i select . Przeplot jest reprezentowany przez zmianę (¢), a wybór jest reprezentowany przez sqiggle (~).

Przeplot działa poprzez pobranie dwóch liczb z zakresu 0-65535 i naprzemiennie ich bitów. Na przykład:

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

Wybierz prace, biorąc dwie liczby z zakresu 0-65535, biorąc bity w pierwszym operandzie, które są w tej samej pozycji co 1s w drugim operandzie, i odpowiednio upakuj te bity.

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

W tym wyzwaniu otrzymasz wyrażenie binarne za pomocą operacji przeplotu lub wyboru. Musisz obliczyć wynik, używając jak najmniejszej liczby bajtów.

Wyrażenie będą jako przestrzeń oddziela ciąg znaków, składający się z liczby całkowitej w 0-65535, przestrzeni albo ¢czy~ , przestrzeni i liczbę całkowitą 0-65535.

Wejście i wyjście może odbywać się za pośrednictwem dowolnego standardowego systemu (STDIN, funkcja, wiersz poleceń itp.). Standardowe luki zabronione.

Przykłady:

5 ¢ 6
54

5 ~ 6
2

51234 ¢ 60003
4106492941

51234 ~ 60003
422

To jest golf golfowy - wygrywa najmniej bajtów. Powodzenia.

EDYCJA: Ponieważ niektóre języki nie obsługują symbolu zmiany (¢) INTERCAL, możesz zamiast tego użyć symbolu dużych pieniędzy ($), z karą 5 bajtów.


10
Trochę surowo karze się ludzi za używanie znaku dolara. To jest coś, na co nie można pomóc.
— Rozpad beta w dniu

9
Właśnie zdałem sobie sprawę, że CLWNPA jest doskonale wymawiane w języku walijskim. W wymawia się jako U w języku hiszpańskim lub OO w języku angielskim.
— Level River St

9
Nie dostaję kary 5 bajtów. C-INTERCAL korzysta z $.
— kirbyfan64sos,

13
O co wszyscy się kłócicie? $ Jest wyraźnie droższy niż ¢. Czego chcesz 99 centów za nic?
— Maks.

6
Nie sądziłem, że INTERCAL pozwoli ci na wprowadzanie liczb dziesiętnych. Nie musisz pisać FIVE ONE TWO THREE FOUR? I czy dane wyjściowe nie powinny być zapisane cyframi rzymskimi?
— Nate Eldredge,

Odpowiedzi:


9

Pyth, 32 31 29 bajtów

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

Wypróbuj online: Regular Input / Test Suite

Dzięki @isaacg za grę w golfa na jednym bajcie.

Wyjaśnienie:

                         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

Można zapisać jeden bajt, zmieniając hMfeTsię smmFd, a następnie przesuwając powielać spoza trójskładnikowej. Ponadto twój bieżący kod to 32 bajty, a nie 33.
— isaacg

@isaacg Wow. Nigdy nie pomyślałbym, że ten sprytny golf. Dzięki. I tak, grałem w golfa w ostatniej chwili podczas pisania wyjaśnień i nie aktualizowałem liczby bajtów.
— Jakube,

2
Naprawdę interesujące jest zobaczyć odpowiedzi Pyth i CJam, prawie zawsze ta sama liczba bajtów, ale Pyth często pokonuje CJam o kilka
— Kametrixom

13

Python 2, 115 112 bajtów

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

Łańcuch w drugim wierszu zawiera pojedynczy niedrukowalny znak \x7d, następny znak po ~.

Wszystkie nadzieje na ładną, pojedynczą lambdę zostają zmiażdżone przez format wejściowy. Prawdopodobnie jest lepszy sposób na odczyt danych wejściowych. Wprowadź jak "51234 ¢ 60003"przez STDIN.

Ta funkcja fłączy dwie następujące funkcje rekurencyjne:

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 bajty za pomocą @xnor)


1
+1 za pierwszą naprawdę konkurencyjną odpowiedź w języku Python. Zastanawiałem się, dlaczego zawracałeś sobie głowę lambda i nie użyłeś tylko wyrażenia, ale wygląda na to, że jest tam jakaś rekurencja? Nie znam Pythona, czekam na wyjaśnienie.
— Level River St

Świetne bicie! Patrzę na kompresowanie wyrażenia stałego terminu. Wyrażenie (a%2*2+b%2)/3**dzapisuje 3 znaki, ale używa uzupełnienia d=1-c. Czy masz jakiś sposób -~(3*c|b%2)na uzupełnienie? W najgorszym wypadku traci 2 znaki 3-3*d. Format and-~x+ymoże być andy-~xtak długi, jak yzaczyna się od symbolu lub liczby.
— xnor

@xnor Rozumiem (b%2+5&4-d). Dzięki!
— Sp3000,

11

CJam, 31 bajtów

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

Wypróbuj online w interpretatorze CJam .

Jak to działa

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

Edytuj teraz pracując z liczbami zamiast ciągów

(nie licząc wiodących spacji, nowych linii i komentarzy)

Przetestuj uruchomienie tego fragmentu w dowolnej przeglądarce zgodnej z EcmaScript 6 (w szczególności nie Chrome, a nie MSIE. Testowałem na Firefox, Safari 9 mogłaby działać)

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 bajtów

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

Nie golfowany:

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

Przykłady:

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

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

5

R, 145 bajtów

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

Niegolfowane + wyjaśnienie:

# 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

Całkiem proste operacje na łańcuchach, a następnie konwersja z powrotem na liczbę całkowitą.

Ograniczone do liczb, które w systemie binarnym mają 99 cyfr (maks. 2 ^ 99-1 = 633825300114114700748351602687).

Dzięki, Sp3000 i 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))

Lub 165 znaków bez ograniczeń:

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

Nie golfowany:

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
Możesz używać zfillzamiast rjustwypełniania zerami
— Sp3000,

Wejścia maks. Przy 16 bitach, a wyjścia przy 32 bitach. 99 bitów to więcej niż wystarczająco.
— isaacg,

Wiem, ale ponieważ „99” zajmuje tyle samo znaków, co „16”, nie ma korzyści z jego ograniczenia.
— Trang Oul,

1
Jeszcze kilka: 1) Nie ma potrzeby, aby zapisać a,b, wystarczy umieścić go w zipz *ikoną, 2) (i if j=='1'else'') -> i[:j>'0']3) Można używać to wskazówka , aby zaoszczędzić na drugiejif/else
— SP3000

1
Moje rozwiązanie okazało się być zbyt blisko twojego, więc tutaj jest tak krótko, jak mogę dostać twoje (126 bajtów).
— Kade,

4

Pyth, 43 bajty

Część mnie czuje się zdenerwowana, publikując tak długą odpowiedź Pyth'a na pytanie Isaacga ...: oP

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

Wyjaśnienie:

                                               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
Uwielbiam twoje zdjęcie profilowe! :)
— kirbyfan64sos

2
@ kirbyfan64sos Blue Kirby jest najlepsza Kirby: o)
— Sok

3

C, 127 123 bajtów + 5 kar = 128

scanfliczy symbol Unicode jako więcej niż jedną postać, co bardzo komplikuje sytuację, więc stosuję karę 5-bajtową za używanie $.

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

Zmiany w stosunku do oryginalnej wersji to:

- Test na $ lub ~ został zmieniony z q&2na q%7. To odwraca wartości prawda / fałsz, umożliwiając operatorowi $ kod przejście przed znakiem : co oznacza, że ​​zbiór nawiasów można wyeliminować.

-Pętla iodlicza teraz moc 2, która jest dłuższa, ale pozwala >>na zastąpienie /i zapisuje niektóre nawiasy.

Oryginalna wersja 127 bajtów

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

Poszedłem z pojedynczą pętlą z warunkami w środku, aby uniknąć narzutu dwóch pętli. W obu przypadkach przesuwam bity operandów do bitu 1 i buduję wynik od najbardziej znaczącego do najmniej znaczącego bitu, przesuwając w lewo wynik (mnożenie przez 2 lub 4).


Grałem w golfa dla Ciebie: main (a, b, q, x, i) {scanf ("% d% c% d", & a, & q, & b); for (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);} Próbowałem grać w golfa w części >> i & 1, ale nie mogłem znaleźć opłacalnego sposobu na zrobienie tego. Udało mi się jednak zapisać 1 znak, umieszczając definicje zmiennych w main. Uwaga: niesprawdzone.
— LambdaBeta,

@LamdaBeta dzięki, nie mogłem znaleźć makra dla >> i & 1, ale udało mi się zagrać w golfa w inny sposób. Umieszczanie zmiennych jako argumentów mainprzyczyn quszkodzenia na mojej maszynie, co jest dziwne. Oczekuję, że prawdziwy problem jest z tym scanf, ale z tego powodu zostawiłem je jako zwykłe deklaracje.
— Level River St

Nie myślałem o tym. Masz rację, q zostanie uszkodzony. Powodem jest to, że podczas gdy dowiadujemy się, że main przyjmuje dwa argumenty, liczbę argumentów wiersza poleceń i tablicę samych argumentów, większość systemów faktycznie dostarcza trzeci argument (zwykle nazywany char * envp []), który opisuje środowisko kod jest uruchamiany (umożliwiając dostęp do zmiennych środowiskowych EG:). Tak więc trzecia wartość w main może być również przypisana do wartości przez system, tym razem scanf jest niewinny.
— LambdaBeta,

@steveverill Myślę, że możesz również usunąć karę 5 bajtów. Właśnie przetestowałem twój kod (używając ALT + 155, aby zrobić ¢) i wydaje się, że działa dobrze. :)
— LambdaBeta,

@LambdaBeta faktycznie eksperymenty pokazują, że jest to kombinacja obu. Przy normalnej deklaracji qgwarantowane jest zero, ale przy deklaracji jako parametrze funkcji qzawiera śmieci 32-bitowe. Nie stanowiłoby to problemu, gdybym przypisał wartość q, ale scanfz "%c"nadpisaniem tylko najmniej znaczących 8 bitów śmieci, pozostawiając pozostałe 24 niezdefiniowane. Mogę mieć szczęście na innym kompilatorze!
— Level River St

3

K5, 53 52 bajty

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

Wersja 53-bajtowa:

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

Nadal potrzebuje trochę więcej gry w golfa.



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

dane wejściowe są podawane przez zastosowanie danych wejściowych do funkcji / operatorów ? i¢ zdefiniowane w kodzie (Haskell nie może zdefiniować operatora~ z przyczyn technicznych).

w zasadzie działa stare podejście rekurencyjne.


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

oczekuje jednego wiersza danych wejściowych

wejście ma się zakończyć po nowej linii z EOF


2

JavaScript ES6 (3 argumenty) 141 138 136 121 119 bajtów

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

Test:

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

JavaScript ES6 (1 argument) 135 133 bajtów

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

Test:

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

PS: Nowa linia jest liczona jako 1 bajt, ponieważ można ją zastąpić ;.


1
0x10000 == 65536 (zapisz 2 znaki)
— edc65

@ edc65, zaktualizowałem odpowiedź.
— Qwertiy,

2
65536 | x, aby uniknąć ~~
— edc65

Dozwolona jest tylko druga wersja - dane wejściowe muszą mieć postać łańcucha rozdzielanego spacjami.
— isaacg,

@isaacg, ok. Ale nie chcę usuwać pierwszego z powodów historycznych.
— Qwertiy,

2

Python 3, 157 bajtów

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

Pełna i objaśniająca wersja znajduje się na moim pastebin .


Możesz zrobić kilka znaków, usuwając spacje wokół operatora „==”, przed „if” i przekazując „base” jako argument pozycyjny.
— Trang Oul,

Dziękuję, że i inni zaoszczędzili 15 znaków! ale podwójny sposób formatowania zwrotu jest wciąż zbyt duży.
— Oliver Friedrich,

Czy używasz 4 spacji na wcięcie? Wystarczy jedna (lub karta).
— Trang Oul,

2
@ BeowulfOF O ile nie określono inaczej, możesz przesłać pełny program lub funkcję. Zasadniczo, która jest krótsza, będzie zależeć od sposobu, w jaki Twój język analizuje konkretne dane wejściowe dla wyzwania (ruby jest zaskakująco niezdarny, na przykład z liczbami ze standardowego wejścia). Istnieją również dwa możliwe sposoby generowania danych wyjściowych: wartość standardowa lub zwracana, które mają zastosowanie do obu (chociaż wartości zwracane z programów są rzadkie).
— Level River St

1
Wydaje się, że używasz etylko raz, nie możesz tego po prostu wstawić?
— Kevin Brown

0

Mathematica, 155 bajtów

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

Ocenia anonimową funkcję, biorąc ciąg znaków jako dane wejściowe. Dodano podział linii dla zachowania przejrzystości.

fi gkonwersja do / z bazy 2. Rifflerobi dokładnie to, co powinno się przeplatać . Chciałem użyć Selectdo wyboru, ale Casesniestety jest lepiej. Ostatnia linia to trochę oszustwo; spacje są zmieniane, na ~które jest operatorem matematycznym, a następnie ciąg znaków jest ewaluowany.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.