aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad S Anwar <mohammad.anwar@yahoo.com>2021-12-06 04:46:26 +0000
committerMohammad S Anwar <mohammad.anwar@yahoo.com>2021-12-06 04:46:26 +0000
commit6c4737f443e8578928bf0144af0065a2b8956ba2 (patch)
treebd830105952d13b134f0fef01f46bde0ce2107c8
parentf2bcb321d4861df329d3f1e9ac0df888eacd98c6 (diff)
downloadperlweeklychallenge-club-6c4737f443e8578928bf0144af0065a2b8956ba2.tar.gz
perlweeklychallenge-club-6c4737f443e8578928bf0144af0065a2b8956ba2.tar.bz2
perlweeklychallenge-club-6c4737f443e8578928bf0144af0065a2b8956ba2.zip
- Tidied up README for James Smith.
-rw-r--r--challenge-141/james-smith/README.md139
1 files changed, 1 insertions, 138 deletions
diff --git a/challenge-141/james-smith/README.md b/challenge-141/james-smith/README.md
index ed48cd9b3e..33593d9731 100644
--- a/challenge-141/james-smith/README.md
+++ b/challenge-141/james-smith/README.md
@@ -1,138 +1 @@
-# Perl Weekly Challenge #140
-
-You can find more information about this weeks, and previous weeks challenges at:
-
- https://theweeklychallenge.org/
-
-If you are not already doing the challenge - it is a good place to practise your
-**perl** or **raku**. If it is not **perl** or **raku** you develop in - you can
-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-140/james-smith/perl
-
-# Challenge 1 - Add binary
-
-***Write a script to simulate the addition of the given binary numbers. The script should simulate something like `$a + $b`. (operator overloading)***
-
-## The solution
-
-To allow for operator overloading we need to create a class. `DecBin` will be that class. We have to override to functions:
-
-* `+` - addition
-* `==` - comparison
-
-We also override `""` - stringify so we can print the numbers if we want.
-
-Our object is simple a scalar reference. So in `new` we just bless the reference to the number than is passed, and show and comparison just return the scalar pointed to by the reference or compares two of these.
-
-The add function is the more complex function. Working backwards digit by digit
-
-* we add the *carry bit* and the last digit of the remaining string;
-* we then use the last digit of this to update the total, but multiplying this by the position multiplier;
-* we then move the multiplier one digit to the left by multiplying by 10;
-* we then divide the *carry bit* by 2, to see if we need to carry to the next number;
-* remove the last digit of the two numbers
-
-We repeat this until we no longer have a carry AND we have processed all digits of the two numbers.
-
-* Note - the *carry bit* will always be 0,1,2,3 after the first addition, as the digits of the two numbers can only be 1 or 0 and the *carry bit* will only ever be 0 and 1 as well.
-
-```perl
-package DecBin;
-
-use overload ('+'=>'bin_add','=='=>'comp','""'=>'show');
-
-sub new { bless \$_[1], $_[0] }
-sub show { ${$_[0]} }
-sub comp { ${$_[0]} == ${$_[1]} }
-
-sub bin_add {
- my($t,$c,$m,$a,$b) = (0,0,1,${$_[0]},${$_[1]});
- $c+=$a%10+$b%10,$t+=$m*($c&1),$m*=10,$c>>=1,$a=int$a/10,$b=int$b/10 while $a||$b||$c;
- DecBin->new($t);
-}
-```
-The long line may be unreadable - so I also include a multi-line version
-
-```perl
-sub bin_add {
- my($t,$c,$m,$a,$b) = (0,0,1,${$_[0]},${$_[1]});
- while ($a||$b||$c) {
- $c += $a%10 + $b%10;
- $t += $m * ($c&1);
- $m *= 10;
- $c >>= 1;
- $a = int $a/10;
- $b = int $b/10;
- }
- DecBin->new($t);
-}
-```
-
-To show that the overloading works - we use the following test script:
-
-```perl
-my @TESTS = (
- [ [ 11, 1 ] , 100 ],
- [ [ 101, 1 ] , 110 ],
- [ [ 100, 11 ] , 111 ],
-);
-foreach(@TESTS) {
- my $x = DecBin->new($_->[0][0]);
- my $y = DecBin->new($_->[0][1]);
- my $z = DecBin->new($_->[1]);
- say join "\t", $x, $y, $x+$y, $z, $x+$y==$z ? 'OK' : 'FAIL';
-}
-```
-
-with output:
-
-```
-11 1 100 100 OK
-101 1 110 110 OK
-100 11 111 111 OK
-```
-
-# Challenge 2 - Multiplication Table
-
-***You are given 3 positive integers, `$i`, `$j` and `$k`. Write a script to print the `$k`th element in the sorted multiplication table of `$i` and `$j`.***
-
-## The solution
-
-Obviously there are two parts to this - a first pass which finds all the numbers and a second pass which counts to find the `$k`th element.
-
-```perl
-sub get_num {
- my($i,$j,$k,$t,%h) = @_;
- $t=$_, map { $h{$t*$_}++ } 1..$j for 1..$i;
- $k-=$h{$_}, ($k<1) && (return $_) for sort { $a<=>$b } keys %h;
-}
-```
-
-Here we do some *naughty* code (as in challenge 1), using `,` to perform multiple commands in one line; using `map` to perform a `for`
-loop (altering values & ignoring the result) and using `&&` to simulate an `if` statement.
-
-In this function each of these is written as a single line. We can expand each of these functions out to see how the algorithm works:
-
-```perl
-sub get_num {
- my($i,$j,$k,$t,%h) = @_;
- for $t (1..$i) {
- $h{$t*$_}++ for 1..$j;
- }
- for (sort {$a<=>$b} keys %h) {
- $k -= $h{$_};
- return $_ if $k<1;
- }
-}
-```
-## Notes
- * In the `my` statement we initalise the first 3 parameters with the values passed in, the remaining 2 values `$t` and `%h` are not assigned a value.
- * The first `for` loop (`for` can be used in place of `foreach` in perl, simply stores the numbers as keys to a hash, whose values are the "frequency" of the number occuring.
- * The second one finds the answer. We first thing we do is sort the numbers into order as the keys of the hash are un-ordered.
- * Rather than working up to `$k` we can work down from it to `0`. So we subtract the frequency of the current number and if the
- value is less than `1` then we know this is the number we are looking for and return it's value.
- * Note we always return in the `for` loop unless there is no answer - so don't need a return at the end.
-
+Solutions by James Smith