BBC BASIC
Код Rev 1 Golfed, 655 символів ASCII, розмір файлів 614
Деякі основні вдосконалення таблиці даних, шляхом переміщення рядка A.B..N
до числа (1*A+2*B+..n*N)+n
перед тим, як шукати, та зберігання лише одного вектора перекладу (інший генерується за кодом.) Більше пояснення, коли я закінчу гольф.
t=PI*2DIMm(9)
c=0z=0INPUTz$
FORi=1TOLEN(z$)d%=VAL(MID$(z$,i))IFd%c+=1m(c)=d%i-=d%=12z+=c*d%
NEXTREPEATREADl,e,f
UNTILl=z+c
l=4-3*(m(3)MOD3=0)-8*(l=59)
DATA69,0,70,65,100,35,66,149,0,49,109,0,52,80,0,55,0,189,39,120,0,44,40,40,58,55,95,47,136,0,59,40,0
VDU23,23,3|
FORr=-9TO19FORs=-9TO9a=1+e*(r*2+s)-f*l*s/4b=1+f*(r*2+s)+e*l*s/4p=40q=0FORk=1TOm(c)/2FORj=1TOc
n=m(j)o=TAN(PI/3)IFe=109ANDn<>4o=1
w=-p*COS(t/n)-q*SIN(t/n)q=p*SIN(t/n)-q*COS(t/n)p=w
u=p:v=q
x=a:y=b
MOVEx,y
FORi=1TO14x+=u*2y+=v*2IFVAL(z$)DRAWx,y ELSEGCOL9LINEx-u-v/o,y-v+u/o,x-u+v/TAN(PI/n),y-v-u/TAN(PI/n)
w=v*COS(t/n)-u*SIN(t/n)u=v*SIN(t/n)+u*COS(t/n)v=w
NEXTNEXT
p=u:q=v
a=x:b=y
NEXTNEXTNEXT
Код 0 гольф-коду, 770 символів ASCII, розмір токенізованих розмірів файлів 728
Все, що я тут зробив, - це видалити коментарі, зайві пробіли та цитати, і поставити все в DATA
одному рядку. Там, звичайно, є місце для більше гольфу.
t=PI*2DIMm(9)
c=0INPUTz$
FORi=1TOLEN(z$)d%=VAL(MID$(z$,i))IFd%c+=1:m(c)=d%:i-=d%=12
NEXTREPEATREADl$,e,f,g,h
UNTILMID$(z$,1-(VAL(z$)=0))=l$
DATA3.3.3.3.3.3,240,0,120,70,3.3.3.3.6,200,70,40,210,3.3.3.4.4,80,0,40,150,3.3.4.3.4,-40,150,150,40,3.12.12,300,0,150,260,3.4.6.4,220,0,110,188,3.6.3.6,160,0,80,140,4.4.4.4,80,0,0,80,4.6.12,0,380,330,-190,4.8.8,272,0,136,136,6.6.6,240,0,120,70
VDU23,23,3|
FORr=-9TO19 FORs=0TO9a=1+e*r+g*s
b=1+f*r+h*s
p=40q=0FORk=1TOm(c)/2FORj=1TOc
n=m(j)o=TAN(PI/3):IFe=220ANDn<>4o=1
w=-p*COS(t/n)-q*SIN(t/n)q=p*SIN(t/n)-q*COS(t/n)p=w
u=p:v=q
x=a:y=b
MOVEx,y
FORi=1TO14x+=u*2y+=v*2IFVAL(z$)DRAWx,y ELSEGCOL9LINEx-u-v/o,y-v+u/o,x-u+v/TAN(PI/n),y-v-u/TAN(PI/n)
w=v*COS(t/n)-u*SIN(t/n)u=v*SIN(t/n)+u*COS(t/n)v=w
NEXTNEXT
p=u:q=v
a=x:b=y
NEXTNEXTNEXT
Пояснення
Це продовження моєї попередньої відповіді рівня 1, але я вирішив опублікувати її окремо, тому що вона досить довга.
2 рівень
Це досягається перекладом моїх шаблонів "рівень 1,5" з моєї попередньої відповіді. Два вектори перекладу для кожної плитки твердо кодуються. Я скористався тим, що рівнобедрений трикутник основи 80 та висоти 70 є дуже хорошим наближенням рівностороннього трикутника, а правий трикутник з гіпотенузним вектором (56,56)
має довжину гіпотенузи дуже близьку до 80.
3 рівень
Щоб побудувати дуали, замість того, щоб побудувати край многокутника, ми побудуємо спицю від середини цього краю до центру багатокутника. Це під прямим кутом до краю і має довжину 1/TAN/(PI/n)
часу вектора (u, v), що в свою чергу наполовину довше ребра.
На жаль, оскільки певні багатокутники в обшивці 3.3.3.3.6
і 3.4.6.4
не наводяться чітко, вони не були б побудовані, якби ми це тільки зробили. Тому спиця також виходить назовні від багатокутника. Зовнішнє розширення управляється змінною o
.
За замовчуванням розширення достатньо, щоб досягти центру трикутника, але для 3.4.6.4
цього його потрібно розширити більше, щоб намалювати дуальні квадрати, які чітко не зображуються. Тому достатньо розширення для заповнення пропущених квадратів застосовується, коли шестикутники та трикутники чітко накреслюються, але нормальне розширення застосовується, коли квадрати чітко накреслюються, щоб уникнути помилкових ліній у сусідніх трикутників.
Ось як вони виглядають без розширень спиць. Отвори у подвійному малюнку добре видно. Правильний вихід можна побачити на головному малюнку внизу відповіді
Коментований код
Відмінності від моєї попередньої відповіді вказуються в рядку
t=PI*2 :REM constant Tau = PI*2
DIMm(9) :REM declare array for the numbers in the input
c=0 :REM number of polygons in the list
INPUTz$
FORi=1TOLEN(z$) :REM for each character in the input
d%=VAL(MID$(z$,i)) :REM use VAL to return the numeric value of the substring to the right and store to integer variable
IF d% c+=1 :m(c)=d%: i-=d%=12 :REM if the last character read was a number, d% contains it, otherwise 0. Advance c and store to m. If it is 12, increment i to skip a character.
NEXT
REM BLOCK OF NEW CODE to define vectors (e,f) and (g,h) for each possible tiling
REPEAT
READ l$,e,f,g,h :REM read an entire line of the data below
UNTIL MID$(z$,1-(VAL(z$)=0))=l$ :REM abort the loop when l$ coincides with the input. the MID$ strips off the 'V' from the input where necessary.
DATA"3.3.3.3.3.3",240,0,120,70
DATA"3.3.3.3.6",200,70,40,210
DATA"3.3.3.4.4",80,0,40,150
DATA"3.3.4.3.4",-40,150,150,40
DATA"3.12.12",300,0,150,260
DATA"3.4.6.4",220,0,110,188
DATA"3.6.3.6",160,0,80,140
DATA"4.4.4.4",80,0,0,80
DATA"4.6.12",0,380,330,-190
DATA"4.8.8",272,0,136,136
DATA"6.6.6",240,0,120,70
VDU23,23,3| :REM change linewidth to 3 (default is 1)
REM END BLOCK OF NEW CODE
FORr=-9TO19 FORs=0TO9 :REM two new loops for translations
a=1+e*r+g*s :REM modified code for
b=1+f*r+h*s :REM coordinates to start drawing at
p=40:q=0 :REM vector of first line
FORk=1TOm(c)/2 :REM draw half as many vertex figures as there are sides on the last polygon in the list
FORj=1TOc :REM for each polygon on the list
n=m(j) :REM n=number of sides
o=TAN(PI/3): IF e=220 AND n<>4 o=1 :REM new code for the spoke extension 1/o.
w=-p*COS(t/n)-q*SIN(t/n) :REM rotate the starting vector anticlockwise by the internal angle of the current polygon
q=p*SIN(t/n)-q*COS(t/n) :REM to avoid overlapping the previous one, if any.
p=w
u=p:v=q :REM make a local copy of the vector and coordinates
x=a:y=b :REM to avoid corruption of p,q,a,b during the drawing of the polygon
MOVE x,y :REM move the graphics cursor to the start without drawing
FORi=1TO14 :REM do 14 iterations regardless of the number of sides on the polygon
x+=u*2 :REM increment x and y by the vector representing the side
y+=v*2 :REM the value is double (u,v) to facilitate drawing duals later
REM if z$ begins with a numeric character, draw an edge. If not, change to red and draw a spoke.
IFVAL(z$) DRAW x,y ELSE GCOL9: LINEx-u-v/o,y-v+u/o,x-u+v/TAN(PI/n),y-v-u/TAN(PI/n)
w=v*COS(t/n)-u*SIN(t/n) :REM rotate the vector clockwise
u=v*SIN(t/n)+u*COS(t/n) :REM through the external angle of the polygon
v=w
NEXT :REM draw next edge of the current polygon
NEXT :REM draw next polygon of the current vertex
p=u:q=v :REM once the vertex is finished, we will be two sides around the perimeter of the last polygon.
a=x:b=y :REM copy the position and direction data into p,q,a,b.
NEXT :REM draw next vertex figure
NEXT :REM close the two new translation loops
NEXT
Вихідні дані
Програма виконує лише одну плитку чи подвійну за кожен пробіг. Однак він малює дуалів червоним кольором. Щоб заощадити місце, я двічі запускав програму, не очищаючи екран, щоб накласти подвійний поверх звичайної плитки.
3.3.3.4.4
3.3.4.4.3
3.4.4.3.3
4.4.3.3.3
4.3.3.3.4
. Чи потрібно підтримувати всі синоніми чи лише лексично найнижчий (як зазначено у запитанні)? Також3.3.3.3.6
існує у двох дзеркальних формах зображення. Я розумію, що це прийнятно.