The Compiler Language With No Pronounceable Acronym, abbreviated INTERCAL, is a very unique programming language. Among its unreproducible qualities are its binary operators.

INTERCAL's two binary operators are interleave (also known as mingle), and select. Interleave is represented with a change (¢), and select is represented with a sqiggle (~).

Interleave works by taking two numbers in the range 0-65535 and alternating their bits. For instance:

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

Select works by taking two numbers in the range 0-65535, taking the bits in the first operand which are in the same position as 1s in the second operand, and right packing those bits.

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

In this challenge, you will be given a binary expression using either the interleave or select operation. You must calculate the result, using the fewest possible bytes.

The expression will be given as a space separated string, consisting of an integer in 0-65535, a space, either ¢ or ~, a space, and an integer in 0-65535.

Input and output may be through any standard system (STDIN, function, command line, etc.). Standard loopholes banned.


5 ¢ 6

5 ~ 6

51234 ¢ 60003

51234 ~ 60003

This is code golf - fewest bytes wins. Good luck.

EDIT: Since some languages do not support INTERCAL's change (¢) symbol, you may use the big money ($) symbol instead, at a 5 byte penalty.

  • 11
    \$\begingroup\$ It's a bit harsh penalising people for the use of the dollar sign. That is something that cannot be helped. \$\endgroup\$
    – Beta Decay
    Commented Aug 10, 2015 at 11:14
  • 9
    \$\begingroup\$ I just realized that CLWNPA is perfectly pronouncable in Welsh. The W is pronounced as U in Spanish or OO in English. \$\endgroup\$ Commented Aug 10, 2015 at 11:58
  • 10
    \$\begingroup\$ I don't get the 5 byte penalty. C-INTERCAL uses the $. \$\endgroup\$ Commented Aug 10, 2015 at 14:42
  • 15
    \$\begingroup\$ What are you all arguing about? A $ is clearly more expensive than a ¢. What, you want 99¢ for nothing? \$\endgroup\$
    – Max
    Commented Aug 10, 2015 at 20:15
  • 6
    \$\begingroup\$ I didn't think INTERCAL would allow you to input numbers with decimal numerals. Don't you have to write FIVE ONE TWO THREE FOUR? And shouldn't the output be in Roman numerals? \$\endgroup\$ Commented Aug 10, 2015 at 22:01

18 Answers 18


Python 2, 115 112 bytes

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

The string on the second line contains a single unprintable character \x7d, the next char after ~.

All hopes of a nice, single lambda get crushed by the input format. There's probably a better way to read in input. Input like "51234 ¢ 60003" via STDIN.

The function f combines the following two recursive functions:

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 bytes with the help of @xnor)

  • 1
    \$\begingroup\$ +1 for the first really competitive Python answer. I was wondering why you bothered with the lambda and didn't just use an expression, but it looks like there's some recursion in there? I don't know Python, I look forward to an explanation. \$\endgroup\$ Commented Aug 10, 2015 at 11:19
  • \$\begingroup\$ Some great bit bashing! I'm looking at compressing the constant term expression. The expression (a%2*2+b%2)/3**d saves 3 chars but uses the complement d=1-c. Do you have a way to do -~(3*c|b%2) with the complement? At worst it loses 2 chars with 3-3*d. Also, the format and-~x+y can be andy-~x as long as y starts with a symbol or number. \$\endgroup\$
    – xnor
    Commented Aug 12, 2015 at 6:33
  • \$\begingroup\$ @xnor Got it, (b%2+5&4-d). Thanks! \$\endgroup\$
    – Sp3000
    Commented Aug 12, 2015 at 8:11

CJam, 31 bytes


Try it online in the CJam interpreter.

How it works

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.

Pyth, 32 31 29 bytes


Try it online: Regular Input / Test Suite

