# RabbitFarm

### 2021-11-28

#### A Binary Addition Simulation / Nth from a Sorted Multiplication: Table The Weekly Challenge 140

*The examples used here are from The Weekly Challenge problem statement and demonstrate
the working solution.*

## Part 1

*You are given two decimal-coded binary numbers, $a and $b. Write a script to simulate the
addition of the given binary numbers.*

### Solution

```
use strict;
use warnings;
sub add_binary{
my($x, $y) = @_;
my $sum = "";
my @a = reverse(split(//, $x));
my @b = reverse(split(//, $y));
if(@b > @a){
my @c = @b;
@b = @a;
@a = @c;
}
my $carry = 0;
for(my $d = 0; $d <= @a - 1; $d++){
my $d0 = $a[$d];
my $d1 = $b[$d];
if($d1){
$sum = "0$sum", $carry = 0 if $d0 == 1 && $d1 == 1 && $carry == 1;
$sum = "1$sum", $carry = 0 if $d0 == 1 && $d1 == 0 && $carry == 0;
$sum = "0$sum", $carry = 1 if $d0 == 1 && $d1 == 1 && $carry == 0;
$sum = "0$sum", $carry = 1 if $d0 == 0 && $d1 == 1 && $carry == 1;
$sum = "0$sum", $carry = 0 if $d0 == 0 && $d1 == 0 && $carry == 0;
$sum = "1$sum", $carry = 0 if $d0 == 0 && $d1 == 0 && $carry == 1;
$sum = "0$sum", $carry = 1 if $d0 == 1 && $d1 == 0 && $carry == 1;
$sum = "1$sum", $carry = 0 if $d0 == 0 && $d1 == 1 && $carry == 0;
}
else{
$sum = "0$sum", $carry = 1, next if $d0 == 1 && $carry == 1;
$sum = "1$sum", $carry = 0, next if $d0 == 0 && $carry == 1;
$sum = "0$sum", $carry = 0, next if $d0 == 0 && $carry == 0;
$sum = "1$sum", $carry = 0, next if $d0 == 1 && $carry == 0;
}
}
$sum = "$carry$sum" if $carry == 1;
return $sum;
}
MAIN:{
print add_binary(11, 1) . "\n";
print add_binary(101, 1) . "\n";
print add_binary(100, 11) . "\n";
}
```

### Sample Run

```
$ perl perl/ch-1.pl
100
110
111
```

### Notes

I have an unusual fondness for Perl's right hand conditional. But that is pretty obvious from the way I wrote this, right?

## Part 2

*You are given 3 positive integers, $i, $j and $k. Write a script to print the $kth
element in the sorted multiplication table of $i and $j.*

### Solution

```
use strict;
use warnings;
sub nth_from_table{
my($i, $j, $k) = @_;
my @table;
for my $x (1 .. $i){
for my $y (1 .. $j){
push @table, $x * $y;
}
}
return (sort {$a <=> $b} @table)[$k - 1];
}
MAIN:{
print nth_from_table(2, 3, 4) . "\n";
print nth_from_table(3, 3, 6) . "\n";
}
```

### Sample Run

```
$ perl perl/ch-2.pl
3
4
```

### Notes

Full Disclosure: At first I wanted to do this in some convoluted way for fun. After
experimenting with, like, nested `map`

s for a few minutes I lost all interest in "fun" and
just went with a couple of `for`

loops!

## References

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

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

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

## Part 1

*You are given two decimal-coded binary numbers, $a and $b. Write a script to simulate the
addition of the given binary numbers.*

### Solution

```
:-initialization(main).
sum_carry(0, 0, 1, 1, 1).
sum_carry(1, 0, 1, 0, 0).
sum_carry(0, 1, 1, 1, 0).
sum_carry(0, 1, 0, 1, 1).
sum_carry(0, 0, 0, 0, 0).
sum_carry(1, 0, 0, 0, 1).
sum_carry(0, 1, 1, 0, 1).
sum_carry(1, 0, 0, 1, 0).
sum_carry(0, 1, 1, 1).
sum_carry(1, 0, 0, 1).
sum_carry(0, 0, 0, 0).
sum_carry(1, 0, 1, 0).
add_binary(A, B, Sum):-
number_chars(A, AChars),
number_chars(B, BChars),
reverse(AChars, ACharsReverse),
reverse(BChars, BCharsReverse),
add_binary(ACharsReverse, BCharsReverse, 0, [], Sum).
add_binary([], [], 0, SumAccum, Sum):-
number_chars(Sum, SumAccum).
add_binary([], [], 1, SumAccum, Sum):-
number_chars(Sum, ['1'|SumAccum]).
add_binary([H|T], [], Carry, SumAccum, Sum):-
number_chars(D, [H]),
sum_carry(S, C, D, Carry),
number_chars(S, [N]),
add_binary(T, [], C, [N | SumAccum], Sum).
add_binary([H0|T0], [H1|T1], Carry, SumAccum, Sum):-
number_chars(D0, [H0]),
number_chars(D1, [H1]),
sum_carry(S, C, D0, D1, Carry),
number_chars(S, [N]),
add_binary(T0, T1, C, [N | SumAccum], Sum).
main:-
add_binary(11, 1, X0),
write(X0), nl,
add_binary(101, 1, X1),
write(X1), nl,
add_binary(100, 11, X2),
write(X2), nl,
halt.
```

### Sample Run

```
$ gplc prolog/ch-1.p
$ prolog/ch-1
100
110
111
```

### Notes

The approach here may seem just a little strange for "simulating a binary addition", but it seemed like a fun idea, given the small number of combinations, to just store all the intermediate results and then retrieve them as needed. This all seems to work ok, except that maybe going back and forth between numbers and chars is a little clunky.

## Part 2

*You are given 3 positive integers, $i, $j and $k. Write a script to print the $kth
element in the sorted multiplication table of $i and $j.*

### Solution

```
:-initialization(main).
multiply(I, J, N):-
between(1, I, Ith),
between(1, J, Jth),
N is Ith * Jth.
multiplication_table(I, J, Table):-
bagof(N, multiply(I, J, N), Table).
nth_from_table(I, J, K, N):-
multiplication_table(I, J, Table),
msort(Table, SortedTable),
nth(K, SortedTable, N).
main:-
nth_from_table(2, 3, 4, N0),
write(N0), nl,
nth_from_table(3, 3, 6, N1),
write(N1), nl,
halt.
```

### Sample Run

```
$ gplc prolog/ch-2.p
$ prolog/ch-2
3
4
```

### Notes

It's maybe a little confusing, to me anyway, that GNU Prolog's `msort/2`

does *not* merge
duplicates but `sort/2`

does. Other than that I have to say that I really like this bit of
Prolog. It seems very clean to me in that no recursion was required, everything is handled
via Prolog itself.

## References

posted at: 16:59 by: Adam Russell | path: /prolog | permanent link to this entry