14
\$\begingroup\$

Objective

Given an integer \$n\$ interpreted as two's complement binary, output two integers, namely the integer consisting of \$n\$'s bits at places of \$2^0, 2^2, 2^4, \cdots\$, and the integer consisting of \$n\$'s bits at places of \$2^1, 2^3, 2^5, \cdots\$.

Note that the input may be negative. Since \$n\$ is interpreted as two's complement binary, nonnegative integers start with infinitely many zeros, and negative integers start with infinitely many ones. As a consequence, nonnegative inputs split into nonnegative outputs, and negative inputs split into negative outputs.

Examples

Here, the integers are represented as decimal.

Input, Output even, Output odd
0, 0, 0
1, 1, 0
2, 0, 1
3, 1, 1
4, 2, 0
5, 3, 0
6, 2, 1
7, 3, 1
8, 0, 2
9, 1, 2
10, 0, 3
11, 1, 3
12, 2, 2
13, 3, 2
14, 2, 3
15, 3, 3
-1, -1, -1
-2, -2, -1
-3, -1, -2
-4, -2, -2

Worked Example

Say the input is 43, or 101011 in binary.

The "even" output selects the bits like this:

...0000101011
... ^ ^ ^ ^ ^

which is ...00001, or 1 in decimal.

The "odd" output selects the bits like this:

...0000101011
...^ ^ ^ ^ ^

which is ...00111, or 7 in decimal.

I/O format

Flexible; default I/O policies apply.

\$\endgroup\$
7
  • 1
    \$\begingroup\$ pardon me for this stupid question - how did you arrive at 3,0 for input of 5 when it's binary representation is 0b_101 \$\endgroup\$ Mar 26 at 4:56
  • \$\begingroup\$ @RAREKpopManifesto So 0bxyz would break to 0bxz and 0by. \$\endgroup\$ Mar 26 at 5:09
  • 1
    \$\begingroup\$ I'd like to see a worked example for each of a positive and negative input. \$\endgroup\$
    – Xcali
    Mar 26 at 6:48
  • \$\begingroup\$ would it be fine if my program required a + before positive integers? so -2 would stay -2, but 2 would have to be inputted as +2 \$\endgroup\$
    – Quadruplay
    Mar 27 at 0:55
  • \$\begingroup\$ @Quadruplay Yes, of course. \$\endgroup\$ Mar 27 at 1:25

14 Answers 14

10
\$\begingroup\$

JavaScript (Node.js), 40 bytes by tsh

-1B from l4m2

-2B from att

f=n=>[p]=n*~n?[f(n>>1)[1]*2|n&1,p]:[n,n]

Try it online!

\$\endgroup\$
2
  • 2
    \$\begingroup\$ f=n=>[p,q]=n+1>>1?[f(n>>1)|q*2|n&1,p]:[n,n] \$\endgroup\$
    – tsh
    Mar 26 at 7:21
  • 2
    \$\begingroup\$ n+1>>1 -> n*~n \$\endgroup\$
    – att
    Mar 26 at 8:24
9
\$\begingroup\$

Python, 53 bytes

