| 12 June 2026 | Challenge 377 |
From Start to End and Back
Task 1: Reverse Existence
Submitted by: Mohammad Sajid Anwar
You are given a string.
Write a script to find whether any substring of length 2 is also present in the reverse of the given string.
Example 1
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.
Solution
As the substring length of 2 looks kind of arbitrary, I’ll generalize the task to any given length.
Perl
Use a captured look-ahead assertion as the sliding substring and step forward until the substring is a substring of the reversed string or the end of the string is reached.
use strict;
use warnings;
use experimental 'signatures';
sub reverse_ex ($str, $length) {
my $rev = reverse $str;
0 + ($str =~ /(?=(.{$length})).(?(?{index($rev, $1) < 0})(*FAIL))/);
}
See the full solution to task 1.
J
A tacit verb is probably not the best solution for this task as we want to apply a dyadic verb to infixes of a noun.
However, the “infix” adverb \ produces a dyadic verb u\ where the left argument specifies the infix size and therefore u can operate as a monad only.
One solution is to bond one noun argument to the dyad, transforming it into a monad. Unfortunately, this operation cannot be done tacitly, but here the non-tacit part may be encapsulated in a conjunction.
Building a monadic verb from named parts:
x u infix_dyad n y(conjunction) appliesx&uto infixes (substrings) ofyhaving a length ofn. Compare this to “infix”:x u\ yappliesuto infixes ofyhaving a length ofx.infix_dyad =. conjunction : 'n&(x&u\) y'any y(monad) performs a logical OR over all items ofyany =. +./x substr_in y(dyad) checks ifyis a substring ofxsubstr_in =. any @: E.~reverse y(monad) reverses the order of items inyreverse =. |.
Finally:
- check if any substring from
yhaving sizemis a substring of reversedy - replace names with values
- force monadic usage
reverse_ex =: adverb define
infix_dyad =. conjunction : 'n&(x&u\) y'
any =. +./
substr_in =. any @: E.~
reverse =. |.
([: any reverse substr_in infix_dyad m ]) f. : [:
)
Obviously, the resulting verb (here for m=:2) is a bit more complex:
2 reverse_ex
([: +./ |. +./@:E.~ (2 : (':'; 'n&(x&u\) y')) 2 ]) :[:
Applying different lengths:
2 reverse_ex 'banana'
1
5 reverse_ex 'banana'
1
6 reverse_ex 'banana'
0
See the full solution.
Task 2: Prefix Suffix
Submitted by: Mohammad Sajid Anwar
You are given an array of strings.
Write a script to find if the two strings (str1, str2) in the given array such that str1 is prefix and suffix of str2. Return the total count of such pairs.
Example 1
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
Solution
Making some assumptions about the solution:
- An array element is not checked against itself. This follows from all examples.
- A pair of equal elements counts only once. This follows from example 4.
- The elements’ order in the array is not significant. This is not explicitly specified and I consider the ordered examples as accidental.
A string x cannot be prefix or suffix of a string y if x’s length exceeds y’s.
Sorting the array by increasing string length therefore permits a pure “look ahead” check.
This way, all of the above assumptions can be fulfilled easily.
Perl
Using a regex to test the prefix and suffix relation and loop strictly forward.
use strict;
use warnings;
sub count_prefix_suffix {
my @arr = sort {length($a) <=> length($b)} @_;
my $count = 0;
while (my $head = shift @arr) {
$head = quotemeta $head;
$count += /^(?=$head).*$head$/ for @arr;
}
$count;
}
See the full solution to task 2.
J
In the following the term suffix appears in two contexts:
- the trailing characters of a string
- the trailing items of an array
Using array suffix for the latter.
Building the final tacit verb from named parts:
x matches y(dyad) produces a binary list where a1indicates thatxstarts as a substring at that position inymatches =. E.x from y(dyad) selects the items ofyat index positions specified byxfrom =. {x idx_ps y(dyad) produces a two-element list of indices (iny) wherexwould start as a prefix and as a suffixidx_ps =. 0 , -@#@[all y(monad) performs a logical AND over all items ofyall =. *./x pre_suf y(dyad) checks ifxis prefix and suffix inypre_suf =. [: all idx_ps from matchessort_by_length y(monad) sorts the listyof boxed items by the lengths of the boxes’ contentsort_by_length =. /: #@>u over_suffices y(adverb) produces the array suffices ofyand appliesudyadically between the first item of each array suffix and the remaining items. This is comparable to the Perl loopwhile ($head = shift @arr) {something($head, @arr)}over_suffices =. ({.` `}.)`:6 \.x u open y(adverb) dyadically appliesuto unboxed argumentsxandyopen =. &>flat y(monad) transformsyof any dimension to a 1-d listflat =. ,sum y(monad) adds all items ofysum =. +/
Finally:
- sort the boxed strings by length
- check if the first item of each array suffix is prefix and suffix in the remaining items
- flatten the result
- count the found matches
- replace names with values
- force monadic use
count_pre_suf =: _(adverb define)
matches =. E.
from =. {
idx_ps =. 0 , -@#@[
all =. *./
pre_suf =. [: all idx_ps from matches
sort_by_length =. /: #@>
over_suffices =. ({.` `}.)`:6 \.
open =. &>
flat =. ,
sum =. +/
sum @: flat @: (pre_suf open over_suffices) @ sort_by_length f. : [:
)
The final verb:
count_pre_suf
+/@:,@:(({. ([: *./ (0 , -@#@[) { E.)&> }.)\.)@(/: #@>) :[:
See the full solution.