RabbitFarm
2025-06-08
The Weekly Challenge 324 (Prolog Solutions)
The examples used here are from the weekly challenge problem statement and demonstrate the working solution.
Part 1: 2D Array
You are given an array of integers and two integers $r and $c. Write a script to create two dimension array having $r rows and $c columns using the given array.
Our solution is short and will be contained in a single file that has the following structure.
We’ll use a straightforward recursive approach.
-
create_array(_, 0, _, []).
create_array(L, Rows, Columns, [Row|T]) :-
create_row(L, Columns, Row, L1),
R is Rows - 1,
create_array(L1, R, Columns, T).
create_row(L, 0, [], L).
create_row([H|T], Columns, [H|Row], L) :-
C is Columns - 1,
create_row(T, C, Row, L).
◇
-
Fragment referenced in 1.
Sample Run
$ gprolog --consult-file prolog/ch-1.p | ?- create_array([1, 2, 3, 4], 2, 2, TwoDArray). TwoDArray = [[1,2],[3,4]] ? yes | ?- create_array([1, 2, 3], 1, 3, TwoDArray). TwoDArray = [[1,2,3]] ? yes | ?- create_array([1, 2, 3, 4], 4, 1, TwoDArray). TwoDArray = [[1],[2],[3],[4]] ? yes | ?-
Part 2: Total XOR
You are given an array of integers. Write a script to return the sum of total XOR for every subset of given array.
GNU Prolog has a sublist/2 predicate which will generate all needed subsets on backtracking. We’ll use this inside of a findall/3. The code required is fairly small, although we’ll define a couple of small utility predicates.
-
total_xor(L, Total):-
findall(S, (
sublist(S, L),
\+ S = []
), SubLists),
maplist(combine, SubLists, Combined),
maplist(subtotal, Combined, SubTotals),
sum_list(SubTotals, Total).
◇
-
Fragment referenced in 3.
-
combine([], 0).
combine([H|T], Combined):-
combine(T, Combined1),
Combined = xor(H, Combined1).
◇
-
Fragment referenced in 3.
Sample Run
$ gprolog --consult-file prolog/ch-2.p | ?- total_xor([1, 3], Total). Total = 6 yes | ?- total_xor([5, 1, 6], Total). Total = 28 yes | ?- total_xor([3, 4, 5, 6, 7, 8], Total). Total = 480 yes | ?-
References
posted at: 14:40 by: Adam Russell | path: /prolog | permanent link to this entry
Two Dimensional XOR Not?
The examples used here are from the weekly challenge problem statement and demonstrate the working solution.
Part 1: 2D Array
You are given an array of integers and two integers $r and $c. Write a script to create two dimension array having $r rows and $c columns using the given array.
The core of the solution is contained in a main loop. The resulting code can be contained in a single file.
-
sub create_array{
my($i, $r, $c) = @_;
my @a = ();
for (0 .. $r - 1){
my $row = [];
for (0 .. $c - 1){
push @{$row}, shift @{$i};
}
push @a, $row;
}
return @a;
}
◇
-
Fragment referenced in 1.
Just to make sure things work as expected we’ll define a few short tests. The double chop is just a lazy way to make sure there aren’t any trailing commas in the output.
-
MAIN:{
my $s = q//;
$s .= q/(/;
do{
$s.= (q/[/ . join(q/, /, @{$_}) . q/], /);
} for create_array [1, 2, 3, 4], 2, 2;
chop $s;
chop $s;
$s .= q/)/;
say $s;
$s = q//;
$s .= q/(/;
do{
$s.= (q/[/ . join(q/, /, @{$_}) . q/], /);
} for create_array [1, 2, 3], 1, 3;
chop $s;
chop $s;
$s .= q/)/;
say $s;
$s = q//;
$s .= q/(/;
do{
$s.= (q/[/ . join(q/, /, @{$_}) . q/], /);
} for create_array [1, 2, 3, 4], 4, 1;
chop $s;
chop $s;
$s .= q/)/;
say $s;
}
◇
-
Fragment referenced in 1.
Sample Run
$ perl perl/ch-1.pl ([1, 2], [3, 4]) ([1, 2, 3]) ([1], [2], [3], [4])
Part 2: Total XOR
You are given an array of integers. Write a script to return the sum of total XOR for every subset of given array.
This is another short one, but with a slightly more involved solution. We are going to compute the Power Set (set of all subsets) of the given array of integers and then for each of these sub-arrays compute and sum the XOR results.
The main section is just some basic tests.
-
MAIN:{
say calculate_total_xor 1, 3;
say calculate_total_xor 5, 1, 6;
say calculate_total_xor 3, 4, 5, 6, 7, 8;
}
◇
-
Fragment referenced in 4.
-
sub calculate_total_xor{
my $total = 0;
for my $a (power_set @_){
my $t = 0;
$t = eval join q/ ^ /, ($t, @{$a});
$total += $t;
}
return $total;
}
◇
-
Fragment referenced in 4.
The Power Set can be computed by using a binary counter. Let’s say we have N elements of the set. We start at 0 x N and continue to 1 x N. At each iteration we compose a subarray by including the ith element from the original array if the ith bit is set. Actually, we arent going to start at 0 x N because we want to exclude the empty set for the purposes of the later XOR computation.
-
sub power_set{
my @a = ();
for my $i (1 .. 2 ** @_- 1){
my @digits = ();
for my $j (0 .. @_ - 1){
push @digits, $_[$j] if 1 == ($i >> $j & 1);
}
push @a, \@digits;
}
return @a;
}
◇
-
Fragment referenced in 4.
Sample Run
$ perl perl/ch-2.pl 6 28 480
References
Power Set Defined
Power Set Calculcation (C++) from TWC 141
The Weekly Challenge 324
Generated Code
posted at: 12:36 by: Adam Russell | path: /perl | permanent link to this entry