Układanie płytek, podana konfiguracja wierzchołków

11

Zadanie

Zadanie polega na kafelkowaniu wielokątów z uwzględnieniem konfiguracji wierzchołków.

Punktacja

Twój wynik jest równy „poziomowi złożoności”, który osiągniesz. Poziomy złożoności są kumulatywne, co oznacza, że ​​aby osiągnąć # 3, musisz także wesprzeć # 1 i # 2.

Zgłoszenia na tym samym poziomie złożoności są rozróżniane według liczby bajtów; najniższe wygrane.

Wejście

Dane wejściowe to ciąg zawierający konfigurację wierzchołków, reprezentujący figurę wierzchołków. Oznacza to oddzieloną kropką listę liczb całkowitych, gdzie każda liczba całkowita (n) reprezentuje zwykły n-gon, połączony wspólnym wierzchołkiem.

Muszą być obsługiwane następujące konfiguracje wierzchołków:

  • 3.3.3.3.3.3
  • 3.3.3.3.6
  • 3.3.3.4.4 (zwróć uwagę, że kolejność jest odzwierciedlona na rysunku wierzchołka, dlatego poniższe różnice się różnią)
  • 3.3.4.3.4
  • 3.12.12
  • 3.4.6.4
  • 3.6.3.6
  • 4.4.4.4
  • 4.6.12
  • 4.8.8
  • 6.6.6

Wyjście - Poziom złożoności nr 1: Rysunek wierzchołka

Na tym poziomie złożoności dane wyjściowe to obraz przedstawiający liczbę wierzchołków odpowiadającą podanemu wejściowi.

Wejście jest poprzedzone znakiem, Fktóry oznacza, że ​​liczba wierzchołków powinna być wyprowadzana, a nie pełne kafelki.

Na przykład F3.6.3.6podaje tę liczbę wierzchołków:

3.6.3.6 rysunek wierzchołka

Wyjście - Poziom złożoności # 2: Układanie płytek

Na tym poziomie złożoności wyjściowym jest obraz pokazujący jednolite kafelkowanie z wykorzystaniem liczby wierzchołków odpowiadającej podanemu wejściowi.

Na przykład 3.6.3.6daje to kafelkowanie:

3.6.3.6

Nie ma ograniczeń dotyczących koloru ani formatu (z wyjątkiem luk prawnych).

Wyjście - Poziom złożoności nr 3: Podwójne układanie płytek

Na tym poziomie złożoności można tworzyć „podwójne kafelki” z każdego kafelka. Osiąga się to poprzez rysowanie linii od środka każdego wielokąta do środka każdego graniczącego wielokąta.

Podwójne kafelkowanie jest określane przez wcześniejsze wprowadzenie za pomocą V.

Na przykład V3.6.3.6daje to podwójne kafelki (na czerwono):

Kafelkowanie V3.6.3.6

jsh
źródło
Niektóre z tych tilings mają synonimy. Na przykład następujący są takie same: 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.6istnieje w dwóch postaciach lustrzanym odbiciem. Rozumiem, że oba są dopuszczalne.
Level River St
Strona, do której prowadzą linki, nie zgadza się z podaną listą. 3.3.3.4.4na przykład brakuje. pl.wikipedia.org/wiki/… dokładnie pasuje do Twojej listy. Rozumiem, że dopuszczalne są zarysy lub wypełnione wielokąty (lub ich kombinacja?) Niektóre dualne są już na liście. Na przykład 4.4.4.4ma swoją podwójność 3.3.3.3.3.3i 6.6.6są wzajemnie dualne. Ponieważ dualne są wyświetlane niezależnie od ich rodziców, rozumiem, że nie ma potrzeby prawidłowego dopasowania z rodzicem.
Level River St
musisz obsługiwać dane wejściowe takie, jakie pojawiają się na liście - możesz obsługiwać synonimy, ale nie musisz - musisz obsługiwać wszystkie dualne, nawet self-dualne.
jsh
kontur / wypełnienie - w każdym razie w porządku. poza lukami dozwolona jest każda stylizacja (zmień kolor na biały, zmniejsz obszar rysowania itp.). wyrównanie nie jest wymagane. Mogę powiedzieć, że nie wolno ci użyć jednego odbicia, 3.3.3.3.6ale skąd miałbyś wiedzieć, który to jest? :)
jsh
Teraz zmieniłeś punktację, co to jest remis? Czy to wciąż najkrótszy kod? Jeśli tak, to czy konfiguracje wierzchołków muszą być oddzielone kropkami, czy możemy wybrać inny symbol, taki jak przecinek lub spację?
Level River St

