Twoim zadaniem na dziś: narysuj smoczą krzywą!
Jeśli nie wiesz, czym jest Dragon Curve, oto wprowadzający film wideo ViHart (Naprawdę fajnie, proszę obejrzyj!)
Twoje zadanie: narysuj smoczą krzywą, powtarzaną co najmniej 9 razy. Nie musisz pokazywać iteracji od 1 do 9, wystarczy pokazać ostatnią krzywą wytworzoną po ukończeniu (co najmniej) 9 iteracji. Krzywa musi być narysowana jako proste linie łączące punkty na krzywej; wynik powinien pasować do jednego z poniższych obrazów, który pokazuje 9 lub więcej iteracji (do odbicia, obrotu, skalowania i zmiany szerokości linii, koloru linii i koloru tła). Twój wynik musi być wystarczająco duży, aby można było odróżnić poszczególne wiersze i utworzone przez nie „pola”; jeśli dwie linie nie przecinają się na krzywej, nie powinny zajmować tych samych lub sąsiadujących pikseli na wyjściu (między nimi powinien być widoczny co najmniej jeden piksel tła). Możesz wyświetlić obraz na ekranie lub zapisać obraz w pliku, który jest akceptowany. Wynik musi być graficzny - nie może to być grafika ASCII.
Najkrótszy kod w bajtach wygrywa, jednak dyrektywy dotyczące bibliotek nie powinny być uwzględniane w liczbie bajtów, a można użyć bibliotek graficznych lub innych bibliotek napisanych dla wybranego języka, jeśli zostały napisane przed wysłaniem.
Dołącz obraz wyników swojego programu.
Pomiń ten akapit, jeśli oglądałeś wideo:Dla tych z was, którzy zdecydowali się nie oglądać wideo, pierwsze 12 iteracji krzywej smoka pokazano poniżej. Na potrzeby tego zadania krzywa smoka jest krzywą generowaną według następującej zasady: weź punkt końcowy bieżącej krzywej, utwórz drugą krzywą obróconą o 90 stopni wokół tego punktu końcowego, tak aby punkt końcowy oryginału krzywa jest punktem początkowym nowej krzywej i łączy dwie krzywe w jedną krzywą w miejscu, w którym się spotykają. Na poniższych obrazach każda nowa iteracja jest generowana przez obrócenie poprzedniej iteracji o 90 stopni w kierunku zgodnym z ruchem wskazówek zegara wokół punktu końcowego każdej iteracji. Kiedy krzywa jest wyświetlana na ekranie, nie jest oczywiste, który koniec liczy się jako „punkt końcowy”, jednak gdy krzywa jest przechowywana jako tablica punktów, łatwo jest zdefiniować „punkt końcowy” jako ostatni punkt w tablica.
Sztuka ascii jest doceniana, ale nie akceptowana: jest to grafika, a nie sztuka ascii.
źródło
Odpowiedzi:
x86, MSDOS, 16 bajtów
Napisałem to jakiś czas temu, o ile mi wiadomo, najmniejszą rutynę tworzenia smoczego fraktala. Nie używa prawdziwych iteracji, raczej drukuje każdy dyskretny piksel wewnątrz fraktala bezpośrednio, pokazując ostateczny obraz. Jest dołączony do wielu innych drobnych produkcji w tym pakiecie . Wersja 16-bajtowa była końcem moich starań, aby fraktal smoka był tak mały, jak to możliwe, począwszy od 2014 roku z tą 32-bajtową produkcją .
Klątwa
Kod
źródło
Python 2/3,
1691671501119878 bajtówZauważ, że import nie jest uwzględniony w liczbie bajtów, zgodnie ze specyfikacją wyzwania.
Dzięki @AlexHall za zapisanie 39 (!) Bajtów i @ nedla2004 na kolejne 13
Zaczyna od wygenerowania listy lub skrętu w prawo (90) i w lewo (-90), a następnie przechodzi przez listę i przesuwa żółwia.
Wygenerowana moc wyjściowa:
EDYCJA: Jeśli jest to zbyt nudne, obejrzyj, dodaj
speed(0)
bezpośrednio przed pierwszymfd(5)
. Będzie działać tak samo, tyle że żółw będzie poruszał się znacznie szybciej.źródło
Logo, 43 bajty
Spróbuj z tłumaczem na http://www.calormen.com/jslogo/#
Wykorzystuje to tę samą zasadę, co moja poprzednia odpowiedź ASCII na sztukę i formułę na wikipedii, z wyjątkiem tego, że odwróciłem kierunek, aby dopasować obraz w pytaniu:
bitand :i -:i
znajduje najmniej znaczący fragmenti
. Dzielimyi
przez to, aby przesunąć wi
prawo wymaganą kwotę, podając wymaganą liczbę nieparzystąk
. Nie ma potrzeby rozróżniania skrętów w lewo i w prawo; po prostu skręcamy w lewo ok*90
stopnie i polegamy na tym, że obrót jest operatoną modulo 360, która wykonuje dla nas ten moduł.Wynik
ht
w razie potrzeby użyj, aby ukryć żółwia.Wyjście (zmodyfikowane)
Poniżej pokazano, jak krzywa jest pojedynczą nicią.
źródło
LindenMASM , 51 bajtów
LindenMASM to język, który jakiś czas temu stworzyłem dla wyzwania, który na zawsze będzie żył w piaskownicy. Wykorzystuje koncepcję systemów Lindenmayera do rysowania krzywych smoka, roślin fraktalnych, trójkątów Sierpińskiego itp.
Kod źródłowy jest następujący:
Aby to skonfigurować
n = 6
na przykład:To tworzy następujący obraz za pomocą Pythona 3
turtle
:W przypadku iteracji może występować niewielka różnica numeracji, ponieważ w systemie Lindenmayer pierwsza iteracja jest pojedynczą linią. Oto jak to wygląda
n = 10
:Dla zabawy, oto jak to wygląda z 15 pokoleniami (z dodatkową instrukcją,
MOV 2
aby zmniejszyć nieco):Kiedy dojdziesz do 20 pokoleń (z
MOV 0.5
), tak naprawdę nie możesz już zobaczyć linii, a utworzenie zajmuje dużo kroków (pary+-
i-+
nie są zoptymalizowane). Oto, co otrzymujesz:Zauważ, że obecny interpreter może przedstawiać problemy graficzne dla mniejszej liczby pokoleń, tzn. Być może nie rysuje się na ekranie. Niestety, kiedy ten interpreter został utworzony, nie było żadnych problemów, możliwa zmiana w Pythonie 3 mogła to spowodować lub może to być po prostu mój system
źródło
Niedociążenie, 196 bajtów
Pomyślałem, że może być interesujące wypróbowanie tego wyzwania w esolangu o niskiej mocy; Niedociążenie radzi sobie całkiem dobrze w przypadku języka z tak małą liczbą poleceń.
Dane wyjściowe to plik SVG z bardzo mocno zagnieżdżonymi znacznikami i niektórymi skrótami golfowymi. Do tej pory nie znalazłem przeglądarki, która może go wyświetlić (Firefox zawiesza się przez kilka minut, próbując go załadować, a zarówno Firefox, jak i Chromium dają pusty ekran). Większość programów do przetwarzania obrazów też nie może go załadować (co utrudnia konwersję na inny format), ale udało mi się załadować go do przeglądarki Eye of Gnome (która jest częścią domyślnej instalacji na Ubuntu). Więc zrobiłem zrzut ekranu obrazu, abyś mógł go zobaczyć (rzeczywisty obraz ma przezroczyste tło, ale tak naprawdę nie możesz zrzut ekranu przezroczysty):
Musimy wyraźnie określić rozmiar obrazu. Wybranie odpowiedniej orientacji obrazu, narysowanie wszystkiego w minimalnym dozwolonym rozmiarze i wykonanie minimalnej liczby iteracji określonych przez wyzwanie, daje nam obraz, który po prostu mieści się w szerokości 99 pikseli, oszczędzając bajt. Fajnie jest, gdy sprawy się tak układają.
Ogólny algorytm używany do rysowania obrazu polega na utrzymywaniu dwóch zmiennych (Niedociążenie nie nazywa zmiennych, ale pomyślałem o nich jako x i y ), oba początkowo puste. Następnie wielokrotnie zamieniamy ( x , y ) na ( x , skręcamy w lewo i poruszamy się do przodu, y ) i ( x , skręcamy w prawo i poruszamy się do przodu, y ). Po dziesięciu iteracjach zarówno x , jak i y utrzymują dziewięciotaktową krzywą smoka.
Istnieje również kilka mikrooptymalizacji i sztuczek związanych z niedociążeniem. W celu uniknięcia zbyt dużo bawić z wierzchu stosu, każdej iteracji pętli, zaczynamy łącząc X i Y w funkcji „powrót ciąg utworzony przez złączenie: x , instrukcją kolei argument funkcji, a move- przekazywanie instrukcji i y . ” Funkcja ta zajmuje tylko jedno miejsce na stosie, więc możemy go powielać, nazywają go
-90
jako argumentu, zamienić wartości zwracanej w ramach dwóch egzemplarzach, i nazywają go90
jako argument, aby zdobyć nowych wartości dla X i Ybez konieczności dotykania więcej niż dwóch górnych elementów stosu (które są zdecydowanie najbardziej dostępne). Ta funkcja jest generowana w czasie wykonywania kodu. Generator jest również generowany w czasie wykonywania kodu, aby umożliwić mu ponowne użycie ciągu,<g transform="translate
który jest również używany do ustawienia początku obrazu. Najpierw generujemy wszystkie otwarte tagi, a następnie, ponieważ wszystkie tagi close są po prostu</g>
, możemy wygenerować 1024 tagi close, po prostu powtarzając ciąg, bez obawy o dopasowanie ich do tagów open. (Efektywne pisanie liczb w niedociążeniu jest samo w sobie interesującym problemem;(:*)::*:**:*
jest jednak prawdopodobnie najbardziej wydajnym sposobem zapisu 1024, co przekłada się na „2 do potęgi (1 + 2 × 2) × 2”.Niedociążenie nie ma żadnych bibliotek graficznych, więc tworzę SVG, używając kombinacji rysowania linii w ustalonej pozycji i obracania obrazu wokół danego punktu; zamiast obracać długopis, odwracamy papier. Chodzi o to, że rysując linię, obracając cały obraz, rysując inną linię, obracając obraz ponownie itp., Możemy skutecznie symulować grafikę żółwia bez konieczności wykonywania arytmetyki lub korzystania z bibliotek graficznych, ponieważ wszystkie linie są rysowane w tej samej lokalizacji. Oczywiście oznacza to, że mamy bardzo mocno zagnieżdżone tagi rotate-the-image, co dezorientuje wiele przeglądarek SVG.
Stylowanie obrazu będzie się liczyć z liczbą bajtów, więc musiałem podać minimalną stylizację potrzebną do wyświetlenia obrazu. Okazuje się, że tak
stroke="#"
, co mniej więcej tłumaczy się jako „linia musi mieć jakiś kolor”; wydaje się, że jest to rozszerzone na rysowanie go na czarno. (Zwykle kolor określa się jako powiedzmy „# 000”.) Domyślnie tło jest przezroczyste. Nie określamy szerokości obrysu, ale wybór wybrany przez Eye of Gnome pozostawia wszystko widoczne.Wielu tłumaczy niedociążenia boryka się z tym programem, np. Ten w Try It Online ulega awarii, ponieważ generuje on bardzo duże ciągi wewnętrznie. Oryginalny internetowy interpreter niedociążenia działa jednak. (Co ciekawe, pierwszy tłumacz był online, więc język był dostępny online, zanim był dostępny offline).
Trochę mnie niepokoi to, że wydaje się, że jest tu tylko 1023 segmentów linii, a my spodziewalibyśmy się 1024. Możliwe, że jeden z segmentów na końcu nie jest rysowany za pomocą tego algorytmu (byłby to zamiast tego rysowana w następnej iteracji). Jeśli to dyskwalifikuje, może być możliwe dostosowanie programu, ale może skończyć się znacznie dłużej. (To nie tak, że to wyzwanie i tak wygra konkurs; jest już kilka krótszych zgłoszeń).
źródło
MATL , 26 bajtów
Jeśli akceptowane są różne skale w dwóch osiach, kod można zmniejszyć do 19 bajtów:
Poniższe cyfry odpowiadają wersji w jednakowej skali (26 bajtów).
Powyższy kod tworzy 9-tą (0-iteracyjną) iterację, czyli dziesiąty obraz w wyzwaniu:
W przypadku innych wartości zmień
9
kod lub zastąp go,i
aby przyjąć liczbę jako dane wprowadzane przez użytkownika. Na przykład wynikiem13
jest:Wyjaśnienie
Korzysta z pętli, aby stopniowo budować tablicę kroków, po których następuje krzywa w płaszczyźnie złożonej. Na przykład pierwsze dwa kroki to
1j
(w górę) i-1
(w lewo).W każdej iteracji kopiowany jest dotychczasowy zestaw kroków. Kopia tablicy jest odwrócona , pomnożona przez
1j
(aby obrócić o 90 stopni) i połączona z oryginałem.Po pętli skumulowana suma kroków daje rzeczywiste punkty, które są następnie wykreślane w płaszczyźnie zespolonej.
źródło
Matematyka 86 bajtów
Jak to działa:
{1,-1}
Wyjścia{1,-1}
. Zasadniczo „wypycha go na stos”. Tę wartość można przywołać za pomocą%
.r=Reverse
w zasadzie po prostu zmienia nazwę funkcji Reverse, ponieważ używam jej dwukrotnie w kodzie. PoGraphics@Line@
prostu pobiera listę punktów i rysuje linię łączącą je. Prawdziwe mięso problemu dzieje się w tym segmencie kodu:Nest[Join[l=Last@#;h=#-l&/@#,r[r@#%&/@h]]&,{{0,0},%},9]
. Powiedz mi - ten segment jest skomplikowany, jak cholera. Oto, coNest
robi:Nest[f,x,9]
wyświetla wynik wywołaniaf[f[f[f[f[f[f[f[f[x]]]]]]]]]
.W moim kodzie ten pierwszy argument
f
to:Join[l=Last@#;h=#-l&/@#,r[r@#%&/@h]]&
drugi argumentx
to{{0,0},%}
(który ocenia{{0,0},{1,-1}}
), a trzeci argumentn
to tylko 9 (co po prostu zastosuje pierwszy argument do drugiego argumentu 9 razy).Najbardziej złożoną częścią tego wszystkiego jest ten pierwszy argument:
Join[l=Last@#;h=#-l&/@#,r[r@#%&/@h]]&
gigantyczny bałagan prawie czystego cukru syntaktycznego. Byłem naprawdę nadużywanie cukru składniowej Mathematica dla tego jednego. Ten wiersz kodu reprezentuje wersję matematyczną anonimowej funkcji, poza tym, że w skrócie zdefiniowałem dwie osobne anonimowe funkcje w ramach tej anonimowej funkcji. Tak, to legalne, ludzie. Rozbijmy to.Join
bierze dwa argumenty. Pierwszym jestl=Last@#;h=#-l&/@#
, a drugim jestr[r@#%&/@h]
.Pierwszym argumentem funkcji Join: Inside „main” anonimowej funkcji
#
jest lista wszystkich punktów na bieżącej iteracji na krzywej.l=Last@#;
Oznacza to więc: „Weź punkt z listy punktów, które otrzymałeś jako dane wejściowe, i przypisz ten punkt do zmiennejl
. Następny segmenth=#-l&/@#
jest nieco bardziej złożony. Oznacza to, że„ masz funkcję. Ta funkcja pobiera punkt na wejściu, odejmujel
od niego i zwraca wynik. Teraz zastosuj tę funkcję do każdego elementu na liście punktów, które otrzymałeś jako dane wejściowe, aby wygenerować listę przesuniętych punktów i przypisz tę nową listę do zmiennejh
.Drugi argument Join:
r[r@#%&/@h]
ma dosłownie najbardziej złożoną składnię, jaką kiedykolwiek napisałem. Nie mogę uwierzyć, że jakikolwiek segment kodu może zawierać coś takiego@#%&/@
- wygląda na to, że przeklinam jak postać z kreskówki w środku programu! Ale można to zepsuć. Pamiętaj -r[x]
pobiera listę punktów i zwraca tę listę w odwrotnej kolejności.r@#%&
to anonimowa funkcja, która odwraca dane wejściowe, a następnie mnoży je przez wartość przechowywaną w%
(która jest{1,-1}
) i zwraca wynik. Zasadniczo obraca wejście o 90 stopni, ale w kodzie tak krótkim, jak to tylko możliwe. Następnier@#%&/@h
oznacza „wyjście nowa lista, która jest każdy punkt wh
obrócony o 90 stopni.”Ogólnie rzecz biorąc,
Join[l=Last@#;h=#-l&/@#,r[r@#*%&/@h]]&
jest funkcją, która pobiera listę punktów jako dane wejściowe i dodaje tę samą listę punktów obróconych o 90 stopni, aby uzyskać następną iterację krzywej. Jest to powtarzane 9 razy, aby uzyskać krzywą smoka. Następnie wynikowa lista punktów jest rysowana na ekranie jako linia. A wynik:źródło
0{,}
... działa, ponieważ0 x
jest0
dla prawie każdegox
i{,}
jest składniowy dla cukru{Null,Null}
.Python 2, 43 bajty
Ta odpowiedź ma 43 bajty, nie licząc instrukcji importu, i jest w dużej mierze oparta na logotypie Level River St oraz wykorzystaniu
i/(i&-i)
ich w kodzie. Wypróbuj online na trinket.ioOto zdjęcie wyniku.
źródło
The shortest code in bytes wins, however include directives for libraries shouldn't be included in the byte count, and you may use graphics libraries or other libraries written for your language of choice if they were written before the posting.
Mathematica,
5655 bajtówObjaśnienie: OEIS A034947
Dla zabawy, oto kolorowa wersja 19. iteracji.
źródło
Mathematica, 63 bajty
Za pomocą
AnglePath
źródło
HTML + JavaScript, 182
źródło
Haskell + diagramy, 179 bajtów
Dane wyjściowe to plik SVG o szerokości 99 pikseli z przezroczystym tłem (obraz o szerokości 9 pikseli miałby obrys zbyt gruby, aby można było cokolwiek rozpoznać). Tutaj jest przeskalowany i skomponowany na białym tle:
źródło
tosh , 518 bajtów
Tosh jest Scratch , ale z tekstem zamiast bloków. Przy 518 bajtach odpowiedź ta jest prawdopodobnie nawet gorsza niż Java.
Ta odpowiedź korzysta z tej samej logiki, co odpowiedź Python @ Theo , ale z ciągami „L” i „R” zamiast liczb, ponieważ możliwości listy Scratcha (a więc i Tosha) są okropne.
Możesz uruchomić go jako projekt Scratch tutaj . (tosh kompiluje się do projektów Scratch)
Wyjaśnienie:
Ta pierwsza część uruchamia program po kliknięciu zielonej flagi (
when flag clicked
), ustawia zmienną ścieżki na „R” i ustawia duszka i scenę w odpowiednim stanie, aby były gotowe do rysowania.Teraz dochodzimy do kodu generowania ścieżki. Wykorzystuje tę samą logikę, co odpowiedź Pythona @ Theo , z wyjątkiem ciągów „R” i „L” zamiast liczb, a zamiast wyrażeń listowych używamy zagnieżdżonych pętli.
Na koniec rysujemy ścieżkę, przechodząc przez każdą literę zmiennej ścieżki i skręcając w lewo lub w prawo w zależności od litery.
źródło