RabbitFarm

2025-03-01

Arrays Intersect in Odd Ways

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

Part 1: Arrays Intersection

You are given a list of array of integers. Write a script to return the common elements in all the arrays.

The complete solution is contained in one file that has a simple structure.

"ch-1.pl" 1


preamble 2
compute array intersections. 3
main 4

For this problem we do not need to include very much. We’re just specifying to use the current version of Perl, for all the latest features in the language. This fragment is also used in Part 2.

preamble 2 ⟩≡


use v5.38;

Fragment referenced in 1, 5.

We’ll take the arrays in pairs and build up a list of common elements. First we compute the common elements of the first two arrays and then proceed to check these against the remaining arrays. If any of these initial common elements are not found in subsequent arrays they are not included in future checks. Finally the remaining common elements are returned. If there are no common elements we return n/a.

compute array intersections. 3 ⟩≡


sub array_intersections{
my @common_elements;
my $x = shift @_;
my $y = shift @_;
if($x && $y){
my @common = map {
my $x = $_;
grep {$x == $_} @{$y}
} @{$x};
push @common_elements, @common;
}
{
$x = shift @_;
my @common = map {
my $x = $_;
grep {$x == $_} @{$y}
} @common_elements;
@common_elements = @common;
redo if @_ > 1;
}
return (join q/, /, @common_elements) || q#n/a#;
}

Fragment referenced in 1.

Now all we need are a few lines of code for running some tests.

main 4 ⟩≡


MAIN:{
say array_intersections [1, 2, 3, 4], [4, 5, 6, 1], [4, 2, 1, 3];
say array_intersections [1, 0, 2, 3], [2, 4, 5];
say array_intersections [1, 2, 3], [4, 5], [6];
}

Fragment referenced in 1.

Sample Run
$ perl perl/ch-1.pl 
1, 4 
2 
n/a
    

Part 2: Sort Odd Even

You are given an array of integers. Write a script to sort odd index elements in decreasing order and even index elements in increasing order in the given array.

"ch-2.pl" 5


preamble 2
sort odd/even. All the code for solving the problem is here. 6
main 7

To solve this problem we need to do the following

1.
seperate the odd and even numbers
2.
sort the two lists as directed
3.
combine the results

Much of this work can be written concisely using map and grep.

sort odd/even. All the code for solving the problem is here. 6 ⟩≡


sub sort_odd_even{
my @i = @_;
my @odds = map { $i[$_] } grep {$_ % 2 != 0} 0 .. @_ - 1;
my @evens = map { $i[$_] } grep {$_ % 2 == 0} 0 .. @_ - 1;
my @odds_sorted = sort {$b <=> $a} @odds;
my @evens_sorted = sort {$a <=> $b} @evens;
my @common_elements;
do {
$common_elements[$_] = shift @odds_sorted if $_ % 2 != 0;
$common_elements[$_] = shift @evens_sorted if $_ % 2 == 0;
} for 0 .. @_ - 1;
return @common_elements;
}

Fragment referenced in 5.

Finally, here’s a few tests to confirm everything is working right.

main 7 ⟩≡


MAIN:{
say join q/, /, sort_odd_even 4, 1, 2, 3;
say join q/, /, sort_odd_even 3, 1;
say join q/, /, sort_odd_even 5, 3, 2, 1, 4;
}

Fragment referenced in 5.

Sample Run
$ perl perl/ch-2.pl 
2, 3, 4, 1 
3, 1 
2, 3, 4, 1, 5
    

References

The Weekly Challenge 310
Generated Code

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