Czasami, kiedy jestem naprawdę znudzony ( naprawdę znudzony), lubię rysować odcinek linii i rysować na nim punkty.
Najpierw rysuję odcinek linii o określonym rozmiarze, który dla pewnej wartości N. wynosi 2 ^ N. Linia będzie reprezentowana przez ciąg .
znaków.
................
Następnie rysuję punkt na lewym końcu. Punkty będą reprezentowane przez X
postacie.
X...............
Następnie podążam za wzorem. Zaczynając od ostatnio narysowanego punktu (który nazywam A), przechodzę do następnego narysowanego punktu (B) na linii (owijając się w razie potrzeby). Następnie przechodzę do następnego wykreślonego punktu na linii (C). Następnie wykreślam nowy punkt w połowie drogi między tym trzecim punktem (C) a następnym już wykreślonym punktem (D).
Ilekroć owijamy się wokół linii, „środek” jest określany w sposób zawijający. Nowo narysowany punkt znajduje się zawsze po prawej stronie C.
Powiedzmy, że następujący wiersz był moją bieżącą linią. Oto, jak wykreśliłbym następne dwa punkty. W tym przykładzie oznaczę każdy ważny punkt literą.
X...A...X.X...X.
^
X...A...B.X...X.
^
X...A...B.C...X.
^
X...A...B.C...D.
^
X...X...X.X.A.X.
^
X...X...X.X.A.B.
^
C...X...X.X.A.B.
^
C...D...X.X.A.B.
^
X.A.X...X.X.X.X.
^
Wracając do poprzedniego przykładu, następny punkt zostanie narysowany na środku linii.
X.......X.......
Być może jest to trochę szczególny przypadek: przejście do następnego punktu po prostu pozostawia początek. Jedynym użytecznym punktem w połowie jest „cykliczny” punkt w połowie (punkt w połowie linii), w przeciwieństwie do kreślenia punktu na sobie.
Poniżej znajduje się seria punktów, które chciałbym narysować na linii od tego miejsca do końca.
X.......X.......
X.......X...X...
X.......X.X.X...
X...X...X.X.X...
X...X...X.XXX...
X.X.X...X.XXX...
X.X.X...XXXXX...
Nie ma już miejsca na wykreślanie następnego punktu, ponieważ musiałby on zostać wciśnięty między dwa sąsiednie punkty, więc osiągnąłem maksymalną głębokość dla podanej wartości N = 4. Ostatni wiersz na powyższej liście jest „ukończony . ”
Wyzwanie
Celem jest napisanie najkrótszego programu / nazwanej funkcji, która wypisze / zwróci wypełniony wiersz dla danej wartości N. Powyższe pokazuje N = 4.
Wejście
Wejście będzie pojedynczą nieujemną liczbą całkowitą N. Długość wygenerowanej linii wyniesie wówczas 2 ^ N.
Wynik
Wyjście będzie zakończoną linią o długości 2 ^ N, utworzoną przez .
i X
znaki. Końcowy znak nowej linii nie ma znaczenia.
Przykład I / O
0
X
1
XX
2
X.XX
3
X.X.XXX.
4
X.X.X...XXXXX...
5
X.X.X...X...X...X.XXX.XXX.......
(c%b+b)%b
? Czy spodziewaszc
się być negatywny?c=0
id=0
można je skrócić do sprawiedliwegoc
id
.int
typy zdefiniowane na poziomie klasy są automatycznie inicjowane na 0.Haskell, 182 bajty
Zastosowanie:
f 5
. Wyjście:X.X.X...X...X...X.XXX.XXX.......
.Niestety Haskell nie ma funkcji scalania w standardowych bibliotekach, więc muszę podać własną (->
%
). Na szczęście muszę scalać tylko nieskończone listy, więc nie muszę obejmować podstawowych przypadków, tj. Pustych list. Nadal kosztuje 40 bajtów.Jak to działa: zamiast ustawiać
X
s bezpośrednio w tablicy, trzymam listę pozycji, w których się znajdują. Co więcej, nie owijam się w,2^N
ale ciągle zwiększam pozycje w kierunku nieskończoności (np. Dla N = 2 ze znakiemX
z przodu wygląda lista pozycji[0,4,8,12,16,20,…]
). Biorę trzeci i czwarty element (c
id
), obliczam nową pozycję(c+d)/2
, zachowuję ją dla listy wyników, łączę starą listę pozycji od pozycji 4 (thed
) z nową, zaczynając od(c+d)/2
i powtarzając. Zatrzymuję się, kiedy się(c+d)/2
równac
. Na koniec dodaję a0
do listy wyników i drukujęX
w podanych pozycjach i.
gdzie indziej.źródło
Mathematica,
110102112108źródło