This is my response to The Weekly Challenge #377.
Input: $str = "abcba"
Output: true
Reverse of given string is "abcba".
The substring "ab" in original string is also present in the reverse
string too.
Example 2:
Input: $str = "racecar"
Output: true
The substring "ce" is present in both.
Example 3:
Input: $str = "abcd"
Output: false
Example 4:
Input: $str = "banana"
Output: true
The substring "an" is present in both.
Example 5:
Input: $str = "hello"
Output: true
The substring "ll" is present in both.
#! /usr/bin/env raku
unit sub MAIN ($str where $str.chars > 1,
:a(:$all),
:v(:$verbose) = $all);
my $reverse = $str.flip;
my $match = False;
for 0 .. $str.chars - 2 -> $i
{
my $substring = $str.substr($i, 2);
my $is-match = $reverse.contains($substring);
say ": '$reverse'.contains('$substring') - { $is-match \
?? "Match" !! "not a match" }" if $verbose;
if $is-match
{
$match = True;
last unless $all;
}
}
say $match;
[3] A string with at least 2 characters.
[5] Using «all mode» will enable «verbose mode» as well.
[7] Use flip to reverse the string.
See docs.raku.org/routine/flip for more information about flip.
[8] No matches found so far.
[10] Iterate over all the starting positions for substrings of length 2.
[12] Get the substring (with substr).
See docs.raku.org/routine/substr for more information about substr.
[14] Does the reversed string contain the substring?
Note the use of contains which does string comparison. We could
have used use a regex instead, but then we would have to deal with
regex meta characters (as e.g. . and *) in the string.
See docs.raku.org/routine/contains for more information about contains.
[19] If so,
[21] We have a match.
[22] Use last to exit the loop, in normal mode. «All mode» will go on,
checking all the remaining substrings.
[25] Say whether or not we have a match.
Running it:
$ ./reverse-existence abcba
True
$ ./reverse-existence racecar
True
$ ./reverse-existence abcd
False
$ ./reverse-existence banana
True
$ ./reverse-existence hello
True
Looking good.
With verbose mode:
$ ./reverse-existence -v abcba
: 'abcba'.contains('ab') - Match
True
$ ./reverse-existence -v racecar
: 'racecar'.contains('ra') - Match
True
$ ./reverse-existence -v abcd
: 'dcba'.contains('ab') - not a match
: 'dcba'.contains('bc') - not a match
: 'dcba'.contains('cd') - not a match
False
$ ./reverse-existence -v banana
: 'ananab'.contains('ba') - not a match
: 'ananab'.contains('an') - Match
True
$ ./reverse-existence -v hello
: 'olleh'.contains('he') - not a match
: 'olleh'.contains('el') - not a match
: 'olleh'.contains('ll') - Match
True
With «all» mode:
$ ./reverse-existence -a abcba
: 'abcba'.contains('ab') - Match
: 'abcba'.contains('bc') - Match
: 'abcba'.contains('cb') - Match
: 'abcba'.contains('ba') - Match
True
$ ./reverse-existence -a racecar
: 'racecar'.contains('ra') - Match
: 'racecar'.contains('ac') - Match
: 'racecar'.contains('ce') - Match
: 'racecar'.contains('ec') - Match
: 'racecar'.contains('ca') - Match
: 'racecar'.contains('ar') - Match
True
$ ./reverse-existence -a abcd
: 'dcba'.contains('ab') - not a match
: 'dcba'.contains('bc') - not a match
: 'dcba'.contains('cd') - not a match
False
$ ./reverse-existence -a banana
: 'ananab'.contains('ba') - not a match
: 'ananab'.contains('an') - Match
: 'ananab'.contains('na') - Match
: 'ananab'.contains('an') - Match
: 'ananab'.contains('na') - Match
True
$ ./reverse-existence -a hello
: 'olleh'.contains('he') - not a match
: 'olleh'.contains('el') - not a match
: 'olleh'.contains('ll') - Match
: 'olleh'.contains('lo') - not a match
True
Input: @array = ("a", "aba", "ababa", "aa")
Output: 4
$array[0], $array[1]: "a" is a prefix and suffix of "aba"
$array[0], $array[2]: "a" is a prefix and suffix of "ababa"
$array[0], $array[3]: "a" is a prefix and suffix of "aa"
$array[1], $array[2]: "aba" is a prefix and suffix of "ababa"
Example 2:
Input: @array = ("pa", "papa", "ma", "mama")
Output: 2
$array[0], $array[1]: "pa" is a prefix and suffix of "papa"
$array[2], $array[3]: "ma" is a prefix and suffix of "mama"
Example 3:
Input: @array = ("abao", "ab")
Output: 0
Example 4:
Input: @array = ("abab", "abab")
Output: 1
$array[0], $array[1]: "abab" is a prefix and suffix of "abab"
Example 5:
Input: @array = ("ab", "abab", "ababab")
Output: 3
$array[0], $array[1]: "ab" is a prefix and suffix of "abab"
$array[0], $array[2]: "ab" is a prefix and suffix of "ababab"
$array[1], $array[2]: "abab" is a prefix and suffix of "ababab"
Example 6:
Input: @array = ("abc", "def", "ghij")
Output: 0
#! /usr/bin/env raku
unit sub MAIN (*@array where @array.elems > 1,
:v(:$verbose));
my $matches = 0;
for @array.combinations(2) -> ($left, $right)
{
check-suffix($left, $right);
next if $left eq $right;
check-suffix($right, $left);
}
sub check-suffix ($left, $right)
{
if $left ~~ /^ $right / && $left ~~ / $right $/
{
say ": + '$left' has prefix & suffix '$right'" if $verbose;
$matches++;
}
elsif $verbose
{
say ": '$left' does not have prefix & suffix '$right'.";
}
}
say $matches;
[3] A slurpy array (the * prefix) with at least two elements.
[6] The result, the number of matches, will end up here.
[8] Iterate over all the combinations of two elements
from the array, with combinations(2). We must treat the result as a
set, i.e. unordered.
See docs.raku.org/routine/combinations for more information about combinations.
[10] Check the two values.
[12] Skip the next one, if the two values are identical - as we do not need the same check repetead.
[14] Check the values in swapped order.
[17] The procedure doing the check.
[19] Does the left value start with the right value && the left
value ends with the right value?
[22] If so, count it as a match.
[30] Print the result; the count of matches.
Running it:
$ ./prefix-suffix a aba ababa aa
4
$ ./prefix-suffix pa papa ma mama
2
$ ./prefix-suffix abaa ab
0
$ ./prefix-suffix abab abab
1
$ ./prefix-suffix ab abab ababab
3
$ ./prefix-suffix abc def ghij
0
Looking good.
With verbose mode:
$ ./prefix-suffix -v a aba ababa aa
: 'a' does not have prefix & suffix 'aba'.
: + 'aba' has prefix & suffix 'a'.
: 'a' does not have prefix & suffix 'ababa'.
: + 'ababa' has prefix & suffix 'a'.
: 'a' does not have prefix & suffix 'aa'.
: + 'aa' has prefix & suffix 'a'.
: 'aba' does not have prefix & suffix 'ababa'.
: + 'ababa' has prefix & suffix 'aba'.
: 'aba' does not have prefix & suffix 'aa'.
: 'aa' does not have prefix & suffix 'aba'
: 'ababa' does not have prefix & suffix 'aa'.
: 'aa' does not have prefix & suffix 'ababa'.
4
$ ./prefix-suffix -v pa papa ma mama
: 'pa' does not have prefix & suffix 'papa'.
: + 'papa' has prefix & suffix 'pa'.
: 'pa' does not have prefix & suffix 'ma'.
: 'ma' does not have prefix & suffix 'pa'.
: 'pa' does not have prefix & suffix 'mama'.
: 'mama' does not have prefix & suffix 'pa'
: 'papa' does not have prefix & suffix 'ma'.
: 'ma' does not have prefix & suffix 'papa'.
: 'papa' does not have prefix & suffix 'mama'.
: 'mama' does not have prefix & suffix 'papa'
: 'ma' does not have prefix & suffix 'mama'.
: + 'mama' has prefix & suffix 'ma'.
2
$ ./prefix-suffix -v abaa ab
: 'abaa' does not have prefix & suffix 'ab'.
: 'ab' does not have prefix & suffix 'abaa'.
0
$ ./prefix-suffix -v abab abab
: + 'abab' has prefix & suffix 'abab'.
1
$ ./prefix-suffix -v ab abab ababab
: 'ab' does not have prefix & suffix 'abab'.
: + 'abab' has prefix & suffix 'ab'.
: 'ab' does not have prefix & suffix 'ababab'.
: + 'ababab' has prefix & suffix 'ab'.
: 'abab' does not have prefix & suffix 'ababab'.
: + 'ababab' has prefix & suffix 'abab'.
3
$ ./prefix-suffix -v abc def ghij
: 'abc' does not have prefix & suffix 'def'.
: 'def' does not have prefix & suffix 'abc'.
: 'abc' does not have prefix & suffix 'ghij'.
: 'ghij' does not have prefix & suffix 'abc'.
: 'def' does not have prefix & suffix 'ghij'.
: 'ghij' does not have prefix & suffix 'def'.
0
Note that I (in [19]) just did what I warned about in [14] in the first part of the challenge; ignore the problem of regex meta characters.
Let us try:
$ ./prefix-suffix -v "abaa" "."
: 'abaa' does not have prefix & suffix '.'.
: '.' does not have prefix & suffix 'abaa'.
0
$ ./prefix-suffix -v "abaa" "a"
: + 'abaa' has prefix & suffix 'a'
: 'a' does not have prefix & suffix 'abaa'.
1
Raku escapes them for us, when interpolated from a string. So this is not a problem. That is nice.
And that's it.