f=lambda x:[x]*(x*~x+2)or[x&1|(r:=f(x//2))[1]*2,r[0]]

Attempt This Online!

Python, 54 bytes

Port of @l4m2's answer (approach in @l4m2's answer has changed quite a bit)

-1 byte thanks to @l4m2

f=lambda x:[x]*(x*~x+2)or[x%2+f(x//4)[0]*2,f(x//2)[0]]

Attempt This Online!

\$\endgroup\$
2
6
\$\begingroup\$

C (gcc), 45 bytes

f(x,y)int*y;{*y=x*~x?x&1|2*f(x>>1,&x):x;x=x;}

Try it online!

Odd bits are returned directly, while even bits are returned through the pointer in the second argument.

Explanation

f(x,                    // recrusive method with integer parameter x
  y)int*y;{             // odd bits are returned; even bits are returned through y
  *y = x * ~x           //   if x * (x - 1) is non zero (i.e. x is not 0 or -1)
      ? x&1 | 2*f(x>>1  //     then y = x&1 | 2*odd_bits(x>>1)
        ,&x)            //          x = even_bits(x>>1)
      : x;              //     else y = x
  x = x;}               //   return x
\$\endgroup\$
5
\$\begingroup\$

Vyxal 3, 12 bytes

„¿⌐bU;ᵛB?„¿⌐

Try it Online! (link is to literate version)

Could be 5 bytes if it wasn't for the negative input requirement.

Explained

negative? if-top: bitwise-not ## „¿⌐
to-binary uninterleave pair vec: from-binary ## bU;ᵛB
input negative? if-top: bitwise-not ## ?„¿⌐
\$\endgroup\$
5
\$\begingroup\$

K (ngn/k), 22 bytes

Returns odd output before even output.

2/64 2#,/|@\^:\(64#2)\

Try it online!

(64#2)\ Get an array of all bits of the integer.
,/|@\^:\ Magic incantation to repeat the leading bit 65 times. Works something like: make all bits zero, index into the array of bits, prepend that result to the bits.
64 2# Reshape the length 128 array into a matrix with two columns.
2/ Convert both columns from base 2.

\$\endgroup\$
5
\$\begingroup\$

Jelly, 12 bytes

»~BṚŒœUḄ~>Ƈ¡

A monadic Link that accepts an integer, \$n\$, and yields a pair of non-negative integers, \$e,o\$ ([even_bits_as_int(n), odd_bits_as_int(n)].

Try it online! Or see the test-suite.

How?

»~BṚŒœUḄ~>Ƈ¡ - Link: integer, N            e.g.: -42                 42
 ~           - bitwise NOT                        41                -43
»            - {N} max {that}                     41                 42
  B          - convert to binary       [1,0,1,0,0,1]      [1,0,1,0,1,0]
   Ṛ         - reverse                 [1,0,0,1,0,1]      [0,1,0,1,0,1]
    Œœ       - unzip               [[1,0,0],[0,1,1]]  [[0,0,0],[1,1,1]]
      U      - reverse each        [[0,0,1],[1,1,0]]  [[0,0,0],[1,1,1]]
       Ḅ     - convert from binary             [1,6]              [0,7]
           ¡ - if...
          Ƈ  - ...keep those for which:
         >   -      greater than {N}?          [1,6] (truthy)        [] (falsey)
        ~    - ...then: bitwise NOT          [-2,-7]              [0,7]
\$\endgroup\$
5
\$\begingroup\$

x86 machine code, 18 bytes

080497c8 <f>:
 80497c8:       be 55 55 55 55          mov    esi,0x55555555
 80497cd:       c4 e2 7a f5 d6          pext   edx,eax,esi
 80497d2:       f7 d6                   not    esi
 80497d4:       c4 e2 7a f5 c6          pext   eax,eax,esi
 80497d9:       c3                      ret

Input is in eax, output in edx:eax.

Try it online!

\$\endgroup\$
4
\$\begingroup\$

Charcoal, 26 bytes

NθI⁻E²↨²⮌Φ⮌↨⁺θ›⁰θ²⁼ι﹪μ²›⁰θ

Try it online! Link is to verbose version of code. Explanation: Charcoal's base conversion simply negates the result if the input is negated, so I have to convert from one's complement to two's complement. Also, the array has its most significant bit first and I don't have an easy way to slice alternate bits depending on the index of the last bit.

Nθ                          First input as a number
     ²                      Literal integer `2`
    E                       Map over implicit range
             θ              Input number
            ⁺               Plus
               ⁰            Literal integer `0`
              ›             Is greater than
                θ           Input number
           ↨                Converted to base
                 ²          Literal integer `2`
          ⮌                 Reversed
         Φ                  Filtered where
                   ι        Outer value
                  ⁼         Equals
                     μ      Inner index
                    ﹪       Modulo
                      ²     Literal integer `2`
        ⮌                   Reversed
      ↨                     Converted from base
       ²                    Literal integer `2`
   ⁻                        Vectorised substract
                        ⁰   Literal integer `0`
                       ›    Is greater than
                         θ  Input number
  I                         Cast to string
                            Implicitly print
\$\endgroup\$
4
\$\begingroup\$

PowerShell Core, 105 bytes

param($a)0,1|%{$k=$_
($c=[Convert])::ToInt16(-join($c::ToString($a,2)|% *ft 32 48|% t*y|?{$i++%2-$k}),2)}

Try it online!

Takes an integer and returns two shorts

\$\endgroup\$
4
\$\begingroup\$

C (gcc), 48

  • 6 bytes saved thanks to @ceilingcat and @l4m2.

TIL modern x86-64 has instructions for this, and they are wrapped in the _pext_*() family of compiler intrinsics.

Not the shortest, but perhaps the fastest. Probably this can be golfed more, but this is as far as I got.

Returns the even bits in the most significant 16 bits and the odd bits in the least significant 16 bits of the returned int.

#define g _pext_u32(i,~0U/3
f(i){i=g)<<16|g*2);}

Try it online!


Experimental

I wanted to play with the execstack approach. TL;DR this is 20 bytes of machine code, but wrapping it as a wchar_t string in c does not produce a shorter answer - 67 bytes. For posterity, this is the work I did. The underlying x86_64 assembly is:

    .globl  f
f:
    movl    $1431655765, %eax
    movl    %eax, %edx
    not     %edx
    pext    %eax, %edi, %eax
    pext    %edx, %edi, %edx
    ret

This uses a new-to-me technique to return 2 values. The cdecl ABI can return in EAX:EDX. GCC does this if a function return type is a simple struct containing 2 int-sized objects. One example of where this happens is glibc ldiv(), which returns quotient and remainder in the ldiv_t struct. So all the assembly has to do is generate odd and even bitmasks, then apply these with the pext instruction to the single int passed in EDI, and save the results in EAX and EDX. The test driver can treat this assembly function as if it is returning an ldiv_t.

Try it online!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ @ceilingcat 48 \$\endgroup\$
    – l4m2
    Mar 27 at 7:38
  • 1
    \$\begingroup\$ Can try other instructions with shorter string literal representations Try it online! \$\endgroup\$
    – ceilingcat
    Apr 19 at 18:53
3
\$\begingroup\$

05AB1E, 15 14 bytes

±‚àbR2ιíCI0‹i±

Try it online or verify all test cases.

Explanation:

±              # Bitwise-NOT (-n-1) the (implicit) input
 ‚             # Pair it with the (implicit) input
  à            # Pop and leave the maximum
   b           # Convert it to binary
    R          # Reverse it
     2ι        # Uninterleave it into 2 parts
       í       # Reverse both parts
        C      # Convert the parts from binary-strings to integers
         I0‹i  # If the input was negative:
             ± #  Bitwise-NOT the values in the pair again
               # (after which the pair is output implicitly as result)
\$\endgroup\$
2
  • 1
    \$\begingroup\$ This seems to give the wrong output for an input of -3. \$\endgroup\$
    – Neil
    Mar 26 at 10:23
  • \$\begingroup\$ @Neil Ugh.. Should be fixed with a much more boring (but correct) approach. \$\endgroup\$ Mar 26 at 11:16
3
\$\begingroup\$

Uiua 0.10.0, 22 bytes

↙2▽2⍜⌵(⊕°⋯◿2⇡⧻.⊂⋯):<0.

Explanation + See it in action

\$\endgroup\$
3
\$\begingroup\$

Easyfuck, 99 87 bytes

ćŁďßżTáPűŰďo␞}Ŕˇóĺo␞)űHOPCĺo␔©H±uä‹˙+Vů")J­SHYľüSHY㻯°áĂ…ő—Öe[yűš·źą«wvRE¸␔<ćóš™TDCS®xť’ä+ž'€µh

due to lack of unicode representations for c1 control characters, they have been replaced by their superscripted abbreviations

Decompressed:

s(}}}})a(>{>{<<}`(>>+<<)}`(>+<))$,.^$/~++>$"J*[>~+<;]>aaaa>Y>YJ[<~s+<~s+;]J$-`(<s<s)JR!.<'2.!.<'@--

Just barely got it under 100. The program expects a +/- before the integer, and the integer must be 8-bit. There's also a version that's 110 bytes long, but it works pretty much the same, it's just that the bit shifting and negating requires a few characters more:

a(>{>{<<}`(>>+<<)b}`(>+<)b)b(<}`(>Y+Y<)>)$,^$/~++$>*.$>IJ[>~>~+`(<+);]J>>aaaaaaaa>Y>YJ[<~+<~+;]JR!.<'2.!.<'@--

I'll explain the smaller version:

functions:

s(}}}})                   this one shifts a byte 4 bits to the right

