## 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.

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..\$#_`

Output:

``````5 11
7 13
11 17
13 19
17 23
23 29
31 37
37 43
41 47
47 53
``````