Przepływu węża, znany również jako krzywa Gosper'a jest fraktalny krzywa rośnie wykładniczo z każdym rozmiaru zlecenia / iteracji procesie prostym. Poniżej znajdują się szczegóły dotyczące budowy i kilka przykładów dla różnych zamówień:
Zamów 1 Flow Snake :
____
\__ \
__/
Zamówienie 2 Flow Snake :
____
____ \__ \
\__ \__/ / __
__/ ____ \ \ \
/ __ \__ \ \/
\ \ \__/ / __
\/ ____ \/ /
\__ \__/
__/
Zamów 3 Flow Snake :
____
____ \__ \
\__ \__/ / __
__/ ____ \ \ \ ____
/ __ \__ \ \/ / __ \__ \
____ \ \ \__/ / __ \/ / __/ / __
____ \__ \ \/ ____ \/ / __/ / __ \ \ \
\__ \__/ / __ \__ \__/ / __ \ \ \ \/
__/ ____ \ \ \__/ ____ \ \ \ \/ / __
/ __ \__ \ \/ ____ \__ \ \/ / __ \/ /
\ \ \__/ / __ \__ \__/ / __ \ \ \__/
\/ ____ \/ / __/ ____ \ \ \ \/ ____
\__ \__/ / __ \__ \ \/ / __ \__ \
__/ ____ \ \ \__/ / __ \/ / __/ / __
/ __ \__ \ \/ ____ \/ / __/ / __ \/ /
\/ / __/ / __ \__ \__/ / __ \/ / __/
__/ / __ \ \ \__/ ____ \ \ \__/ / __
/ __ \ \ \ \/ ____ \__ \ \/ ____ \/ /
\ \ \ \/ / __ \__ \__/ / __ \__ \__/
\/ / __ \/ / __/ ____ \ \ \__/
\ \ \__/ / __ \__ \ \/
\/ \ \ \__/ / __
\/ ____ \/ /
\__ \__/
__/
Budowa
Rozważ kolejność zbudowania 1 Flow Snake'a ze ścieżką zawierającą 7 krawędzi i 8 wierzchołków (oznaczonych poniżej. Powiększone dla możliwości):
4____5____6
\ \
3\____2 7\
/
0____1/
Teraz dla każdego następnego zamówienia po prostu zastępujesz krawędzie obróconą wersją tego oryginalnego wzoru zamówienia 1. Aby wymienić krawędzie, użyj 3 następujących zasad:
1 W przypadku poziomej krawędzi zamień ją na oryginalny kształt w następujący sposób:
________
\ \
\____ \
/
____/
2 W przypadku /
krawędzi ( 12
w powyższej konstrukcji) zamień ją na następującą obróconą wersję:
/
/ ____
\ / /
\/ /
/
____/
3 W przypadku \
krawędzi ( 34
i 67
powyżej) zamień ją na następującą obróconą wersję:
/
/ ____
\ \ \
\ \ \
\ /
\/
Na przykład będzie wyglądać kolejność 2 z wierzchołkami z oznaczonej kolejności 1
________
\ \
________ \____ \6
\ \ / /
\____ \5___/ / ____
/ \ \ \
4___/ ________ \ \ \7
/ \ \ \ /
/ ____ \____ \2 \/
\ \ \ / /
\ \ \3___/ / ____
\ / \ / /
\/ ________ \/ /
\ \ /
\____ \1___/
/
0___/
Teraz dla dowolnego wyższego rzędu wystarczy rozbić bieżący poziom na krawędzie o długości 1 /
, 1 \
lub 2 _
i powtórzyć proces. Należy pamiętać, że nawet po wymianie wspólne wierzchołki między dowolnymi dwoma kolejnymi krawędziami są nadal zbieżne.
Wyzwanie
- Musisz napisać funkcję pełnego programu, który odbiera jedną liczbę całkowitą
N
za pomocą argumentu STDIN / ARGV / function lub najbliższego odpowiednika i wypisuje kolejnośćN
Flow Snake na STDOUT. - Wejściowa liczba całkowita jest zawsze większa niż
0
. - Nie powinno być żadnych spacji wiodących, które nie są częścią wzoru.
- Nie powinno być ani końcowych spacji, ani wystarczającej spacji końcowych do wypełnienia wzoru, aby całkowicie wypełnić minimalny prostokąt ograniczający.
- Końcowy znak nowej linii jest opcjonalny.
Zabawne fakty
- Flow Snakes to gra słów o Snow Flakes, która przypomina ten wzór dla rzędu 2 i wyższych
- Flow and Snakes faktycznie odgrywają rolę we wzorze, ponieważ wzór składa się z jednej przepływającej przez nie ścieżki.
- Jeśli zauważysz uważnie, wzorzec rzędu 2 (a także wyższy) składa się z rotacji wzorca rzędu 1 obróconego na wspólnym wierzchołku bieżącej i poprzedniej krawędzi.
- Istnieje wariant węży przepływowych spoza ASCII, który można znaleźć tutaj i w kilku innych miejscach.
To jest code-golf, więc wygrywa najkrótszy kod w bajtach!
Tabela liderów
Pierwszy post z serii generuje tabelę wyników.
Aby mieć pewność, że Twoje odpowiedzi się pojawią, zacznij każdą odpowiedź od nagłówka, używając następującego szablonu Markdown:
# Language Name, N bytes
gdzie N
jest rozmiar twojego zgłoszenia. Jeśli poprawić swój wynik, to może zachować stare porachunki w nagłówku, uderzając je przez. Na przykład:
# Ruby, <s>104</s> <s>101</s> 96 bytes
Odpowiedzi:
CJam, 144 bajty
Dodano nową linię, aby uniknąć przewijania. Wypróbuj online
Program działa w kilku krokach:
źródło
Python 2,
428411388 bajtówTen był dość trudny. Wzory nie zachowują swoich proporcji po każdym kroku, co oznacza, że bardzo trudno jest proceduralnie utworzyć obraz z jego poprzednika. To, co robi ten kod, choć jest dość nieczytelne po intensywnym golfie matematyki, w rzeczywistości wyznacza granicę od początku do końca za pomocą funkcji rekurencyjnie zdefiniowanej
D
.Rozmiar był również problemem i skończyłem dopiero na środku
5*3**n
kwadratowego boku i później kadrowałem rzeczy, chociaż jeśli wymyślę lepszy sposób obliczenia rozmiaru, mógłbym go zmienić.źródło
r=[s*[" "]for i in range(s)]
->r=[[" "]*s]*s]
*
powtarza zmienny przedmiotów .l
, przełączając sięprint'\n'.join()
na drukowanie wewnątrz pętli for, używającreturn[...][t]+x,
i usuwając nawiasy z(t%2)
. Możesz także użyć,min(c.find('\\')%s for c in S)
jeśli zmienisz nazwę listy,S
aby nie zastępowała początkowej wartościs
.JavaScript ( ES6 ), 356
362 370To trudne ...
Każdy kształt jest przechowywany jako ścieżka. Istnieje 6 podstawowych bloków konstrukcyjnych (3 + 3 do tyłu)
0
przekątna w górę od lewej do prawej dolnej (4
do tyłu)1
ukośna dolna lewa do góry prawa (5
do tyłu)2
pozioma od lewej do prawej (6
do tyłu)Dla każdego z nich istnieje krok zastępujący, który należy zastosować przy zwiększaniu kolejności:
0
->0645001
(wstecz4
->5441024
)1
->2116501
(wstecz5
->5412556
)2
->2160224
(wstecz6
->0664256
)wartości wstępnie wypełnione w
h
tablicy, nawet jeśli elementy 4..6 można uzyskać z 0..2 za pomocąAby uzyskać kształt dla podanej kolejności, ścieżka jest wbudowana w zmienną p, stosując wielokrotnie podstawienia. Następnie główna pętla iteruje zmienną p i rysuje kształt w tablicy g [], gdzie każdy element jest rzędem.
Począwszy od pozycji (0,0), każdy indeks może stać się ujemny (indeks y przy wysokich rzędach). Unikam ujemnych indeksów y przesuwających całą tablicę g, ilekroć znajduję ujemną wartość y. Nie obchodzi mnie, czy indeks x staje się ujemny, ponieważ w JS dozwolone są indeksy ujemne, tylko trochę trudniejsze w zarządzaniu.
W ostatnim kroku skanuję główną tablicę za pomocą .map, ale dla każdego wiersza muszę użyć jawnej pętli for (;;), używając
b
zmiennej, która zawiera najmniej osiągnięty indeks x (który będzie <0).w
console.log
w wersji znajduje się przydatna nowa linia wiodąca, którą można łatwo zamienić na nową linię kończącą 2 wiersze, tak jak w wersji fragmentu.Przydatny fragment do przetestowania (w przeglądarce Firefox):
źródło
Haskell, 265 bajtów
(Uwaga: na GHC przed 7.10, będzie trzeba dodać
import Control.Applicative
lub wymienićabs<$>
zmap abs$
).Uruchom online na Ideone.com
f n :: Int -> IO ()
rysujen
flownake poziomu . Rysunek jest obliczany w kolejności bitmap, a nie wzdłuż krzywej, co pozwala algorytmowi działać w przestrzeni O (n) (to znaczy logarytmicznie w rozmiarze rysunku). Prawie połowa moich bajtów jest przeznaczona na obliczanie, który prostokąt narysować!źródło
Perl,
334 316309Parametr pobrany na standardowym wejściu. Przetestuj mnie .
źródło
Haskell,
469419390385365 bajtówfunkcja f :: Int-> IO () przyjmuje na wejściu liczbę całkowitą i wypisuje węża przepływu
źródło
$
w definicjik
i wymienić(!!)a
z(a!!)
którego można się pozbyć z niektórych nawiasach. Poza tym wydaje się, że znasz wiele sztuczek. NiceC,
479474468827 bajtówChyba nie ma pobicia od Perla i Haskella, ale ponieważ nie ma tu jeszcze zgłoszenia C:
Aby zaoszczędzić miejsce na wywołaniu atoi (), dla poziomu wykorzystywana jest liczba argumentów przekazywanych do programu.
Program działa w trybie O (n ^ 3) lub gorszym; najpierw ścieżka jest obliczana raz, aby znaleźć współrzędne min / maks, a następnie dla każdej pary (x, y) jest obliczana raz, aby znaleźć znak w tej konkretnej lokalizacji. Strasznie wolno, ale oszczędza na administrowaniu pamięcią.
Przykład uruchom na http://codepad.org/ZGc648Xi
źródło
X,Y,K,L,M,N,i,j,c;
zamiastint X,Y,K,L,M,N,i,j,c;
imain(l)
zamiastvoid main(int l)
Python 2,
523502475473467450437 bajtówPffft, kosztowało mnie jakieś 3 godziny, ale było fajnie!
Chodzi o podzielenie zadania na kilka etapów:
Oto kod w postaci bez golfa:
Edycja: Zmieniłem język na Python 2, aby był zgodny z moją odpowiedzią dla # 3 (i oszczędza również 6 dodatkowych bajtów)
źródło
l.extend(x)
sięl+=x
. Prawdopodobnie możesz też użyć codegolf.stackexchange.com/questions/54/… zamiast tego,.split()
którego używasz (zrobiłem coś podobnego w mojej odpowiedzi)extend
Pari / GP, 395
Pętla nad pozycjami znaków x, y i obliczanie, jaki znak ma zostać wydrukowany. Umiarkowane próby zminimalizowania, zdobyte spacją i rozebrane komentarze.
Każdy znak jest pierwszą lub drugą komórką sześciokątną. Lokalizacja komórki to liczba zespolona z podzielona na podstawę b = 2 + w z cyframi 0, 1, w ^ 2, ..., w ^ 5, gdzie w = e ^ (2pi / 6) szósty pierwiastek jedności. Cyfry te są przechowywane jako rozróżnienie od 1 do 7, a następnie przenoszone od góry do dołu przez tabelę stanu dla obrotu netto. Jest to w stylu kodu Flownake autorstwa Eda Shoutena (
xytoi
), ale tylko dla rotacji netto, bez przekształcania cyfr w indeks „N” na ścieżce. Zakresy odnoszą się do początku 0 w środku kształtu. Dopóki limit nie jest punktem końcowym, są one środkiem sześciokąta o długości 2 znaków i potrzebny jest tylko 1 z tych znaków. Ale gdy początkiem i / lub końcem węża jest X limit, potrzebne są 2 znaki, czyli k = 0 początek i koniec <3. Pari ma wbudowane „quady”, takie jak sqrt (-3), ale to samo można zrobić z częściami rzeczywistymi i urojonymi osobno.źródło