Even and earn
Weekly challenge 303 — 6 January 2025
Week 303: 6 Jan 2025
You are given a list (3 or more) of positive integers, @ints. Write a script to return all even 3-digits integers that can be formed using the integers in the given list.
Example 1 Input: @ints = (2, 1, 3, 0) Output: (102, 120, 130, 132, 210, 230, 302, 310, 312, 320) Example 2 Input: @ints = (2, 2, 8, 8, 2) Output: (222, 228, 282, 288, 822, 828, 882)
This is an interesting challenge in there are two generic classes of solution.
Firstly we could use subsets and permutations, say from Algorithm::Combinatorics.
In step 1 we take all subsets from @ints
, and then all permutations
of each subset. For each permutation we concatenate the members and
see if the result is 3 digits long, even and unique. There's a lot
of calculation in that, but it works and gives the correct result
within a couple of seconds for up to 10 members in @ints
. It then
gets rapidly slower.
The second method, which is what I have submitted, is more complicated,
but it does handle @ints
even up to 100 members in a few seconds.
In summary, it:
That's rather messy, but it is pretty fast.
#!/usr/bin/perl # Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge use v5.26; # The Weekly Challenge - 2025-01-06 use utf8; # Week 303 - task 1 - 3-digits even use warnings; # Peter Campbell Smith binmode STDOUT, ':utf8'; three_digits_even(2, 2, 8, 8, 2); three_digits_even(12, 7, 99, 9); three_digits_even(22, 44, 66); three_digits_even(122, 244, 366); three_digits_even(1, 2, 3, 4, 5); three_digits_even(1, 12, 124, 1234, 4, 2); # longer example my @ints; push @ints, int(rand(100)) for 0 .. 30; three_digits_even(@ints); sub three_digits_even { my (@ints, $j, $int, %results, @even_ones, @even_twos, @odd_ones, @odd_twos, @all_ones, $a, $b, $k, $l); @ints = @_; # first pass through for $j (0 .. $#ints) { $int = $ints[$j]; # anything longer than 3 digits can be discarded next if length($int) > 3; # anything 3 digits long and even can be added to results if (length($int) == 3) { $results{$int} = 1 if ($int & 1) == 0; next; } # now make lists of twos and ones if ($int =~ m|^[24680]$|) { push @even_ones, $int; } elsif ($int =~ m|^[13579]$|) { push @odd_ones, $int; } elsif ($int =~ m|[24680]$|) { push @even_twos, $int; } else { push @odd_twos, $int; } } # valid results are any one followed by an even two for $a (@even_ones, @odd_ones) { for $b (@even_twos) { $results{"$a$b"} = 1; } } # or any two followed by an even one for $a (@even_twos, @odd_twos) { for $b (@even_ones) { $results{"$a$b"} = 1; } } # or any two ones followed by an even one @all_ones = (@even_ones, @odd_ones); for $j (0 .. scalar @all_ones - 1) { for $k (0 .. scalar @all_ones - 1) { next if $j == $k; for $l (0 ... scalar @all_ones - 1) { next if $l == $j or $l == $k or ($all_ones[$l] & 1); $results{"$all_ones[$j]$all_ones[$k]$all_ones[$l]"} = 1; } } } say qq[\nInput: \@ints = (] . join(', ', @ints) . ')'; say qq[Output: (] . join(', ', sort keys %results) . ')'; }
Input: @ints = (2, 2, 8, 8, 2) Output: (222, 228, 282, 288, 822, 828, 882) Input: @ints = (12, 7, 99, 9) Output: (712, 912) Input: @ints = (22, 44, 66) Output: () Input: @ints = (122, 244, 366) Output: (122, 244, 366) Input: @ints = (1, 2, 3, 4, 5) Output: (124, 132, 134, 142, 152, 154, 214, 234, 254, 312, 314, 324, 342, 352, 354, 412, 432, 452, 512, 514, 524, 532, 534, 542) Input: @ints = (1, 12, 124, 1234, 4, 2) Output: (112, 122, 124, 142, 212, 214, 412) Input: @ints = (9, 69, 63, 53, 19, 32, 43, 83, 97, 79, 89, 5, 25, 99, 48, 90, 32, 74, 8, 74, 72, 30, 28, 58, 38, 87, 52, 30, 88, 73, 6) Output: (196, 198, 256, 258, 286, 288, 306, 308, 326, 328, 386, 388, 436, 438, 486, 488, 526, 528, 530, 532, 536, 538, 548, 552, 558, 568, 572, 574, 586, 588, 590, 596, 598, 628, 630, 632, 636, 638, 648, 652, 658, 672, 674, 688, 690, 696, 698, 726, 728, 736, 738, 746, 748, 796, 798, 828, 830, 832, 836, 838, 848, 852, 856, 858, 872, 874, 876, 878, 886, 888, 890, 896, 898, 906, 908, 928, 930, 932, 938, 948, 952, 956, 958, 968, 972, 974, 976, 978, 986, 988, 990, 996, 998)
Any content of this website which has been created by Peter Campbell Smith is in the public domain