Update: The code is wrong. Do not use it. I am trying to write a different one.

Probably not a clever approach. The border cases might need some tweaking.

#!/usr/bin/perl use Data::Dumper; use warnings; use strict; sub combine { my %result; while (my $triple = shift) { my ($left, $right, $value) = @$triple; if (not exists $result{$left}{R} or $result{$left}{R} > $value) { $result{$left}{R} = $value; } if (not exists $result{$right}{L} or $result{$right}{L} > $value) { $result{$right}{L} = $value; } } return \%result; } # combine sub dec { my $time = shift; my ($day, $hour, $min) = $time =~ /(..)(..)(..)/; $min--; if ($min < 0) { $min = 59; $hour--; if ($hour < 0) { $hour = 23; $day--; die if ($day < 0); } } return sprintf '%02d%02d%02d', $day, $hour, $min; } # dec sub tangle { my $combined = combine(@_); my @keys = sort keys %$combined; my $value; my @result; my $overlap; for my $i (0 .. $#keys) { if (defined $value) { my $new = $combined->{$keys[$i]}{R}; my $old = $combined->{$keys[$i]}{L}; die if defined $old and $old < $value; if (defined $new) { $overlap++; if ($new < $value) { push @{ $result[-1] }, dec($keys[$i]), $value; push @result, [$keys[$i]]; $value = $new; } } else { $overlap--; if (not $overlap) { push @{ $result[-1] }, $keys[$i], $value; undef $value; } else { my $next = $combined->{$keys[$i+1]}{L}; if ($next > $value) { push @{ $result[-1] }, dec($keys[$i]), $value; push @result, [$keys[$i]]; $value = $next; } } } } else { # not defined $value $value = $combined->{$keys[$i]}{R}; die unless defined $value; push @result, [$keys[$i]]; $overlap++; } } return @result; } # tangle sub daysplit { return map { my ($start, $end, $value) = @$_; my $from = 0 + substr $start, 0, 2; my $to = 0 + substr $end, 0, 2; if ($from < $to) { my $split; my $newfrom = sprintf('%02d', $from) . '2359'; $split = [[$start, $newfrom, $value]]; push @$split, map { [sprintf('%02d', $_) . '0000', sprintf('%02d', $_) . '2359', $value] } $from + 1 .. $to - 1; my $newto = sprintf('%02d', $to) . '0000'; push @$split, [$newto, $end, $value]; @$split; } else { $_; } } @_; } # daysplit my @listone = (['010000','010010',2],['010200','010210',5],['012359',' +020001',3]); my @listtwo = (['010005','010015',1],['010207','010211',4]); my @result = daysplit(tangle(@listone, @listtwo)); print Dumper \@result;


In reply to Re: Date Array Convolution by choroba
in thread Date Array Convolution by alanonymous

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.