| 17 April 2026 | Challenge 369 |
Divided Tags
Task 1: Valid Tag
Submitted by: Mohammad Sajid Anwar
You are given a given a string caption for a video.
Write a script to generate tag for the given string caption in three steps as mentioned below:
- Format as camelCase
Starting with a lower-case letter and capitalising the first letter of each subsequent word. Merge all words in the caption into a single string starting with a #. - Sanitise the String
Strip out all characters that are not English letters (a-z or A-Z). - Enforce Length
If the resulting string exceeds 100 characters, truncate it so it is exactly 100 characters long.
Example 1
Input: $caption = "Cooking with 5 ingredients!"
Output: "#cookingWithIngredients"
Example 2
Input: $caption = "the-last-of-the-mohicans"
Output: "#thelastofthemohicans"
Example 3
Input: $caption = " extra spaces here"
Output: "#extraSpacesHere"
Example 4
Input: $caption = "iPhone 15 Pro Max Review"
Output: "#iphoneProMaxReview"
Example 5
Input: $caption = "Ultimate 24-Hour Challenge: Living in a Smart Home controlled entirely by Artificial Intelligence and Voice Commands in the year 2026!"
Output: "#ultimateHourChallengeLivingInASmartHomeControlledEntirelyByArtificialIntelligenceAndVoiceCommandsIn"
Solution
The task is more difficult as it seems: The concept of a word is not defined and the “usual” definition is not consistent with the examples.
The “usual” definition of a word would be “a sequence of alphabetic characters that is neither preceded nor succeeded by an alphabetic character”.
However, example 2 does not agree with this definition.
A modified definition of a word could be “a sequence of alphabetic characters including hyphens that is neither preceded nor succeeded by an alphabetic character and that starts with and ends in an alphabetic character”.
This definition may be translated one-to-one into a regular expression.
Perl
An almost straightforward task implementation:
- convert the string to lower case
- identify words as described above
- convert the first character of each word to upper case
- drop non-alphabetic characters
- convert the first character of the remaining string to lower case
- prepend a hash-sign
- truncate the remaining string to 100 characters
use strict;
use warnings;
sub valid_tag {
substr '#' . lcfirst(
lc(shift) =~
s/(?<![a-z])(?=[a-z])([-a-z]+)(?<=[a-z])(?![a-z])/\u$1/gr =~
tr/a-zA-Z//cdr
),
0, 100;
}
See the full solution to task 1.
J
The J implementation is very similar and maybe even simpler.
- convert the string to lower case
- find start indices of words except the first
- replace characters at the found index positions with their upper case versions
- drop non-alphabetic characters
- prepend a hash sign
- truncate the remaining string at 100 characters
require 'regex'
am =: e.&(a. {~ 97+i.26) NB. get mask of (lower case) alphabetic characters
NB. get indices of word beginnings except the first
wi =: (<(<0);0;0)&{@('(?<![a-z])(?=[a-z])[-a-z]+(?<=[a-z])(?![a-z])'&rxmatches)
trunc =: ] {.~ [ <. #@] NB. truncate y at pos x
NB. convert to lower case, find indices of word beginnings, convert characters
NB. at these indices to upper case, drop non-alpha characters, prepend '#' and
NB. restrict to 100 characters
tag =: (100 trunc '#' , am # wi ((toupper@{)`[)} ])@tolower
echo tag 'Cooking with 5 ingredients!'
See the full solution.
Task 2: Group Division
Submitted by: Mohammad Sajid Anwar
You are given a string, group size and filler character.
Write a script to divide the string into groups of given size. In the last group if the string doesn’t have enough characters remaining fill with the given filler character.
Example 1
Input: $str = "RakuPerl", $size = 4, $filler = "*"
Output: ("Raku", "Perl")
Example 2
Input: $str = "Python", $size = 5, $filler = "0"
Output: ("Pytho", "n0000")
Example 3
Input: $str = "12345", $size = 3, $filler = "x"
Output: ("123", "45x")
Example 4
Input: $str = "HelloWorld", $size = 3, $filler = "_"
Output: ("Hel", "loW", "orl", "d__")
Example 5
Input: $str = "AI", $size = 5, $filler = "!"
Output: "AI!!!"
Solution
Perl
By appending the filler character $size - 1 times, the string becomes long enough to contain all requrired characters and it will not contain an additional full group.
Take as many full-sized groups from the resulting string as possible. This may be achieved with a global regex-match in list context.
use strict;
use warnings;
use experimental 'signatures';
sub group_division ($str, $size, $filler) {
($str . $filler x ($size - 1)) =~ /.{$size}/g;
}
See the full solution to task 2.
J
J has the “Shape” verb $ that will, with two additional modifiers, do the full job.
x $!.m!.>. y reshapes y in the dimensions specified by x, filling missing elements with the provided atom m.
With x as _ size this will create as many size-sized groups as required to use all elements of y.
In an interactive console example 2 looks as simple as:
_ 5 $!.'0'!.>. 'Python'
A direct definition of an adverb generating such a result might be written as:
{{_&,@[ $!.m!.>. ]}}
As this is a challenge, it should be given as a tacit adverb. Such a definition somewhat obscures the logic.
NB. tacit adverb inserting the fill atom in a verb train
NB. usage: size fill group str
group =: (_&,@[)`(($!.)!.>.)`]`:6
echo 5 '*' group 'Python'
There are some benefits from utilizing the “Shape” core verb:
The type of str is not relevant as long it is compatible with the fill atom.
Actually, str need not be a character array, it may be a numeric array or an array of boxed items, too.
Furthermore, the empty string '' used as the fill operand will be interpreted as the default fill atom matching the type of the right argument: space for character arrays, zero for numeric arrays and the empty box for a list of boxes.
3 '' group 'abcd'
abc
d
3 '' group 1 2 3 4
1 2 3
4 0 0
3 '' group 1; 1 2; 1 2 3; 1 2 3 4
┌───────┬───┬─────┐
│1 │1 2│1 2 3│
├───────┼───┼─────┤
│1 2 3 4│ │ │
└───────┴───┴─────┘
See the full solution.
Mixing Tasks and Dividing Tags
The solutions to both tasks may be chained and mixed:
$ j/ch-2.ijs $(perl/ch-1.pl 'Cooking with 5 ingredients!') 5 \#
#cook
ingWi
thIng
redie
nts##