From a34551b3241a8ce24e844669ef7a9e96d3b53bfc Mon Sep 17 00:00:00 2001 From: James Smith Date: Mon, 5 Jul 2021 13:27:54 +0100 Subject: Update README.md --- challenge-120/james-smith/README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/challenge-120/james-smith/README.md b/challenge-120/james-smith/README.md index 4f84100cee..d751eefe8c 100644 --- a/challenge-120/james-smith/README.md +++ b/challenge-120/james-smith/README.md @@ -38,31 +38,31 @@ Given a time we can compute the position of the hour hand as `$hr*30+$min/2` and We can then get the angle between the two as: `($hr*60+$min-$min*12)/2` -We want to reduce this modulo `360` to map the value to the range `0` - `360`. **BUT** we note that `$min` may be odd and the value of the angle may therefore may not be a whole number. To get round this we perform the modulus (by `720`) before the divide by `2`. +To make sure the angle is between `-360` and `360` we have to ensure that the hour is between `0` and `11`, by reducing it module 12. We then get the absolute value so we have a value between `0` and `360` -This gives us a number between `0` and `360`. But we need a number between `0` and `180`. To map the range `180` - `360` we can either use an IF OR we can note that if we +We need a number between `0` and `180`. To map the range `180` - `360` we can either use an IF OR we can note that if we do `abs(angle - 180)` we get the complementary angle. So we just subtract this from `180` giving the method below... ```perl sub clock_angle_1_liner { - 180-abs((60*(substr$_[0],0,2)-11*substr$_[0],3)%720/2-180); + 180-abs(abs((substr$_[0],0,2)%12*30-5.5*substr$_[0],3)-180); } ``` -Compared to this (perhaps slightly more readable) method there is about a 60% performance gain [avoiding variables!] +Compared to this (perhaps slightly more readable) method there is about a 85% performance gain [avoiding variables!] ```perl sub clock_angle { my($h,$m) = split /:/,shift; - my $t = abs($h*60-$m*11)%720/2; + my $t = abs($h%12*30-$m*5.5); return $t > 180 ? 360-$t : $t; } ``` -**Note** We can gain more speed (90% faster than "simple" method and about 15% faster than the 1-liner) by removing the first `substr` but to do so we need to disable `numeric` warnings - `no warnings qw(numeric)`. +**Note** We can gain more speed (110% faster than "simple" method and about 15% faster than the 1-liner) by removing the first `substr` but to do so we need to disable `numeric` warnings - `no warnings qw(numeric)`. ```perl sub clock_angle_fast { - 180-abs((60*$_[0]-11*substr$_[0],3)%720/2-180); + 180-abs(abs($_[0]%12*30-5.5*substr$_[0],3)-180); } ``` -- cgit