Thanks to @isaacg for golfing off one byte.


                         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
  • \$\begingroup\$ You can save one byte by changing hMfeT to smmFd and then moving the duplicate s outside the ternary. Also, your current code is 32 bytes, not 33. \$\endgroup\$
    – isaacg
    Commented Aug 10, 2015 at 12:49
  • \$\begingroup\$ @isaacg Wow. I would never have thought that clever golf. Thanks. And yeah, did a last minute golf while writing the explanation and didn't update the byte count. \$\endgroup\$
    – Jakube
    Commented Aug 10, 2015 at 13:00
  • 2
    \$\begingroup\$ It's really interesting to see Pyth and CJam answers, almost always the same byte count, but Pyth often beats CJam by a few \$\endgroup\$
    – Kametrixom
    Commented Aug 10, 2015 at 21:59

JavaScript (ES6), 103 117 119 124

Edit now working with numbers instead of strings

(not counting leading spaces, newlines and comments)

Test running the snippet on any EcmaScript 6 compliant browser (notably not Chrome not MSIE. I tested on Firefox, Safari 9 could go)

    for(m=r=0,[a,o,b]=s.split` `;i>0;i<<=1) // loop until bit 31 of i is set


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


Matlab, 119 113 bytes

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 =

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

R, 145 bytes

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 + explanation:

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

Python 3, 174 166 148 126

Pretty straightforward, string operations, then conversion back to integer.

Limited to numbers which in binary have 99 digits (max 2^99-1 = 633825300114114700748351602687).

Thanks, Sp3000 and Vioz!

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

Or 165 chars, without limit:

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)]
    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
  • 2
    \$\begingroup\$ You can use zfill instead of rjust for padding with zeroes \$\endgroup\$
    – Sp3000
    Commented Aug 10, 2015 at 9:25
  • \$\begingroup\$ Inputs max out at 16 bits, and outputs at 32 bits. 99 bits is more than enough. \$\endgroup\$
    – isaacg
    Commented Aug 10, 2015 at 11:13
  • \$\begingroup\$ I know, but since '99' takes as much characters as '16', there's no benefit of limiting it. \$\endgroup\$
    – Trang Oul
    Commented Aug 10, 2015 at 11:20
  • 1
    \$\begingroup\$ A few more: 1) You don't need to save a,b, just put it in the zip with a * splat, 2) (i if j=='1'else'') -> i[:j>'0'] 3) You can use this tip to save on the other if/else \$\endgroup\$
    – Sp3000
    Commented Aug 10, 2015 at 13:02
  • 1
    \$\begingroup\$ My solution ended up being too close to yours, so here's as short as I could get yours (126 bytes). \$\endgroup\$
    – Kade
    Commented Aug 10, 2015 at 15:44

Pyth, 43 bytes

Part of me feels nervous posting such a long Pyth answer on isaacg's question... :oP



                                               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
    \$\begingroup\$ I love your profile picture! :) \$\endgroup\$ Commented Aug 10, 2015 at 21:09
  • 2
    \$\begingroup\$ @kirbyfan64sos Blue Kirby is best Kirby :o) \$\endgroup\$
    – Sok
    Commented Aug 11, 2015 at 7:42

C, 127 123 bytes + 5 penalty = 128

scanf counts the unicode symbol as more than one character which complicates things a lot, so I'm applying the 5-byte penalty for using $.

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 changes from the original version are:

-The test for $ or ~ has been revised from q&2 to q%7. This reverses the true/false values, allowing the code for $ operator to go before the : which means a set of parentheses can be eliminated.

-The i loop now counts down in powers of 2 which is longer, but permits >> to be substituted by / and saves some parentheses.

Original version 127 bytes

  scanf("%d %c %d",&a,&q,&b);
      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

