#!/usr/local/bin/perl -w $|=1; $HORIZ = int (2995/100); # altura inicial $VERT = int (1250/100); # ancho $GRID = 1; # escalado (nulo) $MAXBIN = 8; $REPORT = 0; if ($REPORT==0){ use integer; } for $i (1..$HORIZ*$GRID){ for $j (1..$VERT*$GRID){ for $z (1..$MAXBIN){ $s[$i][$j][$z]=0; } } } # H W # 2995 1250 # N H W # 1 420 240 # 1 400 240 # 2 2035 95 # 6 1138 731 # 4 1464 611 # 2 2057 416 $o[1][1]=420; $o[1][2]=240; $o[2][1]=400; $o[2][2]=240; $o[3][1]=2035; $o[3][2]=95; $o[4][1]=2035; $o[4][2]=95; $o[5][1]=1138; $o[5][2]=731; $o[6][1]=1138; $o[6][2]=731; $o[7][1]=1138; $o[7][2]=731; $o[8][1]=1138; $o[8][2]=731; $o[9][1]=1138; $o[9][2]=731; $o[10][1]=1138; $o[10][2]=731; $o[11][1]=1464; $o[11][2]=611; $o[12][1]=1464; $o[12][2]=611; $o[13][1]=1464; $o[13][2]=611; $o[14][1]=1464; $o[14][2]=611; $o[15][1]=2057; $o[15][2]=416; $o[16][1]=2057; $o[16][2]=416; $N = 16; # número de objetos for $i (1 .. $N){ # generación aleatoria de dimensiones $o[$i][1]=int $o[$i][1]/100; $o[$i][2]=int $o[$i][2]/100; $o[$i][3]=0; $o[$i][4]=$o[$i][1]*$o[$i][2]; } $BIN=1; for (;;){ # bucle principal do{ $k = 1+int(rand($N)); }until($o[$k][3]==0); # hasta encontrar un objeto libre $h = int (.5+rand()); if ($h==0) { # rotación de 90 grados ($o[$k][1],$o[$k][2])=($o[$k][2],$o[$k][1]); } $ok=0; $kontador=0; for $i (1..$HORIZ*$GRID){ $a = $i+$o[$k][1]; for $j (1..$VERT*$GRID){ $b = $j+$o[$k][2]; if (defined($s[$a][$b][$BIN]) || $ok==1){ if ($ok==0){ if (($s[$i][$j][$BIN]==0 && $s[$a][$b][$BIN]==0 && $s[$a][$j][$BIN]==0 && $s[$i][$b][$BIN]==0)){ $ok=1; $o[$k][3]=$BIN; # el objeto está asignado $origi=$i; $origj=$j; $limith=$a-1; $limitv=$b-1; } } if ($ok==1 && $i>=$origi && $j>=$origj && $i<=$limith && $j<=$limitv) { if ($s[$i][$j][$BIN]!=0){ destroy($s[$i][$j][$BIN]); } $s[$i][$j][$BIN]=$k; # se asigna el objeto al elemento $kontador++; # last if ($kontador==$o[$k][4]); } } } } if ($kontador != $o[$k][4]){ # warn "Error de objeto - altura baja"; # print "contador $kontador - tamaño $o[$k][4]\n"; destroy($k); $fallo++; if ($fallo>=$N/2) { $fallo=0; # report(); $BIN++; } } $counter=0; for (1..$N){ if ($o[$_][3]>0){ $counter++; } } if ($counter==$N){ report(); exit; } } sub report { for $z (1..$BIN){ $count=0; for $i (1 .. $HORIZ*$GRID){ for $j (1 .. $VERT*$GRID){ if ($s[$i][$j][$z]!=0) { $count++; } } } $percent = 100*$count/($HORIZ*$GRID*$VERT*$GRID); if ($REPORT) { for $i (1..$HORIZ*$GRID){ # dibujar el resultado for $j (1..$VERT*$GRID){ print chr(33+$s[$i][$j][$z] % 90); # ! = espacio libre } print "\n"; } }else{ print "Bin $z: lista de objetos\n"; for $k (1..$N){ if ($o[$k][3]==$z){ print "$k: $o[$k][1] x $o[$k][2]\n"; } } } print "BIN $z. La ocupación es del $percent%\n"; } } sub destroy { my $kk = $_[0]; $o[$kk][3]=0; # libera al objeto de debajo for my $ii (1..$HORIZ*$GRID){ for my $jj (1..$VERT*$GRID){ if ($s[$ii][$jj][$BIN]==$kk) { $s[$ii][$jj][$BIN]=0; # desocupa el espacio } } } } __END__