实施INTERCAL的二元运算符


29

没有明显首字母缩写的编译器语言,INTERCAL的缩写,是一种非常独特的编程语言。其不可复制的品质包括其二进制运算符。

INTERCAL的两个二进制运算符进行交织(也称为mingle),然后选择。交错表示为变化(¢),选择表示为花样(〜)。

交织通过取0-65535范围内的两个数字并将其位交替来进行。例如:

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

Select的工作方式是取0-65535范围内的两个数字,取第一个操作数中与第二个操作数中1s位置相同的位,并右包装这些位。

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 2015年

9
我刚刚意识到CLWNPA在威尔士语中的发音很完美。W在西班牙语中发音为U,在英语中发音为OO。
水平河圣

9
我没有得到5字节的罚款。C-INTERCAL使用$
kirbyfan64sos

13
你们都在吵什么 $显然比¢贵。什么,你什么都不想要99¢?
最多

6
我认为INTERCAL不会允许您使用十进制数字输入数字。你不用写FIVE ONE TWO THREE FOUR吗?而且输出不应该是罗马数字吗?
Nate Eldredge

Answers:


9

珀斯32 31 29字节

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

在线尝试:常规输入/测试套件

感谢@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三进制之外。此外,当前的代码是32个字节,而不是33
isaacg

@isaacg哇。我永远也不会想到那种聪明的高尔夫。谢谢。是的,在编写说明时进行了最后一分钟的打球,并且没有更新字节数。
2015年

2
看到Pyth和CJam的答案,几乎总是相同的字节数,真的很有趣,但是Pyth经常比CJam差几个
Kametrixom 2015年

13

Python 2中,115个 112字节

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,下一个字符为~

输入格式粉碎了一个好的Lambda的所有希望。可能有更好的输入输入方法。"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
+1是第一个真正具有竞争力的Python答案。我想知道为什么您不去使用lambda而不只是使用表达式,而是在其中似乎有一些递归?我不了解Python,我期待一个解释。
水平河圣

一些伟大的扑!我正在研究压缩常数项表达式。该表达式(a%2*2+b%2)/3**d节省3个字符,但使用补码d=1-c。您有办法处理-~(3*c|b%2)互补吗?在最坏的情况下,它会损失2个字符3-3*d。此外,格式and-~x+y可以是andy-~x只要y用符号或数字开始。
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

的JavaScript(ES6),103 117 119 124

编辑现在使用数字而不是字符串

(不包括前导空格,换行符和评论)

测试在任何符合EcmaScript 6的浏览器上运行该代码段(值得注意的是,Chrome不是MSIE。我在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,119 113字节

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

Python 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
您可以使用zfill代替rjust零填充
Sp3000 2015年

输入最大为16位,输出为32位。99位绰绰有余。
isaacg 2015年

我知道,但是由于“ 99”与“ 16”一样多的字符,因此限制它没有任何好处。
董里(Trang Oul)2015年

1
还有一些:1)您不需要保存a,b,只需将它zip*splat 一起放在其中,2)(i if j=='1'else'') -> i[:j>'0']3)您可以使用此技巧进行保存if/else
Sp3000,2015年

1
我的解决方案最终与您的解决方案太接近了,所以是我能得到的(126字节)。
卡德2015年

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 2015年

2
@ kirbyfan64sos Blue Kirby是最好的Kirby:o)
Sok

3

C,127123字节+ 5罚单= 128

scanf将unicode符号视为一个以上的字符,这使事情变得非常复杂,因此我对施加了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);}

对原始版本的更改是:

-$或〜的测试已从修改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 2015年

@LamdaBeta谢谢,我找不到>> i&1的宏,但我设法用另一种方法打高尔夫球。将变量作为main导致原因的参数q放在我的计算机上,这很奇怪。我希望真正的问题在于scanf,但是由于这个原因,我将它们保留为常规声明。
水平河圣

我没想到。没错,q将会损坏。原因是,虽然我们了解到main具有两个参数,即命令行参数的数量和参数本身的数组,但是大多数系统实际上提供了第三个参数(通常称为char * envp []),该参数描述了环境代码运行(允许访问EG:环境变量)。因此main中的第三个值也可以由系统分配一个值,这次scanf是无害的。
LambdaBeta 2015年

@steveverill我想您也可以删除5个字节的罚款。我刚刚测试了您的代码(使用ALT + 155使¢),它似乎可以正常工作。:)
LambdaBeta 2015年

实际上,@ LambdaBeta实验表明这是两者的结合。使用普通声明q可以保证为零,但是使用函数作为声明时,参数q包含32位垃圾。如果我为分配了一个值q,那将不是问题,但是scanf"%c"仅覆盖垃圾的至少显著8位,离开未定义的其他24个。我可能会幸运地得到另一个编译器!
水平河圣

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

通过将输入应用于函数/运算符来给出输入,?¢在代码中进行定义(Haskell无法定义运算符~出于技术原因,)。

基本上可以使用旧的递归方法。


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

希望输入一行

用EOF换行后预期输入将终止


2

的Javascript 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"

的Javascript 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"

PS:新行计为1字节,因为可以用代替;


1
0x10000 == 65536(节省2个字符)
edc65

@ edc65,我已经更新了答案。
2015年

2
65536 | x避免~~
edc65

仅允许使用第二个版本-输入必须以空格分隔的字符串形式。
isaacg 2015年

@isaacg,好。但是由于历史原因,我不想删除第一个。
2015年

2

Python 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个字符!但是格式化返回值的两倍方法仍然很多。
奥利弗·弗里德里希

另外,您是否每个缩进使用4个空格?一个(或选项卡)就足够了。
董里2015年

2
@BeowulfOF除非另有说明,否则您可以提交完整的程序或函数。通常,较短的时间取决于您的语言解析挑战特定输入的方式(例如,ruby的stdin中的数字令人惊讶地笨拙)。您也有两种可能的输出方式:stdout或返回值,这两种方式都适用(尽管从程序返回的值很少。)
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的infix运算符,然后评估该字符串。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.