I went with a single loop with the conditionals inside to avoid the overhead of two loops. In both cases I rightshift the bits of the operands down to the 1's bit, and build up the result from the most significant to least significant bit, leftshifting the result (multiplying by 2 or 4) as I go.

  • \$\begingroup\$ I golfed it for you: 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 tried golfing away the >>i&1 parts, but couldn't find a cost effective way to do it. I was able to save 1 character however by putting the variable definitions in main. Note: untested. \$\endgroup\$
    – LambdaBeta
    Commented Aug 10, 2015 at 12:28
  • \$\begingroup\$ @LamdaBeta thanks, I couldn't find a macro for >>i&1 but I have managed to golf it another way. Putting the variables as arguments of main causes q to be corrupted on my machine, which is strange. I expect the real problem is with scanf, but because of that I have left them as normal declarations. \$\endgroup\$ Commented Aug 10, 2015 at 13:37
  • \$\begingroup\$ I hadn't thought of that. You are right, q will be corrupted. The reason is that while we learn that main takes two arguments, the count of command-line arguments and an array of the arguments itself, most systems actually provide a third argument (typically called char*envp[]) which describes the environment the code is run in (granting access to EG: environment variables). Thus the third value in main may also be assigned a value by the system, scanf is innocent this time. \$\endgroup\$
    – LambdaBeta
    Commented Aug 10, 2015 at 15:33
  • \$\begingroup\$ @steveverill I think you can also remove the 5 byte penalty. I just tested your code (using ALT+155 to make ¢) and it seems to work fine. :) \$\endgroup\$
    – LambdaBeta
    Commented Aug 10, 2015 at 15:38
  • \$\begingroup\$ @LambdaBeta actually experimentation shows it's a combination of both. With the normal declaration q is guaranteed to be zero, but with the declaration as a function parameter q contains 32-bit garbage. That wouldn't be a problem if I assigned a value to q, but scanf with "%c" only overwrites the least significant 8 bits of the garbage, leaving the other 24 undefined. I might get lucky on another compiler! \$\endgroup\$ Commented Aug 10, 2015 at 21:55

K5, 53 52 bytes

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

53-byte version:

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

Still needs a bit more golfing.


CJam, 61 50 46 41 34 bytes

Thanks @Dennis for pointing out a 4 bytes golf.


Try it online.

  • 1
    \$\begingroup\$ ]{}/ is a noop. \$\endgroup\$
    – Dennis
    Commented Aug 10, 2015 at 16:00
  • 1
    \$\begingroup\$ @Dennis Thanks. I should probably get some sleep... \$\endgroup\$ Commented Aug 10, 2015 at 18:43

Haskell, 77

a¢b=g a+2*b¢h a
a?b=g a*g b+(1+g b)*h a?h b

