Perl Weekly Challenge 367.
My solutions (task 1 and task 2 ) to the The Weekly Challenge - 367.
Task 1: Max Odd Binary
Submitted by: Mohammad Sajid Anwar
You are given a binary string that has at least one ‘1’.
Write a script to rearrange the bits in such a way that the
resulting binary number is the maximum odd binary number
and return the resulting binary string. The resulting string
can have leading zeros.
Example 1
Input: $str = "1011"
Output: "1101"
"1101" is max odd binary (13).

Example 2
Input: $str = "100"
Output: "001"
"001" is max odd binary (1).

Example 3
Input: $str = "111000"
Output: "110001"

Example 4
Input: $str = "0101"
Output: "1001"

Example 5
Input: $str = "1111"
Output: "1111"

The solution is quite simple: move one 1 to the rightmost position to make the result odd. Move all the other ones to the leftmost positions to get the largest possible number. A simple way to do this is to first move all 1’s to the left of all 0’s by repeatedly substituting ‘01’ by ‘10’, and finally moving the leftmost 1 to the rightmost position. This may be done with a oneliner.
Examples:
perl -E '
for(@ARGV){$i=$_;1 while s/01/10/g;s/^1(.*)$/${1}1/; say "$i -> $_"}
' 1011 100 111000 0101 1111
Results:
1011 -> 1101
100 -> 001
111000 -> 110001
0101 -> 1001
1111 -> 1111
An alternative is to count ones and zeroes and then print the resulting groups.
perl -E '
for(@ARGV){$z=length()-($o=grep$_,split"");say "$_ -> ",1 x--$o,0 x$z,1}
' 1011 100 111000 0101 1111
Results:
1011 -> 1101
100 -> 001
111000 -> 110001
0101 -> 1001
1111 -> 1111
The full code is:
1 # Perl weekly challenge 367
2 # Task 1: Max Odd Binary
3 #
4 # See https://wlmb.github.io/2026/03/30/PWC367/#task-1-max-odd-binary
5 use v5.36;
6 use feature "try";
7 die <<~"FIN" unless @ARGV;
8 Usage: $0 B0 B1...
9 to find the largest odd binary number from the binary
10 digits in the binary string Bn
11 FIN
12 for(@ARGV){
13 try {
14 die "Only 0's and 1's allowed: $_" unless /^[01]*$/;
15 die "At least one 1 required: $_" unless /1/;
16 my $ones = grep $_, split "";
17 my $zeroes=length()-$ones;
18 say "$_ -> ", "1" x ($ones-1), "0" x $zeroes, "1";
19 }
20 catch($e){ warn $e; }
21 }
22
Examples:
./ch-1.pl 1011 100 111000 0101 1111
Results:
1011 -> 1101
100 -> 001
111000 -> 110001
0101 -> 1001
1111 -> 1111
Task 2: Conflict Events
Submitted by: Mohammad Sajid Anwar
You are given two events start and end time.
Write a script to find out if there is a conflict between
the two events. A conflict happens when two events have
some non-empty intersection.
Example 1
Input: @event1 = ("10:00", "12:00")
@event2 = ("11:00", "13:00")
Output: true
Both events overlap from "11:00" to "12:00".

Example 2
Input: @event1 = ("09:00", "10:30")
@event2 = ("10:30", "12:00")
Output: false
Event1 ends exactly at 10:30 when Event2 starts.
Since the problem defines intersection as non-empty, exact
boundaries touching is not a conflict.

Example 3
Input: @event1 = ("14:00", "15:30")
@event2 = ("14:30", "16:00")
Output: true
Both events overlap from 14:30 to 15:30.

Example 4
Input: @event1 = ("08:00", "09:00")
@event2 = ("09:01", "10:00")
Output: false
There is a 1-minute gap from "09:00" to "09:01".

Example 5
Input: @event1 = ("23:30", "00:30")
@event2 = ("00:00", "01:00")
Output: true
They overlap from "00:00" to "00:30".

I first convert all times to minutes, to facilitate the comparisons. The linear intervals (a,b) and (c,d) overlap if c<b and a<d. However, these intervals are in a circle. It is possible that b<a or d<c, which may be fixed by adding 24*60=1440 minutes. Furthermore, it may be necessary to shift one of the intervals by + or -1440 before making the comparisons. This fits a three-liner.
Examples:
perl -E '
$d=1440;for(@ARGV){@m=map{($h,$m)=split":";60*$h+$m}split" ";do{$m[$_+1]
+=$d if$m[$_]>$m[$_+1]}for(0,2);say"$_ -> ",c(0,@m)||c($d,@m)||c(-$d,@m)?
"T":"F";}sub c($o,@m){$m[0]+$o<$m[3]&&$m[1]+$o>$m[2]}
' "10:00 12:00 11:00 13:00" "09:00 10:30 10:30 12:00" "14:00 15:30 14:30 16:00" \
"08:00 09:00 09:01 10:00" "23:30 00:30 00:00 01:00"
Results:
10:00 12:00 11:00 13:00 -> T
09:00 10:30 10:30 12:00 -> F
14:00 15:30 14:30 16:00 -> T
08:00 09:00 09:01 10:00 -> F
23:30 00:30 00:00 01:00 -> T
The full code is:
1 # Perl weekly challenge 367
2 # Task 2: Conflict Events
3 #
4 # See https://wlmb.github.io/2026/03/30/PWC367/#task-2-conflict-events
5 use v5.36;
6 use feature qw(try);
7 die <<~"FIN" unless @ARGV;
8 Usage: $0 E0 E1...
9 to find if the events En are conflicting, where
10 En is a space separated string of four times
11 "T0 T1 T2 T3", each of the form HH:MM. T0 and T1 are
12 starting and ending times for one event, T2 and T3 correspond
13 to the second event
14 FIN
15 my $day=24*60;
16 for(@ARGV){
17 try {
18 die "Wrong format: $_" unless /^\s*((\d\d):(\d\d)(\s|$)){4}$/;
19 my @minutes = map {my ($hour,$min) = split":"; 60*$hour + $min} split" ";
20 do{$minutes[$_+1] +=$day if $minutes[$_] > $minutes[$_+1]} for(0,2);
21 my $result = overlap(0, @minutes)
22 || overlap($day, @minutes)
23 || overlap(-$day,@minutes);
24 say "$_ -> ", $result?"True":"False";
25 }
26 catch($e){warn $e; }
27 }
28
29 sub overlap($offset, $w, $x, $y, $z){
30 $w + $offset < $z && $x + $offset >$y
31 }
Examples:
./ch-2.pl "10:00 12:00 11:00 13:00" "09:00 10:30 10:30 12:00" "14:00 15:30 14:30 16:00" \
"08:00 09:00 09:01 10:00" "23:30 00:30 00:00 01:00"
Results:
10:00 12:00 11:00 13:00 -> True
09:00 10:30 10:30 12:00 -> False
14:00 15:30 14:30 16:00 -> True
08:00 09:00 09:01 10:00 -> False
23:30 00:30 00:00 01:00 -> True
/;