Peter’s blog ✴ Week 121 ✴ 12 July 2021

THE WEEKLY CHALLENGE
The masked salesman

The Perl Camel

Task 1

Invert bit

You are given integers 0 <= $m <= 255 and 1 <= $n <= 8. Write a script to invert bit $n from the end of the binary representation of $m and print the decimal representation of the new binary number.

Examples


Input: $m = 12, $n = 3
Output: 8

Binary representation of $m = 00001100
Invert 3rd bit from the end = 00001000
Decimal equivalent of 00001000 = 8

Input $m = 18, $n = 4
Output: 26

Binary representation of $m = 00010010
Invert 4th bit from the end = 00011010
Decimal equivalent of 00011010 = 26

Analysis

To do this I first create $mask, which is the number with only bit $n set, ie 2 ** ($n - 1).

Then if $m & $mask is greater than zero, bit $n is 1 and the desired result is $m - $mask. Conversely, if the bit is zero, the result is $m + $mask;

I am sorry that the 'Try it' feature is currently working very slowly or not at all owing to some issue with my web hosting provider.

Try it 

Try running the script with any input:



example: 200



example: 5

Script


#!/usr/bin/perl

# Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge

use v5.26;    # The Weekly Challenge - 2021-07-12
use utf8;     # Week 121 - task 1 - &&task_name
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';
use Encode;

invert_bit(12, 3);
invert_bit(18, 4);
invert_bit(237, 7);

sub invert_bit {
    
    my ($m, $n, $mx, $mask, $bit);
    
    # initialise
    ($m, $n) = @_;
    
    # find mask and check whether set in $m
    $mask = 2 ** ($n - 1);
    $bit = $m & $mask;

    # if bit is set in $m subtract $mask, else add it
    $mx = $bit ? $m - $mask : $m + $mask;
    
    say qq[\nInput: \$m = ] . sprintf('%3d = %08b', $m, $m) . qq[, \$n = $n];
    say qq[Output:     ] . sprintf('%3d = %08b', $mx, $mx);
}

8 lines of code
Completed after the closing date and not submitted to GitHub

Output from script


Input: $m =  12 = 00001100, $n = 3
Output:       8 = 00001000

Input: $m =  18 = 00010010, $n = 4
Output:      26 = 00011010

Input: $m = 237 = 11101101, $n = 7
Output:     173 = 10101101

 

Any content of this website which has been created by Peter Campbell Smith is in the public domain