33 lines
1.5 KiB
Text
33 lines
1.5 KiB
Text
fcn nonoblocks(blocks,cells){
|
|
if(not blocks or blocks[0]==0) vm.yield( T(T(0,0)) );
|
|
else{
|
|
if(not ( blocks.sum(0) + blocks.len() -1<=cells ))
|
|
throw(Exception.AssertionError("Those blocks will not fit in those cells"));
|
|
blength,brest:=blocks[0], blocks[1,*]; # Deal with the first block of length
|
|
minspace4rest:=brest.reduce('+(1),0); # The other blocks need space
|
|
# Slide the start position from left to max RH index allowing for other blocks.
|
|
foreach bpos in (cells - minspace4rest - blength +1){
|
|
if(not brest) # No other blocks to the right so just yield this one.
|
|
vm.yield(T(T(bpos,blength)));
|
|
else{
|
|
# More blocks to the right so create a *sub-problem* of placing
|
|
# the brest blocks in the cells one space to the right of the RHS of
|
|
# this block.
|
|
offset:=bpos + blength +1;
|
|
# recursive call to nonoblocks yields multiple sub-positions
|
|
foreach subpos in (Utils.Generator(nonoblocks,brest,cells - offset)){
|
|
# Remove the offset from sub block positions
|
|
rest:=subpos.pump(List,'wrap([(bp,bl)]){ T(offset + bp, bl) });
|
|
# Yield this block plus sub blocks positions
|
|
vm.yield(T( T(bpos,blength) ).extend(rest) );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
# Pretty print each run of blocks with a different letter for each block of filled cells
|
|
fcn pblock(vec,cells){
|
|
vector,ch:=cells.pump(List(),"_".copy), ["A".."Z"];
|
|
vec.apply2('wrap([(a,b)]){ a.walker(b).pump(Void,vector.set.fp1(ch.next())) });
|
|
String("|",vector.concat("|"),"|");
|
|
}
|