#!/usr/local/bin/perl -w $|=1; # strip packing 2D with rotation $HORIZ = 2; # altura inicial $VERT = 60; # ancho $GRID = 1; # escalado (nulo) for $i (1..$HORIZ*$GRID*10_000){ # máxima altura for $j (1..$VERT*$GRID){ $s[$i][$j]=0; } } $N = shift || 90; # número de objetos for $i (1 .. $N){ # generación aleatoria de dimensiones $l = 2+int (rand(10)*$GRID); $w = 2+int (rand(6)*$GRID); if ($w > $l) { ($w, $l) = ($l, $w); } # swap $o[$i][1]=$l; $o[$i][2]=$w; $o[$i][3]=0; $o[$i][4]=$l*$w; } $MAXpercent=0; for (;;){ for $i (1 .. $HORIZ*$GRID){ for $j (1 .. $VERT*$GRID){ $s[$i][$j]=0; } } $HORIZ=2; for $i (1 .. $N){ $o[$i][3]=0; } 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; $HORIZ++; # se sube la altura en una unidad $cc=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]) || $ok==1){ if ($ok==0){ if (($s[$i][$j]==0 && $s[$a][$b]==0 && $s[$a][$j]==0 && $s[$i][$b]==0)){ $ok=1; $o[$k][3]=1; # 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]!=0){ destroy($s[$i][$j]); } $s[$i][$j]=$k; # se asigna el objeto al elemento $kontador++; # last if ($kontador==$o[$k][4]); } } if ($i==$HORIZ*$GRID && $s[$i][$j]==0) { $cc++; } } } if ($cc==$VERT*$GRID){ $HORIZ--; } if ($kontador != $o[$k][4]){ # warn "Error de objeto - altura baja"; # print "contador $kontador - tamaño $o[$k][4]\n"; destroy($k); } if ($limitv-$origj+1 != $o[$k][2] && $limitv-$origj+1 != $o[$k][1]){ warn "Error de w o l"; } if ($limith-$origi+1 != $o[$k][1] && $limith-$origi+1 != $o[$k][2]){ warn "Error de l o w"; } $ok=0; for $i (1..$N){ if ($o[$i][3]==0) { $ok=1; } } last if ($ok==0); # si todos los objetos están asignados, acabar } $count=0; for $i (1 .. $HORIZ*$GRID){ for $j (1 .. $VERT*$GRID){ if ($s[$i][$j]!=0) { $count++; } } } $percent = 100*$count/($HORIZ*$GRID*$VERT*$GRID); if ($percent >= $MAXpercent){ $MAXpercent = $percent; for $i (1..$HORIZ*$GRID){ # dibujar el resultado for $j (1..$VERT*$GRID){ print chr(33+$s[$i][$j] % 90); # ! = espacio libre } print "\n"; } print "$HORIZ\n"; # decir la altura print "La ocupación es del $percent%\n"; } } sub destroy { my $kk = @_; $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]==$kk) { $s[$ii][$jj]=0; # desocupa el espacio } } } } __END__ Referecias: www.math.tu-dresden.de/~belov/publ/text030908_SUBMIT.ps