The Bear's Den

Enter at your own risk

Binary Regularities

Task 1: Binary Date

Submitted by: Mohammad Sajid Anwar


You are given a date in the format YYYY-MM-DD.

Write a script to convert it into binary date.

Example 1

Input: $date = "2025-07-26"
Output: "11111101001-111-11010"

Example 2

Input: $date = "2000-02-02"
Output: "11111010000-10-10"

Example 3

Input: $date = "2024-12-31"
Output: "11111101000-1100-11111"

Solution

It would be easy to split the input string at hyphens and print the resulting parts as binary numbers. As the given input shall represent a date, there shall be at least a check for validity. Using Date::Manip::Date::parse_date to parse input data has the side effect of permitting a lot of input formats beyond "2025-07-29", including "Jul 29 2025" or even "Last Tuesday in July 2025".

use strict;
use warnings;
use Date::Manip::Date;

sub binary_date {
    my $date = Date::Manip::Date->new;
    $date->parse_date(shift) && die $date->err;
    sprintf "%b-%b-%b", $date->printf(qw(%Y %f %e));
}

See the full solution to task 1.

Task 2: Odd Letters

Submitted by: Mohammad Sajid Anwar


You are given a string.

Write a script to find out if each letter in the given string appeared odd number of times.

Example 1

Input: $str = "weekly"
Output: false

w: 1 time
e: 2 times
k: 1 time
l: 1 time
y: 1 time

The letter 'e' appeared 2 times i.e. even.

Example 2

Input: $str = "perl"
Output: true

Example 3

Input: $source = "challenge"
Output: false

Solution

It is possible to match a string containing a character that appears an even number of times with a single regex. If that regex does not match, all characters are odd.

In pseudo-code it could look like:

/
    (.)             # match a single character
    (?<!\1.+)       # that is not preceded by itself
    ([^\1]*\1)      # and followed by any number of other characters and itself
    (?:(?-1){2})*   # and followed by an even number of the previous sub-expression
    (?!.*\1)        # and not followed by itself
/x

However, there are two issues:

We need to work around these:

Putting these together results in:

use strict;
use warnings;

sub odd_letters {
    shift !~ /
    (.)
    (?!(?=(.*))(\1.+(?=\g{-2}$)|(?<=(?=x^|(?-1)).)))    # Grimy's trick
    ((??{qr([^$1]*)})\1)    # postponed sub-expression
    (?:(?-1){2})*
    (?!.*\1)
    /x;
}

See the full solution to task 2.


If you have a question about this post or if you like to comment on it, feel free to open an issue in my github repository.