diff options
| author | irifkin <ianrifkin@ianrifkin.com> | 2023-11-29 14:37:11 -0500 |
|---|---|---|
| committer | irifkin <ianrifkin@ianrifkin.com> | 2023-11-29 14:37:11 -0500 |
| commit | 4c7c82fd82af45e00923f93b2cc41558f0c7c10e (patch) | |
| tree | 7283ad0c8389e4df248e1a5680ed9c6dda1046ee | |
| parent | 2cbcaebea8b7040874a054e50d578d312ab369a5 (diff) | |
| download | perlweeklychallenge-club-4c7c82fd82af45e00923f93b2cc41558f0c7c10e.tar.gz perlweeklychallenge-club-4c7c82fd82af45e00923f93b2cc41558f0c7c10e.tar.bz2 perlweeklychallenge-club-4c7c82fd82af45e00923f93b2cc41558f0c7c10e.zip | |
Perl solution for ch. 245 and initial draft of short blog post
| -rw-r--r-- | challenge-245/ianrifkin/README.md | 82 | ||||
| -rw-r--r-- | challenge-245/ianrifkin/blog.txt | 1 | ||||
| -rw-r--r-- | challenge-245/ianrifkin/perl/ch-1.pl | 77 | ||||
| -rw-r--r-- | challenge-245/ianrifkin/perl/ch-2.pl | 107 |
4 files changed, 267 insertions, 0 deletions
diff --git a/challenge-245/ianrifkin/README.md b/challenge-245/ianrifkin/README.md new file mode 100644 index 0000000000..6d044c531d --- /dev/null +++ b/challenge-245/ianrifkin/README.md @@ -0,0 +1,82 @@ +# Language popularity and largest of 3 + +Challenge 245: https://theweeklychallenge.org/blog/perl-weekly-challenge-245/ + +## Task 1: Sort Language + +``` +You are given two array of languages and its popularity. + +Write a script to sort the language based on popularity. + +Example 1 +Input: @lang = ('perl', 'c', 'python') + @popularity = (2, 1, 3) +Output: ('c', 'perl', 'python') +Example 2 +Input: @lang = ('c++', 'haskell', 'java') + @popularity = (1, 3, 2) +Output: ('c++', 'java', 'haskell') +``` + +My first instinct to solve this was to align the two arrays (lang and popularity) into a hash. While this made sense I quickly realized I would still have the step of sorting based on the keys. This should still have worked but since the arrays have the same indices I didn't really need to combine them into a hash. + +I sorted the popularity array and outputted the indices in sort order (not the values): +`my @pop_sort_idx = sort { $popularity[$a] <=> $popularity[$b] } 0 .. $#popularity;` + +With that I return an array of the languages in sort order using the inputted langage array in the order of the sorted popularity: `@lang[@pop_sort_idx];` + +## Task 2: Largest of Three + +``` +You are given an array of integers >= 0. + +Write a script to return the largest number formed by concatenating some of the given integers in any order which is also multiple of 3. Return -1 if none found. + + +Example 1 +Input: @ints = (8, 1, 9) +Output: 981 + +981 % 3 == 0 +Example 2 +Input: @ints = (8, 6, 7, 1, 0) +Output: 8760 +Example 3 +Input: @ints = (1) +Output: -1 +``` + +This was fun to think through. The first part of the problem is to create an array of all potential numbers sorted from biggest to smallest. The second part of the problem is simpler -- ouput the biggest number (if available) that is divisible by 3. + +In Challenge 244 I used Algorithm::Combinatoric::partitions so I decided to start with that again here. I take the input number and use `partitions` to generate the various "partitions" e.g. for 9,8,1 it is: 981, 98, 91, 9, 81, 8, 1. +``` +my @parts = partitions(\@ints); +``` + +This only gets me part of the way there. I then need each of those numbers in every order (e.g. I need 89 in addition to 98). I decided to use Algorithm::Permute to take the partitions and create all these permutations. +``` +for (my $i=0; $i<@parts-1; $i++) { + foreach ( @{$parts[$i]} ) { + my @parts = $_; + my $p_iterator = Algorithm::Permute->new ( \@{$parts[0]} ); +``` + +Finally I will take the output from Algorithm::Permute and push it into an array of all the numbers to try: +``` +while (my @perm = $p_iterator->next) { + push(@numbers_to_try, join('', @perm)); +} +``` + +At this point I have a randomly sorted array of every number to try. I next need to find out which number (if any) is the largest number divisible by 3. +``` +foreach my $num_2_try (sort { $b <=> $a } @numbers_to_try) { + return $num_2_try unless $num_2_try % 3; +} +``` + +The above loop will return the first number (the largest number) divisible by 3. If it doesn't find one then after this loop there is a `return -1` so that the default behavoir matches the requirements. + +--- +The full code with comments is available at https://github.com/manwar/perlweeklychallenge-club/tree/master/challenge-245/ianrifkin diff --git a/challenge-245/ianrifkin/blog.txt b/challenge-245/ianrifkin/blog.txt new file mode 100644 index 0000000000..74387c5aab --- /dev/null +++ b/challenge-245/ianrifkin/blog.txt @@ -0,0 +1 @@ +https://github.com/manwar/perlweeklychallenge-club/tree/master/challenge-245/ianrifkin#readme diff --git a/challenge-245/ianrifkin/perl/ch-1.pl b/challenge-245/ianrifkin/perl/ch-1.pl new file mode 100644 index 0000000000..cdcfe89983 --- /dev/null +++ b/challenge-245/ianrifkin/perl/ch-1.pl @@ -0,0 +1,77 @@ +use v5.30.3; +use warnings; +use strict; +use Getopt::Long; +use Pod::Usage; + +# Task 1: Sort Language + +my $man = 0; +my $help = 0; +GetOptions ('help|?' => \$help, man => \$man + ) + or pod2usage(2); + +pod2usage(1) if $help; +pod2usage(-exitstatus => 0, -verbose => 2) if $man; + +# Example 1 +my @lang = ('perl', 'c', 'python'); +my @popularity = (2, 1, 3); +say sort_lang(\@lang, \@popularity); +#Output: ('c', 'perl', 'python') + +#Example 2 +@lang = ('c++', 'haskell', 'java'); +@popularity = (1, 3, 2); +say sort_lang(\@lang, \@popularity); +#Output: ('c++', 'java', 'haskell') + +sub sort_lang { + my ($lang, $popularity) = @_; + # Get indices of popularity array in sort order + my @pop_sort_idx = sort { $popularity[$a] <=> $popularity[$b] } 0 .. $#popularity; + # Return sorted language array using indices of sorted popularity numbers + return "@lang[@pop_sort_idx]"; +} + +__END__ + +=head1 Challenge 245, Task 1: Sort Language, by IanRifkin + +You are given two array of languages and its popularity. + +Write a script to sort the language based on popularity. + +Example 1 +Input: @lang = ('perl', 'c', 'python') + @popularity = (2, 1, 3) +Output: ('c', 'perl', 'python') +Example 2 +Input: @lang = ('c++', 'haskell', 'java') + @popularity = (1, 3, 2) +Output: ('c++', 'java', 'haskell') + +See https://theweeklychallenge.org/blog/perl-weekly-challenge-245/#TASK1 for more information on this challenge + +=head1 SYNOPSIS + +perl ./ch-1.pl [options] + +=head1 OPTIONS + +=over 8 + +=item B<-help> + +Print a brief help message and exits. + +=item B<-man> + +Prints the manual page and exits. + +=back + + + + diff --git a/challenge-245/ianrifkin/perl/ch-2.pl b/challenge-245/ianrifkin/perl/ch-2.pl new file mode 100644 index 0000000000..0ed48deed8 --- /dev/null +++ b/challenge-245/ianrifkin/perl/ch-2.pl @@ -0,0 +1,107 @@ +use v5.30.3; +use warnings; +use strict; +use Getopt::Long; +use Pod::Usage; +use Algorithm::Permute; +use Algorithm::Combinatorics qw(partitions); + + +# Task 2: Largest of Three + +my $man = 0; +my $help = 0; +GetOptions ('help|?' => \$help, man => \$man + ) + or pod2usage(2); + +pod2usage(1) if $help; +pod2usage(-exitstatus => 0, -verbose => 2) if $man; + +# Example 1 +my @ints = (8, 1, 9); +say largest(@ints); +# Output: 981 + +# Example 2 +@ints = (8, 6, 7, 1, 0); +say largest(@ints); +# Output: 8760 + +# Example 3 +@ints = (1); +say largest(@ints); +# Output: -1 + +sub largest { + my @ints = @_; #input array of indidviual ints + + # form an an array of all the possible numbers to try + my @numbers_to_try; + # use Algorithm::Combinatoric::partitions to generate all the combinations of numbers + # e.g. for 9,8,1 it is: 981, 98, 91, 9, 81, 8, 1 + my @parts = partitions(\@ints); + for (my $i=0; $i<@parts-1; $i++) { + foreach ( @{$parts[$i]} ) { + my @parts = $_; + # use Algorithm::Permute to take the partitions and create every order of the numbers + # e.g. for an input of 91 it would output 91 and 19 + my $p_iterator = Algorithm::Permute->new ( \@{$parts[0]} ); + while (my @perm = $p_iterator->next) { + push(@numbers_to_try, join('', @perm)); + } + } + } + + # Use array of potential numbers in numerical descending sort order + # to determine if any are divisible by 3 + foreach my $num_2_try (sort { $b <=> $a } @numbers_to_try) { + # return the first (biggest) number found + return $num_2_try unless $num_2_try % 3; + } + return -1 #default return value of -1 if no number found +} + +__END__ + +=head1 Challenge 245, Task 2: Largest of Three, by IanRifkin + +You are given an array of integers >= 0. + +Write a script to return the largest number formed by concatenating some of the given integers in any order which is also multiple of 3. Return -1 if none found. + +Example 1 +Input: @ints = (8, 1, 9) +Output: 981 + +981 % 3 == 0 +Example 2 +Input: @ints = (8, 6, 7, 1, 0) +Output: 8760 +Example 3 +Input: @ints = (1) +Output: -1 + +See https://theweeklychallenge.org/blog/perl-weekly-challenge-245/#TASK2 for more information on this challenge + +=head1 SYNOPSIS + +perl ./ch-1.pl [options] + +=head1 OPTIONS + +=over 8 + +=item B<-help> + +Print a brief help message and exits. + +=item B<-man> + +Prints the manual page and exits. + +=back + + + + |
