#!/usr/bin/perl use strict; use warnings; my @universe = (1, 10); my @ranges = ( [ 1, 3 ], [2, 7], [10, 2] ); # Normalize the lists my @nrm_rng = map { ($$_[0] < $$_[1]) ? $_ : ( [ $$_[0]-$universe[1], $$_[1] ], [ $$_[0], $$_[1] + $universe[1]-$universe[0] ] ) } @ranges; # Dump lists printf("% 2u ",$_) for $universe[0] .. $universe[1]; print "\n"; print "-- " for $universe[0] .. $universe[1]; print "\n"; for my $R (@nrm_rng) { printf("%2s ", ($_>= $$R[0] and $_<=$$R[1]) ? "XX" : "") for $universe[0] .. $universe[1]; print ": ($$R[0], $$R[1])\n"; } my $arMax; my @out; my @working; for my $col ($universe[0] .. $universe[1]) { $arMax=undef; # Add and remove working lists based on column position push @working, grep { $col>=$$_[0] } @nrm_rng; @nrm_rng = grep { $col < $$_[0] } @nrm_rng; @working = grep { $col<=$$_[1] } @working; # Compute result for each list for (@working) { $$_[2] = 3+2*min(abs($col-$$_[0]),abs($col-$$_[1])); if (!defined($arMax) or ($$arMax[2]<$$_[2]) or ($$arMax[2]==$$_[2] and $$arMax[1]<$$_[1]) ) { $arMax=$_; } } $out[$col] = defined($arMax) ? sprintf("% 2u",$$arMax[2]) : ' 1'; # print "$col ", # "wrk: ", join(", ", map { "(".join(",",@$_).")" } @$_, @working), "\n"; # Remove lists that will no longer give us values @working = grep { $_ eq $arMax or $$arMax[1] < $$_[1] } @working; } print "FINAL: ", join(' ', @out), "\n"; sub min { my ($l, $r) = (@_); return ($l<$r) ? $l : $r; } #### roboticus@Work: /Work/Perl/PerlMonks $ perl 868827_ranges_and_such.pl 1 2 3 4 5 6 7 8 9 10 -- -- -- -- -- -- -- -- -- -- XX XX XX : (1, 3) XX XX XX XX XX XX : (2, 7) XX XX : (0, 2) XX : (10, 11) 5 5 5 7 7 5 3 1 1 3 : FINAL