Perl Weekly Challenge W022 - Sexy Primes
I was googling about perl, hoping to see an active community that is dedicated to perl. I have been an active member of codesignal and I primarily use perl to solve the challenges. And then, I came across the website perlweeklychallenge.org that is being maintained by Mohammad Anwar. The website as the name implies, post challenges every week it usually consist of three tasks.
Task #1 - Sexy Prime
For this week, the first task is to print the first 10 sexy primes
Write a script to print first 10 Sexy Prime Pairs. Sexy primes are prime numbers that differ from each other by 6. For example, the numbers 5 and 11 are both sexy primes, because 11 - 5 = 6. The term “sexy prime” is a pun stemming from the Latin word for six: sex. For more information, please checkout wiki page.
Solution #1
Below is my perl5 solution for the task:
Note: The code was intentionally obfuscated for fun (The syntax highlighter fails in $'
)
@_=grep{@_[ map $x*$_,$_..@_/($x=$_) ] =0 if $_[$_] > 1}@_=0..54;
map { ($_[$_]-$_[$'] == 6) && print "$_[$'] $_[$_]\n" for $_+//..$#_ } 0..$#_;
The first line of the code:
@_=grep{@_[ map $x*$_,$_..@_/($x=$_) ] =0 if $_[$_] > 1}@_=0..54;
Is a actually a sieve of erathosenes. It is an algorithm which finds all primes up to any given limit. In my code this is set by the range 0-54. The maximum value 54 was chosen to limit the sexy primes generated to exactly ten (10) pairs.
The range of values from 0 to 54 are stored in @_ with the code:
@_=0..54;
It was then later on grep'd with:
@_[ map $x*$_,$_..@_/($x=$_) ] =0 if $_[$_] > 1
This piece of code set the multiples of current value of
$_
(from $_ to max range / $_) to 0 when $_
is greater than 1, leaving only numbers without multiples (primes).The prime numbers are then stored to array
@_
which was later used in the next line of code:map { ($_[$_]-$_[$'] == 6) && print "$_[$'] $_[$_]\n" for $_+//..$#_ } 0..$#_;
The code is pretty straight-forward, two prime values are printed if their difference is equal to 6. But the use of match //
and $'
variable is a bit tricky, its a golfing technique to avoid use of another variable to store the value of $_
from map which will be used inside the for loop.
The trick is that with //
, the value of $_
from map is transferred to the perl special variable $'
and would return 1 in: for $_+//..$#_
equivalent to for $_+1..$#_
See perlvar for more info
Output:
5 11
7 13
11 17
13 19
17 23
23 29
31 37
37 43
41 47
47 53
Welcome on board Yet Ebreo. Happy to see you blog about your first solutions to the Perl Weekly Challenge.
Thanks! I am not really good at writing though.