Max Conflict
with Raku

by Arne Sommer

Max Conflict with Raku

[391] Published 5. April 2026.

This is my response to The Weekly Challenge #367.

#367.1 Max Odd Binary 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"

We get the highest possible value by placing all the 1s before the 0s. An odd number is achieved by placing a 1 at the very end. As the input number has at least 1 of them (the 1s), we can take the leftmost value and insert it at the right.

File: max-odd-binary
#! /usr/bin/env raku

subset Binary1 where /^<[01]>+$/ && /1/;        # [1]

unit sub MAIN (Binary1 $binary, :v($verbose));  # [2]

my @digits = $binary.comb.sort: -*;             # [3]

say ": Digits sorted: { @digits.join(", ") }" if $verbose;

@digits.push: @digits.shift;                    # [4]

say ": Digits w/trailing 1: { @digits.join(", ") }" if $verbose;

my $result = @digits.join;                      # [5]

say ": \"$result\" is max odd binary ({ $result.parse-base(2) })"
  if $verbose;

say $result;                                    # [6]

[1] A Custom type for the binary input, with at least one 1 in it.

[2] Apply the custom type on the input.

[3] Get the digits in reversed sorted order, i.e. with all the 1s (one or more of them) before the 0s (zero or more of them). The -* sorts on the negative version of each value, so we do not have to reverse the result.

[4] Get the first element (which is a 1, with shift) and move it to the end. (with push) This gives us an odd number (as the rightmost digit in a binary value has the decimal value of 1, if set).

[5] Glue the digits together again,

[6] and print the result.

Running it:

$ ./max-odd-binary 1011
1101

$ ./max-odd-binary 100
001

$ ./max-odd-binary 111000
110001

$ ./max-odd-binary 0101
1001

$ ./max-odd-binary 1111
1111

Looking good.

With verbose mode:

$ ./max-odd-binary -v 1011
: Digits sorted: 1, 1, 1, 0
: Digits w/trailing 1: 1, 1, 0, 1
: "1101" is max odd binary (13)
1101

$ ./max-odd-binary -v 100
: Digits sorted: 1, 0, 0
: Digits w/trailing 1: 0, 0, 1
: "001" is max odd binary (1)
001

$ ./max-odd-binary -v 111000
: Digits sorted: 1, 1, 1, 0, 0, 0
: Digits w/trailing 1: 1, 1, 0, 0, 0, 1
: "110001" is max odd binary (49)
110001

$ ./max-odd-binary -v 0101
: Digits sorted: 1, 1, 0, 0
: Digits w/trailing 1: 1, 0, 0, 1
: "1001" is max odd binary (9)
1001

$ ./max-odd-binary -v 1111
: Digits sorted: 1, 1, 1, 1
: Digits w/trailing 1: 1, 1, 1, 1
: "1111" is max odd binary (15)
1111

#367.2 Conflict Events 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".

A custom grammar seems like a good fit here. See e.g. this Grammar Tutorial for a good explanation.

File: conflict-event
#! /usr/bin/env raku

unit sub MAIN ($event1, $event2, :v($verbose));              # [1]

grammar Event                                                # [2]
{
  token TOP       { <hhmm> <space> <hhmm> }                  # [3]
  token hhmm      { <hh> <colon> <mm>  }                     # [4]
  token space     { \s }                                     # [5]
  token colon     { ":" }                                    # [6]
  token hh        { <[01]> <[0..9]> | 20 | 21 | 22 | 23 }    # [7]
  token mm        { <[012345]> <[0..9]> }                    # [8]
}

my $e1 = Event.parse($event1);                               # [9]
my $e2 = Event.parse($event2);                               # [9a]

die "Illegal syntax in 1. event" unless $e1;                 # [10]
die "Illegal syntax in 2. event" unless $e2;                 # [10a]

