INTERCAL의 이진 연산자 구현


29

INTERCAL로 약칭되는 약어가없는 컴파일러 언어 는 매우 고유 한 프로그래밍 언어입니다. 재현 할 수없는 특성 중에는 이진 연산자가 있습니다.

INTERCAL의 두 이항 연산자는 인터리브 (라고도 어울려 ), 및 선택 . 인터리브는 변경 (¢)으로 표시되고 select는 sqiggle (~)로 표시됩니다.

인터리브는 0-65535 범위에서 두 개의 숫자를 취하고 비트를 번갈아 사용합니다. 예를 들어 :

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

Select는 0-65535 범위의 두 숫자를 취하여 두 번째 피연산자의 1과 동일한 위치에있는 첫 번째 피연산자의 비트를 가져 와서 해당 비트를 올바르게 패킹하여 작동합니다.

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

이 도전에서는 인터리브 또는 선택 작업을 사용하여 이진식이 제공됩니다. 가능한 적은 바이트를 사용하여 결과를 계산해야합니다.

식은 공백으로 구분 된 문자열로 제공되며 0-65535의 정수, 공백 ¢또는 또는 ~공백, 0-65535의 정수로 구성됩니다.

입출력은 표준 시스템 (STDIN, 기능, 명령 행 등)을 통해 이루어질 수 있습니다. 표준 허점은 금지되었습니다.

예 :

5 ¢ 6
54

5 ~ 6
2

51234 ¢ 60003
4106492941

51234 ~ 60003
422

이것은 코드 골프입니다-가장 적은 바이트가 이깁니다. 행운을 빕니다.

편집 : 일부 언어는 INTERCAL의 변경 (¢) 기호를 지원하지 않으므로 대신 5 바이트 벌금에 큰 돈 ($) 기호를 사용할 수 있습니다.


10
달러 기호를 사용하는 사람들에게 약간의 처벌을가합니다. 그것은 도울 수없는 것입니다.
Beta Decay

9
CLWNPA는 웨일스 어에서 완벽하게 발음 할 수 있다는 것을 깨달았습니다. W는 스페인어로 U로, 영어로 OO로 발음됩니다.
Level River St

9
5 바이트 페널티를 얻지 못했습니다. C-INTERCAL은을 사용합니다 $.
kirbyfan64sos

13
당신은 모두 무엇에 대해 논쟁하고 있습니까? $는 ¢보다 분명히 더 비쌉니다. 아무것도, 99 ¢를 원하십니까?
최대

6
INTERCAL을 사용하면 십진수로 숫자를 입력 할 수 있다고 생각하지 않았습니다. 쓰지 않아도 FIVE ONE TWO THREE FOUR되나요? 그리고 출력이 로마 숫자로 표시되어서는 안됩니까?
Nate Eldredge

답변:


9

Pyth, 32 31 29 바이트

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

온라인 사용해보기 : 일반 입력 / 테스트 스위트

1 바이트를 골라 낸 @isaacg에게 감사합니다.

설명:

                         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

당신은 변경하여 하나의 바이트를 저장할 수 hMfeTsmmFd다음 중복 이동 s외부에게 삼항합니다. 또한 현재 코드는 33 바이트가 아닌 32 바이트입니다.
isaacg

@isaacg 와우. 나는 그 영리한 골프를 생각하지 않았을 것입니다. 감사. 그리고, 설명을 쓰는 동안 막판 골프를 쳤고 바이트 수를 업데이트하지 않았습니다.
Jakube

2
Pyth와 CJam이 거의 항상 같은 바이트 수로 응답하는 것을 보는 것은 정말 흥미 롭습니다. 그러나 Pyth는 종종 CJam보다 몇
배나 뛰어납니다

13

파이썬 2, 115112 바이트

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

두 번째 줄의 문자열에는 인쇄 할 수없는 단일 문자 ( \x7d다음 문자 다음)가 포함 ~됩니다.

멋진 단일 람다에 대한 모든 희망은 입력 형식에 의해 분쇄됩니다. 입력을 읽는 더 좋은 방법이있을 것입니다. "51234 ¢ 60003"STDIN을 통해 같은 입력 .

이 함수 f는 다음 두 가지 재귀 함수를 결합합니다.

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의 도움으로 3 바이트)


1
최초의 경쟁적인 Python 답변에 +1. 나는 왜 당신이 람다를 귀찮게하고 표현을 사용하지 않았는지 궁금해했지만 거기에 재귀가있는 것처럼 보입니까? 나는 파이썬을 모른다. 나는 설명을 고대한다.
Level River St

