Black and white shirt 2
Perl 5, 254 bytes



sub f{@s=map[$_&gt;$_[0]||0,$_&gt;$_[0]?$_[3]:$_[2],1],1..$_[0]+$_[1];while(join('',map$$_[0],@s)=~/01|10/){($c,$p)=&amp;{$_[4]};(@w=sort{$p*($$b[1]&lt;=&gt;$$a[1])}grep$$_[2]&amp;&amp;$$_[0]eq$c,@s)[0][2]=0;@s=grep$$_[2]||++$$_[2]&amp;&amp;--$$_[1],@s if@w&lt;2}sort{$b&lt;=&gt;$a}map$$_[1],@s}


Try it online!

Ungolfed but same – with tests:

use Test::More tests=&gt;6;
sub fu {
  my($countb,$countw,$durb,$durw,$get_todays)=@_;            #get 5 inputs
  my @s=( (map{{col=&gt;'b',dur=&gt;$durb,clean=&gt;1}}1..$countb),   #init shirts array
          (map{{col=&gt;'w',dur=&gt;$durw,clean=&gt;1}}1..$countw) );
  while(join('',map$$_{col},@s)=~/bw|wb/){                   #while still both colors left
    my($col,$p) = &amp;$get_todays;                              #todays color and preference
    my @w = grep $$_{clean} &amp;&amp; $$_{col} eq $col, @s;         #@w=wearable shirts
    my $shirt = (sort{$p*($$b{dur}&lt;=&gt;$$a{dur})}@w)[0];       #pick todays shirt w/most|least durability left 
    $$shirt{clean}=0;                                        #dirty in the evening
    map{$$_{clean}=1;$$_{dur}--}grep!$$_{clean},@s if @w==1; #wash if there was only one this morning
    @s=grep$$_{dur}&gt;0,@s;                                    #toss out worn outs
  }
  return sort{$b&lt;=&gt;$a}map$$_{dur},@s
}
my @test=(
'1 1 1 1 bh',                                                             '1',
'1 3 1 10 wh bh',                                                         '10 10 9',
'1 5 2 10 wh wh bh wl wl wl bh',                                          '10 10 9 8 8',
'2 5 1 10 bh wh wh wl bl',                                                '10 10 9 9 9',
'1 5 6 5 wl wh bl wl wh bl wl wh bl wl wl bl wl wl wl bl wl wl wl wl bl', '4 3 2 1',
'1 1 1 10 bl wh wh wh wh wh wh wh wh wh wh wh wh',                        '10'  #should see sequence not empty
);
while(@test){
  my($countb,$countw,$durb,$durw,@col)=split' ',shift@test;
  my @expected                        =split' ',shift@test;
  my $msg='';
  my $feederu=sub{ (shift(@col)//do{@expected='!',$msg='sequence ran out!'})
                   =~/(.)(.)/;($1,{h=&gt;1,l=&gt;-1}-&gt;{$2}) };
  my $feeder=sub{ (shift(@col)//do{@expected='!',$msg='sequence ran out!'})
                   =~/(.)(.)/;($1 eq 'w'||0,{h=&gt;1,l=&gt;-1}-&gt;{$2}) };
  my @got=fu($countb,$countw,$durb,$durw,$feederu);
 #my @got=f($countb,$countw,$durb,$durw,$feeder);
  $msg='sequense not empty' if @col;
  is(join(" ",@got),
     join(" ",@expected), $msg);
}