BBC BASIC, 570 514 490 байт ASCII
Завантажте перекладача за посиланням http://www.bbcbasic.co.uk/bbcwin/download.html
435 байт маркірується
Повна програма відображає вхід L.bmp
на екрані, а потім модифікує його для пошуку рішення.
*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
Пояснення
Зауважте, що в BBC основна відстань становить 1 піксель = 2 одиниці, тому сітка 50х50 пікселів стає сіткою 100х100.
Ми використовуємо рекурсивну функцію для розміщення у формі 2 великих трикутників, середнього трикутника, квадрата та паралелограма. Більш рання форма у списку малюється до наступного рекурсивного виклику. якщо рекурсивний виклик повертається, не знаходячи рішення, більш рання форма обертається чорним кольором і спробується нова позиція попередньої форми.
Як тільки ці п'ять фігур намальовано, розміщення двох маленьких трикутників - це просто формальність. Треба намалювати одну з них, хоча для того, щоб їх знешкодити, якщо вони мають спільний край. Ми забарвлюємо лише один із двох маленьких трикутників. Інший залишився в натуральному чорному кольорі.
Розміщення кожної фігури робиться в різних координатах x, y та в 4 різних обертаннях. Щоб перевірити, чи є вільний простір для малювання фігури, ми використовуємо шаблон нижче, під кутом 45 градусів. Обертання проводяться навколо *
8 тестових пікселів у двох півколах радіусом 9 та 81 одиниці і потрапляють на випромінюючі лінії з непарними кратними 22,5 градусами до осей x та y.
Для великого трикутника всі 8 просторів повинні бути чіткими. Для інших форм лише деякі клітини повинні бути чіткими, щоб наносити маску.
+----+---- 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.
Як тільки буде встановлено, що форма підійде, її потрібно намалювати. Якщо це трикутник, на який він побудований PLOT 85
, якщо це паралелограм, то число на 32 вище (зауважте, що для PLOT
цілей ми вважаємо квадрат особливим паралелограмом). У будь-якому випадку потрібно дати 3 послідовних вершини. Друга вершина - це походження форми (позначена *
у наведеній вище таблиці), за винятком великого трикутника, де (до обертання) це -1,-1.
інші 2 вершини, можуть мати x і y координати -1,0 or 1
, витягнуті з основи 3 закодовані числа, потім масштабуються на 99 і обертаються за необхідності шляхом перетворення з c
і s
.
Невикористаний код
*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
Вихідні дані
Це монтаж рішень, знайдених програмою для тестових випадків. Використання 99 замість 100 з міркувань для гольфу залишає невеликі чорні прогалини. Оскільки фігури перемальовуються під час обшуків, для запуску деяких випадків може знадобитися кілька секунд, і спостерігати досить захоплююче.