# ETOOBUSY ðŸš€ minimal blogging for the impatient

# PWC119 - Swap Nibbles

**TL;DR**

Here we are with TASK #1 from the Perl Weekly Challenge #119. Enjoy!

# The challenge

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.

Example`Input: $N = 101 Output: 86 Binary representation of decimal 101 is 1100101 or as 2 nibbles (0110)(0101). The swapped nibbles would be (0101)(0110) same as decimal 86. Input: $N = 18 Output: 33 Binary representation of decimal 18 is 10010 or as 2 nibbles (0001)(0010). The swapped nibbles would be (0010)(0001) same as decimal 33.`

# The questions

Iâ€™ve become increasingly lazy at finding out questions for challenges,
as Colin Crainâ€™s review remind me almost weekly. As an example, there
was *a lot* of space for interpretation in challenge Number
Sequence, but I just assumed that we were talking about increasing
sequences. Iâ€™m not sure I would stick to my solution in hindsight.

Anyway, this challenge seems to be pretty tight in the requirements. Weâ€™re talking about positive integers whose value is less than or equal to 255, which means that itâ€™s possible to consider a binary representation with exactly two nibbles for each valid candidate.

Of course we might argue that the definition of *nibble* leaves some
interpretation to irritating people like me, because aggregation does
not necessarily imply adjacency or alignment to multiples of 4 bits. So,
for sake of irritating the reader, Iâ€™ll go on and say that, in my
interpretation:

- inputs are always considered as fitting a full octet, represented in binary as a sequence of exactly 8 bits
- the sequence can be divided into two nibbles, one including the first four bits of the sequence, the other including the last four bits.

I wonder what Iâ€™m leaving out!

# The solution

This can be addressed with bit fiddling only:

```
#!/usr/bin/env raku
use v6;
sub swap-nibbles (Int:D $N where 0 < $N <= 255) { $N +& 0x0F +< 4 +| $N +> 4 }
my @inputs = @*ARGS ?? @*ARGS !! < 101 18 >;
swap-nibbles(+$_).put for @inputs;
```

Thanks to the precedence rules, the expression does not need parentheses, although this goes at the expense of readability. This is probably a more maintainable version:

```
(
($N +& 0x0F) # isolate the least-significant nibble
+< 4 # shift it 4 bits to the left, i.e. in the position
) # of the other nibble
+| # then "or" this with
($N +> 4) # the most-significant nibble moved 4 bits to the
# right, i.e. in the position of the other nibble
```

There is no need to mask the higher nibble before moving it onto the
lower one, because the input constraints on `$N`

already exclude
that thereâ€™s no bit set beyond the high nibble, and the shift to the
right will ditch the lower nibble.

On with the Perl equivalent, more or less:

```
#!/usr/bin/env perl
use v5.24;
sub swap_nibbles { ($_[0] & 0x0F) << 4 | $_[0] >> 4 }
my @inputs = @ARGV ? @ARGV : qw< 101 18 >;
say swap_nibbles($_) for @inputs;
```

Weâ€™re losing signatures and input validation here, which is fair for making the point of a challenge but would probably need to be highlighted in an interview!

I also find it interesting that the operators precedence is slightly
different here than in Raku, and we need to force the masking
operation `$_[0] & 0x0F`

to happen before the shift to the left
(otherwise, `perl`

would interpret it as `$_[0] & (0x0F << 4)`

, i.e.
`$_[0] & 0xF0`

, i.e. *keep the high nibble as it is!*).

Well, I guess itâ€™s everything for this challenge task!

*Comments? Octodon, Twitter, GitHub, Reddit, or drop me a line!*