Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   заполнить блок полностью прямоугольниками (https://javascript.ru/forum/misc/70472-zapolnit-blok-polnostyu-pryamougolnikami.html)

рони 07.09.2017 18:01

заполнить блок полностью прямоугольниками
 
Для любителей задач, дан массив весов площади прямоугольников, длина и ширина любая, порядок тоже, заполнить контейнер полностью, желательно разнообразная длина и ширина блоков, вариант заполнения случайный.
дано:
<!DOCTYPE html>

<html>
<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <style type="text/css">
  #slider{
    height: 500px;
    width: 700px;
    border: 1px solid rgb(0, 0, 255);
    position: relative;
    color: rgb(255, 255, 255);
    text-align: center;

  }
  #slider div{
     box-sizing: border-box;
     border: 1px solid rgb(255, 255, 0)
  }

  </style>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

  <script>
$(function() {
function rgb()
{ var r=parseInt(Math.random()*255);
    var g=parseInt(Math.random()*255);
    var b=parseInt(Math.random()*255);
    return "rgb("+r+", "+g+", "+b+")"

}
var a = [700,500]// размер контейнера
var t = [7,9,3,7,7,9,1,1,1,7,1,3,1,3,1,9,5,9,3,1];
//for (var i=0; i<20; i++)  {t[i]= Math.random()*10|0+1}
// ваш код
});
  </script>
</head>

<body>
<div id="slider"></div>
<p></p>
</body>
</html>


возможный результат
<!DOCTYPE html>

<html>
<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <style type="text/css">
  #slider{
    height: 500px;
    width: 700px;
    border: 1px solid rgb(0, 0, 255);
    position: relative;
    color: rgb(255, 255, 255);
    text-align: center;

  }
  #slider div{
     box-sizing: border-box;
     border: 1px solid rgb(255, 255, 0)
  }

  </style>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
  <script>
$(function() {

});
  </script>
</head>

<body>
<body>
    <div id="slider">
        <div style="left: 0px; top: 0px; position: absolute; width: 87.5px; height: 45.4545px; line-height: 45.4545px; background-color: rgb(225, 170, 209);">1</div>
        <div style="left: 0px; top: 45.4545px; position: absolute; width: 87.5px; height: 45.4545px; line-height: 45.4545px; background-color: rgb(225, 170, 209);">1</div>
        <div style="left: 0px; top: 90.9091px; position: absolute; width: 87.5px; height: 409.091px; line-height: 409.091px; background-color: rgb(170, 24, 236);">9</div>
        <div style="left: 87.5px; top: 0px; position: absolute; width: 190.909px; height: 104.167px; line-height: 104.167px; background-color: rgb(200, 234, 224);">5</div>
        <div style="left: 87.5px; top: 104.167px; position: absolute; width: 190.909px; height: 62.5px; line-height: 62.5px; background-color: rgb(20, 212, 108);">3</div>
        <div style="left: 87.5px; top: 166.667px; position: absolute; width: 190.909px; height: 187.5px; line-height: 187.5px; background-color: rgb(170, 24, 236);">9</div>
        <div style="left: 87.5px; top: 354.167px; position: absolute; width: 190.909px; height: 145.833px; line-height: 145.833px; background-color: rgb(254, 154, 63);">7</div>
        <div style="left: 278.409px; top: 0px; position: absolute; width: 95.1979px; height: 292.453px; line-height: 292.453px; background-color: rgb(254, 154, 63);">7</div>
        <div style="left: 373.607px; top: 0px; position: absolute; width: 95.1979px; height: 292.453px; line-height: 292.453px; background-color: rgb(254, 154, 63);">7</div>
        <div style="left: 468.805px; top: 0px; position: absolute; width: 46.239px; height: 86.0155px; line-height: 86.0155px; background-color: rgb(225, 170, 209);">1</div>
        <div style="left: 515.044px; top: 0px; position: absolute; width: 46.239px; height: 86.0155px; line-height: 86.0155px; background-color: rgb(225, 170, 209);">1</div>
        <div style="left: 561.283px; top: 0px; position: absolute; width: 138.717px; height: 86.0155px; line-height: 86.0155px; background-color: rgb(20, 212, 108);">3</div>
        <div style="left: 468.805px; top: 86.0155px; position: absolute; width: 57.7988px; height: 206.437px; line-height: 206.437px; background-color: rgb(20, 212, 108);">3</div>
        <div style="left: 526.604px; top: 86.0155px; position: absolute; width: 173.396px; height: 206.437px; line-height: 206.437px; background-color: rgb(170, 24, 236);">9</div>
        <div style="left: 278.409px; top: 292.453px; position: absolute; width: 38.3264px; height: 103.774px; line-height: 103.774px; background-color: rgb(225, 170, 209);">1</div>
        <div style="left: 278.409px; top: 396.226px; position: absolute; width: 38.3264px; height: 103.774px; line-height: 103.774px; background-color: rgb(225, 170, 209);">1</div>
        <div style="left: 316.736px; top: 292.453px; position: absolute; width: 19.1632px; height: 207.547px; line-height: 207.547px; background-color: rgb(225, 170, 209);">1</div>
        <div style="left: 335.899px; top: 292.453px; position: absolute; width: 57.4897px; height: 207.547px; line-height: 207.547px; background-color: rgb(20, 212, 108);">3</div>
        <div style="left: 393.388px; top: 292.453px; position: absolute; width: 172.469px; height: 207.547px; line-height: 207.547px; background-color: rgb(170, 24, 236);">9</div>
        <div style="left: 565.857px; top: 292.453px; position: absolute; width: 134.143px; height: 207.547px; line-height: 207.547px; background-color: rgb(254, 154, 63);">7</div>
    </div>
    <p>7,9,3,7,7,9,1,1,1,7,1,3,1,3,1,9,5,9,3,1</p>

