aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordrbaggy <js5@sanger.ac.uk>2022-05-02 10:30:21 +0100
committerdrbaggy <js5@sanger.ac.uk>2022-05-02 10:30:21 +0100
commit11ce61d5df739402e98a4043d4b1f6682dccdea5 (patch)
treecfe63414f7054301f9d37f5f19df5b6ad85888f0
parenta702e0aa6757e66d221f111f9effb9358db2ee1e (diff)
downloadperlweeklychallenge-club-11ce61d5df739402e98a4043d4b1f6682dccdea5.tar.gz
perlweeklychallenge-club-11ce61d5df739402e98a4043d4b1f6682dccdea5.tar.bz2
perlweeklychallenge-club-11ce61d5df739402e98a4043d4b1f6682dccdea5.zip
pushing new code and README.md
-rw-r--r--challenge-163/james-smith/README.md108
-rw-r--r--challenge-163/james-smith/blog.txt1
-rw-r--r--challenge-163/james-smith/perl/ch-2.pl4
3 files changed, 71 insertions, 42 deletions
diff --git a/challenge-163/james-smith/README.md b/challenge-163/james-smith/README.md
index 248d432347..0c8c17cdc5 100644
--- a/challenge-163/james-smith/README.md
+++ b/challenge-163/james-smith/README.md
@@ -1,6 +1,6 @@
-[< Previous 161](https://github.com/drbaggy/perlweeklychallenge-club/tree/master/challenge-161/james-smith) |
-[Next 163 >](https://github.com/drbaggy/perlweeklychallenge-club/tree/master/challenge-163/james-smith)
-# The Weekly Challenge 162
+[< Previous 162](https://github.com/drbaggy/perlweeklychallenge-club/tree/master/challenge-162/james-smith) |
+[Next 164 >](https://github.com/drbaggy/perlweeklychallenge-club/tree/master/challenge-164/james-smith)
+# The Weekly Challenge 163
You can find more information about this weeks, and previous weeks challenges at:
@@ -12,58 +12,86 @@ submit solutions in whichever language you feel comfortable with.
You can find the solutions here on github at:
-https://github.com/drbaggy/perlweeklychallenge-club/tree/master/challenge-162/james-smith
+https://github.com/drbaggy/perlweeklychallenge-club/tree/master/challenge-163/james-smith
-# Challenge 1 - Validate ISBN-13
+# Challenge 1 - Sum bitwise operator
-***Write a script to generate the check digit of given ISBN-13 code. Checksum is generated by summing the numbers in the odd positions with 3 times the sum of the numbers in the even positions. The checksum digit is the number you would add to get a total of 0***
+***You are given list positive numbers, `@n`. Write script to calculate the sum of bitwise `&` operator for all unique pairs.***
## The solution
-Rather than computing the checksum - as we have ISBN numbers with the checksum we will validate the numbers {checking the checksum calculated is equal to the last digit in the ISNB number].
+As with all code there is:
+
+ * an initial phase where we set the sum to 0.
+ * a processing phase where we compute the sum:
+ * In this we repeatedly shift the first element of the list and:
+ * and it with all remaining elements keeping the sum.
+ * a final phase where we just return this sum.
+
+If we can't guarantee there are no duplicates in the list we add an
+extra part to the initial phase to remove these duplicates.
+
+This gives us:
```perl
-sub validate_isbn13 {
- my @p = ( my $s = 0, grep {/\d/} split //, $_[0] );
- $s += 3*shift(@p) + shift @p while @p;
- !($s%10);
-}
+sub bit_sum_compact {
+ my $t = 0;
+
+ my %hash = map { $_ => 1 } @_;
+ @_ = keys %hash;
-sub checksum_isbn13 {
- my($s,@p) = ( 0, @{[grep {/\d/} split //, $_[0]]}[0..11] ); ## Remove checksum if present..
- $s -= shift(@p) + 3*shift @p while @p;
- $s%10;
+ while(@_>1) {
+ my $a = shift;
+ $t+= $a&$_ for @_;
+ }
+
+ $t;
}
+
+```
+
+# Challenge 2 - Summations
+
+***You are given a list of positive numbers, `@n`. Write a script to find out the summations as described below.***
+
+## Solution.
+
+For a given row we drop the first element, then the remaining cells are the cumulative sum of the previous row. *e.g.*
+
+```
+ a b c d
+ b b+c b+c+d
+ b+c b+c+b+c+d
+ b+c+b+c+d = 2b+2c+d
```
-# Challenge 2 - Wheatstone-Playfair
+Similarly to the first element we at each interation shift of the first element.
-***Implement encryption and decryption using the Wheatstone-Playfair cipher.***
+ * This time our initial phase is empty (except for showing the input when dumping the table)
+ * Our loop phase:
+ * throws away the first entry (`shift`)
+ * initializes the cumulative sum (`t=0`)
+ * computes the next row `@_ = map { $t+$_ } @_`
+ * {we just `say @_` at each loop if we want to see the table}
+ * The final stage again just returns the last element of the array - the total we want.
-I'm not going to try and explain this here - but refer you to wikipedia https://en.wikipedia.org/wiki/Playfair_cipher
+```perl
+sub summation_with_table {
+ my $t;
+ say "@_";
+ shift, ($t=0), say join ' ', @_ = map { $t+=$_ } @_ while @_>1;
+ shift;
+}
+```
-First we note the only difference between encryption and decryption is the direction we move left->right up->down of *vv*, so we can implement these with a single "function" and two wrappers "emcrypt" and "decrypt". Often two way ciphers have this feature.
+If we don't need the table but just the final value at the end, we can simplify this to:
-We first create a hash and array which map the letter to their position and their position to the letter. This makes the future calculations easier
```perl
-sub encrypt { return _crypt( 1,@_); }
-sub decrypt { return _crypt(-1,@_); }
-
-sub _crypt {
- my($off,$key,$p,$out,@r,%l) = (shift,shift,0,''); ## Initialise variables and get mapping...
- ($_ eq 'j' && ($_='i')), exists $l{$_} || ($l{$_}=[int $p/5,($p++)%5]) for grep { /[a-z]/ } split(//,$key),'a'..'i','j'..'z';
- $r[$l{$_}[0]][$l{$_}[1]]=$_ for keys %l;
-
- my @seq = grep {/[a-z]/} split //, shift =~ s{j}{i}gr; ## Prep sequence
-
- while(my($m,$n)=splice @seq,0,2) { ## Loop through letter pairs
- unshift(@seq,$n), $n='x' if $n && $n eq $m and $n ne 'x'; ## Deal with case when both letters the same
- $n ||= 'x'; ## Pad if required...
- $out.= $l{$m}[0] eq $l{$n}[0] ? $r[ $l{$m}[0] ][($l{$m}[1]+$off)%5] . $r[ $l{$n}[0] ][($l{$n}[1]+$off)%5]
- : $l{$m}[1] eq $l{$n}[1] ? $r[($l{$m}[0]+$off)%5][ $l{$m}[1] ] . $r[($l{$n}[0]+$off)%5][ $l{$n}[1] ]
- : $r[ $l{$m}[0] ][ $l{$n}[1] ] . $r[ $l{$n}[0] ][ $l{$m}[1] ]
- ;
- }
- $out;
+sub summation {
+ my $t;
+ shift, ($t=0), @_ = map { $t+=$_ } @_ while @_>1;
+ shift;
}
```
+
+In both these challenges we use the *perl*ism that within a postfix loop we can stitch together multiple statements into a single statement by the use of `,` (or any operator usually `||`, `&&` or `?:`). This leaves the beauty of the postfix loop while allowing multiple statements.
diff --git a/challenge-163/james-smith/blog.txt b/challenge-163/james-smith/blog.txt
new file mode 100644
index 0000000000..e7832a6a47
--- /dev/null
+++ b/challenge-163/james-smith/blog.txt
@@ -0,0 +1 @@
+https://github.com/drbaggy/perlweeklychallenge-club/tree/master/challenge-163/james-smith
diff --git a/challenge-163/james-smith/perl/ch-2.pl b/challenge-163/james-smith/perl/ch-2.pl
index 8430c3609a..63b36970ab 100644
--- a/challenge-163/james-smith/perl/ch-2.pl
+++ b/challenge-163/james-smith/perl/ch-2.pl
@@ -22,12 +22,12 @@ say '';
sub summation_with_table {
my $t;
say "@_";
- shift, ($t=0), say "@{[ @_ = map { $t+=$_ } @_ ]}" while @_>1;
+ shift, ($t=0), say join ' ', @_ = map { $t+=$_ } @_ while @_>1;
shift;
}
sub summation {
my $t;
- shift, ($t=0), (@_ = map { $t+=$_ } @_) while @_>1;
+ shift, ($t=0), @_ = map { $t+=$_ } @_ while @_>1;
shift;
}