a(>{>{<<}`(>>+<<)}`(>+<)) this one shifts the next 2 cells to the left once, 
                          and then shifts the current cell twice, the first shift increments
                          the second next cell if a 1 was lost, the second increments the
                          first next cell
calculations:
$,.^$/~++>$"J*[>~+<;]>aaaa>Y>YJ[<~s+<~s+;]

$,.^$/                                     take a char of input, output it, xor it with "-",
                                           and divide by self yielding 0 if "-", 1 if not

      ~++>$"                               NOT and increment twice, turning 0 into 1 and vice
                                           versa, then go to next cell, copy the initialized 
                                           "-" to storage, and input an 8-bit integer into 
                                           2nd cell

            J*[>~+<;]                      multiply first cell by "-", and if non-zero, 
                                           NOT and increment the 2nd cell

                     >aaaa                 apply function "a" to 2nd cell 4 times

                          >Y>Y             reverse order of bits of cells 3 and 4

                              J[<~s+<~s+;] if 1st bit is non-zero, apply NOT, "s", and 
                                           increment cells 3 and 4
printing:
J$-`(<s<s)JR!.<'2.!.<'@--

J$-`(<s<s)                copy 1st cell to storage and if 0 apply "s" to cells 3 and 4

          JR!.<'2.!.<'    clear screen and print:
                          [storage][cell4][space][storage][cell3]

                      @   end program

                       -- initializer data

note: if the 1st character is neither + nor -, the program acts as if it received a +

\$\endgroup\$
2
\$\begingroup\$

Java, 79 bytes

int[]f(int n){return new int[]{n*~n<0?f(n>>2)[0]*2|n%2:n,n*~n<0?f(n>>1)[0]:n};}

It's been a while since I've used a recursive approach in Java. Perhaps an iterative lambda with String return could be shorter, but I'm not sure.

Try it online.

Explanation:

int[]f(int n){         // Recursive method with integer parameter & integer-array return:
  return new int[]{    //  Return a new integer-array, with two items:
    n*~n<0?            //   If `n*(-n-1)` is negative:
      f(n>>2)          //    Do a recursive call with `n` bitwise right-shifted by 2
             [0]       //    Take its singular result
                *2     //    Multiply it by 2
                  |    //    Bitwise-OR it by:
                   n%2 //     `n` modulo-2
    :                  //   Else (`n*(-n-1)` is 0 instead):
     n,                //    Simply use `n` as is
    n*~n<0?            //   Repeat the same if-statement:
      f(n>>1)          //    Do a recursive call to `n` bitwise right-shifted by 1 instead
             [0]       //    And take its singular result
    :n};}              //   With a similar else-block
\$\endgroup\$

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.