</body>
</body>
</html>

j0hnik 07.09.2017 20:37

Дробями заполнять можно?

рони 07.09.2017 20:41

j0hnik,
да
<!DOCTYPE html>

<html>
<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <style type="text/css">
  #slider{
    height: 500px;
    width: 700px;
    border: 1px solid rgb(0, 0, 255);
    position: relative;
    color: rgb(255, 255, 255);
    text-align: center;

  }
  #slider div{
     box-sizing: border-box;
     border: 1px solid rgb(255, 255, 0)
  }

  </style>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
  <script>
$(function() {

});
  </script>
</head>

<body>
<body>
<div id="slider"><div style="left: 0px; top: 0px; position: absolute; width: 160.241px; height: 23.9234px; line-height: 23.9234px; background-color: rgb(51, 16, 104);">1</div><div style="left: 0px; top: 23.9234px; position: absolute; width: 160.241px; height: 215.311px; line-height: 215.311px; background-color: rgb(151, 57, 18);">9</div><div style="left: 0px; top: 239.234px; position: absolute; width: 160.241px; height: 23.9234px; line-height: 23.9234px; background-color: rgb(51, 16, 104);">1</div><div style="left: 0px; top: 263.158px; position: absolute; width: 160.241px; height: 167.464px; line-height: 167.464px; background-color: rgb(32, 11, 117);">7</div><div style="left: 0px; top: 430.622px; position: absolute; width: 104.985px; height: 69.378px; line-height: 69.378px; background-color: rgb(89, 123, 254);">1.9</div><div style="left: 104.985px; top: 430.622px; position: absolute; width: 55.2555px; height: 69.378px; line-height: 69.378px; background-color: rgb(51, 16, 104);">1</div><div style="left: 160.241px; top: 0px; position: absolute; width: 92.0044px; height: 125px; line-height: 125px; background-color: rgb(130, 143, 63);">3</div><div style="left: 160.241px; top: 125px; position: absolute; width: 92.0044px; height: 375px; line-height: 375px; background-color: rgb(151, 57, 18);">9</div><div style="left: 252.245px; top: 0px; position: absolute; width: 343.626px; height: 36.8151px; line-height: 36.8151px; background-color: rgb(187, 132, 215);">3.3</div><div style="left: 595.871px; top: 0px; position: absolute; width: 104.129px; height: 36.8151px; line-height: 36.8151px; background-color: rgb(51, 16, 104);">1</div><div style="left: 252.245px; top: 36.8151px; position: absolute; width: 164.962px; height: 162.671px; line-height: 162.671px; background-color: rgb(32, 11, 117);">7</div><div style="left: 417.208px; top: 36.8151px; position: absolute; width: 212.094px; height: 162.671px; line-height: 162.671px; background-color: rgb(151, 57, 18);">9</div><div style="left: 629.302px; top: 36.8151px; position: absolute; width: 70.6981px; height: 162.671px; line-height: 162.671px; background-color: rgb(130, 143, 63);">3</div><div style="left: 252.245px; top: 199.486px; position: absolute; width: 89.2958px; height: 300.514px; line-height: 300.514px; background-color: rgb(32, 11, 117);">7</div><div style="left: 341.541px; top: 199.486px; position: absolute; width: 38.2696px; height: 300.514px; line-height: 300.514px; background-color: rgb(130, 143, 63);">3</div><div style="left: 379.811px; top: 199.486px; position: absolute; width: 40.8209px; height: 131.475px; line-height: 131.475px; background-color: rgb(53, 42, 206);">1.4</div><div style="left: 379.811px; top: 330.961px; position: absolute; width: 40.8209px; height: 169.039px; line-height: 169.039px; background-color: rgb(202, 42, 180);">1.8</div><div style="left: 420.632px; top: 199.486px; position: absolute; width: 279.368px; height: 68.6104px; line-height: 68.6104px; background-color: rgb(235, 17, 1);">5</div><div style="left: 420.632px; top: 268.097px; position: absolute; width: 148.776px; height: 231.903px; line-height: 231.903px; background-color: rgb(151, 57, 18);">9</div><div style="left: 569.408px; top: 268.097px; position: absolute; width: 130.592px; height: 231.903px; line-height: 231.903px; background-color: rgb(22, 22, 126);">7.9</div></div>
<p>7,9,3,7,7.9,9,1,1,1,7,1.4,3,1,3,1.9,9,5,9,3.3,1.8</p>


