## Challenge 1

Create a script to demonstrate Ackermann function. The Ackermann function is defined as below, m and n are positive number:

A(m, n) = n + 1 if m = 0 A(m, n) = A(m - 1, 1) if m > 0 and n = 0 A(m, n) = A(m - 1, A(m, n - 1)) if m > 0 and n > 0

As a challenge, that’s very clear. That is very close to the code you’d need.

``````#!/usr/bin/env perl

use strict;
use warnings;
use utf8;
use feature qw{ postderef say signatures state switch };
no warnings
qw{ experimental::postderef experimental::smartmatch experimental::signatures };

say a( 1, 2 );
say a( 2, 2 );
say a( 2, 5 );
exit;

sub a ( \$m, \$n ) {
die 'Invalid input' unless \$m >= 0 && \$n >= 0;
return \$n + 1 if \$m == 0;
return a( \$m - 1, 1 ) if \$m > 0 && \$n == 0;
return a( \$m - 1, a( \$m, \$n - 1 ) ) if \$m > 0 && \$n > 0;
}
``````

I mean, adding `return` and sigils and replacing `and` with `&&` and you’re mostly there.

This is my code as uploaded, but looking back, using Memoize so repeated lookups are handled would be a quick thing to make this very recursive code faster.

ADDENDUM: I used Memoize and Benchmark to test, and using a memoized function made it, for `a(2,5)`, 15x faster. I mean, it went from 45 millionths of a second to 3 millionth of a second, but speed is speed, and as we get to higher values and deeper recursion, it adds up.

ADDENDUM 2: “It adds up” does not say enough. This is creazy recursive,and all the times you hit `return \$n + 1 if \$m == 0` means you can get `\$n` to `a(0,5440808)`, which is where my code died. I think that’s a big recursive stack problem, but I’m not sure. I’ve seen others mention bigint, and I’m not sure I won’t have to go there.

## Challenge 2

Create a script to parse URL and print the components of URL. According to Wiki page, the URL syntax is as below:

scheme:[//[userinfo@]host[:port]]path[?query][#fragment]

For example: `jdbc:mysql://user:password@localhost:3306/pwc?profile=true#h1`

``````   scheme:   jdbc:mysql
host:     localhost
port:     3306
path:     /pwc
query:    profile=true
fragment: h1
``````

I had problems with this one, which I explain in the comments.

``````#!/usr/bin/env perl

use strict;
use warnings;
use utf8;
use feature qw{ postderef say signatures state switch };
no warnings
qw{ experimental::postderef experimental::smartmatch experimental::signatures };

# Create a script to parse URL and print the components of URL.
# According to Wiki page, the URL syntax is as below:

# scheme:[//[userinfo@]host[:port]]path[?query][#fragment]

my @list;
push @list, 'http://slashdot.org/';
push @list, 'https://en.wikipedia.org/wiki/URL';
push @list, 'https://github.com/manwar/perlweeklychallenge-club/pulse';
push @list, 'https://perlweeklychallenge.org/blog/perl-weekly-challenge-017/';
push @list, 'https://practimer.me:443/#5m0s';
push @list, 'https://www.perlmonks.org/?node_id=818843';

@list = @ARGV if scalar @ARGV; # replace test list if anything is entered

# by the URL definition on wikipedia, jdbc:mysql is not a valid scheme
# and the scheme contains a trailing colon.

# Notes on implementation:
# + this is VERY ascii-centric code, and unicode and emoji are allowed
#   in URLs. Take, for example, i❤️tacos.ws
# + schemas and TLDs are constrained, not just to ascii, but to a small
#   (but larger than before) list. Yeah, you can override this with your
#   hosts file, but otherwise, all URLs should end (case-insensitive)
#   with a string in this list:
#       http://data.iana.org/TLD/tlds-alpha-by-domain.txt
# + similarly, the lists for path and query are limited to values
#   fitting my dataset. There have been path separator bugs: IE
#   would count \ as a separator, while Mozilla would not, so
#   you could hide information from Windows browsers /with\this\path

# So, this is a very naive implementation, needing more work before
# it can be trusted with real-world URLs. So, except when it's done
# for fun, like here, use something like Mojo::URL to split it up
# for you https://metacpan.org/pod/Mojo::URL

for my \$url ( sort @list ) {
my ( \$scheme, \$userinfo, \$host, \$port, \$path, \$query, \$fragment ) =
\$url =~ m{
^
(\w[A-Za-z0-9\+\.\-\:]+)://   # schema
(?:([^@]+)@)?                 # userinfo
([\w\.]+)                     # host
(?:\:(\d+))?                  # port
(/[\w/\+\.\-]*)               # path
(?:\?([\w/\+\.\-\=]+))?       # query
(?:\#([^#]+))?                # fragment
\$
}mxis;
\$scheme   //= '';
\$userinfo //= '';
\$host     //= '';
\$port     //= '';
\$path     //= '';
\$query    //= '';
\$fragment //= '';

say <<"END";
URL         \$url
scheme      \$scheme
userinfo    \$userinfo
host        \$host
port        \$port
path        \$path
query       \$query
fragment    \$fragment
END
}

__DATA__

scheme      ftp
userinfo
host        ftp.cerias.purdue.edu
port
query
fragment

URL         http://slashdot.org/
scheme      http
userinfo
host        slashdot.org
port
path        /
query
fragment

URL         https://en.wikipedia.org/wiki/URL
scheme      https
userinfo
host        en.wikipedia.org
port
path        /wiki/URL
query
fragment

URL         https://github.com/manwar/perlweeklychallenge-club/pulse
scheme      https
userinfo
host        github.com
port
path        /manwar/perlweeklychallenge-club/pulse
query
fragment

scheme      https
userinfo
port
path        /mail/u/0/
query
fragment    inbox/FMfcg

URL         https://perlweeklychallenge.org/blog/perl-weekly-challenge-017/
scheme      https
userinfo
host        perlweeklychallenge.org
port
path        /blog/perl-weekly-challenge-017/
query
fragment

URL         https://practimer.me:443/#5m0s
scheme      https
userinfo
host        practimer.me
port        443
path        /
query
fragment    5m0s

URL         https://www.perlmonks.org/?node_id=818843
scheme      https
userinfo
host        www.perlmonks.org
port
path        /
query       node_id=818843
fragment

scheme      jdbc:mysql
host        localhost
port        3306
path        /pwc
query       profile=true
fragment    h1
``````

As I said, I do not trust this to be complete. I do trust it to handle all entries in my test suite, but that’s not enough.

I do, however, trust Mojo::URL.

``````#!/usr/bin/env perl

use strict;
use warnings;
use utf8;
use feature qw{ postderef say signatures state switch };
no warnings
qw{ experimental::postderef experimental::smartmatch experimental::signatures };

use Mojo::URL;

# Create a script to parse URL and print the components of URL.
# According to Wiki page, the URL syntax is as below:

# scheme:[//[userinfo@]host[:port]]path[?query][#fragment]

my @list;
push @list, 'http://slashdot.org/';
push @list, 'https://en.wikipedia.org/wiki/URL';
push @list, 'https://github.com/manwar/perlweeklychallenge-club/pulse';
push @list, 'https://perlweeklychallenge.org/blog/perl-weekly-challenge-017/';
push @list, 'https://practimer.me:443/#5m0s';
push @list, 'https://www.perlmonks.org/?node_id=818843';

# Mojo::URL does NOT like the example URL

@list = @ARGV if scalar @ARGV;    # replace test list if anything is entered

for my \$url ( sort @list ) {
my \$mojo     = Mojo::URL->new(\$url);
my \$scheme   = \$mojo->scheme || '';
my \$userinfo = \$mojo->userinfo || '';
my \$host     = \$mojo->host || '';
my \$port     = \$mojo->port || '';
my \$path     = \$mojo->path || '';
my \$query    = \$mojo->query || '';
my \$fragment = \$mojo->fragment || '';

say <<"END";
URL         \$url
scheme      \$scheme
userinfo    \$userinfo
host        \$host
port        \$port
path        \$path
query       \$query
fragment    \$fragment
END
}
``````

If you have any questions or comments, I would be glad to hear it. Ask me on Twitter or make an issue on my blog repo.