약간의 강타! 상수 항 표현을 압축하는 중입니다. 이 식은 (a%2*2+b%2)/3**d3 개의 문자를 저장하지만 보완을 사용합니다 d=1-c. 당신이 할 수있는 방법이 있나요 -~(3*c|b%2)보수와를? 최악의 경우으로 2자를 잃습니다 3-3*d. 또한 형식 and-~x+y은 기호 또는 숫자 andy-~xy시작하는 한 길 수 있습니다 .
xnor

@xnor 알았습니다 (b%2+5&4-d). 감사!
Sp3000

11

CJam, 31 바이트

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

CJam 통역사 에서 온라인으로 사용해보십시오 .

작동 원리

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

자바 스크립트 (ES6) 103 117 119 124

문자열 대신 숫자로 작업하면서 편집

(앞의 공백, 줄 바꿈 및 주석은 포함하지 않음)

EcmaScript 6 호환 브라우저에서 스 니펫 실행 테스트 (특히 MSIE가 아닌 Chrome이 아닙니다. Firefox에서 테스트 한 경우 Safari 9로 이동 가능)

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, 119113 바이트

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

언 골프 드 :

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

예 :

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

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

5

R, 145 바이트

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

언 골프 + 설명 :

# 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

파이썬 3 174 166 148 126

매우 간단하고 문자열 연산 후 정수로 다시 변환합니다.

이진수로 99 자리 숫자로 제한됩니다 (최대 2 ^ 99-1 = 633825300114114700748351602687).

감사합니다, Sp3000과 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))

또는 제한없이 165 자 :

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

언 골프 드 :

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
0으로 채우는 zfill대신 대신 사용할 수 있습니다.rjust
Sp3000

입력은 최대 16 비트이고 출력은 32 비트입니다. 99 비트면 충분합니다.
isaacg 2016 년

알고 있지만 '99'는 '16'만큼 많은 문자를 사용하므로 제한의 이점이 없습니다.
Trang Oul

1
몇 가지 더 : 1) 저장하지 않아도됩니다 a,b. 그냥 표시 zip와 함께 넣습니다 *. 2) (i if j=='1'else'') -> i[:j>'0']3) 이 팁 을 사용 하여 다른 것을 저장할 수 있습니다.if/else
Sp3000

1
내 솔루션 그래서, 너무 가까이 너의 었죠 여기 내가 당신 (126 바이트)를 얻을 수있는 한 짧게.
Kade

4

Pyth, 43 바이트

내 일부는 isaacg의 질문에 대해 긴 Pyth 답변을 긴장시키는 느낌이 들었습니다 ... : oP

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

설명 :

                                               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
나는 당신의 프로필 사진을 사랑합니다! :)
kirbyfan64sos 2016 년

2
@ kirbyfan64sos Blue Kirby가 최고 Kirby입니다 : o)
Sok

3

C, 127123 바이트 + 5 페널티 = 128

scanf유니 코드 기호를 여러 문자로 간주하여 많은 것을 복잡하게하므로을 사용하기 위해 5 바이트 페널티를 적용합니다 $.

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

원본 버전의 변경 사항은 다음과 같습니다.

$ 또는 ~을위한 -THE 시험에서 개정되었습니다 q&2q%7. 이것은 true / false 값을 반대로하여 $ 연산자의 코드가 앞에 :오도록하여 괄호 세트를 제거 할 수 있음을 의미합니다.

년 - i루프는 이제 더 이상 2의 거듭 제곱에서 카운트 다운하지만 허가 >>로 치환되는 /일부 괄호를 저장합니다.

원본 버전 127 바이트

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

두 개의 루프 오버 헤드를 피하기 위해 내부에 조건이있는 단일 루프를 사용했습니다. 두 경우 모두 피연산자의 비트를 1의 비트로 오른쪽 이동하고 최상위 비트에서 최하위 비트로 결과를 작성하여 결과를 왼쪽으로 시프트합니다 (2 또는 4 곱하기).


내가 당신을 위해 골프 : 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);} >> i & 1 부품을 골라 내려고했지만 비용 효율적인 방법을 찾지 못했습니다. 그러나 변수 정의를 main에 넣어서 1 문자를 저장할 수있었습니다. 참고 : 테스트되지 않았습니다.
LambdaBeta

@LamdaBeta 덕분에 >> i & 1에 대한 매크로를 찾을 수 없었지만 다른 방법으로 골프를 쳤습니다. 변수를 변수로 인수를 지정 main하면 q내 컴퓨터에서 손상 될 수 있습니다. 나는 진짜 문제가와 함께 scanf있다고 생각하지만, 그 때문에 정상적인 선언으로 남겨 두었습니다.
Level River St

