Możesz napisać program lub funkcję, która otrzyma nieparzystą, dodatnią liczbę całkowitą n
, gdzie n >= 3
jako argument funkcji, argument wiersza poleceń lub na STDIN (lub odpowiedniku dla twojego systemu) i wypisze na STDOUT (lub odpowiedniku systemu) spiralę ASCII która obraca się do wewnątrz zgodnie z ruchem wskazówek zegara, gdzie górna krawędź ma dokładnie n
długość znaków. n+1
Oczywiście pierwsza prawa krawędź powinna być długa. Na przykład,
Wejście:
11
Wynik:
***********
*
********* *
* * *
* ***** * *
* * * * *
* * * * * *
* * *** * *
* * * *
* ******* *
* *
***********
Połowy:
- Twój program nie może wykorzystywać więcej niż
O(log n)
pamięć . - Twój program może drukować tylko znaki
*
(ASCII 42),(ASCII 32),
<CR>
(ASCII 13) i<LF>
(ASCII 10). - Twój program musi wydrukować ciąg, a nie zwrócić go z funkcji.
- Ograniczenie Big-O dotyczy tylko pamięci , nie ma żadnych ograniczeń dotyczących czasu wykonywania .
- Końcowy znak nowej linii jest opcjonalny.
- Jeśli twój język nie obsługuje dużych typów liczb całkowitych, nie musisz obsługiwać wyższych wartości niż obsługuje, ale nie możesz użyć tego jako sztuczki, by powiedzieć „och, cóż, nie muszę obsługiwać powyżej X, więc może po prostu stworzyć ogromną tablicę o maksymalnym rozmiarze za każdym razem ”
Standardowe luki są jak zwykle zakazane.
n
w pamięci O (1).n
wymagalog n
bitów. Wraz ze wzrostemn
zwiększa się również przestrzeń potrzebna do przechowywania. Czy może mówisz o tym z ograniczoną liczbą zmiennych?n
?Odpowiedzi:
C,
125121 bajtówWersja golfowa To nie ma zmiennej
k
. Zmiennak
jest używana w wersji bez golfa, aby poprawić czytelność.for
Zmieniono również warunki warunkowe pętli i{}
usunięto jeden zestaw niepotrzebnych . Kolejny zestaw{}
można usunąć, migrującputs("")
wewnątrz nawiasówj
pętli w pozycji inicjalizacji, ale oznaczałoby to nowy wiersz na początku danych wyjściowych, więc tego nie zrobiłem.Drukuje
n
szeroką przezn+1
wysoką spiralę jak na przykładzie.Wyjaśnienie
Zasadniczo połowę wartości
n
(zaokrąglając w dół) i uruchomić dwie pętle: zewnętrzną jednegoi
z-n/2-1
don/2+1
drukowania wierszy (i=0
jest tłumione dzięki czemu otrzymujemyn+1
wiersze) i wewnętrzną jednegoj
z (-n/2
don/2
Używamy wydrukować znaki).expression & 1
Drukować paski , oraz warunekj*j<i*i
decydujący o tym, czy wydrukować pionowe czy poziome paski (pionowe po bokach, gdzie bezwzględna wielkośći
jest większa, i poziome u góry i na dole). Konieczne+n
jest dostosowanie, aby pomóc w prawidłowym zakończeniu w zależności od tego, czyn/2
jest nieparzysty, czy parzysty.k
wynosi zwykle 1 i zapewnia korektę faktu, że wartości bezwzględnei
mieszczą się w zakresie od 1 do,n/2+1
natomiast wartości bezwzględnej
mieszczą się w zakresie od 0 don/2
. Gdybyk
zawsze było 1, otrzymalibyśmy koncentryczne prostokąty, ale jest on odwracany do 0, gdyi==j&i<=0
tak, że przekątny rząd komórek jest odwrócony, tworząc spiralę.nie wziął udziału w programie testowym
Wynik
źródło
C, 118 bajtów
Kod przed końcowym golfem:
Kluczową obserwacją jest to, że wzór jest prawie serią koncentrycznych kwadratów. Z kilkoma drobnymi zmarszczkami:
y = x + 1
przekątnej należy odwrócić do środka kształtu.Poza tym kod po prostu zapętla wszystkie pozycje, oblicza odległość Czebyszewa od środka dla każdej pozycji i emituje jeden z dwóch znaków w zależności od tego, czy odległość jest parzysta czy nieparzysta. I emitowanie nowego wiersza dla ostatniej pozycji każdej linii.
Ponieważ istnieje tylko kilka zmiennych skalarnych, a znaki są emitowane jeden po drugim, użycie pamięci jest oczywiście stałe.
źródło
p
, myślę, że popełnisz błąd w meta.codegolf.stackexchange.com/q/4939/15599 . Nie jestem również pewien, czy deklarować zmienne globalne podczas przesyłania funkcji. Oczywiście, gdybym to zrobił, moja odpowiedź byłaby o 4 bajty krótsza. Założyłemp
.C ++, 926 bajtów
To nie jest eleganckie, ale nie zajmuje dużo pamięci dla dużej liczby n. Ponadto istnieje (prawie na pewno) około 20 postaci, które można dalej grać w golfa, ale nie mogę już dłużej na to patrzeć.
Krótkie wyjaśnienie:
To dzieli linie w spiralach na dwa typy: te z ****** pośrodku i te z \ s \ s \ s \ s \ s w środku. Wtedy jasne jest, że każda linia składa się z kilku „*”, środka i niektórych „*”. Dokładne ustalenie, ile z każdej rzeczy jest proste, jeśli spojrzysz na wzór wystarczająco długo. Trudną rzeczą było wydrukowanie środka spirali, który właściwie zakodowałem na stałe za pomocą warunkowego. Okazało się to przydatne, ponieważ linie *** i \ s \ s \ s przełączają się na nieparzyste / nawet tam.
Testy:
Wejście:
55
(Myślę, że te duże wyglądają najfajniej)Wynik:
Wejście:
3
Wynik:
Uwaga: nie jestem informatykiem / studentem CS i nie wiem, jak udowodnić, że używa to pamięci O (log n). Mogę tylko ustalić, co zrobić na podstawie linków w pytaniu. Byłbym wdzięczny, gdyby ktoś mógł potwierdzić / zaprzeczyć, jeśli ta odpowiedź jest prawidłowa. Moją logiką dla ważności tej odpowiedzi jest to, że nigdy nie przechowuje żadnej zmiennej wielkości opartej na n, z wyjątkiem samego wejścia. Zamiast tego pętla for, która działa n razy, oblicza wartości całkowite na podstawie n. Istnieje taka sama liczba tych wartości, niezależnie od danych wejściowych.
Uwaga 2: To nie działa dla n = 1 z powodu mojej metody radzenia sobie ze środkiem. Łatwo byłoby to naprawić za pomocą warunkowych, więc jeśli ktoś znajdzie się w odległości kilku znaków od mojej odpowiedzi, naprawię to;)
Graj z nim na ideone.
źródło
n
. Typowym przykładem, który nie spełnia tego wymagania, byłby jakiś ciąg / bufor / tablica, która zawiera pełną linię danych wyjściowych.n=1
, ponieważ nie uważam takiej specjalnej obudowy za interesującą.Haskell, 151 bajtów
Przykład użycia:
Dzięki lenistwu Haskella działa to w stałej pamięci. Wykorzystuje oczywiste podejście, czyli zapętlenie nad
y
ix
, a wybór między*
i, w zależności od
x
odpowiednioy
jest parzysty lub nieparzystyn/2
jest parzysty lub nieparzystyźródło
Common Lisp - 346
Iteracyjne rozwiązanie ze stałym zużyciem pamięci. Powyższe powoduje intensywne wykorzystanie zmiennych
#n=
i#n#
czytników. Chociaż istnieją bardziej bezpośrednie podejścia, tutaj zacząłem od funkcji rekurencyjnej i zmodyfikowałem ją tak, aby symulowała rekurencję za pomocągoto
instrukcji: jest to prawdopodobnie nieczytelne.Wyjście dla wszystkich wartości wejściowych od 0 do 59 .
Oryginalna wersja rekurencyjna z informacjami o debugowaniu
(uwaga:
terpri
oznaczanewline
)Na przykład:
Zobacz także tę pastę ze wszystkimi wynikami od 0 do 59 (to nie to samo co powyżej, ta jest bardziej szczegółowa).
Wersja iteracyjna z informacjami debugowania
źródło
n
a stos wywołań odpowiednio rośnie, ale w tym przypadku możemy symulować rekurencję za pomocą dwóch pętli: jednej zn
malejącą id
rosnącą (aż n <= 3 ) i kolejna zd
malejącą do zera. Nie mam teraz dużo czasu, aby nad tym popracować, ale postaram się odpowiednio zaktualizować odpowiedź. Przy okazji, istnieją bardziej bezpośrednie sposoby drukowania spirali, ale fajnie było próbować zdefiniować ją rekurencyjnie.CJam, 72 bajty
Jest to dość bezpośrednia konwersja mojego rozwiązania C do CJam. Nie tak krótki, jak zwykle można oczekiwać od rozwiązania CJam, ale ten naprawdę cierpi z powodu ograniczenia pamięci. Wspólne zalety tworzenia wyników na stosie, który jest automatycznie zrzucany na końcu, i korzystania z fantazyjnych operacji na listach / ciągach, wszystko to wychodzi poza okno. To generuje i wysyła rozwiązanie po jednym znaku na raz. Stos zawiera tylko kilka liczb całkowitych w czasie wykonywania i jest pusty na końcu.
Mimo że nie jest to świetny sposób wyświetlania języka golfowego, jest on znacznie krótszy niż kod C tylko dlatego, że notacja jest bardziej zwarta.
Wyjaśnienie:
źródło