UPDATE
About your code, I can't understand what is the problem because it is not clear. I would like to give you some tips:
-When you need to work with someone (like here if you need help, or in a project, etc), you should share the same identical things that you know.
-In this case, where the language is not a specification, you should abstract the code as much as you can, pseudo-code is a good begin.
-you can describes the problems you met, from some example but also from images and schemes.
-If you add a specific codification to represent the problem you should respect that codification.
It is not really clear how your code works because it seems an hybrid between js and a pseudo-code. For what I can understand, the first logic error it seems to be related to the space division (rows columns): for example if you have 4 elements 1x1 (rows x columns) they will fill 1 row but, if you have 1 element 1x1,1 element 2x1 (rows x columns), 1 element 1x1 (rows x columns) and another element 2x1 (rows x columns), they complete a row, but you will also find some pieces in the row below, and you doesn't seems to registers this kind of behaviour in your code.
I hope to have understood well, here the jsfiddle and here the code:
<!DOCTYPE html>
<head>
<style>
.pad div{
margin:1px;
}
.pad{
background-color:#FFF;
border:#000 1px solid;
}
</style>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<body>
<script>
var pieceN=50;
var pieces = [];
const multip = 75;
var actualmaxheight=0;
const h=600;
const w=300;
const maxrows = 5;
const maxcols = 4;
var id="";
var actualcontent=0;
$('body').append('<div id="content'+actualcontent+'" class="pad" style="'+
'height:'+(h+4)+'px;width:'+(w+4)+'px"></div>');
id='content'+actualcontent;
actualcontent++;
//creating objects n times
for(var i=0; i<(pieceN); i++){
color=(Math.floor(Math.random()*16777215)).toString(16);
if(color.length==5){ color=color+'0'};
if(color.length==4){ color=color+'00'};
//for faster thing I'll use an already sorted array
eit = Math.floor((Math.random()*maxrows)+1);
wid = Math.floor((Math.random()*maxcols)+1);
pieces.push({
'height': eit*multip,
'width': wid*multip,
'rows': eit,
'cols': wid,
'color':'#'+color
});
}
var copy=pieces;
var i =0;
//while i is less then the number of the objects -1
//the last element will be inserted afther this cycle
//it can be also inserted in the cylce, anyway it's only 1 loop
while(i<pieces.length-1){
//if there is enough height for the element in the container
if(h-actualmaxheight>=parseInt(pieces[i].height)){
//the width fill te container width (insert)
if(parseInt(pieces[i].width)==w){
document.getElementById(id).innerHTML+=
'<div id="'+pieces.length+'" style="'+
'width:'+pieces[i].width+'px;'+
'height:'+pieces[i].height+'px;'+
'background-color:'+pieces[i].color+';'+
'float:left"></div>';
actualmaxheight+=parseInt(pieces[i].height);
}else{//if the width don't fill te container
//if this elem+nextone width fill the container width (insert x 2)
if(((parseInt(pieces[i].width)+parseInt(pieces[i+1].width))==w) && (parseInt(pieces[i].height)==parseInt(pieces[i+1].height))){
document.getElementById(id).innerHTML+=
'<div id="'+i+'" style="'+
'width:'+pieces[i].width+'px;'+
'height:'+pieces[i].height+'px;'+
'background-color:'+pieces[i].color+';'+
'float:left"></div>'+
'<div id="'+(i+1)+'" style="'+
'width:'+pieces[i+1].width+'px;'+
'height:'+pieces[i+1].height+'px;'+
'background-color:'+pieces[i+1].color+';'+
'float:left"></div>';
actualmaxheight+=parseInt(pieces[i].height);
i++;//because 2 inserted
}else{
//else we insert 1 elem + 1 filling element
document.getElementById(id).innerHTML+=
'<div id="'+i+'" style="'+
'width:'+pieces[i].width+'px;'+
'height:'+pieces[i].height+'px;'+
'background-color:'+pieces[i].color+';'+
'float:left"></div>'+
'<div id="'+(pieces.length+100)+'" style="'+
'width:'+(w-pieces[i].width)+'px;'+
'height:'+pieces[i].height+'px;'+
'background-color:'+pieces[i].color+';'+
'float:left"></div>';
actualmaxheight+=parseInt(pieces[i].height);
}
}
i++;//we surely inserted an elem
}else{
//else the container have not enough height for this elem
//fill the height with a black block and don't increase i
//because we inserted nothing
document.getElementById(id).innerHTML+=
'<div id="'+(pieces.length+1000)+'" style="'+
'width:'+w+'px;'+
'height:'+(h-actualmaxheight)+'px;'+
'background-color:#000000;'+
'float:left;color:#FFFFFF">here to fill H</div>';
$('body').append('<div id="content'+actualcontent+'" class="pad" style="'+
'height:'+(h+6+actualcontent*1.2)+'px;width:'+(w+4)+'px;color:#FFFFFF"></div>');
id='content'+actualcontent++; //id of the container updated
actualmaxheight=0;//reset height
}
}
//insert last element
i=pieces.length-1;//get its array index
if(h-actualmaxheight>=pieces[i].height){//there is enough height in this container
//the elem fill the width
if(parseInt(pieces[i].width)==w){
actualmaxheight+=pieces[i].height;
document.getElementById(id).innerHTML+=
'<div id="'+pieces.length+'" style="'+
'width:'+pieces[i].width+'px;'+
'height:'+pieces[i].height+'px;'+
'background-color:'+pieces[i].color+';'+
'float:left"></div>'+
'<div id="'+(pieces.length+1000)+'" style="'+
'width:'+w+'px;'+
'height:'+(h-actualmaxheight)+'px;'+
'background-color:#000000;color:#FFFFFF;'+
'float:left">here to fill H</div>';
}else{ //the elem don't fill the width
actualmaxheight+=pieces[i].height;
document.getElementById(id).innerHTML+=
'<div id="'+pieces.length+'" style="'+
'width:'+pieces[i].width+'px;'+
'height:'+pieces[i].height+'px;'+
'background-color:'+pieces[i].color+';'+
'float:left"></div>'+
'<div id="'+(pieces.length+10000)+'" style="'+
'width:'+(w-pieces[i].width)+'px;'+
'height:'+pieces[i].height+'px;'+
'background-color:'+pieces[i].color+';'+
'float:left"></div>'+
'<div id="'+(pieces.length+1000)+'" style="'+
'width:'+w+'px;'+
'height:'+(h-actualmaxheight)+'px;'+
'background-color:#000000;color:#FFFFFF;'+
'float:left">here to fill H</div>';
}
}else{//there is not enough height in this container
if(parseInt(pieces[i].width)==w){//the elem fill the width
//fill the height with a black block
document.getElementById(id).innerHTML+=
'<div id="'+(pieces.length+1000)+'" style="'+
'width:'+pieces[i].width+'px;'+
'height:'+(h-actualmaxheight)+'px;'+
'background-color:#000000;color:#FFFFFF;'+
'float:left">here to fill H</div>';
//create another container and add the elem + black block to fill the height
actualmaxheight=parseInt(pieces[i].height);
$('body').append('<div id="content'+actualcontent+'" class="pad" style="'+
'height:'+(h+4)+'px;width:'+(w+4)+'px">'+
'<div id="'+pieces.length+'" style="'+
'width:'+pieces[i].width+'px;'+
'height:'+pieces[i].height+'px;'+
'background-color:'+pieces[i].color+';'+
'float:left"></div>'+
'<div id="'+(pieces.length+1000)+'" style="'+
'width:'+w+'px;'+
'height:'+(h-actualmaxheight)+'px;'+
'background-color:#000000;color:#FFFFFF;'+
'float:left">here to fill H</div>'+
'</div>');
}else{//the elem don't fill the width
//fill the height with a black block to fill the height
document.getElementById(id).innerHTML+=
'<div id="'+(pieces.length+1000)+'" style="'+
'width:'+w+'px;'+
'height:'+(h-actualmaxheight)+'px;'+
'background-color:#000000;color:#FFFFFF;'+
'float:left">here to fill H</div>';
actualmaxheight=parseInt(pieces[i].height);
//create another container and add the elem + 1 elem to fill the width
//+ 1 black block to fill the height
$('body').append('<div id="content'+actualcontent+'" class="pad" style="'+
'height:'+(h+4)+'px;width:'+(w+4)+'px">'+
'<div id="'+pieces.length+'" style="'+
'width:'+pieces[i].width+'px;'+
'height:'+pieces[i].height+'px;'+
'background-color:'+pieces[i].color+';'+
'float:left"></div>'+
'<div id="'+(pieces.length+100)+'" style="'+
'width:'+(w-pieces[i].width)+'px;'+
'height:'+pieces[i].height+'px;'+
'background-color:'+pieces[i].color+';'+
'float:left"></div>'+
'<div id="'+(pieces.length+1000)+'" style="'+
'width:'+w+'px;'+
'height:'+(h-actualmaxheight)+'px;'+
'background-color:#000000;color:#FFFFFF;'+
'float:left">here to fill H</div>'+
'</div>');
}
}
/*
//print the elments
for(var i=0; i<(copy.length); i++){
$('body').append('<div id="el'+i+'"'+
'style="width:'+copy[i].width+'px;'+
'height:'+copy[i].height+'px;'+
'background-color:'+copy[i].color+';float:left"></div>'
);
}
*/
</script>
</body>
</html>
I would like to clear some points
- Does the object dimensions are multiple of something or they are just random?
- Where you need to add a filling piece, near every pieces for which you can't find another piece with same height and 300 as sum of widths?
- an object can be fit with many object or less depending on how many object you want to search, this clearly increase the time needed.
Anyway to present something, I wrote this algorithm (jsfiddle) that can or cannot be useful, depending on what are you searching :
<!DOCTYPE html>
<head>
<style>
.pad div{
margin:1px;
}
.pad{
background-color:#FFF;
border:#000 1px solid;
}
</style>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<body>
<script>
var pieceN=50;
var pieces = [];
var actualmaxheight=0;
var h=600;
var w=300;
var flag=0;
$('body').append('<div id="content0" class="pad" style="'+
'height:'+(h+4)+'px;width:'+(w+4)+'px"></div>');
//creating objects n times
for(var i=0; i<(pieceN); i++){
color=(Math.floor(Math.random()*16777215)).toString(16);
if(color.length==5){ color=color+'0'};
//for faster thing I'll use an already sorted array
pieces.push({
'height': Math.floor((Math.random()*600)+1),
'width':Math.floor((Math.random()*150)+1),
'color':'#'+color
});
}
var copy=pieces;
id='content0';
//for all the elements aren't placed(i remove every placed element)
for(i=0;i<pieces.length;i++){
flag=0;
k=0;
//while k<pieces.length confront every piece[k] with piece[i]
while(k<pieces.length){
//if exist 2 piece with sum of width==w(300), the same height and the actual container have enough height, let's add them
if(parseInt(pieces[i].width)+parseInt(pieces[k].width)==w && pieces[i].height==pieces[k].height && ((h-actualmaxheight)>parseInt(pieces[i].height))){
document.getElementById(id).innerHTML+='<div id="e'+(i+k)+'"'+
'style="width:'+pieces[i].width+'px;'+
'height:'+pieces[i].height+'px;'+
'background-color:'+pieces[i].color+';float:left"></div>'+
'<div id="e'+(k+i)+'2"'+
'style="width:'+pieces[k].width+'px;'+
'height:'+pieces[k].height+'px;'+
'background-color:'+pieces[k].color+';float:left"></div>';
actualmaxheight+=parseInt(pieces[i].height);
//remove them from the array
pieces = $.grep( pieces, function(n,index){
return index != k;
});
pieces = $.grep( pieces, function(n,index){
return index != i;
});
flag=1;
}
k++;
}
//if we inserted 0 elements in the while before, we have 2 reason
//1) there aren't 2 elements which satisfy the rules
//in this case we add the element with an element created to fill the empty space orizontal
if(flag==0){
for(j=0;j<pieces.length;j++){
if((h-actualmaxheight)>parseInt(pieces[j].height)){
document.getElementById(id).innerHTML+='<div id="e'+i+'"'+
'style="width:'+pieces[j].width+'px;'+
'height:'+pieces[j].height+'px;'+
'background-color:'+pieces[j].color+';float:left"></div>'+
'<div id="e'+i+'2"'+
'style="width:'+(w-parseInt(pieces[j].width))+'px;'+
'height:'+pieces[j].height+'px;'+
'background-color:'+pieces[j].color+';float:left"></div>';
actualmaxheight+=parseInt(pieces[j].height);
pieces = $.grep( pieces, function(n,index){
return index != j;
});
}
}
}
//2) there isn't an element which can be conained in the space remained in the container
//in this case we add a black stripe to fill the space vertical
if(actualmaxheight<h){
document.getElementById(id).innerHTML+='<div id="e'+j+i*k+'"'+
'style="width:300px;'+
'height:'+(h-actualmaxheight)+'px;'+
'background-color:#000000;float:left;color:#FFFFFF">i fill the space</div>';
}
//then we create a new container to repeat until all the elements are placed
$('body').append('<div class="pad" id="content'+j+'"'+
'style="margin-top:10px;'+
'height:'+(h+4)+'px;width:'+(w+4)+'px"></div>');
id='content'+j;
actualmaxheight=0;
i=0;
}
//print the elments
for(var i=0; i<(copy.length); i++){
$('body').append('<div id="el'+i+'"'+
'style="width:'+copy[i].width+'px;'+
'height:'+copy[i].height+'px;'+
'background-color:'+copy[i].color+';float:left"></div>'
);
}
</script>
</body>
</html>