### Perl Weekly Challenge: Week 99

#### Challenge 1:

**Pattern Match**

You are given a string `$S`

and a pattern `$P`

.

Write a script to check if given pattern validate the entire string. Print 1 if pass otherwise 0.

The patterns can also have the following characters:

**? - Match any single character.**

*** - Match any sequence of characters.**

##### Example 1

```
Input: $S = "abcde" $P = "a*e"
Output: 1
```

##### Example 2

```
Input: $S = "abcde" $P = "a*d"
Output: 0
```

##### Example 3

```
Input: $S = "abcde" $P = "?b*d"
Output: 0
```

##### Example 4

```
Input: $S = "abcde" $P = "a*c?e"
Output: 1
```

This is a very limited subset of regular expressions so all that needs to be done is to convert it to the equivalant Perl regexp syntax.

```
$P =~ s/\*/.*/g;
$P =~ s/\?/./g;
```

Then the resulting regexp is applied to `$S`

. It is placed in a capture group so that ...

```
$S =~ /($P)/;
```

... we can compare what got matched to `$S`

(also checking that something got captured in
the first place.) If the result and `$S`

are equal, it means the entire string was matched so
we print 1. Otherwise, we print 0.

```
say q{}, (defined $1 && $S eq $1) ? 1 : 0;
```

This is the Raku translation:

```
sub MAIN(
Str $S, #= a string.
Str $P #= a pattern.
) {
```

Rakus ability to call methods and chain them together makes the code very compact. Note
the use of `<{ ... }>`

to interpolate code into the middle of a regexp.

```
$S ~~ / ( <{ $P.subst('*', '.*', :g).subst('?', '.', :g) }> ) /;
say ($0 && $S eq $0) ?? 1 !! 0;
}
```

#### Challenge 2:

**Unique Subsequence**

You are given two strings `$S`

and `$T`

.

Write a script to find out count of different unique subsequences matching `$T`

without changing the position of characters.

##### Example 1

```
Input: $S = "littleit', $T = 'lit'
Output: 5
1: [lit] tleit
2: [li] t [t] leit
3: [li] ttlei [t]
4: litt [l] e [it]
5: [l] ittle [it]
```

##### Example 2

```
Input: $S = "london', $T = 'lon'
Output: 3
1: [lon] don
2: [lo] ndo [n]
3: [l] ond [on]
```

Like the previous problem, this one also involves creating a regexp. While I did solve it, I'm kind of uncomfortable with how I did it. I have a feeling that there must be a better way.

The first thing I did was to make an array of regex patterns which will represent subsequences.
And I added a literal match of `$T`

as the first one.

Then I split `T`

into a set of subsequences with a 'gap' between the first group of letters and
the second group where the gap was succesively replaced by a regexp representing the potential difference
btween `$S`

and the two groups.

So for example, if `$S = 'london'`

which has 6 characters and `$T = 'lon'`

which has 3, the maximum
size of the gap can be 6 - 3 = 3 characters. so for each one of `l,on`

, and `lo,n`

(`lon`

is already taken care of,)
I insert `.{1}`

, `.{2}`

, and `.{3}`

making a total of 2 * 3 = 6 extra patterns.

```
my @patterns = ( $T );
for my $i (0 .. (length $T) - 2) {
for my $j (1 .. (length $S) - (length $T)) {
my @t = split //, $T;
$t[$i] .= ".{$j}";
my $pattern = join q{}, @t;
push @patterns, $pattern;
}
}
```

Having completed our list of patterns we go through each one and count all the ones that match and finally, print the result.

```
my $count = 0;
for my $pattern (@patterns) {
if ($S =~ /($pattern)/) {
$count++;
}
}
say $count;
```

This is what the algorithm above looks like translated to Raku.

```
sub MAIN (
Str $S, #= a string.
Str $T #= a subsequence to be matched in <S>
) {
my @patterns = ( $T );
for 0 .. $T.chars - 2 -> $i {
for 1 .. $S.chars - $T.chars -> $j {
my @t = $T.comb;
@t[$i] ~= " . ** {$j} ";
@patterns.push( / <{ @t.join(q{}) }> / );
}
}
my $count = 0;
for @patterns -> $pattern {
if $S ~~ / ( $pattern ) / {
$count++;
}
}
say $count;
}
```