</body>
</body>
</html>

j0hnik 07.09.2017 20:45

Рони а количество элементов? тоже любое? :)

рони 07.09.2017 21:01

j0hnik,
да, но варианты полпикселя на треть пикселя, плохо визуализируются, решите задачу хотябы для length от 2 до 100. :)

j0hnik 07.09.2017 21:40

<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<div style="width:900px; height:700px; overflow:hidden; border: 1px solid gray; position:relative;"></div>
	<script>
var i = 1000;
while(i--) document.querySelector('div').insertAdjacentHTML('beforeend', '<div style="width:'+Math.random()*300+'px; height:'+Math.random()*300+'px; background-color:#'+Math.random().toString(16).slice(2,8)+'; top:'+(Math.random()*700-50)+'px; left:'+(Math.random()*900-50)+'px; position:absolute">'+Math.floor(Math.random()*9)+'</div>');
	</script>
</script>
</body>
</html>


:)

Rasy 07.09.2017 22:07

j0hnik,
Я так понимаю тут соль задачи не использовать зет-индексы, т.е наложение слоев друг на друга. А вместить все фигуры в пространство матаном...

рони,
Начнем с двух:)
<!DOCTYPE html>

<html>
<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <style type="text/css">
  #slider{
    font-size: 22px;
    height: 500px;
    width: 700px;
    border: 1px solid rgb(0, 0, 255);
    position: relative;
    color: rgb(255, 255, 255);
    text-align: center;

  }
  #slider div{
     box-sizing: border-box;
     border: 1px solid rgb(255, 255, 0)
  }
  </style>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

  <script>
    $(function() {

      function rgb() {
        var r = parseInt(Math.random() * 255);
        var g = parseInt(Math.random() * 255);
        var b = parseInt(Math.random() * 255);
        return "rgb(" + r + ", " + g + ", " + b + ")";
      }

      function rand(c) {
        return Math.random()*c|0+1;
      }

      var a = [700, 500];
      var t = [];
      var h = [];
      var hs = 0;
      var ws = 0;

      for (var i=0; i<2; i++)  { t[i] = rand(10); }

      function value(x, xs) {
        do {
          for (var z = 0; z < t.length; z++) { x[z] = rand(700); }
          xs = x.reduce(function(a,b){ return a + b; });
        } while(xs != a[1]);

        return x;
      }

      h = value(h, hs);

      function rects(h) {
        var s = document.getElementById('slider');
        for (var k = 0; k < t.length; k++) {
          var rect = document.createElement('div');
          rect.style.width =  '100%';
          rect.style.height = h[k]+'px';
          rect.style.lineHeight = h[k]+'px';
          rect.style.backgroundColor = rgb();
          rect.textContent = t[k];
          s.appendChild(rect);
        }

      }

      rects(h);
      document.getElementsByTagName('p')[0].textContent = t;


    });

  </script>
