aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad S Anwar <Mohammad.Anwar@yahoo.com>2022-12-06 10:58:10 +0000
committerGitHub <noreply@github.com>2022-12-06 10:58:10 +0000
commitc61cf475b68328854a9fcabef2396d664ca22b93 (patch)
tree307e094772208e61932457ba9a3d58851139d724
parent1b8545aea27156dd81e6b0ee7f86660d7bf8af28 (diff)
parenta9ea6c43fba6620b202e52edb5616c14337962bf (diff)
downloadperlweeklychallenge-club-c61cf475b68328854a9fcabef2396d664ca22b93.tar.gz
perlweeklychallenge-club-c61cf475b68328854a9fcabef2396d664ca22b93.tar.bz2
perlweeklychallenge-club-c61cf475b68328854a9fcabef2396d664ca22b93.zip
Merge pull request #7208 from drbaggy/master
iffy!
-rw-r--r--challenge-194/james-smith/README.md125
-rw-r--r--challenge-194/james-smith/blog.txt2
-rw-r--r--challenge-194/james-smith/perl/ch-1.pl38
-rw-r--r--challenge-194/james-smith/perl/ch-2.pl18
4 files changed, 98 insertions, 85 deletions
diff --git a/challenge-194/james-smith/README.md b/challenge-194/james-smith/README.md
index d73a9cf49b..50abcdd7c8 100644
--- a/challenge-194/james-smith/README.md
+++ b/challenge-194/james-smith/README.md
@@ -1,7 +1,7 @@
-[< Previous 192](https://github.com/drbaggy/perlweeklychallenge-club/tree/master/challenge-192/james-smith) |
-[Next 194 >](https://github.com/drbaggy/perlweeklychallenge-club/tree/master/challenge-194/james-smith)
+[< Previous 193](https://github.com/drbaggy/perlweeklychallenge-club/tree/master/challenge-193/james-smith) |
+[Next 195 >](https://github.com/drbaggy/perlweeklychallenge-club/tree/master/challenge-195/james-smith)
-# The Weekly Challenge 193
+# The Weekly Challenge 194 - *iffy* solutions
You can find more information about this weeks, and previous weeks challenges at:
@@ -15,109 +15,64 @@ You can find the solutions here on github at:
https://github.com/drbaggy/perlweeklychallenge-club/tree/master/challenge-193/james-smith
-# Task 1 - Binary string
+# Task 1 - Digital Clock
-***You are given an integer, `$n > 0`. Write a script to find all possible binary numbers of size `$n`.***
+***You are given time in the format `hh:mm` with one missing digit. Write a script to find the highest digit between `0`-`9` that makes it valid time.***
## Solution
+Both solutions today use an ***IIFE*** (Immediately Invoked Function Expression) pronounced *iffy*. To remove the need for temporary variables. Each takes as input the result of an array method, here `split` and in the 2nd task `sort`.
-This weeks task 1 is relatively simple. (1) We need to work out what the minimum and maximum
-integers are and then just print them padded to the right length. Thankfully Perl is great
-at this as it is integral to it's design.
+In this case we split the parameter into it's consitutant characters - the hours being in `0` & `1` and the minutes in `3` and `4`. Using a series of ternary operators we work out which position the "`?`" is in and work out what is the best digit for this place.
-The largest value is '(2^n)-1' and the template for `sprintf` is '`%0{n}b`'. Which gives us
+If the "`?`" is in one of the minute slots this is easy as the value is either `5` or `9`.
+
+If it is in the hour slot we have to make sure the hour is less than 24. So if "`?`" is the first digit, we know that that can be a `2` only if the second digit is less than `4` and if it is in the second digit then the digit can only be `0` - `3` if the 1st digit is `2`.
```perl
-sub all_binary { ## Make a template so we don't have
- my $t = "%0$_[0]b"; ## to do interpolation everytime
- map { sprintf $t, $_ } 0 .. (1<<$_[0])-1 ## Need brackets as - is actioned
-} ## before <<.
+sub digit_2359 {
+ sub {
+ $_[0] eq '?' ? ( $_[1]<4 ? 2 : 1 )
+ : $_[1] eq '?' ? ( $_[0]<2 ? 9 : 3 )
+ : $_[3] eq '?' ? 5
+ : 9
+ }->( split //, $_[0] );
+}
```
-# Task 2 - Odd String
-
-***You are given a list of strings of same length, `@s`. Write a script to find the odd string in the given list. Use positional value of alphabet starting with 0, i.e. `a = 0`, `b = 1`, ... `z = 25`.***
-
-You are given a list of integers greater than or equal to zero, `@list`. Write a script to distribute the number so that each members are same. If you succeed then print the total moves otherwise print `-1`
-
-## Solution
-
-To find the unique string we note:
-
-If word one isn't equivalent to word 2 then the word we are looking for is one of these two (the one which doesn't match the 3rd word)
-o/w we are looking for the first word that is not equivalent.
-### Try 1 - for every string compute a string signature
+My original code allowed `24:00` as a valid value - this gave a slightly more complicated sub...
```perl
-sub sig_str {
- my @Q = map { ord $_ } split //,$_[0];
- join '', map { chr(96 + $Q[$_]-$Q[$_+1]) } 0..$#Q-1
-}
-
-sub odd_string_sig {
- my $x = sig_str( $_[0] );
- return $_[ $x eq sig_str( $_[2] ) ] if $x ne sig_str( $_[1] );
- splice@_,0,2;
- $x eq sig_str( $_ ) || return $_ for @_
+sub digit_2400 {
+ sub {
+ $_[0] eq '?' ? ( $_[1]<4 ? 2 : $_[1]==4 && $_[3]==0 && $_[4]==0 ? 2 : 1 )
+ : $_[1] eq '?' ? ( $_[0]<2 ? 9 : $_[3]==0 && $_[4]==0 ? 4 : 3 )
+ : $_[3] eq '?' ? 5
+ : 9
+ }->( split //, $_[0] );
}
```
-### Try 2 - replace signature with an array ref, here we write an sig_check which compares a string against arrayref.
+# Task 2 - Frequency Equalizer
-```perl
-sub sig {
- my @Q = map { ord $_ } split //,$_[0];
- [ map { $Q[$_]-$Q[$_+1] } 0..$#Q-1 ]
-}
+***You are given a string made of alphabetic characters only, `a`-`z`. Write a script to determine whether removing only one character can make the frequency of the remaining characters the same.***
-sub sig_check {
- my( $sig, $str ) = @_;
- my @Q = map { ord $_ } split //,$str;
- $Q[$_]-$Q[$_+1] == $sig->[$_] || return 0 for 0..$#Q-1;
- return 1
-}
+## Solution
-sub odd_string_sig_check {
- my $x = sig( $_[0] );
- return $_[ sig_check( $x, $_[2] ) ] if !sig_check( $x, $_[1] );
- splice@_,0,2;
- sig_check( $x, $_ ) || return $_ for @_
-}
-```
+Again we use and IIFE. This time taking the value of the sorted values from `%f` (being the frequencies of each letter).
+For the method to be true. The sorted values must be:
+
+ * `n`, `n`, `n`, ...., `n`, `n+1`
-### Try 3... A bit outside in...
+In fact if we reverse the sort (switch `$a` and `$b` around in the comparison) we have:
-We start by working out which are the equivalent words to the first word.
+ * `n+1`, `n`, `n`, ...., `n`, `n`
-Any word is equivalent if it is in this list... So comparisons are light weight...
+So check to see if the first is one more than the second and the second is the same
+as the last.
```perl
-sub odd_string_eqs {
- my @Q = map { ord $_ } split//,$_[0];
- my $l=255;
- $l > $_ && ($l=$_) for @Q;
- my $h=0;
- $h < $_ && ($h=$_) for @Q;
- my %eqs = map {
- my $o = $_;
- join( '', map {chr $_+$o} @Q ) => 1
- } 97-$l .. 122-$h;
- return $_[ exists $eqs{$_[2]} ]
- unless exists $eqs{$_[1]};
- splice@_,0,2;
- exists $eqs{$_} || return $_ for @_
+sub check {
+ my %f; $f{$_} ++ for split //, $_[0];
+ sub { @_>2 && $_[0]==$_[1]+1 && $_[-1]==$_[1] }->(sort {$b<=>$a} values %f) || 0;
}
```
-The lines prior to the `return` - compute this map.
-
-### Performance
-
-How much faster are these... depends on how far along the list you need to go until you find the unique element.
-Testing a list of strings with the odd one in a random location - we saw:
-
-| Method | Speed up |
-|----------------------- |--------: |
-| signature | x 1.0 |
-| signature array | x 1.4 |
-| Equalivalent strings | x 2.5 |
-
diff --git a/challenge-194/james-smith/blog.txt b/challenge-194/james-smith/blog.txt
new file mode 100644
index 0000000000..33001b6b41
--- /dev/null
+++ b/challenge-194/james-smith/blog.txt
@@ -0,0 +1,2 @@
+
+https://github.com/drbaggy/perlweeklychallenge-club/tree/master/challenge-194/james-smith
diff --git a/challenge-194/james-smith/perl/ch-1.pl b/challenge-194/james-smith/perl/ch-1.pl
new file mode 100644
index 0000000000..35d08c6689
--- /dev/null
+++ b/challenge-194/james-smith/perl/ch-1.pl
@@ -0,0 +1,38 @@
+#!/usr/local/bin/perl
+
+use strict;
+
+use warnings;
+use feature qw(say);
+use Test::More;
+use Benchmark qw(cmpthese timethis);
+
+my @TESTS = (
+ ['?3:00',2,2],
+ ['1?:00',9,9],
+ ['2?:00',3,4],
+ ['12:?5',5,5]
+ ['12:5?',9,9]
+);
+
+is( digit_2359( $_->[0] ), $_->[1] ) for @TESTS;
+is( digit_2400( $_->[0] ), $_->[2] ) for @TESTS;
+done_testing();
+
+sub digit_2359 {
+ sub {
+ $_[0] eq '?' ? ( $_[1]<4 ? 2 : 1 )
+ : $_[1] eq '?' ? ( $_[0]<2 ? 9 : 3 )
+ : $_[3] eq '?' ? 5
+ : 9
+ }->( split //, $_[0] );
+}
+
+sub digit_2400 {
+ sub {
+ $_[0] eq '?' ? ( $_[1]<4 ? 2 : $_[1]==4 && $_[3]==0 && $_[4]==0 ? 2 : 1 )
+ : $_[1] eq '?' ? ( $_[0]<2 ? 9 : $_[3]==0 && $_[4]==0 ? 4 : 3 )
+ : $_[3] eq '?' ? 5
+ : 9
+ }->( split //, $_[0] );
+}
diff --git a/challenge-194/james-smith/perl/ch-2.pl b/challenge-194/james-smith/perl/ch-2.pl
new file mode 100644
index 0000000000..c99ad2db52
--- /dev/null
+++ b/challenge-194/james-smith/perl/ch-2.pl
@@ -0,0 +1,18 @@
+#!/usr/local/bin/perl
+
+use strict;
+
+use warnings;
+use feature qw(say);
+use Test::More;
+use Benchmark qw(cmpthese timethis);
+
+my @TESTS = ( ['abbc',1],['xyzyyxz',1],['xzxz',0] );
+
+is( check( $_->[0] ), $_->[1] ) for @TESTS;
+done_testing();
+
+sub check {
+ my %f; $f{$_} ++ for split //, $_[0];
+ sub { @_>2 && $_[0]==$_[1]+1 && $_[-1]==$_[1] }->( sort {$b<=>$a} values %f ) || 0;
+}