나는 그것을 생각하지 않았다. 맞습니다, q는 손상 될 것입니다. 그 이유는 main이 명령 행 인수 수와 인수 배열의 두 가지 인수를 취하는 반면 대부분의 시스템은 실제로 코드를 환경을 설명하는 세 번째 인수 (일반적으로 char * envp []라고 함)를 제공하기 때문입니다. 에서 실행됩니다 (EG에 대한 액세스 권한 부여 : 환경 변수). 따라서 main의 세 번째 값에도 시스템에 의해 값이 할당 될 수 있습니다. 이번에는 scanf가 결백합니다.
LambdaBeta

@steveverill 5 바이트 페널티도 제거 할 수 있다고 생각합니다. 방금 코드를 테스트하고 (ALT + 155를 사용하여 ¢) 제대로 작동하는 것 같습니다. :)
LambdaBeta

@LambdaBeta 실제로 실험은 그것이 둘의 조합임을 보여줍니다. 일반 선언 q은 0이 보장되지만 함수 매개 변수 선언 q은 32 비트 가비지를 포함합니다. 그건 내가하면 문제가되지 않을 것입니다 할당 에 값을 q하지만, scanf함께 "%c"정의되지 않은 다른 (24)를 떠나, 쓰레기의 최하위 8 개 비트를 덮어 씁니다. 다른 컴파일러에서 운이 좋을 수도 있습니다!
Level River St

3

K5, 53 52 바이트

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

53 바이트 버전 :

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

여전히 조금 더 골프가 필요합니다.



3

하스켈, 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

입력 기능 / 운영자에게 입력을인가함으로써 부여 ?하고 ¢(하스켈 연산자를 정의 할 수없는 코드에서 정의 된 ~기술을 이유로).

기본적으로 오래된 재귀 접근법을 사용합니다.


2

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

한 줄의 입력을 기대합니다

EOF로 줄 바꿈 후 입력이 종료 될 것으로 예상 됨


2

자바 스크립트 ES6 (3 개 인자) (141) (138) 136 121 119 바이트

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

테스트:

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

자바 스크립트 ES6 (1 인수) 135 133 바이트

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

테스트:

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

추신 : 새 줄은로 대체 될 수 있으므로 1 바이트로 계산됩니다 ;.


1
0x10000 == 65536 (2 문자 저장)
edc65

@ edc65, 답변을 업데이트했습니다.
Qwertiy

2
65536 | x 피하기 ~~
edc65

두 번째 버전 만 허용됩니다. 입력은 공백으로 구분 된 문자열 형식이어야합니다.
isaacg

@isaacg, 알았어. 그러나 역사적 이유로 첫 번째 것을 삭제하고 싶지 않습니다.
Qwertiy

2

파이썬 3, 157 바이트

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

전체 및 설명 버전은 pastebin 에서 찾을 수 있습니다 .


'if'앞의 '=='연산자 주위의 공백을 제거하고 'base'를 위치 인수로 전달하여 몇 개의 문자를 동일하게 만들 수 있습니다.
Trang Oul

감사합니다. 일부는 15자를 절약했습니다! 그러나 반환 형식을 두 배로 늘리는 방법은 여전히 ​​많습니다.
Oliver Friedrich

또한 들여 쓰기 당 4 개의 공백을 사용합니까? 하나 (또는 ​​탭)이면 충분합니다.
Trang Oul

2
@BeowulfOF 달리 명시되지 않는 한 전체 프로그램이나 기능을 제출할 수 있습니다. 일반적으로 더 짧은 것은 언어가 챌린지에 대한 특정 입력을 구문 분석하는 방식에 따라 다릅니다 (예를 들어 루비는 놀랍게도 stdin의 숫자로 어색합니다). 또한 두 가지 방법으로 출력 할 수 있습니다 : stdout 또는 return value, 둘 다에 적용 가능 (프로그램의 리턴 값은 드물지만)
Level River St

1
e한 번만 사용하는 것 같습니다. 인라인 할 수 없습니까?
케빈 브라운

0

Mathematica, 155 바이트

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

문자열을 입력으로 사용하는 익명 함수로 평가합니다. 명확성을 위해 줄 바꿈이 추가되었습니다.

fg기본 2에서 /로 변환이 Riffle정확히 수행 인터리브가 가정된다. 내가 사용하고 싶었 Select을위한 선택 하지만, Cases더 나은 불행하게도이다. 마지막 줄은 약간의 속임수입니다. 공백 ~은 Mathematica의 중위 연산자 로 변경되고 문자열은 평가됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.