BBC BASIC
Rev 1 Kod do gry w golfa, 655 znaków ASCII, tokenizowany rozmiar pliku 614
Kilka istotnych ulepszeń w tabeli danych, mieszając ciąg znaków A.B..N
z liczbą (1*A+2*B+..n*N)+n
przed spojrzeniem w górę, i przechowując tylko jeden wektor tłumaczenia (drugi jest generowany przez kod.) Więcej wyjaśnień, kiedy skończę grać w golfa.
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
Rev 0 Kod w golfa, 770 znaków ASCII, tokenizowany rozmiar pliku 728
Wszystko, co tutaj zrobiłem, to usunięcie komentarzy, niepotrzebnych białych znaków i cudzysłowów oraz umieszczenie wszystkich DATA
w jednym wierszu. Z pewnością jest miejsce na więcej golfa.
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
Wyjaśnienie
Jest to kontynuacja mojej poprzedniej odpowiedzi na poziomie 1, ale postanowiłem opublikować ją osobno, ponieważ jest dość długa.
Poziom 2
Osiąga się to poprzez tłumaczenie moich szablonów „poziomu 1.5” z mojej poprzedniej odpowiedzi. Dwa wektory translacji dla każdego kafelka są zakodowane na stałe. Korzystam z faktu, że trójkąt równoramienny podstawy 80 i wysokości 70 jest bardzo dobrym przybliżeniem trójkąta równobocznego, a trójkąt prawy z wektorem przeciwprostokątnym (56,56)
ma długość przeciwprostokątną bardzo zbliżoną do 80.
Poziom 3
Aby narysować wykresy dualne, zamiast kreślenia krawędzi wielokąta, wykreślamy szprychę od środka tej krawędzi do środka wielokąta. Jest to prostopadłe do krawędzi i ma długość 1/TAN/(PI/n)
razy wektor (u, v), który z kolei jest o połowę dłuższy niż krawędź.
Niestety, ponieważ niektóre wielokąty w tilings 3.3.3.3.6
i 3.4.6.4
nie są drukowane wyraźnie, nie zostałyby one wykreślone, gdybyśmy tylko to zrobili. Dlatego szprycha rozciąga się również na zewnątrz od wielokąta. Zewnętrzne rozszerzenie jest kontrolowane przez zmienną o
.
Domyślnie rozszerzenie jest wystarczające, aby dotrzeć do środka trójkąta, ale 3.4.6.4
w celu narysowania podwójnych kwadratów, które nie zostały wyraźnie narysowane, należy je rozszerzyć bardziej. Występuje więc wystarczające rozszerzenie, aby wypełnić brakujące kwadraty, gdy sześciokąty i trójkąty są drukowane jawnie, ale normalne rozszerzenie jest stosowane, gdy kwadraty są drukowane jawnie, aby uniknąć fałszywych linii w sąsiednich trójkątach.
Oto jak wyglądają bez rozszerzeń szprych. Otwory w podwójnym wzorze są wyraźnie widoczne. Prawidłowe wyjście można zobaczyć na głównym obrazie u dołu odpowiedzi
Skomentowany kod
Różnice w stosunku do mojej poprzedniej odpowiedzi są oznaczone liniowo
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
Wynik
Program wykonuje tylko jedno kafelkowanie lub podwójny dla każdego uruchomienia. Jednak rysuje podwójne na czerwono. Aby zaoszczędzić miejsce, uruchomiłem program dwukrotnie bez czyszczenia ekranu w celu nałożenia podwójnego na zwykłe kafelki.
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
. Czy musimy poprzeć wszystkie synonimy, czy tylko najniższy leksykalnie (jak podano w pytaniu)? Ponadto,3.3.3.3.6
istnieje w dwóch postaciach lustrzanym odbiciem. Rozumiem, że oba są dopuszczalne.