Odpowiedzi:

9

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..Nz liczbą (1*A+2*B+..n*N)+nprzed 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 DATAw 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.6i 3.4.6.4nie 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.4w 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

wprowadź opis zdjęcia tutaj

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.

wprowadź opis zdjęcia tutaj

Level River St
źródło
8

Matematyka

Poziom 1 zawiera podstawowe szablony kafelków, które są wielokrotnie stemplowane, aby kafelkować płaszczyznę.

Poziom 2 wykonuje kafelki.

Wciąż są 2 tile, których nie byłem w stanie osiągnąć. Wydaje się, że wymagają rotacji, a także tłumaczenia.

Poziom 1: Liczba wierzchołków (559 bajtów)

nGon[n_]:=
{ColorData[46,"ColorList"][[n]],Polygon@Switch[n,
3,{{0,0},{-1/2,.866},{-1,0},{0,0}},
4,{{0,0},{0,1},{-1,1},{-1,0},{0,0}},
6,Table[{Cos[i 2Pi/n],Sin[i 2Pi/n]}+{-.5,.866},{i,0,n}],
8,Table[1.31{Cos[i Pi/4],Sin[i Pi/4]}+{-0.5`,1.207},{i,1/2,9}],
_,Table[2{Cos[i 2Pi/n],Sin[i 2Pi/n]}+{-0.5176,1.932},{i,1/2,13}]]}
innerAngle[n_]:=180-360/n
g[{}]=0;
g[a_]:=-(Plus@@innerAngle/@a)

h[{{},__,out_}]:=out
h[{list_,angles_,out_}]:=(
z=GeometricTransformation[nGon[l=list[[1]]],RotationTransform[g[angles] Degree]];
h[{Rest@list,Append[angles,l],Append[out,z]}])

Testowanie

Row[Graphics[{EdgeForm[{Blue}], #}, 
      ImageSize -> 70] & @@ {h[{#, {}, {}}]} & /@ {{3, 3, 3, 3, 3, 
    3}, {3, 3, 3, 3, 6}, {3, 3, 3, 4, 4}, {3, 3, 4, 3, 4}, {3, 12, 
    12}, {3, 4, 6, 4}, {3, 6, 3, 6}, {4, 4, 4, 4}, {4, 6, 12}, {4, 8, 
    8}, {6, 6, 6}}]

znaczki pocztowe


Poziom 2: Kafelkowanie (690 dodatkowych bajtów)

Reguły zwracają przesunięcia i wcięcia w kafelkach dla każdej konfiguracji.

r to podstawowa funkcja generująca przechyłki.

ppokazuje szablon i odpowiednie kafelki. Białe spacje odpowiadają tym, które nie są objęte szablonem.

rules={
{3,6,3,6}-> {2,3.47,0,0},
{4,4,4,4}-> {1,1,0,0},
{6,6,6}-> {3,2.6,1.5,0},
{3,3,3,3,3,3}-> {1.5,1.74,0,.9},
{3,3,3,3,6}-> {2,2.6,-0.4,1.8},

{4,6,12}->{4.2,4.9,0,2.5},
{3,3,4,3,4}-> {1.87,1.86,-.5,-0.5},
{4,8,8}-> {3.4,3.4,0,0},
{3,3,3,4,4}-> {2,1.87,.52,0},
{3,12,12}-> {3.82,6.73,0,0},
{3,4,6,4}-> {1.4,4.3,0(*1.375*)-1,-2.4}};


r[nGons_]:=
Module[{horizHop,vertHop,indent,downIndent},
{horizHop,vertHop,indent,downIndent}=(nGons/.rules);
Graphics[{EdgeForm[{Blue}],Table[GeometricTransformation[h[{#,{},{}}]&/@{nGons},
TranslationTransform[{
If[MemberQ[{{3,3,4,3,4},{3,3,3,3,6},{3,4,6,4}},nGons],indent *row,indent Boole[OddQ[row]]]+col horizHop,
If[MemberQ[{{3,3,4,3,4},{3,3,3,3,6},{3,4,6,4}},nGons],downIndent *col,downIndent Boole[OddQ[col]]]-row vertHop}]],
{col,0,5},{row,0,4}]},ImageSize-> 250]]

p[nGon_]:=Row[{Graphics[{EdgeForm[{Blue}],h[{nGon,{},{}}]},ImageSize->70],r@nGon}];

Testowanie

Trójkątne płytki

p[{3, 3, 3, 3, 3, 3}]

trójkątny


sześciokątny

p[{6, 6, 6}]

sześciokątny


kwadrat

p[{4, 4, 4, 4}]

kwadrat


nieznany

p[{3, 3, 4, 3, 4}]

archimedes1


ścięty kwadrat

p[{4, 8, 8}]

ścięty kwadrat


triheksagonalny

p[{3, 6, 3, 6}]

triheksagonalny


ścięty sześciokątny

p[{3, 12, 12}]

ścięty sześciokątny


anonimowy

p[{3, 3, 3, 3, 6}]

nachylony


wydłużony trójkątny

p[{3, 3, 3, 4, 4}]

wydłużony trójkątny


Tilings do rozgryzienia

lewo

DavidC
źródło
Jestem prawie na tym samym etapie co ty. Mogę tworzyć kafelki, ale wypracowanie kafelków zajmie trochę czasu. Steveverill wiki zamieszczony w jego komentarzach sprawia, że ​​wygląda na to, że należy wspierać różne schematy. Musisz się trochę uczyć :)
MickyT
Micky, Przemieszczenie pionowe i poziome płytki zależy od numeru wiersza, nr kol. używając przesunięć unikalnych dla danego przypadku. Rozpracowuję je jeden po drugim, a później uogólniam.
DavidC
@DavidCarraher świetny start. Dokonałem zmiany kryteriów punktacji, które mogą mieć na ciebie wpływ.
jsh
Jak dotąd dobrze! Jeśli zmniejszysz translację poziomą o 3.3.3.3.3.3połowę, aby jednostki zachodziły na siebie, możesz pozbyć się tych diamentów i naprawić płytki. Masz jeszcze wiele do zrobienia w sprawie 3.3.3.3.6, 3.4.6.4a 4.6.12jednak.
Level River St
Re 4.6.12 anyone know what it should look like?- Wszystkie wymagane nachylenia są na stronie en.wikipedia.org/wiki/… . Zobacz mój komentarz do pytania. To jest inna strona niż ta wymieniona w pytaniu. Ale i tak 4.6.12jest również pokazywany na tej stronie.
Level River St
6

R

Krok 1

Oto mój wysiłek w budowaniu płytek. Płytka, aby przejść dalej. To nie sprawdza poprawności danych wejściowych, więc inwalidzi będą rysować dziwne płytki. Dane wejściowe wpisuje się po pierwszym wierszu

i=as.numeric(unlist(strsplit(readline(),"[.]")))
e=c()
for(n in 1:length(i)){
    o=sum(c(0,180-360/i[1:n-1]))
    for(z in 1:i[n]){
        e=c(e,(360/i[n])*(z-1)+o)
    }
}
f=pi/180
plot(c(0,cumsum(sin(e*f))),c(0,cumsum(cos(e*f))),type="l")

wprowadź opis zdjęcia tutaj

Krok # 1, # 2 i # 3: 1898

Wreszcie wróciłem do tego. Większość tego zajmuje zajęcie się ustawianiem przesunięć i obsługą specjalnych przypadków :). Edycja: Flaga V dla dualów jest teraz obsługiwana

Ogólny proces to:

  • Wprowadź dane i stwórz listę
  • Utwórz listę kątów, aby narysować początkową płytkę
  • Obliczyć środki każdego wielokąta, to jest kafelek i wektory z nich, aby przeciąć krawędzie
  • Określ rysowany zestaw płytek i zrób listę przesunięć kątowych. Niektóre płytki mają dodatkowe wielokąty, które pomagają w wypełnianiu dziur.
  • Narysuj płytki
  • Narysuj duals

Prawdopodobnie mogę jeszcze trochę golfa.

##Get input (Enter by itself then type in the tile scheme)
i=strsplit(readline(),"[.]")[[1]]
## Run once i is set
q=0
if(substr(i[1],1,1)=="V"){q=1;i[1]=substr(i[1],2,9)}
i=as.numeric(i)
f=pi/180
e=x=y=q=p=c()
l=length(i)
d=1/(2*tan(pi/3))
g=1/(2*sin(pi/3))
for(n in 1:l){o=sum(c(0,180-360/i[1:n-1]))
r=1/(2*sin(pi/i[n]))
a=o+(180-360/i[n])/2
b=1/(2*tan(pi/i[n]))+d
for(z in 1:i[n]){x=c(x,r*sin(a*f))
y=c(y,r*cos(a*f))
q=c(q,b)
p=c(p,(360/i[n])*(z-1)+o-90)
e=c(e,(360/i[n])*(z-1)+o)}}
if(sum(i)==18&l==6){h=c(60,0);w=c(60,120)}
if(sum(i)==18&l==5){h=c(0,0,60);w=c(60,120,60)
e=c(e,0,-60,60,180,60,180)
x=c(x,g*sin(-30*f),g*sin(-30*f),g*sin(90*f))
y=c(y,1+g*cos(-30*f),1+g*cos(-30*f),1)
q=c(q,d+d,d+d,d+d)
p=c(p,-30,90,-30)}
if(sum(i)==17&l==5&sum(abs(diff(c(i,i[1]),1)))==2){h=c(0,0);w=c(90,60)}
if(sum(i)==17&l==5&sum(abs(diff(c(i,i[1]),1)))==4){h=c(0,30);w=c(270,300)}
if(sum(i)==17&l==4){h=c(0,30,-30);w=c(60,30,90)
e=c(e,150,120,210,300)
x=c(x,sin(150*f)+g*sin(90*f),sin(150*f)+sin(210*f)/2)
y=c(y,cos(150*f)+(1/(2*cos(pi/3)))*cos(90*f),cos(150*f)+cos(210*f)/2)
q=c(q,1,1)
p=c(p,210,120)}
if(sum(i)==18&l==4){h=c(0,0);w=c(120,120)}
if(sum(i)==16&l==4){h=c(0,0);w=c(90,90)}
if(sum(i)==27&l==3){h=c(0,-30,0,30);w=c(60,90,120,150,180)}
if(sum(i)==22&l==3){h=c(0,-30,30,90,60,30)
w=c(90,150,120,90,60,30)
e=c(e,0,-30,-60,30,120,210,30,90,150)
q=q-d+1/(2*tan(pi/4));q[13]=q[17]=q[21]=q[21]+3}
if(sum(i)==20&l==3){h=c(0,-45,-90);w=c(90,0,45)}
if(sum(i)==18&l==3){h=c(0,60,0,-60);w=c(0,60,120,60)}
hx=sum(sin(h*f))
hy=sum(cos(h*f))
wx=sum(sin(w*f))
wy=sum(cos(w*f))
plot(0,0,type="n")
par(pin=c(5,5),usr=c(0,20,0,20))
for(c in -20:20){for(j in -20:20){lines(c((c*hx)+(j*wx)+0,(c*hx)+(j*wx)+cumsum(sin(e*f))),c((c*hy)+(j*wy)+0,(c*hy)+(j*wy)+cumsum(cos(e*f))),type="l")
if(q){for(n in 1:length(x)){lines(c((c*hx)+(j*wx)+x[n],(c*hx)+(j*wx)+x[n]+q[n]*sin(p[n]*f)),c((c*hy)+(j*wy)+y[n],(c*hy)+(j*wy)+y[n]+q[n]*cos(p[n]*f)),col="RED")}}}}

wprowadź opis zdjęcia tutaj wprowadź opis zdjęcia tutaj wprowadź opis zdjęcia tutaj

MickyT
źródło
Wow, tylko 4 godziny za mną. I też ładnie wyglądają, +1! Czy masz już wszystkie sprawy?
Level River St
@steveverrill Dzięki i działa dla wszystkich przypadków w pytaniu.
MickyT,
4

BBC BASIC

Pobierz emulator na http://www.bbcbasic.co.uk/bbcwin/bbcwin.html

Poziom 1

wprowadź opis zdjęcia tutaj

Poziom 1,5

Poziom 1,5 to moje własne oznaczenie, ale jest to ważny kamień milowy w mojej metodzie.

Przesunięcie liczb wierzchołków nie zawsze prowadzi do prawidłowego sąsiadowania. W niektórych przypadkach brakuje linii.

Moim rozwiązaniem jest obejście największego wielokąta, rysowanie liczby wierzchołków dla każdego drugiego wierzchołka tego wielokąta. Jest to ogólne rozwiązanie dla wszystkich przypadków. Zauważ, że największy wielokąt ma zawsze parzystą liczbę boków, a liczba wierzchołków często zmienia się w kierunku zgodnym z ruchem wskazówek zegara / przeciwnie do kierunku ruchu wskazówek zegara podczasokoła wielokąta. Widać to najwyraźniej za pomocą 4.6.12, ale jest to również prawdą 4.8.8i 3.12.12: gdy oglądane z dowolnego konkretnego 8-gona lub 12-gona, naprzemienne wierzchołki są wzajemnie odbiciami lustrzanymi. Tak też dzieje się, nieco mniej oczywiste, z 3.3.3.4.4i 3.3.4.3.4: patrząc z dowolnego kwadratu, przemienne wierzchołki są wzajemnie odbiciami lustrzanymi.

Algorytm, którego używam do przesuwania 2 boków wokół wielokąta, polega na tym, aby zawsze wykonywać 14 iteracji pętli rysującej krawędzie, niezależnie od tego, ile krawędzi ma wielokąt. 8 jest współczynnikiem 16, dlatego podczas rysowania ośmiokątów kursor graficzny kończy się 16-14 = 2 wierzchołkami za miejscem, w którym się zaczął. 3- 4- 6- i 12-gony mają boki o współczynniku 12, więc kursor graficzny kończy się o 14-12 = 2 wierzchołki przed początkiem.

Liczby można zobaczyć poniżej. Jutro mam nadzieję opracować prawidłowe tłumaczenia, aby ukończyć kafelkowanie. We wszystkich przypadkach narysowane są wystarczające linie, aby ukończyć poziom 2 tylko z tłumaczeniami. W niektórych przypadkach rysuje się znacznie więcej niż wymagane minimum, ale nie ma problemu z nakładaniem się: reguły nie mówią nic o rysowaniu linii tylko raz :-)

Ogólnie rzecz biorąc, największy wielokąt jest ostatni na liście. Niestety jest jeden przypadek, w którym tak nie jest: 3.4.6.4dlatego rysunek narysowany w tym przypadku jest wyśrodkowany na kwadracie, a nie na sześciokącie. Jest wystarczająca liczba wierszy, aby ukończyć poziom 2 przy użyciu samych tłumaczeń, chociaż będą pewne kwadraty, które nie zostaną wyraźnie narysowane. Spowoduje to pewne problemy na poziomie 3 (na szczęście myślę, że wiem, jak to rozwiązać). Podobnie z 3.3.3.3.6wystarczającą liczbą linii do ukończenia poziomu 2 przy użyciu samych tłumaczeń, ale będą pewne trójkąty, które nie zostaną wyraźnie narysowane.

wprowadź opis zdjęcia tutaj

Kod

Kod poziomu 1.5 został skomentowany, aktywowany jest tylko kod poziomu 1. Istnieją cztery linie rozpoczynające się od REM. Usuń je, REMaby aktywować poziom 1.5.

  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

  FORi=1TOc PRINTm(i),:NEXT                       :REM parsing check for debugging.


  a=601:b=601                                     :REM coordinates to start drawing at
  p=40:q=0                                        :REM vector of first line

  REM 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

    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
      IFVAL(z$) DRAW x,y ELSE LINEx-u,y-v,x-u,y-v :REM if the first character of the input is a number, draw the side of the polygon. The ELSE part is unfinished and will be for drawing duals.
      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

  REM p=u:q=v                                     :REM once the vertex is finished, we will be two sides around the perimeter of the last polygon.
  REM a=x:b=y                                     :REM copy the position and direction data into p,q,a,b.
  REM NEXT                                        :REM draw next vertex figure

Poziomy 2 i 3

Zobacz moją drugą odpowiedź.

Level River St
źródło