Manipulating characters
Weekly challenge 185 — 3 October 2022
Week 185: 3 Oct 2022
You are given a list of codes in a random format.
Write a script to mask first four characters which are (a-z,0-9)
and keep the rest as it is.
Example 1 Input: @list = ('ab-cde-123', '123.abc.420', '3abc-0010.xy') Output: ('xx-xxe-123', 'xxx.xbc.420', 'xxxx-0010.xy') Example 2 Input: @list = ('1234567.a', 'a-1234-bc', 'a.b.c.d.e.f') Output: ('xxxx567.a', 'x-xxx4-bc', 'x.x.x.x.e.f')
Examination of the examples suggests that we are given an arbitrary string of characters, and are required to change the first 4 instances of [a-z0-9]
to 'x'.
Again a solution using a regular expression can do the work in a single line: s|^(.*?)[a-z0-9](.*?)[a-z0-9](.*?)[a-z0-9](.*?)[a-z0-9]|$1x$2x$3x$4x|
That's a little hard to read, but essentially it breaks the string at the four characters of interest and the (possibly empty) substrings in between them, and then joins the latter up with 'x's.
For this to work I am taking the hard line that any valid input to the task has at least 4 characters matching [a-z0-9]. If that assertion fails, then I think the single regular expression has to be replaced with a loop over 4 attempts to replace one character with 'x'.
But what if one of the first four [a-z0-9] characters in the string is already 'x'? Are we to ignore it or process it:
axbcdef -> xxxxxef
or axbcdef -> xxxxdef
?
The first of these fails the task criteria because it has masked the fifth [a-z0-9] character in violation of 'mask the first four and keep the rest'. The second of these fails the criteria because the second character in the string is 'x' before and after and is therefore not masked, violating 'mask the first four'.
So, obliquely, I think we can say that none of the first four [a-z0-9] characters in the string can be 'x'.
#!/usr/bin/perl # Peter Campbell Smith - 2022-10-02 # PWC 185 task 1 use v5.28; use utf8; use warnings; binmode(STDOUT, ':utf8'); my (@tests, $test, @list, $item, $j, $output); @tests = (['ab-cde-123', '123.abc.420', '3abc-0010.xy'], ['A5h&kP.....z', '!"£$%^&*()', 'xxxx00000', 'abcd', 'ǀØΨ£‡⁇ aaaa']); # loop over tests for $test (@tests) { @list = @$test; # initialise say qq[\nInput: \@list = (] . join(', ', @list) . ')'; $output = ''; # loop over items within test for $item (@list) { $item =~ s|^(.*?)[a-z0-9](.*?)[a-z0-9](.*?)[a-z0-9](.*?)[a-z0-9]|$1x$2x$3x$4x|; $output .= qq[$item, ]; } # and print the answer say qq[Output: (] . substr($output, 0, -2) . ')'; }
Input: @list = (ab-cde-123, 123.abc.420, 3abc-0010.xy) Output: (xx-xxe-123, xxx.xbc.420, xxxx-0010.xy) Input: @list = (A5h&kP.....z, !"£$%^&*(), xxxx00000, abcd, ǀØΨ£‡⁇ aaaa) Output: (Axx&xP.....x, !"£$%^&*(), xxxx00000, xxxx, ǀØΨ£‡⁇ xxxx)
Any content of this website which has been created by Peter Campbell Smith is in the public domain