</head>

<body>
  <div id="slider"></div>
  <p></p>
</body>
</html>

рони 07.09.2017 22:40

Rasy,
у меня блок 3 больше чем блок 5 ??? пост№7

рони 07.09.2017 22:44

Rasy,
2 блока с одинаковым весом - площадь обоих блоков должна быть одинакова

рони 07.09.2017 22:53

j0hnik,
площадь всех блоков равна площади контейнера -- когда блок один -- при любом весе он равен контейнеру -- два блока с одинаковым весом поделят блок пополам, картинка для [1,1] и [1/4,1/4] или [300,300] , будет одинакова, либо две одинаковых строки, либо 2 одинаковых столбца. когда три там уже чуть разнообразнее

рони 07.09.2017 23:01

2 блока с одинаковым весом

<!DOCTYPE html>

<html>
<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <style type="text/css">
  #slider{
    height: 500px;
    width: 700px;
    border: 1px solid rgb(0, 0, 255);
    position: relative;
    color: rgb(255, 255, 255);
    text-align: center;

  }
  #slider div{
     box-sizing: border-box;
     border: 1px solid rgb(255, 255, 0)
  }

  </style>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
  <script>
$(function() {

});
  </script>
</head>

<body>
<body>
<div id="slider"><div style="left: 0px; top: 0px; position: absolute; width: 350px; height: 500px; line-height: 500px; background-color: rgb(57, 102, 227);">5</div><div style="left: 350px; top: 0px; position: absolute; width: 350px; height: 500px; line-height: 500px; background-color: rgb(57, 102, 227);">5</div></div>
<p>5,5</p>


</body>
</body>
</html>


2 блока с разным весом
<!DOCTYPE html>

<html>
<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <style type="text/css">
  #slider{
    height: 500px;
    width: 700px;
    border: 1px solid rgb(0, 0, 255);
    position: relative;
    color: rgb(255, 255, 255);
    text-align: center;

  }
  #slider div{
     box-sizing: border-box;
     border: 1px solid rgb(255, 255, 0)
  }

  </style>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
  <script>
$(function() {

});
  </script>
</head>

<body>
<body>
<div id="slider"><div style="left: 0px; top: 0px; position: absolute; width: 490px; height: 500px; line-height: 500px; background-color: rgb(249, 71, 164);">7</div><div style="left: 490px; top: 0px; position: absolute; width: 210px; height: 500px; line-height: 500px; background-color: rgb(157, 160, 196);">3</div></div>
<p>3,7</p>


</body>
</body>
</html>

3 блока с одинаковым весом
<!DOCTYPE html>

<html>
<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <style type="text/css">
  #slider{
    height: 500px;
    width: 700px;
    border: 1px solid rgb(0, 0, 255);
    position: relative;
    color: rgb(255, 255, 255);
    text-align: center;

  }
  #slider div{
     box-sizing: border-box;
     border: 1px solid rgb(255, 255, 0)
  }

  </style>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
  <script>
$(function() {

});
  </script>
</head>