my $start1 = $e1<hhmm>[0]<hh> * 60 + $e1<hhmm>[0]<mm>;       # [11]
my $stop1  = $e1<hhmm>[1]<hh> * 60 + $e1<hhmm>[1]<mm>;       # [11a]
my $start2 = $e2<hhmm>[0]<hh> * 60 + $e2<hhmm>[0]<mm>;       # [12]
my $stop2  = $e2<hhmm>[1]<hh> * 60 + $e2<hhmm>[1]<mm>;       # [12a]

if $start1 > $start2                                         # [13]
{                                                            # [13a]
  ($start1, $stop1, $start2, $stop2) = ($start2, $stop2, $start1, $stop1);
  say ": Swapped event 1 & 2 so that 1 starts first" if $verbose;
}

my $overnight1 = $start1 > $stop1;                           # [14]
my $overnight2 = $start2 > $stop2;                           # [14a]

if $verbose
{
  say ": Event1: $start1 - $stop1 Overnight:$overnight1";
  say ": Event2: $start2 - $stop2 Overnight:$overnight2";
}
					
if $overnight1 == $overnight2 == True                       # [15]
{
  say True;                                                 # [15a]
}

elsif $overnight1 == $overnight2 == False                   # [16]
{
  say $start2 < $stop1;                                     # [16a]
}

elsif $overnight1 == True                                   # [17]
{
  say ( $stop1 > $start2 || $start1 < $stop2 );             # [17a]
}

elsif $overnight2 == True                                   # [18]
{
  say ( $stop2 > $start1 || $start2 < $stop1 );             # [18a]
}

[1] The two event strings without constraints. That will be done in [9] and [9a]. See the "Running it" section for the string syntax.

[2] A custom grammer for an event.

[3] The starting token must have the name «TOP». It cntains two time values separated by a space.

See docs.raku.org/syntax/token for more information about token.

[4] The time value token.

[5] The actual space,

[6] and colon.

[7] The hour value,

[8] and the minute value.

[9] Apply the grammer on the event string(s) with parse.

See docs.raku.org/routine/parse for more information about parse.

[10] Get the start and stop [10a] times for the first event, as minutes past midnight.

[11] Ditto for the second event.

[12] Swap the events if required, so that the first one is the first to start. This makes the conflict checks easier.

[13] Check if the events are overnight events

[14] If both events are overnight, we have a conflict.

[15] If none are overnight, we have a conflict if the second one starts before the end of the first one.

[16] If the first one (only) is overnight, we have a conflict if the first one ends before the start of second one - or the first one starts before the end of the second one.

[16] If the second one (only) is overnight; the same logic as above. Swap the events in the checks.

Running it:

$ ./conflict-event "10:00 12:00" "11:00 13:00"
True

$ ./conflict-event "09:00 10:30" "10:30 12:00"
False

$ ./conflict-event "14:00 15:30" "14:30 16:00"
True

$ ./conflict-event "08:00 09:00" "09:01 10:00"
False

$ ./conflict-event "23:30 00:30" "00:00 01:00"
True

Looking good.

With verbose mode:

$ ./conflict-event -v "10:00 12:00" "11:00 13:00"
: Event1: 600 - 720 Overnight:False
: Event2: 660 - 780 Overnight:False
True

$ ./conflict-event -v "09:00 10:30" "10:30 12:00"
: Event1: 540 - 630 Overnight:False
: Event2: 630 - 720 Overnight:False
False

$ ./conflict-event -v "14:00 15:30" "14:30 16:00"
: Event1: 840 - 930 Overnight:False
: Event2: 870 - 960 Overnight:False
True

$ ./conflict-event -v "08:00 09:00" "09:01 10:00"
: Event1: 480 - 540 Overnight:False
: Event2: 541 - 600 Overnight:False
False

$ ./conflict-event -v "23:30 00:30" "00:00 01:00"
: Swapped event 1 & 2 so that 1 starts first
: Event1: 0 - 60 Overnight:False
: Event2: 1410 - 30 Overnight:True
True

And that's it.