You are given a positive integer
$N
.Write a script to swap the two nibbles of the binary representation of the given number and print the decimal number of the new binary representation.
A nibble is a four-bit aggregation, or half an octet.
To keep the task simple, we only allow integer less than or equal to
255
.
Input: $N = 101 Output: 86
Binary representation of decimal
101
is1100101
or as 2 nibbles(0110)(0101)
. The swapped nibbles would be(0101)(0110)
same as decimal86
.Input: $N = 18 Output: 33
Binary representation of decimal
18
is10010
or as 2 nibbles(0001)(0010)
. The swapped nibbles would be(0010)(0001)
same as decimal33
.
Whether the input integers are less than 255
or not doesn't make
the task much easier. So, we will allow positive integers exceeding 255
.
If we take a number, and look at its binary representation, we get
\[ \ldots b_{10} b_{9} b_{8} b_7 b_6 b_5 b_4 b_3 b_2 b_1 b_0 \]
Swapping the last two nibbles, we get:
\[ \ldots b_{10} b_{9} b_{8} b_3 b_2 b_1 b_0 b_7 b_6 b_5 b_4 \]
Now, we could take the number, get a binary representation, swap the two nibbles using a regular expression or substrings, and turn this back into a decimal number.
But we can achieve the same things by manipulating the bits directly. To do this, we first split the original number, which will call \(N\), into three parts:
\[ \begin{array}{rccccccccccc|rcrl} \ldots & b_{10} & b_9 & b_8 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & (N & \& & \sim & \text{0xFF}) \\ \ldots & 0 & 0 & 0 & b_7 & b_6 & b_5 & b_4 & 0 & 0 & 0 & 0 & (N & \& & & \text{0xF0}) \\ \ldots & 0 & 0 & 0 & 0 & 0 & 0 & 0 & b_3 & b_2 & b_1 & b_0 & (N & \& & & \text{0x0F}) \\ \hline \ldots & b_{10} & b_9 & b_8 & b_7 & b_6 & b_5 & b_4 & b_3 & b_2 & b_1 & b_0 & & & & \end{array} \]
We can now shift the bits of the latter two parts four positions to the right or left:
\[ \begin{array}{rccccccccccc|rcrlcc} \ldots & b_{10} & b_9 & b_8 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & (N & \& & \sim & \text{0xFF}) & & \\ \ldots & 0 & 0 & 0 & 0 & 0 & 0 & 0 & b_7 & b_6 & b_5 & b_4 & (N & \& & & \text{0xF0}) & >> & 4 \\ \ldots & 0 & 0 & 0 & b_3 & b_2 & b_1 & b_0 & 0 & 0 & 0 & 0 & (N & \& & & \text{0x0F}) & << & 4 \\ \hline \ldots & b_{10} & b_9 & b_8 & b_3 & b_2 & b_1 & b_0 & b_7 & b_6 & b_5 & b_4 & & & & \end{array} \]
We can now use a bitwise-or (|
) or just plain addition to of
the three parts above to get the final result.
With the input number in $_
:
say + ($_ & ~0xFF) | ($_ & 0x0F) << 4 | ($_ & 0xF0) >> 4
Find the full program on GitHub.
AWK does not have bitwise operators. But we can replace each of
bitwise operations with arithmetic. Here, the input number is
in $1
:
print (($1 - ($1 % 256)) + ($1 % 16) * 16 + int (($1 % 256) / 16))
Find the full program on GitHub.
With the input number in num
:
echo $(((num & ~0xFF) | (num & 0x0F) << 4 | (num & 0xF0) >> 4))
Find the full program on GitHub.
bc doesn't have bitwise operators either, so we use arithmetic.
With the input number in num
:
num - (num % 256) + (num % 16) * 16 + (num % 256) / 16
Find the full program on GitHub.
There are no bitwise operations in Befunge-93, so we have to use arithmetic. Befunge-93 also limits numerical literals to single digits. And the language is stack based. This leads to:
& :1+!#@_ : 44* % 44** \ 44*/ + . 55+,
We start off by reading in a numeric value &
.
We then check whether we're at end-of-file; in that case, the value read
is -1
. If so, we want to quit the program. First, we duplicate the value
just read (:
), add one to it (1+
), and flip the resulting truth value
(!
). We skip the next command (#@
), and then make a decision: if the
top of the stack is false (which it is if we are not at end-of-file), we
continue to the right, else we go left (_
). If we go left, we exit the
program (@
).
If we go right, we can calculate the wanted value. First, we duplicate
the top of the stack again (:
). We then push 4
twice on the stack,
and multiply the them, resulting in having 16
on top of the stack
(44*
). Now, we mod the (duplicate of) the read in value with the
16
on the top of the stack (%
) — this is the value of the last
nibble. We then multiply this value with 16
(44**
).
We now have on the top of the stack the last nibble of the input
value, shifted four bits the to left. The next value on the stack
is the input value. We now swap the two values on top of the stack
(\
), and divide the top of the stack by 16
(44*/
). Befunge-93
does integer division only, so we have the value of the penultimate
nibble on top of the stack.
Since the second value of the stack is the last nibble shifted by four
bits, we just have to add the two values to get the final result: (+
),
which we then print (.
), followed by a newline (55+,
) (a newline
has ASCII value 10
).
The program counter now automatically wraps to the beginning again, as the program is laid out on a torus.
Note that Befunge-93 only handles values up to 255
, so we're not
making any attempt to handle values exceeding 255
.
Find the full program on GitHub.
With the input number in num
:
printf ("%d\n", (num & ~0xFF) | (num & 0x0F) << 4 | (num & 0xF0) >> 4);
Find the full program on GitHub.
Go doesn't have an unary operator to flip all the bits of its
argument (~
), but it does have a binary operator which does
the same thing: (&^
). With the input number in num
:
fmt . Printf ("%d\n", (num &^ 0xFF) | (num & 0x0F) << 4 | (num & 0xF0) >> 4)
Find the full program on GitHub.
With the input number in num
:
System . out . println ((num & ~0xFF) | (num & 0x0F) << 4 | (num & 0xF0) >> 4);
Lua does not have bitwise operators. So, like AWK, we're using
arithmetic. With the input number in num
:
print ( (num - (num % 0x100))
+ ((num % 0x010) * 0x010)
+ math . floor ((num % 0x100) / 0x010))
Find the full program on GitHub.
With the input number in num
:
console . log ((+num & ~0xFF) | (+num & 0x0F) << 4 | (+num & 0xF0) >> 4)
Find the full program on GitHub.
Free Pascal does have the standard bitwise operators, but they are
named differently. It uses and
, or
and not
where most languages
use &
, |
and ~
. To shift bits to the left or to the right,
the operators shl
and shr
are used. Free Pascal uses a dollar ($
)
prefix to indicate hexadecimal literals.
Which leads to the following code, with the input number in num
:
writeln ((num and not $FF) or (num and $0F) shl 4 or (num and $F0) shr 4);
Find the full program on GitHub.
With the input number in num
:
print ((num & ~0xFF) | (num & 0x0F) << 4 | (num & 0xF0) >> 4)
Find the full program on GitHub.
R does not have bitwise operators, but it does have bitwise
functions.
So our R solution is a bit more wordy. With the input number in num
:
cat (bitwOr (bitwOr (bitwAnd (n, bitwNot (0xFF)),
bitwShiftL (bitwAnd (n, 0x0F), 4)),
bitwShiftR (bitwAnd (n, 0xF0), 4)), "\n")
Find the full program on GitHub.
With the input number in num
:
puts ((num & ~0xFF) | (num & 0x0F) << 4 | (num & 0xF0) >> 4)
Find the full program on GitHub.
Scheme does not have bitwise operators, but
bitwise functions. Bitwise or and bitwise and are named
logior
and logand
, bitwise not is called lognot
, and shifting
bits is done with ash
(arithmetic shift). A negative second argument
to ash
shifts to the right, else it shifts left.
Hexadecimal literals in Scheme are prefixed with #x
.
This leads to, with the input number in num
:
(format #t "~d\n" (logior (logand num (lognot #xFF))
(ash (logand num #x0F) 4)
(ash (logand num #xF0) -4)))
Find the full program on GitHub.
With the input number in num
:
puts [expr ($num & ~0xFF) | ($num & 0x0F) << 4 | ($num & 0xF0) >> 4]
Find the full program on GitHub.