The Bear's Den

Enter at your own risk

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:

  1. 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 #.
  2. Sanitise the String
    Strip out all characters that are not English letters (a-z or A-Z).
  3. 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:

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.

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##