#!/usr/bin/perl -s use v5.16; use Test2::V0; use List::Util 'pairs'; use List::MoreUtils 'any'; use experimental 'signatures'; our ($tests, $examples); run_tests() if $tests || $examples; # does not return die <[0][0] < $_->[1][0] && $_->[1][0] < $_->[0][1] && $_->[0][1] < $_->[1][1] && return 1 for [$i, $k], [$k, $i]; } # Traversing backwards seems to be a bit easier to handle. sub conflicting_intervals (@intervals) { my @conflicts; while (defined (my $i = pop @intervals)) { unshift @conflicts, $i if any {conflicting($_, $i)} @intervals; } @conflicts; } ### Examples and tests sub run_tests { SKIP: { skip "examples" unless $examples; is [conflicting_intervals([1, 4], [3, 5], [6, 8], [12, 13], [3, 20])], [[3, 5], [3, 20]], 'example 1'; is [conflicting_intervals([3, 4], [5, 7], [6, 9], [10, 12], [13, 15])], [[6, 9]], 'example 2'; } SKIP: { skip "tests" unless $tests; # Let # [i₀, i₁) ≤ [k₀, k₁) if i₁ ≤ k₀ # [i₀, i₁) < [k₀, k₁) if i₁ < k₀ etc. is conflicting([0, 1], [0, 1]), F(), 'i = k'; is conflicting([0, 1], [1, 2]), F(), 'i ≤ k'; is conflicting([1, 2], [0, 1]), F(), 'i ≥ k'; is conflicting([0, 1], [2, 3]), F(), 'i < k'; is conflicting([2, 3], [0, 1]), F(), 'i > k'; is conflicting([1, 2], [0, 3]), F(), 'i ⊂ k'; is conflicting([0, 3], [1, 2]), F(), 'i ⊃ k'; is conflicting([0, 1], [0, 2]), F(), 'i ⊂ k, i₀ = k₀'; is conflicting([0, 2], [0, 1]), F(), 'i ⊃ k, i₀ = k₀'; is conflicting([1, 2], [0, 2]), F(), 'i ⊂ k, i₁ = k₁'; is conflicting([0, 2], [1, 2]), F(), 'i ⊃ k, i₁ = k₁'; is conflicting([2, 1], [0, 3]), F(), 'i = ∅'; is conflicting([0, 3], [2, 1]), F(), 'k = ∅'; is conflicting([0, 2], [3, 1]), F(), 'k = ∅'; is conflicting([3, 1], [0, 2]), F(), 'i = ∅'; is conflicting([3, 2], [0, 1]), F(), 'i = ∅, i > k'; is conflicting([0, 1], [3, 2]), F(), 'k = ∅, i < k'; is conflicting([1, 0], [2, 3]), F(), 'i = ∅, i < k'; is conflicting([2, 3], [1, 0]), F(), 'k = ∅, i > k'; is conflicting([0, 2], [1, 3]), T(), 'conflict: i ⊈ k, i ≰ k, i ⊉ k, i ≱ k'; is conflicting([1, 3], [0, 2]), T(), 'conflict: i ⊈ k, i ≰ k, i ⊉ k, i ≱ k'; is [conflicting_intervals([3, 5], [6, 8], [12, 13], [3, 20])], [], 'example 1 without the conflicting (1, 4)'; is [conflicting_intervals([0, 1], [1, 2], [2, 3])], [], 'lined up'; is [conflicting_intervals([1, 2], [0, 4])], [], 'contained'; is [conflicting_intervals([0, 2], [1, 1])], [], 'non conflicting empty interval'; is [conflicting_intervals([1, 1], [0, 2])], [], 'non conflicting empty interval'; } done_testing; exit; }