# RabbitFarm

### 2021-07-11

#### Swapping Bits / Time Angle

The examples used here are from the weekly challenge problem statement and demonstrate the working solution.

## Part 1

You are given a positive integer \$N less than or equal to 255. Write a script to swap the odd positioned bits with the even positioned bits and print the decimal equivalent of the new binary representation.

### Solution

``````
use strict;
use warnings;
sub swap_bits{
my(\$n) = @_;
my \$bits = substr(unpack("B32", pack("N", shift)), 24, 8);
my @bits = split(//, \$bits);
for(my \$i = 0; \$i < @bits; \$i += 2){
@bits[\$i, \$i + 1] = @bits[\$i + 1, \$i];
}
my \$swapped_decimal = unpack("N", pack("B32", substr("0" x 32 . join("", @bits), -32)));
return \$swapped_decimal;
}

MAIN:{
my \$N;
\$N = 101;
print swap_bits(\$N) . "\n";
\$N = 18;
print swap_bits(\$N) . "\n";
}
``````

### Sample Run

``````
\$ perl perl/ch-1.pl
154
33
``````

### Notes

This code re-uses much of the code from last week's challenge solution. The only difference here is the for loop which swaps the even/odd bits.

## Part 2

You are given time \$T in the format hh:mm. Write a script to find the smaller angle formed by the hands of an analog clock at a given time.

### Solution

``````
use strict;
use warnings;
sub clock_angle{
my(\$h, \$m) = split(/:/, \$_);
my \$angle = abs(0.5 * (60 * \$h - 11 * \$m));
\$angle = 360 - \$angle if \$angle > 180;
return \$angle;
}

MAIN:{
my \$T;
\$T = "03:10";
print clock_angle(\$T) . "\n";
\$T = "04:00";
print clock_angle(\$T) . "\n";
}
``````

### Sample Run

``````
\$ perl perl/ch-1.pl
35
120
``````

### Notes

Perhaps not a whole lot going on here: the time is broken into hour and minute parts and then the angle is computed directly from those values.

## References

Challenge 120

posted at: 17:41 by: Adam Russell | path: /perl | permanent link to this entry

#### The Weekly Challenge 120 (Prolog Solutions)

The examples used here are from the weekly challenge problem statement and demonstrate the working solution.

## Part 1

You are given a positive integer \$N less than or equal to 255. Write a script to swap the odd positioned bits with the even positioned bits and print the decimal equivalent of the new binary representation.

### Solution

``````
:-initialization(main).

length(Bits, L),

bits(N, Bits):-
bits(N, [], Bits).
bits(0, Bits, Bits).
bits(N, Bit_Accum, Bits):-
B is N /\ 1,
N0 is N >> 1,
bits(N0, [B|Bit_Accum], Bits).

swap([], []).
swap([H0, H1|T], [H1, H0|ST]):-
swap(T, ST).

decimal(Bits, Decimal):-
decimal(Bits, 0, Decimal).
decimal([], Decimal, Decimal).
decimal([H|T], DecimalAccum, Decimal):-
length([H|T], B),
D is (H * 2 ** (B - 1)) + DecimalAccum,
decimal(T, D, Decimal).

main:-
bits(18, B),
decimal(Swapped, Decimal),
write(Decimal), nl,
halt.
``````

### Sample Run

``````
\$ gprolog --consult-file prolog/ch-1.p
GNU Prolog 1.4.5 (32 bits)
Compiled Dec  3 2020, 00:37:14 with gcc
By Daniel Diaz
33.0
``````

### Notes

Working with bitwise operators in Prolog is something I have done a bit before. This code most notably borrows from a solution to Challenge 079. Here that `set_bit/2` predicate is repurposed as `bits/2` which returns a list of bits for any given number.

The list of bits must be padded (`pad/2`), the bits swapped (`swap/2`), and then the decimal value of the swapped bits calculated (`decimal/2`).

## Part 2

You are given time \$T in the format hh:mm. Write a script to find the smaller angle formed by the hands of an analog clock at a given time.

### Solution

``````
:-initialization(main).

clock_angle(Time, Angle):-
append(H, [58|M], Time),
number_codes(Hour, H),
number_codes(Minutes, M),
A is abs(0.5 * (60 * Hour - 11 * Minutes)),
((A > 180, Angle is 360 - A); Angle = A).

main:-
clock_angle("03:10", Angle),
write(Angle), nl,
halt.
``````

### Sample Run

``````
\$ gprolog --consult-file prolog/ch-2.p
GNU Prolog 1.4.5 (32 bits)
Compiled Dec  3 2020, 00:37:14 with gcc
By Daniel Diaz
`clock_angle/2` starts out by splitting the hh:mm formatted time into the hour and minute parts, by way of append. 58 is the character code for the ':'. Once this is done, and that is perhaps the most prological part of the code, the formula for the angle is applied.