JavaScript 782 725 caracteres
primer post, se gentil!
El programa ahora se llama a través de la función envuelta. Por ejemplo: (function(e,f,g){...})(100,200,10)
.
function C(e,f,g,c,a,d){if(0>g-a||g+a>e||0>c-a||c+a>f)return d;for(var b in d)if(Math.sqrt(Math.pow(d[b].x-g,2)+Math.pow(d[b].y-c,2))<2*a)return d;d.push({x:g,y:c});for(b=0;b<Math.PI;)XX=Math.cos(b)*a*2+g,YY=Math.sin(b)*a*2+c,d=C(e,f,XX,YY,a,d),b+=.01;return d}
(function(e,f,g){var c=e+f,a,d;for(a=[];a.length<g;)a=d=c,a=C(e,f,a,d,c,[]),c-=.01;console.log("Highest possible radius: "+Math.round(100*c)/100);e='<svg width="'+e+'" height="'+f+'"><rect width="'+e+'" height="'+f+'" style="fill:red" />';for(var b in a)console.log("Circle "+b+" Focus: ("+Math.round(100*a[b].x)/100+", "+Math.round(100*a[b].y)/100+")"),e+='<circle cx="'+a[b].x+'" cy="'+a[b].y+'" r="'+c+'" fill="blue" />';console.log(e+"</svg>")})(400,300,13);
Prueba 1
(function(e,f,g){...})(200,200,4)
Highest possible radius: 49.96
Circle 1 Focus: (49.97, 49.97)
Circle 2 Focus: (149.91, 49.97)
Circle 3 Focus: (149.99, 149.91)
Circle 4 Focus: (50.05, 149.91)
<svg width="200" height="200"><rect width="200" height="200" style="fill:blue;" /><circle cx="49.97000000021743" cy="49.97000000021743" r="49.960000000217434" fill="white" /><circle cx="149.9100000006523" cy="49.97000000021743" r="49.960000000217434" fill="white" /><circle cx="149.98958489212322" cy="149.90996831285986" r="49.960000000217434" fill="white" /><circle cx="50.04958489168835" cy="149.90996831285986" r="49.960000000217434" fill="white" /></svg>
Obviamente, esperaríamos que el radio fuera exactamente 50, pero por las razones discutidas en los comentarios de la pregunta, no pude hacerlo razonablemente. El SVG se ve así ...
Prueba 2
(function(e,f,g){...})(100,400,14)
Highest possible radius: 26.55
Circle 1 Focus: (26.56, 26.56)
Circle 2 Focus: (79.68, 26.56)
Circle 3 Focus: (132.8, 26.56)
Circle 4 Focus: (185.92, 26.56)
Circle 5 Focus: (239.04, 26.56)
Circle 6 Focus: (292.16, 26.56)
Circle 7 Focus: (345.28, 26.56)
Circle 8 Focus: (372.63, 72.1)
Circle 9 Focus: (319.52, 73.25)
Circle 10 Focus: (265.47, 72.64)
Circle 11 Focus: (212.35, 73.25)
Circle 12 Focus: (159.23, 72.64)
Circle 13 Focus: (106.11, 73.25)
Circle 14 Focus: (52.99, 72.64)
<svg width="400" height="100"><rect width="400" height="100" style="fill:blue;" /><circle cx="26.560000000311106" cy="26.560000000311106" r="26.550000000311105" fill="white" /><circle cx="79.68000000093332" cy="26.560000000311106" r="26.550000000311105" fill="white" /><circle cx="132.80000000155553" cy="26.560000000311106" r="26.550000000311105" fill="white" /><circle cx="185.92000000217774" cy="26.560000000311106" r="26.550000000311105" fill="white" /><circle cx="239.04000000279996" cy="26.560000000311106" r="26.550000000311105" fill="white" /><circle cx="292.16000000342217" cy="26.560000000311106" r="26.550000000311105" fill="white" /><circle cx="345.2800000040444" cy="26.560000000311106" r="26.550000000311105" fill="white" /><circle cx="372.6271770491687" cy="72.09972230654316" r="26.550000000311105" fill="white" /><circle cx="319.5195599732359" cy="73.24663493712801" r="26.550000000311105" fill="white" /><circle cx="265.47097406711805" cy="72.63752174440503" r="26.550000000311105" fill="white" /><circle cx="212.35454341475625" cy="73.25330971030218" r="26.550000000311105" fill="white" /><circle cx="159.23097406587362" cy="72.63752174440503" r="26.550000000311105" fill="white" /><circle cx="106.11454341351183" cy="73.25330971030218" r="26.550000000311105" fill="white" /><circle cx="52.99097406462921" cy="72.63752174440503" r="26.550000000311105" fill="white" /></svg>
Y el SVG se ve así ...
Prueba 3
(function(e,f,g){...})(400,400,3)
Highest possible radius: 101.68
Circle 1 Focus: (101.69, 101.69)
Circle 2 Focus: (298.23, 153.98)
Circle 3 Focus: (154.13, 298.19)
<svg width="400" height="400"><rect width="400" height="400" style="fill:blue;" /><circle cx="101.69000000059772" cy="101.69000000059772" r="101.68000000059772" fill="white" /><circle cx="298.2343937547503" cy="153.97504264473156" r="101.68000000059772" fill="white" /><circle cx="154.13153961740014" cy="298.19269546075066" r="101.68000000059772" fill="white" /></svg>
Y el SVG se ve así ...
No todos son bonitos.
Cómo funciona
Código sin golf a continuación. Este programa tiene dos supuestos:
- Un círculo siempre estará en la esquina. Esto parece una apuesta bastante segura.
- Cada círculo siempre estará tocando otro círculo. No veo por qué no lo serían.
El programa comienza calculando un radio grande basado en las dimensiones de la caja. Luego trata de encajar un círculo en la esquina de la caja. Si ese círculo encaja, extiende una línea de diámetro desde ese círculo e intenta crear un círculo al final de la línea. Si el nuevo círculo encaja, se extenderá otra línea desde el nuevo círculo. Si no encaja, la línea oscilará 360 grados, buscando espacios abiertos. Si el cuadro se llena antes de que se cree el número deseado de círculos, el radio se reduce y todo comienza de nuevo.
Código sin Golf (fragmento)
// this functions attempts to build a circle
// at the given coords. If it works, it will
// spawn additional circles.
function C(x, y, X, Y, r, cc){
// if this circle does not fit in the rectangle, BAIL
if(X-r < 0 || X+r > x || Y-r < 0 || Y+r > y)
return cc;
// if this circle is too close to another circle, BAIL
for(var c in cc){
if( Math.sqrt(Math.pow(cc[c].x - X, 2) + Math.pow(cc[c].y - Y, 2)) < (r*2) )
return cc;
}
// checks passed so lets call this circle valid and add it to stack
cc.push({"x": X, "y": Y});
// now rotate to try to find additional spots for circles
var a = 0; // radian for rotation
while(a < Math.PI){
XX = Math.cos(a)*r*2 + X;
YY = Math.sin(a)*r*2 + Y;
cc = C(x, y, XX, YY, r, cc);
a += .01; // CHANGE FOR MORE OR LESS PRECISION
}
return cc;
}
// this function slowly reduces the radius
// and checks for correct solutions
// also prints svg graphic code
(function B(x, y, n){
var r = x + y; // pick a big radius
var X, Y; // these are the coords of the current circle. golf by combining this with `var r..`?
var cc = []; // array of coordinates of the circles
// while we cant fit n circles, reduce the radius and try again
while(cc.length < n){
X = Y = r;
cc = C(x, y, X, Y, r, []);
r-=.01; // CHANGE FOR MORE OR LESS PRECISION
}
console.log('Highest possible radius: ' + Math.round(r*100)/100);
var s = '<svg width="' + x + '" height="' + y + '"><rect width="' + x + '" height="' + y + '" style="fill:red" />';
for(var c in cc){
console.log('Circle '+c+' Focus: (' + Math.round(cc[c].x*100)/100 + ', ' + Math.round(cc[c].y*100)/100 + ')');
s += '<circle cx="' + cc[c].x + '" cy="' + cc[c].y + '" r="' + r + '" fill="blue" />';
}
s += '</svg>';
console.log(s);
document.write(s);
})(150, 150, 5);