<body>
<body>
<div id="slider"><div style="left: 0px; top: 0px; position: absolute; width: 233.333px; height: 500px; line-height: 500px; background-color: rgb(81, 21, 8);">15</div><div style="left: 233.333px; top: 0px; position: absolute; width: 466.667px; height: 250px; line-height: 250px; background-color: rgb(81, 21, 8);">15</div><div style="left: 233.333px; top: 250px; position: absolute; width: 466.667px; height: 250px; line-height: 250px; background-color: rgb(81, 21, 8);">15</div></div>
<p>15,15,15</p>


</body>
</body>
</html>


3 блока с разным весом
<!DOCTYPE html>

<html>
<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <style type="text/css">
  #slider{
    height: 500px;
    width: 700px;
    border: 1px solid rgb(0, 0, 255);
    position: relative;
    color: rgb(255, 255, 255);
    text-align: center;

  }
  #slider div{
     box-sizing: border-box;
     border: 1px solid rgb(255, 255, 0)
  }

  </style>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
  <script>
$(function() {

});
  </script>
</head>

<body>
<body>
<div id="slider"><div style="left: 0px; top: 0px; position: absolute; width: 370.588px; height: 500px; line-height: 500px; background-color: rgb(215, 53, 192);">9</div><div style="left: 370.588px; top: 0px; position: absolute; width: 329.412px; height: 62.5px; line-height: 62.5px; background-color: rgb(9, 51, 201);">1</div><div style="left: 370.588px; top: 62.5px; position: absolute; width: 329.412px; height: 437.5px; line-height: 437.5px; background-color: rgb(205, 33, 238);">7</div></div>
<p>7,1,9</p>


</body>
</body>
</html>

j0hnik 07.09.2017 23:24

Рони, да я понял, это прикол, думал оцените юмор.
Ваша задача наподобие как задача с рюкзаком или акциями, помните тут в форуме мелькала? у меня с математикой не очень к сожалению =(

Rasy 07.09.2017 23:40

Цитата:

Сообщение от рони
у меня блок 3 больше чем блок 5 ??? пост№7

Пробный трай. Не обессудь. Без формул не решить, сам знаешь.

MallSerg 07.09.2017 23:45

Задача с виду не очень сложная если я правильно ее понял.
Массив делится на две части после у каждой части считается вес. общая площадь делится на полученную пропорцию веса каждой части. затем каждая полученная часть массива делится на более меньшие части и так пока не дойдет до неделимой части.
Алгоритм Рони палит всегда вертикальная черта в центре потом правая часть делится по горизонтали затем левая по вертикали и.т.д.

рони 07.09.2017 23:53

j0hnik,
думаю это раз 500 проще рюкзака ... как наполнить рюкзак не знаю.
может тогда тогда задачку на рекурсию поможешь решить, из массива надо сделать дерево, постепенно складывая несколько элементов, пока их больше 2, сохраняя этапы суммирования.
a = [1,2,3,4,5,6,7,8,9];//исходный массив
a1 = [6, 22, 17];
a2 = [28,17];
a3 = [45]
структура любая на ваше усмотрение, но такая что можно получить любой узел.

рони 07.09.2017 23:53

MallSerg,
:victory:

j0hnik 08.09.2017 01:54

Рони
var a = [1,2,3,4,5,6,7,8,9], n = a.length-1, b = new Array(n); 
for (var i=0; i<n; i++) {
a=[a.shift()+a.shift(), ...a];
b[i]=[...a];
}
console.log(b);

рони 08.09.2017 07:36

j0hnik,
спасибо, но не то.

destus 08.09.2017 08:52

рони,
Задача об упаковке в контейнеры
http://codeincomplete.com/posts/bin-packing/demo/

j0hnik 08.09.2017 09:06

Цитата:

Сообщение от рони (Сообщение 464026)
j0hnik,
спасибо, но не то.

Рекурсия обязательна? или нужно складывать не два элемента, а больше?
В общем чуть подробнее если можно..

рони 08.09.2017 09:16

destus,
спасибо

рони 08.09.2017 09:26

j0hnik,
нужно дерево, примерно так
{sum : 45, p : [28,17], child : [{sum : 28 , p : [6,22]}, {sum : 17 , p : [8,9]}]};

рекурсия не обзательна.


Часовой пояс GMT +3, время: 11:32.