aboutsummaryrefslogtreecommitdiff
path: root/challenge-092/arne-sommer/raku/insert-interval
blob: cb08c0e98a5f9a53c558415ff160ce92228ddbf9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#! /usr/bin/env raku

unit sub MAIN (:$S = "(1,4),(8,10)", :$N ="(2,6)", :v(:$verbose));

my $s = $S.EVAL;
my $n = $N.EVAL;

class interval
{
  has $.start;
  has $.stop;

  method inside ($value)
  {
    return $.start <= $value <= $.stop;
  }

  method mergable (interval $new)
  {
    return True if $.start -1 < $new.start < $.stop +1;
    return True if $.start -1 < $new.stop  < $.stop +1;
    return False;	
  }
  method merge (interval $new)
  {
    return interval.new(start => min($.start, $new.start),
                        stop  => max($.stop,  $new.stop));
  }
  method Str
  {
    return "({ $.start },{ $.stop })";
  }
}

my @all = @$s.map({ interval.new(start => $_[0], stop => $_[1]) });
my $m = interval.new(start => $n[0], stop => $n[1]);

@all.push($m);

@all = @all.sort: { $^a.start <=> $^b.start ||  $^a.stop <=> $^b.stop };

my @result;

my $first = @all.shift;

loop
{
  last unless @all.elems;

  my $second = @all.shift;
  if $first.mergable($second)
  {
    # say ":m" if $verbose;
    my $new = $first.merge($second);
    $first = $new;
    next;
  }
  elsif $first.stop < $second.start + 1
  {
    # say ":<" if $verbose;
    @result.push($first);
    $first = $second;
    next;
  }
  else
  {
    # say ":>" if $verbose;
    @result.append($first, $second, @all);
    $first = Any;
    last;
  }
}

@result.push($first) if $first;

say @result.join(", ");