## Perl Weekly Challenge W023 - Difference, Factors and Poem

This week's challenge is composed of three tasks.The first one is to get the n-th order of forward difference of a given list.

**Task #1 - N-th order difference:**

Suppose we have list (X) of numbers: 5, 9, 2, 8, 1, 6 and we would like to create 1st order forward difference series (Y). So using the formula Y(i) = X(i+1) - X(i), we get the following numbers: (9-5), (2-9), (8-2), (1-8), (6-1). In short, the final series would be: 4, -7, 6, -7, 5. If you noticed, it has one less number than the original series. Similary you can carry on 2nd order forward difference series like: (-7-4), (6+7), (-7-6), (5+7) => -11, 13, -13, 12.

**Solution:**

```
use strict;
use warnings;
use 5.010;
my ($n, @list) = @ARGV;
die "Usage: ch-1.pl
``` \n\tn must be less than the number of elements in list\n\tlist values are space separated\n" if !@ARGV;
die "n($n) must be less than the number(".@list.") of elements in list\n" if $n>= @list;
(@list = map $list[$_]-$list[$_-1],1..$#list) for 1..$n;
say "@list";

My solution is pretty straight-forward. It shows the usage when no arguments are passed. And also checks if the value of N is greater than or equal to number of elements in list, an invalid case.

It iterates through the @list using map from index 1 to last index, the difference of the current element and previous is then returned for each iteration. The resulting list is saved in @list and the process is repeated N times. The final value of @list is then printed

**Task #2 - Prime Factorization:**

Next task is prime factorization. In this task, I've implemented three different methods:

- Using system command
`factor`

- Using
`factor`

in ntheory module - Using trial division and modulo

Create a script that prints Prime Decomposition of a given number. The prime decomposition of a number is defined as a list of prime numbers which when all multiplied together, are equal to that number. For example, the Prime decomposition of 228 is 2,2,3,19 as 228 = 2 * 2 * 3 * 19.

**Solution: Backticks and**

`factor`

```
my $n = $ARGV[0];
#Backticks solution using factor, works both on windows and linux :D
say "Using backticks and factor system command:";
say `factor $n`=~s/.+: //r;
```

The command factor prints out the factors of the specified number which basically accomplishes the task at hand. The substitution in the code is to remove the input number+colon in the output. I've been using this method in code golfing where prime factorization is needed.

**Solution: Module ntheory**

`factor`

```
use ntheory 'factor';
my $n = $ARGV[0];
@r = factor $n;
say "@r\n";
```

**Solution: Trial division and modulo**

```
use bigint;
my @r;
my $n = $ARGV[0];
@r = ();
while ($n % 2<1) {
push @r, 2;
$n /= 2;
}
my $f = 3;
while ($f*$f<=$n) {
while ($n % $f<1) {
push @r, $f;
$n /= $f;
}
$f+=2;
}
$n>1 && push @r, $n;
say "@r\n";
```

This method is the slowest compared to the first two. The performance is greatly affected by the number of factors. A large number with lesser prime factors tends to be slower.

**Task #3 - Random Poem:**

This is my first attempt in doing API. There is a "little push" (being the easiest) in the task description for me to take on the challenge. So thanks, @Mohammad S Anwar!

Write a script to use Random Poems API. This is the easiest API, I have come across so far. You donâ€™t need API key for this. They have only route to work with (GET). The API task is optional but we would love to see your solution.

**Solution:**

```
use strict;
use warnings;
use 5.010;
use LWP::Simple qw(get);
use JSON;
binmode STDOUT, ":encoding(UTF-8)";
my $api_content = get "https://www.poemist.com/api/v1/randompoems";
my @data = @{ JSON->new->utf8->decode($api_content) };
#Printing the info of the first poem
say "$data[0]{title} - $data[0]{poet}{name} - $data[0]{url}\n";
#Printing the content of the first poem
say "$data[0]{content}";
```

In this task, I used the get command from LWP module. The API returns a string in JSON format so I used JSON module to decode and save the structure in an array @data

The API returns 5 random poems in each call which can be accessed using indices from 0 to 4. Information in @data can be retrieved as follows:

`$data[index]{title|content|poet}{name}`

## Leave a comment