input is given by applying the input to the functions/operators ? and ¢ defined in the code (Haskell can't define an operator ~ for technical reasons).

basically works the old recursive approach.


J, 173

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

expects one line of input

input expected to terminate after new line with EOF


Javascript ES6 (3 arguments) 141 138 136 121 119 bytes




Javascript ES6 (1 argument) 135 133 bytes

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: New line is counted as 1 byte as it can be replaced by ;.

  • 1
    \$\begingroup\$ 0x10000 == 65536 (save 2 chars) \$\endgroup\$
    – edc65
    Commented Aug 10, 2015 at 21:20
  • \$\begingroup\$ @edc65, I've updated the answer. \$\endgroup\$
    – Qwertiy
    Commented Aug 10, 2015 at 21:43
  • 2
    \$\begingroup\$ 65536|x to avoid ~~ \$\endgroup\$
    – edc65
    Commented Aug 10, 2015 at 21:46
  • \$\begingroup\$ Only the second version is allowed - the input must be in the form of a space delimited string. \$\endgroup\$
    – isaacg
    Commented Aug 11, 2015 at 6:16
  • \$\begingroup\$ @isaacg, ok. But I don't want to delete the first for historical reasons. \$\endgroup\$
    – Qwertiy
    Commented Aug 11, 2015 at 6:25

Python 3, 157 bytes

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

Full and explanatory version can be found on my pastebin.

  • \$\begingroup\$ You can same a few chars by removing spaces around '==' operator, before 'if' and by passing 'base' as positional argument. \$\endgroup\$
    – Trang Oul
    Commented Aug 10, 2015 at 9:14
  • \$\begingroup\$ Thank you, that and some others have saved 15 chars! but the doubled way of formatting the return is still to much. \$\endgroup\$ Commented Aug 10, 2015 at 9:19
  • \$\begingroup\$ Also, do you use 4 spaces per indent? One (or tab) is enough. \$\endgroup\$
    – Trang Oul
    Commented Aug 10, 2015 at 9:25
  • 2
    \$\begingroup\$ @BeowulfOF Unless otherwise specified, you can submit a full program or a function. Generally, which is shorter will depend on the way your language parses the specific input for the challenge (ruby is surprisingly clumsy with numbers from stdin for example). You also have two possible ways to output: stdout or return value, which are applicable to both (though return values from programs are rare.) \$\endgroup\$ Commented Aug 10, 2015 at 10:24
  • 1
    \$\begingroup\$ You only appear to use e once, can't you just inline it? \$\endgroup\$ Commented Aug 11, 2015 at 1:39

Vyxal, 201 bitsv2, 25.125 bytes


Try it Online!



Possibly golfable?

  • 1
    \$\begingroup\$ 22 \$\endgroup\$
    – emanresu A
    Commented Dec 5, 2023 at 19:51
  • \$\begingroup\$ @emanresuA You can remove ₈²+ and vḢ and get the exact same results. Try it Online! \$\endgroup\$ Commented Dec 15, 2023 at 23:00

Mathematica, 155 bytes

ToExpression@StringReplace[#,{" "->"~","~"->"s"}]&

Evaluates to an anonymous function taking the string as input. Line breaks added for clarity.

f and g convert to/from base 2. Riffle does exactly what interleave is supposed to. I wanted to use Select for select but Cases is better unfortunately. The last line is a bit of trickery; spaces are changed to ~ which is Mathematica's infix operator, then the string is eval'd.


Go, 186 bytes

func c(a,b uint)(o uint){for i:=0;i<16;i++{o|=(a&1<<(2*i+1))|(b&1<<(2*i))
func s(a,b uint)(o uint){for i,j:=0,0;i<16;i++{if b&1>0{o|=a&1<<j;j++}

Attempt This Online!

c is interleave, and s is select.



func c(a,b uint)(o uint){       // init return value in `o` with zero value
for i:=0;i<16;i++{              // for each bit (in the uint16)...
o|=                             // OR to `o`...
   (a&1                         // the last bit of `a`
       <<                       // shifted left by
         (2*i+1))               // the current bit * 2 + 1
                 |              // OR-ed with
                  (b&1          // the last bit of `b`
                      <<        // shifted left by
                        (2*i))  // the current bit * 2
a>>=1;b>>=1}                    // discard the last bit of `a` and `b`


func s(a,b uint)(o uint){ // init return value in `o` with zero value
for i,j:=0,0;i<16;i++{    // for each bit (in the uint16)...
if b&1==1{                // if the current bit in `b` is 1...
          o|=             // OR to `o`...
             a&1          // the last bit of `a`
                <<j       // shifted over by the number of 1s so far
                   ;j++}  // increment the number of 1s
a>>=1;b>>=1}              // discard last bit of `a` and `b`
  • \$\begingroup\$ does this work with ¢ and ~ \$\endgroup\$
    – pacman256
    Commented Dec 5, 2023 at 15:48
  • \$\begingroup\$ @Pacmanboss256 It does not, because it does not parse STDIN. These are 2 functions, each of which does the operations described in the OP. Doing input parsing as well would just add some code that would call this submission's code anyway. \$\endgroup\$
    – bigyihsuan
    Commented Dec 5, 2023 at 16:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.