I found this interesting, so I began to hack a bit...

SORRY, I have to catch my plane (already late), so this goes without cleanup or further comment for now. I will come back to this node tomorrow...

our $oopser = 0; # protect from endless loops $#empsh = 20; # prefill worktable for my $sh (1 .. 21) { # 21 shifts are 7 days with 3 shifts for my $shid (1 .. 3) { # every shift has 3 mandtory workers # find a free worker my $emp = 0; $oopser = 0; while ($emp == 0) { $oopser++; die if $oopser > 100; $emp = int( 1 + rand(20) ); # take a random worker $emp = 0 if $empsh->[$emp][$sh]; # already assigned } $empsh[$emp][$sh] = "work ($shid)"; # work this shift (8 hours +) $empsh[$emp][$sh+1] = 'free (+)'; # and have 2 shifts rest ( +16 hours) $empsh[$emp][$sh+2] = 'free (++)'; # (German law says 11 hour +s between shifts) $shcount[$sh]++; # no of worker per shift } foreach my $emp (@empsh) { # all other workers are unassigned on t +his shift $emp->[$sh] ||= ' - '; } } my %emplist = map { $_ => $_ } (1 .. 20); # workerlist, delete()able $oopser = 0; while (keys %emplist) { # check for remaining every worker (maybe add +"sort rand()" $oopser++; die if $oopser > 100; my @shnum = (); # no of shifts per worker for my $emp (keys %emplist) { foreach my $tag (@{ $empsh[$emp] }) { $shnum[$emp]++ if $tag =~ /^work/; # count his working shi +fts } if ($shnum[$emp] == 5) { # worked 5 shifts? delete $emplist{$emp}; } # (each worker has to work exactly 5 shifts a week) } EMP: foreach my $emp (keys %emplist) { # who has to work more? my $sh = 1; while ($empsh[$emp][$sh] ne ' - ') { # find a unassigned shift + for this worker if ($sh > 21) { # oops, none found? delete $emplist{$emp}; print STDERR "$emp has underwork\n"; next EMP; # re-run this program then } $sh++; } if ($shcount[$sh] >= 5) { # shift full $empsh[$emp][$sh] = 'free (shift full)'; } elsif ($empsh[$emp][$sh+1] =~ /^work/) { # no 2 shifts rest possible $empsh[$emp][$sh] = 'free (-)'; } elsif ($empsh[$emp][$sh+2] =~ /^work/) { # no 2 shifts rest possible $empsh[$emp][$sh] = 'free (--)'; } else { # hehe, work here! $empsh[$emp][$sh] = 'work (backup)'; $empsh[$emp][$sh+1] = 'free (+)'; $empsh[$emp][$sh+2] = 'free (++)'; } } } # now print print "<table border><tr><td>***"; for my $sh (1 .. 21) { print "<th>-$sh-"; } print "<td>"; for my $emp (1 .. 20) { print "<tr><th>", $emp; for my $sh (1 .. 21) { print "<td>", $empsh[$emp][$sh]; } } print "</table>";
Yes, it's mess :-)

Search, Ask, Know

In reply to Re: Rostering Staff: Architecture? Not strictly Perl by Beechbone
in thread Rostering Staff: Architecture? Not strictly Perl by Cody Pendant

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.