BBC BASIC, 570 514 490 bytes ASCII
Descargue el intérprete en http://www.bbcbasic.co.uk/bbcwin/download.html
435 bytes tokenizados
El programa completo muestra una entrada L.bmp
en la pantalla, luego la modifica para encontrar una solución.
*DISPLAY L
t=PI/8q=FNa(1)
DEFFNa(n)IFn=7END
LOCALz,j,p,i,c,s,x,y,m,u,v
F.z=0TO99u=z MOD10*100v=z DIV10*100ORIGINu,v
F.j=0TO12S.4p=0F.i=j+3TOj+9S.2c=9*COS(i*t)s=9*SIN(i*t)p=p*4-(POINT(c,s)<>0)*2-(POINT(9*c,9*s)<>0)N.
m=n:IFn=5A.(43A.p)=0p=0m=7
IF(ASCM."??O|(C",n)-64A.p)=0THEN
F.i=-1TO0GCOL0,-i*n:c=99*COS(j*t)s=99*SIN(j*t)y=402/3^m MOD3-1MOVE-c-s*y,c*y-s:x=n<3MOVEc*x-s*x,s*x+c*x:x=2778/3^m MOD3-1y=5775/3^m MOD3-1PLOT85-32*(n MOD6>3),c*x-s*y,s*x+c*y:IFi q=FNa(n+1)ORIGINu,v
N.
ENDIF
N.N.=0
Explicación
Tenga en cuenta que en BBC basic una distancia de 1 píxel = 2 unidades, por lo que la cuadrícula de 50x50 píxeles se convierte en una cuadrícula de 100x100.
Usamos una función recursiva para colocar los 2 triángulos grandes, triángulo mediano, cuadrado y paralelogramo en la forma. La forma anterior de la lista se dibuja antes de realizar la siguiente llamada recursiva. Si una llamada recursiva regresa sin encontrar una solución, la forma anterior se sobreescribe en negro y se intenta una nueva posición de la forma anterior.
Una vez que se dibujan estas cinco formas, colocar los dos triángulos pequeños es solo una formalidad. Sin embargo, es necesario dibujar uno de ellos para distinguirlos si comparten una ventaja común. Solo coloreamos uno de los dos triángulos pequeños. El otro queda en negro natural.
Se intenta colocar cada forma en diferentes coordenadas x, y y en 4 rotaciones diferentes. Para probar si hay espacio libre para dibujar una forma, usamos la plantilla a continuación, con ángulos de 45 grados. Las rotaciones se realizan alrededor de los *
8 píxeles probados y están en 2 semicírculos de radio de 9 y 81 unidades y caen en líneas radiantes en múltiplos impares de 22.5 grados a los ejes x e y.
Para un triángulo grande, los 8 espacios deben estar libres. Para otras formas, solo algunas de las celdas deben estar claras para que se aplique una máscara.
+----+---- Shape Mask HGFEDCBA Mask decimal
|\ E/|\G /
| \/F|H\/ 1,2. Large triangle 11111111 -1
|C/\ | / 3. Med triangle 00001111 15
|/ D\|/ 4. Square 00111100 60
+----* 5. Parallelogram 11101000 -24
|\ B/ 6. Small triangle 00000011 3
|A\/ 7. Parallogr reversed 00101011 43
| / Note: reversed parallelogram is checked/drawn at recursion depth n=5
|/ with a special check, but the coordinates are encoded as m=7.
Una vez que se establece que una forma se ajustará, debe dibujarse. Si es un triángulo con el que se traza PLOT 85
, si es un paralelogramo, el número es 32 más alto (tenga en cuenta que para PLOT
fines consideramos un cuadrado como un paralelogramo especial). En cualquier caso, se deben dar 3 vértices consecutivos. El segundo vértice es el origen de la forma (marcada *
en la tabla anterior) excepto en el caso del triángulo grande, donde (antes de la rotación) es -1,-1.
Los otros 2 vértices pueden tener coordenadas x e y de las -1,0 or 1
cuales se extraen de la base 3 números codificados, luego escalados por 99 y rotados según sea necesario mediante transformación con c
y s
.
Código sin golf
*DISPLAY L
t=PI/8 :REM Constant 22.5 degrees.
q=FNa(1) :REM Call function, return dummy value to q
END :REM End the program gracefully if no solution. Absent in golfed version.
DEFFNa(n) :REM Recursive function to place shapes.
IFn=7END :REM If n=7 solution found, end program.
LOCALk,z,j,p,i,c,s,x,y,m,u,v :REM declare local variables for function.
k=ASCMID$("??O|(C",n)-64 :REM Bitmasks for big tri, big tri, med tri, sq, normal paralellogram, small tri.
FORz=0TO99 :REM For each point on the grid
u=z MOD10*100:v=z DIV10*100 :REM calculate its x and y coordinates relative to bottom left of screen
ORIGINu,v :REM and set the origin to this point.
FORj=0TO12STEP4 :REM For each rotation 0,90,180,270deg
p=0 :REM assume no non-black pixels found
FORi=j+3TOj+9STEP2 :REM test angles of 3,5,7,9 times 22.5 deg anticlockwise from right x axis.
c=9*COS(i*t) :REM Coords of test points at radius ll
s=9*SIN(i*t)
p*=4 :REM Leftshift any existing data in p
p-=(POINT(c,s)<>0)*2+(POINT(9*c,9*s)<>0) :REM and check pixels at radius 11 and 99.
NEXT
m=n :REM The index of the shape to plot normally corresponds with recursion depth n.
IF n=5 AND (43ANDp)=0 p=0:m=7 :REM If n=5 check if a reverse parallelogram is possible (mask 43). If so, clear p and change m to 7.
REM :REM Check p against mask k, if the shape fits then...
IF (k ANDp)=0 THEN
FOR i=-1 TO 0 :REM draw the shape in colour, and if deeper recursions prove unsuccesful, redraw it in black.
GCOL0,-i*n :REM Colour is equal to n.
c=99*COS(j*t) :REM Set parameters c and s for scaling by 99
s=99*SIN(j*t) :REM and rotation by 0,90,180 or 270 as appropriate.
x=-1 :REM For vertex 1, x=-1 always.
y=402/3^m MOD3-1 :REM Lookup y value for vertex 1.
MOVEc*x-s*y,s*x+c*y :REM Use c and s to transform the vertex and move to it.
x=n<3 :REM For vertex 2, coords are 0,0 except for large triangle where they are -1,-1
y=x :REM in BBC BASIC, TRUE=-1
MOVEc*x-s*y,s*x+c*y :REM Use c and s to transform the vertex and move to it.
x=2778/3^m MOD3-1 :REM Lookup x and y value for vertex 3.
y=5775/3^m MOD3-1 :REM PLOT85 uses last 2 points + specified point to make triangle, PLOT85+32 makes paralelogram (or square.)
PLOT85-32*(n MOD6>3),c*x-s*y,s*x+c*y :REM Use c and s to transform the vertex and draw shape.
IFi q=FNa(n+1):ORIGINu,v :REM If i=-1 recurse to next level. If it fails, reset the origin before replotting this level's shape in black.
NEXT
ENDIF
NEXT
NEXT
=0 :REM Dummy value to return from function
Salida
Este es un montaje de las soluciones encontradas por el programa para los casos de prueba. El uso de 99 en lugar de 100 por razones de golf deja algunos pequeños espacios negros. Como las formas se vuelven a dibujar durante las búsquedas, puede tardar unos segundos en ejecutarse en algunos casos, y es bastante fascinante de ver.