The solutions below are not mine. This week, I saw outstanding solutions from
James Curtis-Smith
and Niels van Dijke.
Therefore, I won't attempt to find better ones, if they exist (I did not found them yet).
TASK #1: Bitwise OR
You are given an array of positive integers, @ints.
Write a script to find out if it is possible to select two or more elements
of the given array such that the bitwise OR of the selected elements has
atlest one trailing zero in its binary representation.
#!/usr/bin/perl use strict; use warnings; sub bitwise_or_james { 1 < grep { ! ($_ & 1) } @_; } # TESTS my (@ints); # Example 1 @ints = (1, 2, 3, 4, 5); print(bitwise_or_james(@ints)); # Output: 1 # Example 2 @ints = (2, 3, 8, 16); print(bitwise_or_james(@ints));# Output: 1 # Example 3 @ints = (1, 2, 5, 7, 9); print(bitwise_or_james(@ints));# Output: undef
We can approach the problem differently: if we know that the bitwise OR of two or more even integers has at least one trailing zero, then can the problem be restated as 'are two or more elements even?'.#!/usr/bin/perl use strict; use warnings; sub bitwise_or_james { 1 < scalar( grep { ! ($_ & 1) } @_ ); }
#!/usr/bin/perl use strict; use warnings; sub bitwise_or_reinier { 1 < scalar( grep { ($_ % 2 == 0) } @_ ); }
#!/usr/bin/perl use strict; use warnings; sub bitwise_or_niels { my $c = 0; for (@_) { $c++ if ($_ & 1) == 0; return (1) if $c > 1; } return (0); }
#!/usr/bin/perl use strict; use warnings; sub distribute_elements_niels { my @a = shift @_; my @b = shift @_; for (@_) { $a[-1] < $b[-1] ? push(@b, $_) : push(@a, $_); } return (@a, @b); } # TESTS my @ints; # Example 1 @ints = (2, 1, 3, 4, 5); print(distribute_elements_niels(@ints)); # Output: (2, 3, 4, 5, 1) # Example 2 @ints = (3, 2, 4); print(distribute_elements_niels(@ints));# Output: (3, 4, 2) # Example 3 @ints = (5, 4, 3, 8); print(distribute_elements_niels(@ints));# Output: (5, 3, 4, 8)